mirror of
https://github.com/github/codeql.git
synced 2026-04-22 07:15:15 +02:00
Merge pull request #19211 from asgerf/js/pp-unit-tests
Support post-procesed inline expectations for query predicates in unit tests
This commit is contained in:
@@ -31,14 +31,14 @@ sensitiveAction
|
||||
| tst.js:23:1:23:25 | require ... .exit() |
|
||||
| tst.js:24:1:24:21 | global. ... .exit() |
|
||||
sensitiveExpr
|
||||
| tst.js:1:1:1:8 | password |
|
||||
| tst.js:2:1:2:8 | PassWord |
|
||||
| tst.js:3:1:3:21 | myPassw ... eartext |
|
||||
| tst.js:4:1:4:10 | x.password |
|
||||
| tst.js:5:1:5:11 | getPassword |
|
||||
| tst.js:5:1:5:13 | getPassword() |
|
||||
| tst.js:6:1:6:13 | x.getPassword |
|
||||
| tst.js:6:1:6:15 | x.getPassword() |
|
||||
| tst.js:7:1:7:15 | get("password") |
|
||||
| tst.js:8:1:8:17 | x.get("password") |
|
||||
| tst.js:21:1:21:6 | secret |
|
||||
| tst.js:1:1:1:8 | password | password |
|
||||
| tst.js:2:1:2:8 | PassWord | password |
|
||||
| tst.js:3:1:3:21 | myPassw ... eartext | password |
|
||||
| tst.js:4:1:4:10 | x.password | password |
|
||||
| tst.js:5:1:5:11 | getPassword | password |
|
||||
| tst.js:5:1:5:13 | getPassword() | password |
|
||||
| tst.js:6:1:6:13 | x.getPassword | password |
|
||||
| tst.js:6:1:6:15 | x.getPassword() | password |
|
||||
| tst.js:7:1:7:15 | get("password") | password |
|
||||
| tst.js:8:1:8:17 | x.get("password") | password |
|
||||
| tst.js:21:1:21:6 | secret | secret |
|
||||
|
||||
@@ -20,4 +20,4 @@ query predicate processTermination(NodeJSLib::ProcessTermination term) { any() }
|
||||
|
||||
query predicate sensitiveAction(SensitiveAction ac) { any() }
|
||||
|
||||
query predicate sensitiveExpr(SensitiveNode e) { any() }
|
||||
query predicate sensitiveExpr(SensitiveNode e, string kind) { kind = e.getClassification() }
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
query: tests.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
@@ -1,11 +1,11 @@
|
||||
password;
|
||||
PassWord;
|
||||
myPasswordInCleartext;
|
||||
x.password;
|
||||
getPassword();
|
||||
x.getPassword();
|
||||
get("password");
|
||||
x.get("password");
|
||||
password; // $ cleartextPasswordExpr sensitiveExpr=password
|
||||
PassWord; // $ cleartextPasswordExpr sensitiveExpr=password
|
||||
myPasswordInCleartext; // $ cleartextPasswordExpr sensitiveExpr=password
|
||||
x.password; // $ cleartextPasswordExpr sensitiveExpr=password
|
||||
getPassword(); // $ cleartextPasswordExpr sensitiveExpr=password
|
||||
x.getPassword(); // $ cleartextPasswordExpr sensitiveExpr=password
|
||||
get("password"); // $ cleartextPasswordExpr sensitiveExpr=password
|
||||
x.get("password"); // $ cleartextPasswordExpr sensitiveExpr=password
|
||||
|
||||
hashed_password;
|
||||
password_hashed;
|
||||
@@ -15,13 +15,13 @@ hashedPassword;
|
||||
|
||||
var exit = require('exit');
|
||||
var e = process.exit;
|
||||
e();
|
||||
exit();
|
||||
e(); // $ processTermination sensitiveAction
|
||||
exit(); // $ processTermination sensitiveAction
|
||||
|
||||
secret;
|
||||
secret; // $ sensitiveExpr=secret
|
||||
|
||||
require("process").exit();
|
||||
global.process.exit();
|
||||
require("process").exit(); // $ processTermination sensitiveAction
|
||||
global.process.exit(); // $ processTermination sensitiveAction
|
||||
|
||||
get("https://example.com/news?password=true")
|
||||
get("https://username:password@example.com")
|
||||
|
||||
@@ -858,17 +858,26 @@ module TestPostProcessing {
|
||||
bindingset[result]
|
||||
string getARelevantTag() { any() }
|
||||
|
||||
predicate tagMatches = PathProblemSourceTestInput::tagMatches/2;
|
||||
bindingset[expectedTag, actualTag]
|
||||
predicate tagMatches(string expectedTag, string actualTag) {
|
||||
PathProblemSourceTestInput::tagMatches(expectedTag, actualTag)
|
||||
or
|
||||
not exists(getQueryKind()) and
|
||||
expectedTag = actualTag
|
||||
}
|
||||
|
||||
bindingset[expectedTag]
|
||||
predicate tagIsOptional(string expectedTag) {
|
||||
// ignore irrelevant tags
|
||||
not expectedTag.regexpMatch(getTagRegex())
|
||||
or
|
||||
// ignore tags annotated with a query ID that does not match the current query ID
|
||||
exists(string queryId |
|
||||
queryId = expectedTag.regexpCapture(getTagRegex(), 3) and
|
||||
queryId != getQueryId()
|
||||
exists(getQueryKind()) and
|
||||
(
|
||||
// ignore irrelevant tags
|
||||
not expectedTag.regexpMatch(getTagRegex())
|
||||
or
|
||||
// ignore tags annotated with a query ID that does not match the current query ID
|
||||
exists(string queryId |
|
||||
queryId = expectedTag.regexpCapture(getTagRegex(), 3) and
|
||||
queryId != getQueryId()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -911,6 +920,28 @@ module TestPostProcessing {
|
||||
not hasPathProblemSink(row, location, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a custom query predicate implies `tag=value` at the given `location`.
|
||||
*
|
||||
* Such query predicates are only allowed in kind-less queries, usually in the form
|
||||
* of a `.ql` file in a test folder, with a same-named `.qlref` file to enable
|
||||
* post-processing for that test.
|
||||
*/
|
||||
private predicate hasCustomQueryPredicateResult(
|
||||
int row, TestLocation location, string element, string tag, string value
|
||||
) {
|
||||
not exists(getQueryKind()) and
|
||||
queryResults(tag, row, 0, location.getRelativeUrl()) and
|
||||
queryResults(tag, row, 1, element) and
|
||||
(
|
||||
queryResults(tag, row, 2, value) and
|
||||
not queryResults(tag, row, 3, _) // ignore if arity is greater than expected
|
||||
or
|
||||
not queryResults(tag, row, 2, _) and
|
||||
value = "" // allow value-less expectations for unary predicates
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the expected value for result row `row`, if any. This value must
|
||||
* match the value at the corresponding path-problem source (if it is
|
||||
@@ -939,6 +970,8 @@ module TestPostProcessing {
|
||||
or
|
||||
value = getValue(row)
|
||||
)
|
||||
or
|
||||
hasCustomQueryPredicateResult(_, location, element, tag, value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user