Skip to content

Commit 74ee101

Browse files
committed
Extend Constant Condition query with String.IsNullOrEmpty.
1 parent 265838a commit 74ee101

File tree

4 files changed

+93
-0
lines changed

4 files changed

+93
-0
lines changed

csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import csharp
1616
import semmle.code.csharp.commons.Assertions
1717
import semmle.code.csharp.commons.Constants
18+
private import semmle.code.csharp.frameworks.System
1819

1920
/** A constant condition. */
2021
abstract class ConstantCondition extends Expr {
@@ -72,6 +73,30 @@ class ConstantIfCondition extends ConstantBooleanCondition {
7273
}
7374
}
7475

76+
/** A constant return value from a function with constant input expression. */
77+
class ConstantReturnValueCondition extends ConstantCondition {
78+
boolean b;
79+
80+
ConstantReturnValueCondition() {
81+
exists(Method m, Call c, Expr expr |
82+
m = any(SystemStringClass s).getIsNullOrEmptyMethod() and
83+
c.getTarget() = m and
84+
this = c and
85+
expr = c.getArgument(0) and
86+
expr.hasValue() and
87+
if expr.getValue().length() > 0 and not expr instanceof NullLiteral
88+
then b = false
89+
else b = true
90+
)
91+
}
92+
93+
override string getMessage() {
94+
if b = true
95+
then result = "Expression is always 'true'."
96+
else result = "Expression is always 'false'."
97+
}
98+
}
99+
75100
/** A constant loop condition. */
76101
class ConstantLoopCondition extends ConstantBooleanCondition {
77102
ConstantLoopCondition() { this = any(LoopStmt ls).getCondition() }
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The `Constant Condition` query was extended to catch cases when `String.IsNullOrEmpty` returns a constant value.

csharp/ql/test/query-tests/Bad Practices/Control-Flow/ConstantCondition/ConstantCondition.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
| ConstantIfCondition.cs:11:17:11:29 | ... == ... | Condition always evaluates to 'true'. |
2020
| ConstantIfCondition.cs:14:17:14:21 | false | Condition always evaluates to 'false'. |
2121
| ConstantIfCondition.cs:17:17:17:26 | ... == ... | Condition always evaluates to 'true'. |
22+
| ConstantIsNullOrEmpty.cs:10:21:10:54 | call to method IsNullOrEmpty | Expression is always 'false'. |
23+
| ConstantIsNullOrEmpty.cs:46:21:46:46 | call to method IsNullOrEmpty | Expression is always 'true'. |
24+
| ConstantIsNullOrEmpty.cs:50:21:50:44 | call to method IsNullOrEmpty | Expression is always 'true'. |
25+
| ConstantIsNullOrEmpty.cs:54:21:54:45 | call to method IsNullOrEmpty | Expression is always 'false'. |
2226
| ConstantNullCoalescingLeftHandOperand.cs:11:24:11:34 | access to constant NULL_OBJECT | Expression is never 'null'. |
2327
| ConstantNullCoalescingLeftHandOperand.cs:12:24:12:27 | null | Expression is always 'null'. |
2428
| ConstantWhileCondition.cs:12:20:12:32 | ... == ... | Condition always evaluates to 'true'. |
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System.Threading.Tasks;
2+
3+
namespace ConstantIsNullOrEmpty
4+
{
5+
internal class Program
6+
{
7+
static void Main(string[] args)
8+
{
9+
{
10+
if (string.IsNullOrEmpty(nameof(args))) // bad: always false
11+
{
12+
}
13+
14+
string? x = null;
15+
if (string.IsNullOrEmpty(x)) // would be nice... bad: always true
16+
{
17+
}
18+
19+
string y = "";
20+
if (string.IsNullOrEmpty(y)) // would be nice... bad: always true
21+
{
22+
}
23+
24+
if (args[1] != null)
25+
y = "b";
26+
if (string.IsNullOrEmpty(y)) // good: non-constant
27+
{
28+
}
29+
30+
string z = " ";
31+
if (string.IsNullOrEmpty(z)) // would be nice... bad: always false
32+
{
33+
}
34+
35+
string a = "a";
36+
if (string.IsNullOrEmpty(a)) // would be nice... bad: always false
37+
{
38+
}
39+
40+
if (args[1] != null)
41+
a = "";
42+
if (string.IsNullOrEmpty(a)) // good: non-constant
43+
{
44+
}
45+
46+
if (string.IsNullOrEmpty(null)) // bad: always true
47+
{
48+
}
49+
50+
if (string.IsNullOrEmpty("")) // bad: always true
51+
{
52+
}
53+
54+
if (string.IsNullOrEmpty(" ")) // bad: always false
55+
{
56+
}
57+
}
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)