Skip to content

Commit 4fc27aa

Browse files
author
Max Schaefer
authored
Merge branch 'master' into pseudo-random-bytes
2 parents a01a9dc + 06dd5f3 commit 4fc27aa

File tree

22 files changed

+92
-16
lines changed

22 files changed

+92
-16
lines changed

change-notes/1.20/analysis-javascript.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
|--------------------------------------------|------------------------------|------------------------------------------------------------------------------|
2222
| Client-side cross-site scripting | More results | This rule now recognizes WinJS functions that are vulnerable to HTML injection. |
2323
| Insecure randomness | More results | This rule now flags insecure uses of `crypto.pseudoRandomBytes`. |
24-
| Unused variable, import, function or class | Fewer false-positive results | This rule now flags fewer variables that are implictly used by JSX elements. |
24+
| Unused parameter | Fewer false-positive results | This rule no longer flags parameters with leading underscore. |
25+
| Unused variable, import, function or class | Fewer false-positive results | This rule now flags fewer variables that are implictly used by JSX elements, and no longer flags variables with leading underscore. |
2526

2627
## Changes to QL libraries
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// semmle-extractor-options: --expect_errors
2+
3+
void functionBeforeError()
4+
{
5+
}
6+
7+
void functionWithError1()
8+
{
9+
aaaaaaaaaa(); // error
10+
}
11+
12+
void functionWithError2()
13+
{
14+
int i = aaaaaaaaaa(); // error
15+
}
16+
17+
void functionAfterError()
18+
{
19+
}

cpp/ql/test/library-tests/sideEffects/functions/sideEffects.expected

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
| cpp.cpp:87:5:87:26 | functionAccessesStatic | int | false |
4444
| cpp.cpp:93:6:93:14 | increment | int & -> void | false |
4545
| cpp.cpp:97:6:97:16 | doIncrement | void | false |
46+
| error.cpp:3:6:3:24 | functionBeforeError | void | true |
47+
| error.cpp:7:6:7:23 | functionWithError1 | void | false |
48+
| error.cpp:12:6:12:23 | functionWithError2 | void | false |
49+
| error.cpp:17:6:17:23 | functionAfterError | void | true |
4650
| file://:0:0:0:0 | operator= | __va_list_tag & | false |
4751
| file://:0:0:0:0 | operator= | __va_list_tag & | false |
4852
| sideEffects.c:4:5:4:6 | f1 | int | true |

cpp/ql/test/query-tests/Likely Bugs/Likely Typos/ExprHasNoEffect/ExprHasNoEffect.expected

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
| calls.cpp:8:5:8:5 | 1 | This expression has no effect. | calls.cpp:8:5:8:5 | 1 | |
22
| calls.cpp:12:5:12:16 | call to thingy | This expression has no effect (because $@ has no external side effects). | calls.cpp:7:15:7:20 | thingy | thingy |
3+
| expr.cpp:8:2:8:2 | 0 | This expression has no effect. | expr.cpp:8:2:8:2 | 0 | |
4+
| expr.cpp:9:7:9:7 | 0 | This expression has no effect. | expr.cpp:9:7:9:7 | 0 | |
5+
| expr.cpp:10:2:10:5 | ... , ... | This expression has no effect. | expr.cpp:10:2:10:5 | ... , ... | |
36
| preproc.c:89:2:89:4 | call to fn4 | This expression has no effect (because $@ has no external side effects). | preproc.c:33:5:33:7 | fn4 | fn4 |
47
| preproc.c:94:2:94:4 | call to fn9 | This expression has no effect (because $@ has no external side effects). | preproc.c:78:5:78:7 | fn9 | fn9 |
58
| template.cpp:19:3:19:3 | call to operator++ | This expression has no effect (because $@ has no external side effects). | template.cpp:9:10:9:19 | operator++ | operator++ |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace Expr {
2+
3+
int i;
4+
5+
void comma_expr_test()
6+
{
7+
i++, i++; // GOOD
8+
0, i++; // BAD (first part)
9+
i++, 0; // BAD (second part)
10+
0, 0; // BAD (whole)
11+
}
12+
13+
}

java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,5 @@ where
8181
not exists(MethodAccess ma | ma.getParent*() = cond) and
8282
not exists(FieldRead fa | fa.getParent*() = cond) and
8383
not exists(ArrayAccess aa | aa.getParent*() = cond)
84-
select loop, "Loop might not terminate, as this $@ is constant within the loop.", cond,
85-
"loop condition"
84+
select cond, "$@ might not terminate, as this loop condition is constant within the loop.", loop,
85+
"Loop"
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
| A.java:6:5:6:16 | stmt | Loop might not terminate, as this $@ is constant within the loop. | A.java:6:11:6:15 | !... | loop condition |
2-
| A.java:12:5:12:19 | stmt | Loop might not terminate, as this $@ is constant within the loop. | A.java:13:11:13:15 | ... > ... | loop condition |
3-
| A.java:27:5:27:38 | stmt | Loop might not terminate, as this $@ is constant within the loop. | A.java:27:20:27:32 | ... < ... | loop condition |
1+
| A.java:6:11:6:15 | !... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:6:5:6:16 | stmt | Loop |
2+
| A.java:13:11:13:15 | ... > ... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:12:5:12:19 | stmt | Loop |
3+
| A.java:27:20:27:32 | ... < ... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:27:5:27:38 | stmt | Loop |

javascript/ql/src/AngularJS/DuplicateDependency.ql

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*/
1111

1212
import javascript
13+
import semmle.javascript.RestrictedLocations
1314

1415
predicate isRepeatedDependency(AngularJS::InjectableFunction f, string name, ASTNode location) {
1516
exists(int i, int j | i < j and
@@ -20,4 +21,4 @@ predicate isRepeatedDependency(AngularJS::InjectableFunction f, string name, AST
2021
from AngularJS::InjectableFunction f, ASTNode node, string name
2122
where isRepeatedDependency(f, name, node) and
2223
not count(f.asFunction().getParameterByName(name)) > 1 // avoid duplicating reports from js/duplicate-parameter-name
23-
select f, "This function has a duplicate dependency '$@'.", node, name
24+
select (FirstLineOf)f.asFunction(), "This function has a duplicate dependency '$@'.", node, name

javascript/ql/src/AngularJS/RepeatedInjection.ql

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
*/
1111

1212
import javascript
13+
import semmle.javascript.RestrictedLocations
1314

1415
from AngularJS::InjectableFunction f, ASTNode explicitInjection
1516
where count(f.getAnExplicitDependencyInjection()) > 1 and
1617
explicitInjection = f.getAnExplicitDependencyInjection()
17-
select f.asFunction(), "This function has $@ defined in multiple places.", explicitInjection, "dependency injections"
18+
select (FirstLineOf)f.asFunction(), "This function has $@ defined in multiple places.", explicitInjection, "dependency injections"

javascript/ql/src/AngularJS/UnusedAngularDependency.ql

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import javascript
1313
import Declarations.UnusedParameter
14+
import semmle.javascript.RestrictedLocations
1415

1516
predicate isUnusedParameter(Function f, string msg, Parameter parameter) {
1617
exists(Variable pv |
@@ -36,4 +37,4 @@ predicate isMissingParameter(AngularJS::InjectableFunction f, string msg, ASTNod
3637

3738
from AngularJS::InjectableFunction f, string message, ASTNode location
3839
where isUnusedParameter(f.asFunction(), message, location) or isMissingParameter(f, message, location)
39-
select location, message
40+
select (FirstLineOf)location, message

javascript/ql/src/Declarations/UnusedParameter.ql

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010

1111
import javascript
12-
import UnusedParameter // local library
12+
import UnusedParameter
1313

1414
from Parameter p
1515
where isAnAccidentallyUnusedParameter(p)

javascript/ql/src/Declarations/UnusedParameter.qll

+3-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ predicate isUnused(Function f, Parameter p, Variable pv, int i) {
4646
// functions without a body cannot use their parameters
4747
f.hasBody() and
4848
// field parameters are used to initialize a field
49-
not p instanceof FieldParameter
49+
not p instanceof FieldParameter and
50+
// common convention: parameters with leading underscore are intentionally unused
51+
pv.getName().charAt(0) != "_"
5052
}
5153

5254
/**

javascript/ql/src/Declarations/UnusedVariable.ql

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ class UnusedLocal extends LocalVariable {
2222
not exists(FunctionExpr fe | this = fe.getVariable()) and
2323
not exists(ClassExpr ce | this = ce.getVariable()) and
2424
not exists(ExportDeclaration ed | ed.exportsAs(this, _)) and
25-
not exists(LocalVarTypeAccess type | type.getVariable() = this)
25+
not exists(LocalVarTypeAccess type | type.getVariable() = this) and
26+
// common convention: variables with leading underscore are intentionally unused
27+
getName().charAt(0) != "_"
2628
}
2729
}
2830

Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
| duplicates.js:2:5:2:18 | function f(){} | This function has a duplicate dependency '$@'. | duplicates.js:3:26:3:31 | 'dup5' | dup5 |
2-
| duplicates.js:6:14:6:57 | ['dup2a ... p2b){}] | This function has a duplicate dependency '$@'. | duplicates.js:6:24:6:30 | 'dup2a' | dup2a |
3-
| duplicates.js:7:14:7:57 | ['dup3b ... p3b){}] | This function has a duplicate dependency '$@'. | duplicates.js:7:24:7:30 | 'dup3b' | dup3b |
4-
| duplicates.js:8:14:8:79 | ['dup4' ... p4C){}] | This function has a duplicate dependency '$@'. | duplicates.js:8:35:8:40 | 'dup4' | dup4 |
2+
| duplicates.js:6:33:6:56 | functio ... up2b){} | This function has a duplicate dependency '$@'. | duplicates.js:6:24:6:30 | 'dup2a' | dup2a |
3+
| duplicates.js:7:33:7:56 | functio ... up3b){} | This function has a duplicate dependency '$@'. | duplicates.js:7:24:7:30 | 'dup3b' | dup3b |
4+
| duplicates.js:8:43:8:78 | functio ... up4C){} | This function has a duplicate dependency '$@'. | duplicates.js:8:35:8:40 | 'dup4' | dup4 |
5+
| duplicates.js:15:35:15:112 | functio ... } | This function has a duplicate dependency '$@'. | duplicates.js:15:25:15:32 | 'dup11a' | dup11a |

javascript/ql/test/query-tests/AngularJS/DuplicateDependency/duplicates.js

+2
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@
1212
.run(['notDup8a', 'notDup8b', function(notDup8a, notDup8b){}]) // OK
1313
.run(['notDup9a', 'notDup9b', function(notDup9c, notDup9d){}]) // OK
1414
.run(['dup10a', 'dup10a', 'dup10a', function(dup10a, dup10a, dup10a){}]) // OK (flagged by js/duplicate-parameter-name)
15+
.run(['dup11a', 'dup11a', function(dup11a, dup11b){ // NOT OK (alert formatting for multi-line function)
16+
}])
1517
;
1618
})();

javascript/ql/test/query-tests/AngularJS/RepeatedInjection/RepeatedInjection.expected

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
| repeated-injection.js:6:5:6:31 | functio ... name){} | This function has $@ defined in multiple places. | repeated-injection.js:8:54:8:73 | ['name', $Injected2] | dependency injections |
33
| repeated-injection.js:10:5:10:31 | functio ... name){} | This function has $@ defined in multiple places. | repeated-injection.js:11:5:11:22 | $Injected3.$inject | dependency injections |
44
| repeated-injection.js:10:5:10:31 | functio ... name){} | This function has $@ defined in multiple places. | repeated-injection.js:12:5:12:22 | $Injected3.$inject | dependency injections |
5+
| repeated-injection.js:33:5:33:84 | functio ... )\\n } | This function has $@ defined in multiple places. | repeated-injection.js:35:5:35:23 | $Injected10.$inject | dependency injections |
6+
| repeated-injection.js:33:5:33:84 | functio ... )\\n } | This function has $@ defined in multiple places. | repeated-injection.js:36:56:36:76 | ['name' ... cted10] | dependency injections |

javascript/ql/test/query-tests/AngularJS/RepeatedInjection/repeated-injection.js

+5
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,9 @@
3030

3131
angular.module('app9').controller('controller9', ['name', function inline9(name){}]); // OK
3232

33+
function $Injected10(name){ // NOT OK (alert formatting for multi-line function)
34+
}
35+
$Injected10.$inject = ['name'];
36+
angular.module('app10').controller('controller10', ['name', $Injected10]);
37+
3338
})();

javascript/ql/test/query-tests/AngularJS/UnusedAngularDependency/UnusedAngularDependency.expected

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
| unused-angular-dependency.js:14:14:14:39 | ["unuse ... n() {}] | This function has 0 parameters, but 1 dependency is injected into it. |
33
| unused-angular-dependency.js:16:14:16:53 | ["used2 ... d2) {}] | This function has 1 parameter, but 2 dependencies are injected into it. |
44
| unused-angular-dependency.js:17:14:17:52 | ["unuse ... n() {}] | This function has 0 parameters, but 2 dependencies are injected into it. |
5+
| unused-angular-dependency.js:18:14:18:105 | ["used2 ... }] | This function has 1 parameter, but 2 dependencies are injected into it. |

javascript/ql/test/query-tests/AngularJS/UnusedAngularDependency/unused-angular-dependency.js

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
.run(f2)
1616
.run(["used2", "unused9", function(used2) {}]) // NOT OK
1717
.run(["unused10", "unused11", function() {}]) // NOT OK
18+
.run(["used2", "unused12", function(used2) { // NOT OK (alert formatting for multi-line function)
19+
}])
1820
;
1921
})();
2022
angular.module('app2')

javascript/ql/test/query-tests/Declarations/UnusedParameter/tst.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,8 @@ var g = f3;
3333
// OK
3434
define(function (require, exports, module) {
3535
module.x = 23;
36-
});
36+
});
37+
38+
// OK: starts with underscore
39+
function f(_p) {
40+
}

javascript/ql/test/query-tests/Declarations/UnusedVariable/UnusedVariable.expected

+2
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@
99
| multi-imports.js:2:1:2:42 | import ... om 'x'; | Unused imports alphabetically, ordered. |
1010
| require-react-in-other-scope.js:2:9:2:13 | React | Unused variable React. |
1111
| typeoftype.ts:9:7:9:7 | y | Unused variable y. |
12+
| underscore.js:6:7:6:7 | e | Unused variable e. |
13+
| underscore.js:7:7:7:7 | f | Unused variable f. |
1214
| unusedShadowed.ts:1:1:1:26 | import ... where'; | Unused import T. |
1315
| unusedShadowed.ts:2:1:2:31 | import ... where'; | Unused import object. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function f(a) {
2+
const [a, // OK: used
3+
_, // OK: starts with underscore
4+
_c, // OK: starts with underscore
5+
d, // OK: used
6+
e, // NOT OK
7+
f] // NOT OK
8+
= a;
9+
return a + d;
10+
}

0 commit comments

Comments
 (0)