From 9b2ef8be10be950ff270ea67c78208527cfe6a39 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Mon, 26 May 2025 11:36:11 +0200 Subject: [PATCH 01/11] JS: add test for DOM access where expression appears to have no side effects --- .../Expressions/ExprHasNoEffect/ExprHasNoEffect.expected | 8 ++++++++ .../test/query-tests/Expressions/ExprHasNoEffect/dom.js | 7 +++++++ 2 files changed, 15 insertions(+) create mode 100644 javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/dom.js diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected index 853e781c88e2..29b6ec70be5d 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected @@ -1,3 +1,11 @@ +| dom.js:2:5:2:30 | a.clien ... ientTop | This expression has no effect. | +| dom.js:2:5:2:50 | a.clien ... === !0 | This expression has no effect. | +| dom.js:2:33:2:50 | a.clientTop === !0 | This expression has no effect. | +| dom.js:3:5:3:20 | a && a.clientTop | This expression has no effect. | +| dom.js:4:5:4:28 | a.clien ... ientTop | This expression has no effect. | +| dom.js:5:18:5:43 | a.clien ... ientTop | This expression has no effect. | +| dom.js:6:18:6:63 | b && (b ... entTop) | This expression has no effect. | +| dom.js:6:23:6:63 | (b.clie ... entTop) | This expression has no effect. | | try.js:22:9:22:26 | x.ordinaryProperty | This expression has no effect. | | tst2.js:2:4:2:4 | 0 | This expression has no effect. | | tst.js:3:1:3:2 | 23 | This expression has no effect. | diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/dom.js b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/dom.js new file mode 100644 index 000000000000..076e277f652c --- /dev/null +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/dom.js @@ -0,0 +1,7 @@ +function f(){ + a.clientTop && a.clientTop, a.clientTop === !0; // $Alert + a && a.clientTop; // $SPURIOUS:Alert + a.clientTop, a.clientTop; // $SPURIOUS:Alert + if(a) return a.clientTop && a.clientTop, a.clientTop === !0 // $SPURIOUS:Alert + if(b) return b && (b.clientTop, b.clientTop && b.clientTop), null // $SPURIOUS:Alert +} From bca1bc7153d9bb8e44c6ebe0898144c518ee5ff1 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Mon, 26 May 2025 11:43:37 +0200 Subject: [PATCH 02/11] JS: Enhance `isDomProperty` to check for `getAPropertyRead` on DOM nodes --- javascript/ql/lib/Expressions/ExprHasNoEffect.qll | 15 +++++++++++++++ .../ExprHasNoEffect/ExprHasNoEffect.expected | 7 ------- .../Expressions/ExprHasNoEffect/dom.js | 10 +++++----- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll index eff5fa7fc989..611e1aa0c3eb 100644 --- a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll +++ b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll @@ -129,6 +129,20 @@ predicate noSideEffects(Expr e) { ) } +/** + * Holds if `e` is a compound expression that may contain sub-expressions with side effects. + * We should not flag these directly as useless since we want to flag only the innermost + * expressions that actually have no effect. + */ +predicate isCompoundExpression(Expr e) { + e instanceof LogicalBinaryExpr + or + e instanceof SeqExpr + or + e instanceof ParExpr and + not e.stripParens() instanceof FunctionExpr +} + /** * Holds if the expression `e` should be reported as having no effect. */ @@ -145,6 +159,7 @@ predicate hasNoEffect(Expr e) { not isDeclaration(e) and // exclude DOM properties, which sometimes have magical auto-update properties not isDomProperty(e.(PropAccess).getPropertyName()) and + not isCompoundExpression(e) and // exclude xUnit.js annotations not e instanceof XUnitAnnotation and // exclude common patterns that are most likely intentional diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected index 29b6ec70be5d..a3fd6e316415 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected @@ -1,11 +1,4 @@ -| dom.js:2:5:2:30 | a.clien ... ientTop | This expression has no effect. | -| dom.js:2:5:2:50 | a.clien ... === !0 | This expression has no effect. | | dom.js:2:33:2:50 | a.clientTop === !0 | This expression has no effect. | -| dom.js:3:5:3:20 | a && a.clientTop | This expression has no effect. | -| dom.js:4:5:4:28 | a.clien ... ientTop | This expression has no effect. | -| dom.js:5:18:5:43 | a.clien ... ientTop | This expression has no effect. | -| dom.js:6:18:6:63 | b && (b ... entTop) | This expression has no effect. | -| dom.js:6:23:6:63 | (b.clie ... entTop) | This expression has no effect. | | try.js:22:9:22:26 | x.ordinaryProperty | This expression has no effect. | | tst2.js:2:4:2:4 | 0 | This expression has no effect. | | tst.js:3:1:3:2 | 23 | This expression has no effect. | diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/dom.js b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/dom.js index 076e277f652c..5d22e4a0bed2 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/dom.js +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/dom.js @@ -1,7 +1,7 @@ function f(){ - a.clientTop && a.clientTop, a.clientTop === !0; // $Alert - a && a.clientTop; // $SPURIOUS:Alert - a.clientTop, a.clientTop; // $SPURIOUS:Alert - if(a) return a.clientTop && a.clientTop, a.clientTop === !0 // $SPURIOUS:Alert - if(b) return b && (b.clientTop, b.clientTop && b.clientTop), null // $SPURIOUS:Alert + a.clientTop && a.clientTop, a.clientTop === !0; //$Alert + a && a.clientTop; + a.clientTop, a.clientTop; + if(a) return a.clientTop && a.clientTop, a.clientTop === !0; + if(b) return b && (b.clientTop, b.clientTop && b.clientTop), null; } From 1f256ab71e6e1dcc9c0ed3812750d0d9c7bf0aa0 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Mon, 26 May 2025 13:00:09 +0200 Subject: [PATCH 03/11] Added change note --- .../ql/src/change-notes/2025-05-30-dom-property-access.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/ql/src/change-notes/2025-05-30-dom-property-access.md diff --git a/javascript/ql/src/change-notes/2025-05-30-dom-property-access.md b/javascript/ql/src/change-notes/2025-05-30-dom-property-access.md new file mode 100644 index 000000000000..2dcb16a8327b --- /dev/null +++ b/javascript/ql/src/change-notes/2025-05-30-dom-property-access.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `js/useless-expression` query now correctly flags only the innermost expressions with no effect, avoiding duplicate alerts on compound expressions. From bf48b5987478f6bd4fce36e71e8eca06fc8ccb82 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Mon, 2 Jun 2025 17:35:23 +0200 Subject: [PATCH 04/11] JS: Removed exclusion of `FunctionExpr` from compound statements. --- javascript/ql/lib/Expressions/ExprHasNoEffect.qll | 3 +-- .../Expressions/ExprHasNoEffect/ExprHasNoEffect.expected | 1 - .../test/query-tests/Expressions/ExprHasNoEffect/uselessfn.js | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll index 611e1aa0c3eb..154be3b606b0 100644 --- a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll +++ b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll @@ -139,8 +139,7 @@ predicate isCompoundExpression(Expr e) { or e instanceof SeqExpr or - e instanceof ParExpr and - not e.stripParens() instanceof FunctionExpr + e instanceof ParExpr } /** diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected index a3fd6e316415..3862c062abf3 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected @@ -12,4 +12,3 @@ | tst.js:50:3:50:36 | new Err ... age(e)) | This expression has no effect. | | tst.js:61:2:61:20 | o.trivialNonGetter1 | This expression has no effect. | | tst.js:77:24:77:24 | o | This expression has no effect. | -| uselessfn.js:1:1:1:26 | (functi ... .");\\n}) | This expression has no effect. | diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/uselessfn.js b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/uselessfn.js index 341644bf6498..309a5915bf13 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/uselessfn.js +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/uselessfn.js @@ -1,3 +1,3 @@ -(function f() { // $ Alert +(function f() { // $MISSING: Alert console.log("I'm never called."); -}) \ No newline at end of file +}) From 46b5ded862219e3ea9ca2353653495fc3d92a26a Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Tue, 3 Jun 2025 15:20:55 +0200 Subject: [PATCH 05/11] JS: Enhance void context propagation --- javascript/ql/lib/Expressions/ExprHasNoEffect.qll | 3 +++ .../Expressions/ExprHasNoEffect/ExprHasNoEffect.expected | 2 ++ .../ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js | 2 +- .../test/query-tests/Expressions/ExprHasNoEffect/uselessfn.js | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll index 154be3b606b0..d25973a90c85 100644 --- a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll +++ b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll @@ -22,6 +22,9 @@ predicate inVoidContext(Expr e) { ) ) or + // propagate void context through parenthesized expressions + inVoidContext(e.getParent().(ParExpr)) + or exists(SeqExpr seq, int i, int n | e = seq.getOperand(i) and n = seq.getNumOperands() diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected index 3862c062abf3..6afcd36bc5c2 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected @@ -11,4 +11,6 @@ | tst.js:49:3:49:49 | new Syn ... o me?") | This expression has no effect. | | tst.js:50:3:50:36 | new Err ... age(e)) | This expression has no effect. | | tst.js:61:2:61:20 | o.trivialNonGetter1 | This expression has no effect. | +| tst.js:75:3:75:3 | o | This expression has no effect. | | tst.js:77:24:77:24 | o | This expression has no effect. | +| uselessfn.js:1:2:1:26 | functio ... d.");\\n} | This expression has no effect. | diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js index a91759e553f1..7fd3fe0d7edf 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js @@ -72,7 +72,7 @@ function g() { Object.defineProperty(o, "nonTrivialGetter2", unknownGetterDef()); o.nonTrivialGetter2; - (o: empty); + (o: empty); // $SPURIOUS:Alert testSomeCondition() ? o : // $ Alert doSomethingDangerous(); diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/uselessfn.js b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/uselessfn.js index 309a5915bf13..e47a25458d44 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/uselessfn.js +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/uselessfn.js @@ -1,3 +1,3 @@ -(function f() { // $MISSING: Alert +(function f() { // $ Alert console.log("I'm never called."); }) From aac56e089a009ddf979c16844c468785e1f65955 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Tue, 3 Jun 2025 15:26:22 +0200 Subject: [PATCH 06/11] JavaScript: Fix false positive on Flow type annotations in `ExprHasNoEffect` --- javascript/ql/lib/Expressions/ExprHasNoEffect.qll | 5 ++++- .../Expressions/ExprHasNoEffect/ExprHasNoEffect.expected | 1 - .../ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll index d25973a90c85..d7744bc21364 100644 --- a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll +++ b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll @@ -174,7 +174,10 @@ predicate hasNoEffect(Expr e) { not exists(fe.getName()) ) and // exclude block-level flow type annotations. For example: `(name: empty)`. - not e.(ParExpr).getExpression().getLastToken().getNextToken().getValue() = ":" and + not exists(ParExpr parent | + e.getParent() = parent and + e.getLastToken().getNextToken().getValue() = ":" + ) and // exclude the first statement of a try block not e = any(TryStmt stmt).getBody().getStmt(0).(ExprStmt).getExpr() and // exclude expressions that are alone in a file, and file doesn't contain a function. diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected index 6afcd36bc5c2..f1beafe0037a 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected @@ -11,6 +11,5 @@ | tst.js:49:3:49:49 | new Syn ... o me?") | This expression has no effect. | | tst.js:50:3:50:36 | new Err ... age(e)) | This expression has no effect. | | tst.js:61:2:61:20 | o.trivialNonGetter1 | This expression has no effect. | -| tst.js:75:3:75:3 | o | This expression has no effect. | | tst.js:77:24:77:24 | o | This expression has no effect. | | uselessfn.js:1:2:1:26 | functio ... d.");\\n} | This expression has no effect. | diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js index 7fd3fe0d7edf..a91759e553f1 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js @@ -72,7 +72,7 @@ function g() { Object.defineProperty(o, "nonTrivialGetter2", unknownGetterDef()); o.nonTrivialGetter2; - (o: empty); // $SPURIOUS:Alert + (o: empty); testSomeCondition() ? o : // $ Alert doSomethingDangerous(); From b7f7092ab3fd95bab224587e0565ab5f21b64173 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Tue, 10 Jun 2025 09:37:40 +0200 Subject: [PATCH 07/11] Added test cases for better test coverage --- .../Expressions/ExprHasNoEffect/ExprHasNoEffect.expected | 2 ++ .../ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js | 3 +++ 2 files changed, 5 insertions(+) diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected index f1beafe0037a..2a792b42e199 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected @@ -12,4 +12,6 @@ | tst.js:50:3:50:36 | new Err ... age(e)) | This expression has no effect. | | tst.js:61:2:61:20 | o.trivialNonGetter1 | This expression has no effect. | | tst.js:77:24:77:24 | o | This expression has no effect. | +| tst.js:83:43:83:46 | null | This expression has no effect. | +| tst.js:84:42:84:45 | null | This expression has no effect. | | uselessfn.js:1:2:1:26 | functio ... d.");\\n} | This expression has no effect. | diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js index a91759e553f1..c9f3366c9add 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js @@ -79,4 +79,7 @@ function g() { consume(testSomeCondition() ? o : doSomethingDangerous()); + + ("release" === isRelease() ? warning() : null); // $ Alert + "release" === isRelease() ? warning() : null; // $ Alert }; From c97da2eda582e4e16cf343fbd725cbbb85382929 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Tue, 10 Jun 2025 10:42:54 +0200 Subject: [PATCH 08/11] Exclude expressions that are part of a conditional expression --- javascript/ql/lib/Expressions/ExprHasNoEffect.qll | 7 +++++++ .../Expressions/ExprHasNoEffect/ExprHasNoEffect.expected | 2 -- .../ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js | 6 ++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll index d7744bc21364..7fdb1e00e2da 100644 --- a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll +++ b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll @@ -178,6 +178,13 @@ predicate hasNoEffect(Expr e) { e.getParent() = parent and e.getLastToken().getNextToken().getValue() = ":" ) and + // exclude expressions that are part of a conditional expression + not exists(ConditionalExpr cond | e.getParent() = cond | + e instanceof NullLiteral or + e instanceof GlobalVarAccess or + e.(NumberLiteral).getIntValue() = 0 or + e.(UnaryExpr).getOperator() = "void" + ) and // exclude the first statement of a try block not e = any(TryStmt stmt).getBody().getStmt(0).(ExprStmt).getExpr() and // exclude expressions that are alone in a file, and file doesn't contain a function. diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected index 2a792b42e199..f1beafe0037a 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/ExprHasNoEffect.expected @@ -12,6 +12,4 @@ | tst.js:50:3:50:36 | new Err ... age(e)) | This expression has no effect. | | tst.js:61:2:61:20 | o.trivialNonGetter1 | This expression has no effect. | | tst.js:77:24:77:24 | o | This expression has no effect. | -| tst.js:83:43:83:46 | null | This expression has no effect. | -| tst.js:84:42:84:45 | null | This expression has no effect. | | uselessfn.js:1:2:1:26 | functio ... d.");\\n} | This expression has no effect. | diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js index c9f3366c9add..6de5ac9a236a 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/tst.js @@ -80,6 +80,8 @@ function g() { consume(testSomeCondition() ? o : doSomethingDangerous()); - ("release" === isRelease() ? warning() : null); // $ Alert - "release" === isRelease() ? warning() : null; // $ Alert + ("release" === isRelease() ? warning() : null); + "release" === isRelease() ? warning() : null; + "release" === isRelease() ? warning() : 0; + "release" === isRelease() ? warning() : undefined; }; From e6f071ce4693d81b6e882ed8d73158b73b7ed35d Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Tue, 10 Jun 2025 13:18:48 +0200 Subject: [PATCH 09/11] Update javascript/ql/lib/Expressions/ExprHasNoEffect.qll Co-authored-by: Asger F --- javascript/ql/lib/Expressions/ExprHasNoEffect.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll index 7fdb1e00e2da..76b6c2bea295 100644 --- a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll +++ b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll @@ -181,7 +181,7 @@ predicate hasNoEffect(Expr e) { // exclude expressions that are part of a conditional expression not exists(ConditionalExpr cond | e.getParent() = cond | e instanceof NullLiteral or - e instanceof GlobalVarAccess or + e.(GlobalVarAccess).getName() = "undefined" or e.(NumberLiteral).getIntValue() = 0 or e.(UnaryExpr).getOperator() = "void" ) and From 496d8d44eb8bb4216dc978358518d72bd5d11fd9 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Tue, 10 Jun 2025 13:19:48 +0200 Subject: [PATCH 10/11] Update javascript/ql/lib/Expressions/ExprHasNoEffect.qll Co-authored-by: Asger F --- javascript/ql/lib/Expressions/ExprHasNoEffect.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll index 76b6c2bea295..48d9b9081362 100644 --- a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll +++ b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll @@ -179,7 +179,7 @@ predicate hasNoEffect(Expr e) { e.getLastToken().getNextToken().getValue() = ":" ) and // exclude expressions that are part of a conditional expression - not exists(ConditionalExpr cond | e.getParent() = cond | + not exists(ConditionalExpr cond | e = cond.getABranch() | e instanceof NullLiteral or e.(GlobalVarAccess).getName() = "undefined" or e.(NumberLiteral).getIntValue() = 0 or From e46581163aee86f85727167986612f1c7a7e1103 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Tue, 10 Jun 2025 13:23:31 +0200 Subject: [PATCH 11/11] Update javascript/ql/lib/Expressions/ExprHasNoEffect.qll Co-Authored-By: Asger F <316427+asgerf@users.noreply.github.com> --- javascript/ql/lib/Expressions/ExprHasNoEffect.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll index 48d9b9081362..9813d9b32ed9 100644 --- a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll +++ b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll @@ -183,7 +183,7 @@ predicate hasNoEffect(Expr e) { e instanceof NullLiteral or e.(GlobalVarAccess).getName() = "undefined" or e.(NumberLiteral).getIntValue() = 0 or - e.(UnaryExpr).getOperator() = "void" + e instanceof VoidExpr ) and // exclude the first statement of a try block not e = any(TryStmt stmt).getBody().getStmt(0).(ExprStmt).getExpr() and