Skip to content

Commit 68f6f9f

Browse files
authored
Merge pull request #19211 from asgerf/js/pp-unit-tests
Support post-procesed inline expectations for query predicates in unit tests
2 parents 04d37c3 + 14c5495 commit 68f6f9f

File tree

5 files changed

+68
-33
lines changed

5 files changed

+68
-33
lines changed

Diff for: javascript/ql/test/library-tests/SensitiveActions/tests.expected

+11-11
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ sensitiveAction
3131
| tst.js:23:1:23:25 | require ... .exit() |
3232
| tst.js:24:1:24:21 | global. ... .exit() |
3333
sensitiveExpr
34-
| tst.js:1:1:1:8 | password |
35-
| tst.js:2:1:2:8 | PassWord |
36-
| tst.js:3:1:3:21 | myPassw ... eartext |
37-
| tst.js:4:1:4:10 | x.password |
38-
| tst.js:5:1:5:11 | getPassword |
39-
| tst.js:5:1:5:13 | getPassword() |
40-
| tst.js:6:1:6:13 | x.getPassword |
41-
| tst.js:6:1:6:15 | x.getPassword() |
42-
| tst.js:7:1:7:15 | get("password") |
43-
| tst.js:8:1:8:17 | x.get("password") |
44-
| tst.js:21:1:21:6 | secret |
34+
| tst.js:1:1:1:8 | password | password |
35+
| tst.js:2:1:2:8 | PassWord | password |
36+
| tst.js:3:1:3:21 | myPassw ... eartext | password |
37+
| tst.js:4:1:4:10 | x.password | password |
38+
| tst.js:5:1:5:11 | getPassword | password |
39+
| tst.js:5:1:5:13 | getPassword() | password |
40+
| tst.js:6:1:6:13 | x.getPassword | password |
41+
| tst.js:6:1:6:15 | x.getPassword() | password |
42+
| tst.js:7:1:7:15 | get("password") | password |
43+
| tst.js:8:1:8:17 | x.get("password") | password |
44+
| tst.js:21:1:21:6 | secret | secret |

Diff for: javascript/ql/test/library-tests/SensitiveActions/tests.ql

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ query predicate processTermination(NodeJSLib::ProcessTermination term) { any() }
2020

2121
query predicate sensitiveAction(SensitiveAction ac) { any() }
2222

23-
query predicate sensitiveExpr(SensitiveNode e) { any() }
23+
query predicate sensitiveExpr(SensitiveNode e, string kind) { kind = e.getClassification() }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
query: tests.ql
2+
postprocess: utils/test/InlineExpectationsTestQuery.ql

Diff for: javascript/ql/test/library-tests/SensitiveActions/tst.js

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
password;
2-
PassWord;
3-
myPasswordInCleartext;
4-
x.password;
5-
getPassword();
6-
x.getPassword();
7-
get("password");
8-
x.get("password");
1+
password; // $ cleartextPasswordExpr sensitiveExpr=password
2+
PassWord; // $ cleartextPasswordExpr sensitiveExpr=password
3+
myPasswordInCleartext; // $ cleartextPasswordExpr sensitiveExpr=password
4+
x.password; // $ cleartextPasswordExpr sensitiveExpr=password
5+
getPassword(); // $ cleartextPasswordExpr sensitiveExpr=password
6+
x.getPassword(); // $ cleartextPasswordExpr sensitiveExpr=password
7+
get("password"); // $ cleartextPasswordExpr sensitiveExpr=password
8+
x.get("password"); // $ cleartextPasswordExpr sensitiveExpr=password
99

1010
hashed_password;
1111
password_hashed;
@@ -15,13 +15,13 @@ hashedPassword;
1515

1616
var exit = require('exit');
1717
var e = process.exit;
18-
e();
19-
exit();
18+
e(); // $ processTermination sensitiveAction
19+
exit(); // $ processTermination sensitiveAction
2020

21-
secret;
21+
secret; // $ sensitiveExpr=secret
2222

23-
require("process").exit();
24-
global.process.exit();
23+
require("process").exit(); // $ processTermination sensitiveAction
24+
global.process.exit(); // $ processTermination sensitiveAction
2525

2626
get("https://example.com/news?password=true")
2727
get("https://username:password@example.com")

Diff for: shared/util/codeql/util/test/InlineExpectationsTest.qll

+41-8
Original file line numberDiff line numberDiff line change
@@ -858,17 +858,26 @@ module TestPostProcessing {
858858
bindingset[result]
859859
string getARelevantTag() { any() }
860860

861-
predicate tagMatches = PathProblemSourceTestInput::tagMatches/2;
861+
bindingset[expectedTag, actualTag]
862+
predicate tagMatches(string expectedTag, string actualTag) {
863+
PathProblemSourceTestInput::tagMatches(expectedTag, actualTag)
864+
or
865+
not exists(getQueryKind()) and
866+
expectedTag = actualTag
867+
}
862868

863869
bindingset[expectedTag]
864870
predicate tagIsOptional(string expectedTag) {
865-
// ignore irrelevant tags
866-
not expectedTag.regexpMatch(getTagRegex())
867-
or
868-
// ignore tags annotated with a query ID that does not match the current query ID
869-
exists(string queryId |
870-
queryId = expectedTag.regexpCapture(getTagRegex(), 3) and
871-
queryId != getQueryId()
871+
exists(getQueryKind()) and
872+
(
873+
// ignore irrelevant tags
874+
not expectedTag.regexpMatch(getTagRegex())
875+
or
876+
// ignore tags annotated with a query ID that does not match the current query ID
877+
exists(string queryId |
878+
queryId = expectedTag.regexpCapture(getTagRegex(), 3) and
879+
queryId != getQueryId()
880+
)
872881
)
873882
}
874883

@@ -911,6 +920,28 @@ module TestPostProcessing {
911920
not hasPathProblemSink(row, location, _, _)
912921
}
913922

923+
/**
924+
* Holds if a custom query predicate implies `tag=value` at the given `location`.
925+
*
926+
* Such query predicates are only allowed in kind-less queries, usually in the form
927+
* of a `.ql` file in a test folder, with a same-named `.qlref` file to enable
928+
* post-processing for that test.
929+
*/
930+
private predicate hasCustomQueryPredicateResult(
931+
int row, TestLocation location, string element, string tag, string value
932+
) {
933+
not exists(getQueryKind()) and
934+
queryResults(tag, row, 0, location.getRelativeUrl()) and
935+
queryResults(tag, row, 1, element) and
936+
(
937+
queryResults(tag, row, 2, value) and
938+
not queryResults(tag, row, 3, _) // ignore if arity is greater than expected
939+
or
940+
not queryResults(tag, row, 2, _) and
941+
value = "" // allow value-less expectations for unary predicates
942+
)
943+
}
944+
914945
/**
915946
* Gets the expected value for result row `row`, if any. This value must
916947
* match the value at the corresponding path-problem source (if it is
@@ -939,6 +970,8 @@ module TestPostProcessing {
939970
or
940971
value = getValue(row)
941972
)
973+
or
974+
hasCustomQueryPredicateResult(_, location, element, tag, value)
942975
}
943976
}
944977

0 commit comments

Comments
 (0)