Skip to content

Commit 89752f4

Browse files
committed
Merge branch 'master' into python-objectapi-to-valueapi-wrongnumberargumentsincall
2 parents 1d4f341 + 5af351e commit 89752f4

File tree

363 files changed

+12820
-14498
lines changed

Some content is hidden

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

363 files changed

+12820
-14498
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ We welcome contributions to our standard library and standard checks. Do you hav
1313

1414
## License
1515

16-
The code in this repository is licensed under [Apache License 2.0](LICENSE) by [GitHub](https://github.com).
16+
The code in this repository is licensed under the [MIT License](LICENSE) by [GitHub](https://github.com).

change-notes/1.24/analysis-cpp.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
2525
| Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) | | This query is no longer run on LGTM. |
2626
| No space for zero terminator (`cpp/no-space-for-terminator`) | Fewer false positive results | This query has been modified to be more conservative when identifying which pointers point to null-terminated strings. This approach produces fewer, more accurate results. |
2727
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | Fewer false positive results | Cases where the tainted allocation size is range checked are now more reliably excluded. |
28+
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | Fewer false positive results | The query now produces fewer, more accurate results. |
2829
| Overloaded assignment does not return 'this' (`cpp/assignment-does-not-return-this`) | Fewer false positive results | This query no longer reports incorrect results in template classes. |
2930
| Unsafe array for days of the year (`cpp/leap-year/unsafe-array-for-days-of-the-year`) | | This query is no longer run on LGTM. |
3031
| Unsigned comparison to zero (`cpp/unsigned-comparison-zero`) | More correct results | This query now also looks for comparisons of the form `0 <= x`. |
@@ -54,3 +55,4 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
5455
* The library now models data flow through formatting functions such as `sprintf`.
5556
* The security pack taint tracking library (`semmle.code.cpp.security.TaintTracking`) uses a new intermediate representation. This provides a more precise analysis of pointers to stack variables and flow through parameters, improving the results of many security queries.
5657
* The global value numbering library (`semmle.code.cpp.valuenumbering.GlobalValueNumbering`) uses a new intermediate representation to provide a more precise analysis of heap allocated memory and pointers to stack variables.
58+
* `freeCall` in `semmle.code.cpp.commons.Alloc` has been deprecated. The`Allocation` and `Deallocation` models in `semmle.code.cpp.models.interfaces` should be used instead.

change-notes/1.24/analysis-javascript.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
| Useless regular-expression character escape (`js/useless-regexp-character-escape`) | Fewer false positive results | This query now distinguishes escapes in strings and regular expression literals. |
8787
| Identical operands (`js/redundant-operation`) | Fewer results | This query now recognizes cases where the operands change a value using ++/-- expressions. |
8888
| Superfluous trailing arguments (`js/superfluous-trailing-arguments`) | Fewer results | This query now recognizes cases where a function uses the `Function.arguments` value to process a variable number of parameters. |
89-
| Incomplete URL scheme check (`js/incomplete-url-scheme-check`) | More results | This query now recognizes more variations of URL scheme checks. |
89+
| Incomplete URL scheme check (`js/incomplete-url-scheme-check`) | More results | This query now recognizes additional variations of URL scheme checks. |
9090

9191
## Changes to libraries
9292

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Improvements to JavaScript analysis
2+
3+
## General improvements
4+
5+
6+
## New queries
7+
8+
| **Query** | **Tags** | **Purpose** |
9+
|---------------------------------------------------------------------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
10+
11+
12+
## Changes to existing queries
13+
14+
| **Query** | **Expected impact** | **Change** |
15+
|--------------------------------|------------------------------|---------------------------------------------------------------------------|
16+
| Misspelled variable name (`js/misspelled-variable-name`) | Message changed | The message for this query now correctly identifies the misspelled variable in additional cases. |
17+
| Uncontrolled data used in path expression (`js/path-injection`) | More results | This query now recognizes additional file system calls. |
18+
| Uncontrolled command line (`js/command-line-injection`) | More results | This query now recognizes additional command execution calls. |
19+
20+
## Changes to libraries
21+
22+
* Added data flow for `Map` and `Set`, and added matching type-tracking steps that can accessed using the `CollectionsTypeTracking` module.

cpp/ql/src/Critical/FileClosed.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import semmle.code.cpp.pointsto.PointsTo
22

3+
/** Holds if there exists a call to a function that might close the file specified by `e`. */
34
predicate closed(Expr e) {
45
fcloseCall(_, e) or
56
exists(ExprCall c |
@@ -8,10 +9,19 @@ predicate closed(Expr e) {
89
)
910
}
1011

12+
/** An expression for which there exists a function call that might close it. */
1113
class ClosedExpr extends PointsToExpr {
1214
ClosedExpr() { closed(this) }
1315

1416
override predicate interesting() { closed(this) }
1517
}
1618

19+
/**
20+
* Holds if `fc` is a call to a function that opens a file that might be closed. For example:
21+
* ```
22+
* FILE* f = fopen("file.txt", "r");
23+
* ...
24+
* fclose(f);
25+
* ```
26+
*/
1727
predicate fopenCallMayBeClosed(FunctionCall fc) { fopenCall(fc) and anythingPointsTo(fc) }

cpp/ql/src/Critical/LoopBounds.qll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,24 @@
22

33
import cpp
44

5+
/**
6+
* An assignment to a variable with the value `0`. For example:
7+
* ```
8+
* int x;
9+
* x = 0;
10+
* ```
11+
* but not:
12+
* ```
13+
* int x = 0;
14+
* ```
15+
*/
516
class ZeroAssignment extends AssignExpr {
617
ZeroAssignment() {
718
this.getAnOperand() instanceof VariableAccess and
819
this.getAnOperand() instanceof Zero
920
}
1021

22+
/** Gets a variable that is assigned the value `0`. */
1123
Variable assignedVariable() { result.getAnAccess() = this.getAnOperand() }
1224
}
1325

cpp/ql/src/Critical/MemoryFreed.qll

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,24 @@ private predicate freed(Expr e) {
44
e = any(DeallocationExpr de).getFreedExpr()
55
or
66
exists(ExprCall c |
7-
// cautiously assume that any ExprCall could be a freeCall.
7+
// cautiously assume that any `ExprCall` could be a deallocation expression.
88
c.getAnArgument() = e
99
)
1010
}
1111

12+
/** An expression that might be deallocated. */
1213
class FreedExpr extends PointsToExpr {
1314
FreedExpr() { freed(this) }
1415

1516
override predicate interesting() { freed(this) }
1617
}
1718

19+
/**
20+
* An allocation expression that might be deallocated. For example:
21+
* ```
22+
* int* p = new int;
23+
* ...
24+
* delete p;
25+
* ```
26+
*/
1827
predicate allocMayBeFreed(AllocationExpr alloc) { anythingPointsTo(alloc) }

cpp/ql/src/Critical/Negativity.qll

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
import cpp
22

3+
/**
4+
* Holds if `val` is an access to the variable `v`, or if `val`
5+
* is an assignment with an access to `v` on the left-hand side.
6+
*/
37
predicate valueOfVar(Variable v, Expr val) {
48
val = v.getAnAccess() or
59
val.(AssignExpr).getLValue() = v.getAnAccess()
610
}
711

12+
/**
13+
* Holds if either:
14+
* - `cond` is an (in)equality expression that compares the variable `v` to the value `-1`, or
15+
* - `cond` is a relational expression that compares the variable `v` to a constant.
16+
*/
817
predicate boundsCheckExpr(Variable v, Expr cond) {
918
exists(EQExpr eq |
1019
cond = eq and
@@ -43,6 +52,18 @@ predicate boundsCheckExpr(Variable v, Expr cond) {
4352
)
4453
}
4554

55+
/**
56+
* Holds if `node` is an expression in a conditional statement and `succ` is an
57+
* immediate successor of `node` that may be reached after evaluating `node`.
58+
* For example, given
59+
* ```
60+
* if (a < 10 && b) func1();
61+
* else func2();
62+
* ```
63+
* this predicate holds when either:
64+
* - `node` is `a < 10` and `succ` is `func2()` or `b`, or
65+
* - `node` is `b` and `succ` is `func1()` or `func2()`
66+
*/
4667
predicate conditionalSuccessor(ControlFlowNode node, ControlFlowNode succ) {
4768
if node.isCondition()
4869
then succ = node.getATrueSuccessor() or succ = node.getAFalseSuccessor()
@@ -52,6 +73,12 @@ predicate conditionalSuccessor(ControlFlowNode node, ControlFlowNode succ) {
5273
)
5374
}
5475

76+
/**
77+
* Holds if the current value of the variable `v` at control-flow
78+
* node `n` has been used either in:
79+
* - an (in)equality comparison with the value `-1`, or
80+
* - a relational comparison that compares `v` to a constant.
81+
*/
5582
predicate boundsChecked(Variable v, ControlFlowNode node) {
5683
exists(Expr test |
5784
boundsCheckExpr(v, test) and
@@ -63,6 +90,14 @@ predicate boundsChecked(Variable v, ControlFlowNode node) {
6390
)
6491
}
6592

93+
/**
94+
* Holds if `cond` compares `v` to some common error values. Specifically, this
95+
* predicate holds when:
96+
* - `cond` checks that `v` is equal to `-1`, or
97+
* - `cond` checks that `v` is less than `0`, or
98+
* - `cond` checks that `v` is less than or equal to `-1`, or
99+
* - `cond` checks that `v` is not some common success value (see `successCondition`).
100+
*/
66101
predicate errorCondition(Variable v, Expr cond) {
67102
exists(EQExpr eq |
68103
cond = eq and
@@ -88,6 +123,14 @@ predicate errorCondition(Variable v, Expr cond) {
88123
)
89124
}
90125

126+
/**
127+
* Holds if `cond` compares `v` to some common success values. Specifically, this
128+
* predicate holds when:
129+
* - `cond` checks that `v` is not equal to `-1`, or
130+
* - `cond` checks that `v` is greater than or equal than `0`, or
131+
* - `cond` checks that `v` is greater than `-1`, or
132+
* - `cond` checks that `v` is not some common error value (see `errorCondition`).
133+
*/
91134
predicate successCondition(Variable v, Expr cond) {
92135
exists(NEExpr ne |
93136
cond = ne and
@@ -113,6 +156,11 @@ predicate successCondition(Variable v, Expr cond) {
113156
)
114157
}
115158

159+
/**
160+
* Holds if there exists a comparison operation that checks whether `v`
161+
* represents some common *error* values, and `n` may be reached
162+
* immediately following the comparison operation.
163+
*/
116164
predicate errorSuccessor(Variable v, ControlFlowNode n) {
117165
exists(Expr cond |
118166
errorCondition(v, cond) and n = cond.getATrueSuccessor()
@@ -121,6 +169,11 @@ predicate errorSuccessor(Variable v, ControlFlowNode n) {
121169
)
122170
}
123171

172+
/**
173+
* Holds if there exists a comparison operation that checks whether `v`
174+
* represents some common *success* values, and `n` may be reached
175+
* immediately following the comparison operation.
176+
*/
124177
predicate successSuccessor(Variable v, ControlFlowNode n) {
125178
exists(Expr cond |
126179
successCondition(v, cond) and n = cond.getATrueSuccessor()
@@ -129,6 +182,10 @@ predicate successSuccessor(Variable v, ControlFlowNode n) {
129182
)
130183
}
131184

185+
/**
186+
* Holds if the current value of the variable `v` at control-flow node
187+
* `n` may have been checked against a common set of *error* values.
188+
*/
132189
predicate checkedError(Variable v, ControlFlowNode n) {
133190
errorSuccessor(v, n)
134191
or
@@ -139,6 +196,10 @@ predicate checkedError(Variable v, ControlFlowNode n) {
139196
)
140197
}
141198

199+
/**
200+
* Holds if the current value of the variable `v` at control-flow node
201+
* `n` may have been checked against a common set of *success* values.
202+
*/
142203
predicate checkedSuccess(Variable v, ControlFlowNode n) {
143204
successSuccessor(v, n)
144205
or

cpp/ql/src/Critical/NewDelete.qll

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,34 @@
55
import cpp
66
import semmle.code.cpp.controlflow.SSA
77
import semmle.code.cpp.dataflow.DataFlow
8+
import semmle.code.cpp.models.implementations.Allocation
9+
import semmle.code.cpp.models.implementations.Deallocation
810

911
/**
1012
* Holds if `alloc` is a use of `malloc` or `new`. `kind` is
1113
* a string describing the type of the allocation.
1214
*/
1315
predicate allocExpr(Expr alloc, string kind) {
14-
isAllocationExpr(alloc) and
15-
not alloc.isFromUninstantiatedTemplate(_) and
1616
(
17-
alloc instanceof FunctionCall and
18-
kind = "malloc"
17+
exists(Function target |
18+
alloc.(AllocationExpr).(FunctionCall).getTarget() = target and
19+
(
20+
target.getName() = "operator new" and
21+
kind = "new" and
22+
// exclude placement new and custom overloads as they
23+
// may not conform to assumptions
24+
not target.getNumberOfParameters() > 1
25+
or
26+
target.getName() = "operator new[]" and
27+
kind = "new[]" and
28+
// exclude placement new and custom overloads as they
29+
// may not conform to assumptions
30+
not target.getNumberOfParameters() > 1
31+
or
32+
not target instanceof OperatorNewAllocationFunction and
33+
kind = "malloc"
34+
)
35+
)
1936
or
2037
alloc instanceof NewExpr and
2138
kind = "new" and
@@ -28,7 +45,8 @@ predicate allocExpr(Expr alloc, string kind) {
2845
// exclude placement new and custom overloads as they
2946
// may not conform to assumptions
3047
not alloc.(NewArrayExpr).getAllocatorCall().getTarget().getNumberOfParameters() > 1
31-
)
48+
) and
49+
not alloc.isFromUninstantiatedTemplate(_)
3250
}
3351

3452
/**
@@ -110,8 +128,20 @@ predicate allocReaches(Expr e, Expr alloc, string kind) {
110128
* describing the type of that free or delete.
111129
*/
112130
predicate freeExpr(Expr free, Expr freed, string kind) {
113-
freeCall(free, freed) and
114-
kind = "free"
131+
exists(Function target |
132+
freed = free.(DeallocationExpr).getFreedExpr() and
133+
free.(FunctionCall).getTarget() = target and
134+
(
135+
target.getName() = "operator delete" and
136+
kind = "delete"
137+
or
138+
target.getName() = "operator delete[]" and
139+
kind = "delete[]"
140+
or
141+
not target instanceof OperatorDeleteDeallocationFunction and
142+
kind = "free"
143+
)
144+
)
115145
or
116146
free.(DeleteExpr).getExpr() = freed and
117147
kind = "delete"

cpp/ql/src/JPL_C/LOC-3/Rule 17/BasicIntTypes.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ predicate allowedTypedefs(TypedefType t) {
3030
* Gets a type which appears literally in the declaration of `d`.
3131
*/
3232
Type getAnImmediateUsedType(Declaration d) {
33-
d.isDefined() and
33+
d.hasDefinition() and
3434
(
3535
result = d.(Function).getType() or
3636
result = d.(Variable).getType()

0 commit comments

Comments
 (0)