Skip to content

Commit 5d7a0b8

Browse files
committed
Merge remote-tracking branch 'upstream/master' into dataflow-ref-parameter
I've accepted the new test output, which shows that this branch fixes two false negatives in the test cases from #2088.
2 parents 19f642f + 24a5301 commit 5d7a0b8

File tree

147 files changed

+10746
-4267
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

147 files changed

+10746
-4267
lines changed

change-notes/1.23/analysis-csharp.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ The following changes in version 1.23 affect C# analysis in all applications.
1616
| **Query** | **Expected impact** | **Change** |
1717
|------------------------------|------------------------|-----------------------------------|
1818
| Dereferenced variable may be null (`cs/dereferenced-value-may-be-null`) | Fewer false positive results | More `null` checks are now taken into account, including `null` checks for `dynamic` expressions and `null` checks such as `object alwaysNull = null; if (x != alwaysNull) ...`. |
19+
| Missing Dispose call on local IDisposable (`cs/local-not-disposed`) | Fewer false positive results | The query has been rewritten in order to identify more dispose patterns. For example, a local `IDisposable` that is disposed of by passing through a fluent API is no longer reported. |
1920

2021
## Removal of old queries
2122

@@ -38,5 +39,6 @@ The following changes in version 1.23 affect C# analysis in all applications.
3839
disabled by default and can be enabled for individual configurations by
3940
overriding `int explorationLimit()`.
4041
* `foreach` statements where the body is guaranteed to be executed at least once, such as `foreach (var x in new string[]{ "a", "b", "c" }) { ... }`, are now recognized by all analyses based on the control flow graph (such as SSA, data flow and taint tracking).
42+
* Fixed the control flow graph for `switch` statements where the `default` case was not the last case. This had caused the remaining cases to be unreachable. `SwitchStmt.getCase(int i)` now puts the `default` case last.
4143

4244
## Changes to autobuilder

change-notes/1.23/analysis-java.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ The following changes in version 1.23 affect Java analysis in all applications.
66

77
| **Query** | **Expected impact** | **Change** |
88
|------------------------------|------------------------|-----------------------------------|
9+
| Dereferenced variable may be null (`java/dereferenced-value-may-be-null`) | Fewer false positives | Certain indirect null guards involving two auxiliary variables known to be equal can now be detected. |
910
| Query built from user-controlled sources (`java/sql-injection`) | More results | The query now identifies arguments to `Statement.executeLargeUpdate` and `Connection.prepareCall` as SQL expressions sinks. |
1011
| Query built from local-user-controlled sources (`java/sql-injection-local`) | More results | The query now identifies arguments to `Statement.executeLargeUpdate` and `Connection.prepareCall` as SQL expressions sinks. |
1112
| Query built without neutralizing special characters (`java/concatenated-sql-query`) | More results | The query now identifies arguments to `Statement.executeLargeUpdate` and `Connection.prepareCall` as SQL expressions sinks. |

change-notes/1.23/analysis-javascript.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
|---------------------------------------------------------------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
1717
| Unused index variable (`js/unused-index-variable`) | correctness | Highlights loops that iterate over an array, but do not use the index variable to access array elements, indicating a possible typo or logic error. Results are shown on LGTM by default. |
1818
| Loop bound injection (`js/loop-bound-injection`) | security, external/cwe/cwe-834 | Highlights loops where a user-controlled object with an arbitrary .length value can trick the server to loop indefinitely. Results are not shown on LGTM by default. |
19+
| Suspicious method name (`js/suspicious-method-name-declaration`) | correctness, typescript, methods | Highlights suspiciously named methods where the developer likely meant to write a constructor or function. Results are shown on LGTM by default. |
1920

2021
## Changes to existing queries
2122

change-notes/1.23/analysis-python.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111
|-----------|----------|-------------|
1212
| Clear-text logging of sensitive information (`py/clear-text-logging-sensitive-data`) | security, external/cwe/cwe-312 | Finds instances where sensitive information is logged without encryption or hashing. Results are shown on LGTM by default. |
1313
| Clear-text storage of sensitive information (`py/clear-text-storage-sensitive-data`) | security, external/cwe/cwe-312 | Finds instances where sensitive information is stored without encryption or hashing. Results are shown on LGTM by default. |
14-
14+
| Binding a socket to all network interfaces (`py/bind-socket-all-network-interfaces`) | security | Finds instances where a socket is bound to all network interfaces. Results are shown on LGTM by default. |

cpp/ql/src/Likely Bugs/Leap Year/LeapYear.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ private predicate additionalLogicalCheck(Expr e, string operation, int valueToCh
3030
/**
3131
* An `Operation` that seems to be checking for leap year.
3232
*/
33-
class CheckForLeapYearOperation extends Operation {
33+
class CheckForLeapYearOperation extends Expr {
3434
CheckForLeapYearOperation() {
3535
exists(BinaryArithmeticOperation bo | bo = this |
3636
bo.getAnOperand().getValue().toInt() = 4 and
@@ -39,8 +39,6 @@ class CheckForLeapYearOperation extends Operation {
3939
additionalLogicalCheck(this.getEnclosingElement(), "%", 400)
4040
)
4141
}
42-
43-
override string getOperator() { result = "LeapYearCheck" }
4442
}
4543

4644
/**

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* on each other without introducing mutual recursion among those configurations.
88
*/
99

10-
private import DataFlowImplCommon
10+
private import DataFlowImplCommon::Public
1111
private import DataFlowImplSpecific::Private
1212
import DataFlowImplSpecific::Public
1313

@@ -1075,6 +1075,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
10751075
flowCandFwd(mid, fromArg, _, config) and
10761076
store(mid, f, node) and
10771077
nodeCand(node, unbind(config)) and
1078+
readStoreCand(f, unbind(config)) and
10781079
apf.headUsesContent(f)
10791080
)
10801081
or
@@ -1175,12 +1176,12 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
11751176
exists(Content f, AccessPathFront apf0 |
11761177
flowCandStore(node, f, toReturn, apf0, config) and
11771178
apf0.headUsesContent(f) and
1178-
consCand(f, apf, unbind(config))
1179+
consCand(f, apf, config)
11791180
)
11801181
or
11811182
exists(Content f, AccessPathFront apf0 |
11821183
flowCandRead(node, f, toReturn, apf0, config) and
1183-
consCandFwd(f, apf0, unbind(config)) and
1184+
consCandFwd(f, apf0, config) and
11841185
apf.headUsesContent(f)
11851186
)
11861187
}
@@ -1221,8 +1222,8 @@ private newtype TAccessPath =
12211222
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
12221223

12231224
/**
1224-
* Conceptually a list of `Content`s followed by a `Type`, but only the first
1225-
* element of the list and its length are tracked. If data flows from a source to
1225+
* Conceptually a list of `Content`s followed by a `Type`, but only the first two
1226+
* elements of the list and its length are tracked. If data flows from a source to
12261227
* a given node with a given `AccessPath`, this indicates the sequence of
12271228
* dereference operations needed to get from the value in the node to the
12281229
* tracked object. The final type indicates the type of the tracked object.
@@ -1260,7 +1261,7 @@ abstract private class AccessPath extends TAccessPath {
12601261

12611262
private class AccessPathNil extends AccessPath, TNil {
12621263
override string toString() {
1263-
exists(DataFlowType t | this = TNil(t) | result = concat(" : " + ppReprType(t)))
1264+
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
12641265
}
12651266

12661267
override AccessPathFront getFront() {
@@ -1276,7 +1277,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
12761277
override string toString() {
12771278
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
12781279
// The `concat` becomes "" if `ppReprType` has no result.
1279-
result = f.toString() + concat(" : " + ppReprType(t))
1280+
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
12801281
)
12811282
}
12821283

@@ -1293,8 +1294,8 @@ private class AccessPathConsCons extends AccessPathCons, TConsCons {
12931294
override string toString() {
12941295
exists(Content f1, Content f2, int len | this = TConsCons(f1, f2, len) |
12951296
if len = 2
1296-
then result = f1.toString() + ", " + f2.toString()
1297-
else result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
1297+
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
1298+
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
12981299
)
12991300
}
13001301

@@ -1625,7 +1626,7 @@ abstract class PathNode extends TPathNode {
16251626
this instanceof PathNodeSink and result = ""
16261627
or
16271628
exists(string s | s = this.(PathNodeMid).getAp().toString() |
1628-
if s = "" then result = "" else result = " [" + s + "]"
1629+
if s = "" then result = "" else result = " " + s
16291630
)
16301631
}
16311632

@@ -2070,7 +2071,7 @@ private module FlowExploration {
20702071

20712072
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
20722073
override string toString() {
2073-
exists(DataFlowType t | this = TPartialNil(t) | result = concat(" : " + ppReprType(t)))
2074+
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
20742075
}
20752076

20762077
override AccessPathFront getFront() {
@@ -2082,8 +2083,8 @@ private module FlowExploration {
20822083
override string toString() {
20832084
exists(Content f, int len | this = TPartialCons(f, len) |
20842085
if len = 1
2085-
then result = f.toString()
2086-
else result = f.toString() + ", ... (" + len.toString() + ")"
2086+
then result = "[" + f.toString() + "]"
2087+
else result = "[" + f.toString() + ", ... (" + len.toString() + ")]"
20872088
)
20882089
}
20892090

@@ -2160,7 +2161,7 @@ private module FlowExploration {
21602161

21612162
private string ppAp() {
21622163
exists(string s | s = this.(PartialPathNodePriv).getAp().toString() |
2163-
if s = "" then result = "" else result = " [" + s + "]"
2164+
if s = "" then result = "" else result = " " + s
21642165
)
21652166
}
21662167

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* on each other without introducing mutual recursion among those configurations.
88
*/
99

10-
private import DataFlowImplCommon
10+
private import DataFlowImplCommon::Public
1111
private import DataFlowImplSpecific::Private
1212
import DataFlowImplSpecific::Public
1313

@@ -1075,6 +1075,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
10751075
flowCandFwd(mid, fromArg, _, config) and
10761076
store(mid, f, node) and
10771077
nodeCand(node, unbind(config)) and
1078+
readStoreCand(f, unbind(config)) and
10781079
apf.headUsesContent(f)
10791080
)
10801081
or
@@ -1175,12 +1176,12 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
11751176
exists(Content f, AccessPathFront apf0 |
11761177
flowCandStore(node, f, toReturn, apf0, config) and
11771178
apf0.headUsesContent(f) and
1178-
consCand(f, apf, unbind(config))
1179+
consCand(f, apf, config)
11791180
)
11801181
or
11811182
exists(Content f, AccessPathFront apf0 |
11821183
flowCandRead(node, f, toReturn, apf0, config) and
1183-
consCandFwd(f, apf0, unbind(config)) and
1184+
consCandFwd(f, apf0, config) and
11841185
apf.headUsesContent(f)
11851186
)
11861187
}
@@ -1221,8 +1222,8 @@ private newtype TAccessPath =
12211222
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
12221223

12231224
/**
1224-
* Conceptually a list of `Content`s followed by a `Type`, but only the first
1225-
* element of the list and its length are tracked. If data flows from a source to
1225+
* Conceptually a list of `Content`s followed by a `Type`, but only the first two
1226+
* elements of the list and its length are tracked. If data flows from a source to
12261227
* a given node with a given `AccessPath`, this indicates the sequence of
12271228
* dereference operations needed to get from the value in the node to the
12281229
* tracked object. The final type indicates the type of the tracked object.
@@ -1260,7 +1261,7 @@ abstract private class AccessPath extends TAccessPath {
12601261

12611262
private class AccessPathNil extends AccessPath, TNil {
12621263
override string toString() {
1263-
exists(DataFlowType t | this = TNil(t) | result = concat(" : " + ppReprType(t)))
1264+
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
12641265
}
12651266

12661267
override AccessPathFront getFront() {
@@ -1276,7 +1277,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
12761277
override string toString() {
12771278
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
12781279
// The `concat` becomes "" if `ppReprType` has no result.
1279-
result = f.toString() + concat(" : " + ppReprType(t))
1280+
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
12801281
)
12811282
}
12821283

@@ -1293,8 +1294,8 @@ private class AccessPathConsCons extends AccessPathCons, TConsCons {
12931294
override string toString() {
12941295
exists(Content f1, Content f2, int len | this = TConsCons(f1, f2, len) |
12951296
if len = 2
1296-
then result = f1.toString() + ", " + f2.toString()
1297-
else result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
1297+
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
1298+
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
12981299
)
12991300
}
13001301

@@ -1625,7 +1626,7 @@ abstract class PathNode extends TPathNode {
16251626
this instanceof PathNodeSink and result = ""
16261627
or
16271628
exists(string s | s = this.(PathNodeMid).getAp().toString() |
1628-
if s = "" then result = "" else result = " [" + s + "]"
1629+
if s = "" then result = "" else result = " " + s
16291630
)
16301631
}
16311632

@@ -2070,7 +2071,7 @@ private module FlowExploration {
20702071

20712072
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
20722073
override string toString() {
2073-
exists(DataFlowType t | this = TPartialNil(t) | result = concat(" : " + ppReprType(t)))
2074+
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
20742075
}
20752076

20762077
override AccessPathFront getFront() {
@@ -2082,8 +2083,8 @@ private module FlowExploration {
20822083
override string toString() {
20832084
exists(Content f, int len | this = TPartialCons(f, len) |
20842085
if len = 1
2085-
then result = f.toString()
2086-
else result = f.toString() + ", ... (" + len.toString() + ")"
2086+
then result = "[" + f.toString() + "]"
2087+
else result = "[" + f.toString() + ", ... (" + len.toString() + ")]"
20872088
)
20882089
}
20892090

@@ -2160,7 +2161,7 @@ private module FlowExploration {
21602161

21612162
private string ppAp() {
21622163
exists(string s | s = this.(PartialPathNodePriv).getAp().toString() |
2163-
if s = "" then result = "" else result = " [" + s + "]"
2164+
if s = "" then result = "" else result = " " + s
21642165
)
21652166
}
21662167

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* on each other without introducing mutual recursion among those configurations.
88
*/
99

10-
private import DataFlowImplCommon
10+
private import DataFlowImplCommon::Public
1111
private import DataFlowImplSpecific::Private
1212
import DataFlowImplSpecific::Public
1313

@@ -1075,6 +1075,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
10751075
flowCandFwd(mid, fromArg, _, config) and
10761076
store(mid, f, node) and
10771077
nodeCand(node, unbind(config)) and
1078+
readStoreCand(f, unbind(config)) and
10781079
apf.headUsesContent(f)
10791080
)
10801081
or
@@ -1175,12 +1176,12 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
11751176
exists(Content f, AccessPathFront apf0 |
11761177
flowCandStore(node, f, toReturn, apf0, config) and
11771178
apf0.headUsesContent(f) and
1178-
consCand(f, apf, unbind(config))
1179+
consCand(f, apf, config)
11791180
)
11801181
or
11811182
exists(Content f, AccessPathFront apf0 |
11821183
flowCandRead(node, f, toReturn, apf0, config) and
1183-
consCandFwd(f, apf0, unbind(config)) and
1184+
consCandFwd(f, apf0, config) and
11841185
apf.headUsesContent(f)
11851186
)
11861187
}
@@ -1221,8 +1222,8 @@ private newtype TAccessPath =
12211222
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
12221223

12231224
/**
1224-
* Conceptually a list of `Content`s followed by a `Type`, but only the first
1225-
* element of the list and its length are tracked. If data flows from a source to
1225+
* Conceptually a list of `Content`s followed by a `Type`, but only the first two
1226+
* elements of the list and its length are tracked. If data flows from a source to
12261227
* a given node with a given `AccessPath`, this indicates the sequence of
12271228
* dereference operations needed to get from the value in the node to the
12281229
* tracked object. The final type indicates the type of the tracked object.
@@ -1260,7 +1261,7 @@ abstract private class AccessPath extends TAccessPath {
12601261

12611262
private class AccessPathNil extends AccessPath, TNil {
12621263
override string toString() {
1263-
exists(DataFlowType t | this = TNil(t) | result = concat(" : " + ppReprType(t)))
1264+
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
12641265
}
12651266

12661267
override AccessPathFront getFront() {
@@ -1276,7 +1277,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
12761277
override string toString() {
12771278
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
12781279
// The `concat` becomes "" if `ppReprType` has no result.
1279-
result = f.toString() + concat(" : " + ppReprType(t))
1280+
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
12801281
)
12811282
}
12821283

@@ -1293,8 +1294,8 @@ private class AccessPathConsCons extends AccessPathCons, TConsCons {
12931294
override string toString() {
12941295
exists(Content f1, Content f2, int len | this = TConsCons(f1, f2, len) |
12951296
if len = 2
1296-
then result = f1.toString() + ", " + f2.toString()
1297-
else result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
1297+
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
1298+
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
12981299
)
12991300
}
13001301

@@ -1625,7 +1626,7 @@ abstract class PathNode extends TPathNode {
16251626
this instanceof PathNodeSink and result = ""
16261627
or
16271628
exists(string s | s = this.(PathNodeMid).getAp().toString() |
1628-
if s = "" then result = "" else result = " [" + s + "]"
1629+
if s = "" then result = "" else result = " " + s
16291630
)
16301631
}
16311632

@@ -2070,7 +2071,7 @@ private module FlowExploration {
20702071

20712072
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
20722073
override string toString() {
2073-
exists(DataFlowType t | this = TPartialNil(t) | result = concat(" : " + ppReprType(t)))
2074+
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
20742075
}
20752076

20762077
override AccessPathFront getFront() {
@@ -2082,8 +2083,8 @@ private module FlowExploration {
20822083
override string toString() {
20832084
exists(Content f, int len | this = TPartialCons(f, len) |
20842085
if len = 1
2085-
then result = f.toString()
2086-
else result = f.toString() + ", ... (" + len.toString() + ")"
2086+
then result = "[" + f.toString() + "]"
2087+
else result = "[" + f.toString() + ", ... (" + len.toString() + ")]"
20872088
)
20882089
}
20892090

@@ -2160,7 +2161,7 @@ private module FlowExploration {
21602161

21612162
private string ppAp() {
21622163
exists(string s | s = this.(PartialPathNodePriv).getAp().toString() |
2163-
if s = "" then result = "" else result = " [" + s + "]"
2164+
if s = "" then result = "" else result = " " + s
21642165
)
21652166
}
21662167

0 commit comments

Comments
 (0)