diff --git a/javascript/ql/src/Declarations/BuiltinRedefined.ql b/javascript/ql/src/Declarations/BuiltinRedefined.ql index 5e7feb92b119..1d500787b238 100644 --- a/javascript/ql/src/Declarations/BuiltinRedefined.ql +++ b/javascript/ql/src/Declarations/BuiltinRedefined.ql @@ -27,12 +27,12 @@ predicate acceptableRedefinition(Identifier id) { // Date = global.Date exists (AssignExpr assgn | id = assgn.getTarget() and - id.getName() = assgn.getRhs().stripParens().(PropAccess).getPropertyName() + id.getName() = assgn.getRhs().getUnderlyingValue().(PropAccess).getPropertyName() ) or // var Date = global.Date exists (VariableDeclarator decl | id = decl.getBindingPattern() and - id.getName() = decl.getInit().stripParens().(PropAccess).getPropertyName() + id.getName() = decl.getInit().getUnderlyingValue().(PropAccess).getPropertyName() ) } diff --git a/javascript/ql/src/Declarations/UnusedParameter.qll b/javascript/ql/src/Declarations/UnusedParameter.qll index 77b15a8caec8..c803f086d7e0 100644 --- a/javascript/ql/src/Declarations/UnusedParameter.qll +++ b/javascript/ql/src/Declarations/UnusedParameter.qll @@ -10,7 +10,7 @@ import javascript * Holds if `e` is an expression whose value is invoked as a function. */ private predicate isCallee(Expr e) { - exists (InvokeExpr invk | e = invk.getCallee().stripParens()) + exists (InvokeExpr invk | e = invk.getCallee().getUnderlyingValue()) } /** diff --git a/javascript/ql/src/Expressions/BadParityCheck.ql b/javascript/ql/src/Expressions/BadParityCheck.ql index 5ab64ab9fcc0..c109c411ae4a 100644 --- a/javascript/ql/src/Expressions/BadParityCheck.ql +++ b/javascript/ql/src/Expressions/BadParityCheck.ql @@ -65,7 +65,7 @@ predicate maybeNegativeVar(Variable v) { // is v ever assigned a potentially negative value? maybeNegative(v.getAnAssignedExpr()) or // is v ever decremented? - exists (DecExpr dec | dec.getOperand().stripParens() = v.getAnAccess()) or + exists (DecExpr dec | dec.getOperand().getUnderlyingReference() = v.getAnAccess()) or // is v ever subject to a compound assignment other than +=, or to // += with potentially negative rhs? exists (CompoundAssignExpr assgn | assgn.getTarget() = v.getAnAccess() | diff --git a/javascript/ql/src/Expressions/BitwiseSignCheck.ql b/javascript/ql/src/Expressions/BitwiseSignCheck.ql index 6f3a7b24070d..f3b615a1e89f 100644 --- a/javascript/ql/src/Expressions/BitwiseSignCheck.ql +++ b/javascript/ql/src/Expressions/BitwiseSignCheck.ql @@ -37,13 +37,13 @@ predicate acceptableSignCheck(BitwiseExpr b) { * is sign-preserving, we shouldn't flag it (and we allow arbitrary shifts, not just 16-bit ones) */ exists (RShiftExpr rsh, LShiftExpr lsh | - rsh = b and lsh = rsh.getLeftOperand().stripParens() and + rsh = b and lsh = rsh.getLeftOperand().getUnderlyingValue() and lsh.getRightOperand().getIntValue() = rsh.getRightOperand().getIntValue() ) } from Comparison e, BitwiseExpr b -where b = e.getLeftOperand().stripParens() and +where b = e.getLeftOperand().getUnderlyingValue() and not e instanceof EqualityTest and e.getRightOperand().getIntValue() = 0 and not acceptableSignCheck(b) diff --git a/javascript/ql/src/Expressions/RedundantExpression.ql b/javascript/ql/src/Expressions/RedundantExpression.ql index 1ed5e22a55dd..ffc7c484e24e 100644 --- a/javascript/ql/src/Expressions/RedundantExpression.ql +++ b/javascript/ql/src/Expressions/RedundantExpression.ql @@ -58,7 +58,7 @@ class RedundantIdemnecantOperand extends RedundantOperand { exists (IdemnecantExpr parent | parent = getParent() and // exclude trivial cases like `1-1` - not parent.getRightOperand().stripParens() instanceof Literal + not parent.getRightOperand().getUnderlyingValue() instanceof Literal ) } } @@ -80,7 +80,7 @@ class RedundantIdempotentOperand extends RedundantOperand { */ class AverageExpr extends DivExpr { AverageExpr() { - getLeftOperand().stripParens() instanceof AddExpr and + getLeftOperand().getUnderlyingValue() instanceof AddExpr and getRightOperand().getIntValue() = 2 } } @@ -91,12 +91,12 @@ class AverageExpr extends DivExpr { class RedundantAverageOperand extends RedundantOperand { RedundantAverageOperand() { exists (AverageExpr aver | - (AddExpr)getParent() = aver.getLeftOperand().stripParens() + (AddExpr)getParent() = aver.getLeftOperand().getUnderlyingValue() ) } override AverageExpr toReport() { - getParent() = result.getLeftOperand().stripParens() + getParent() = result.getLeftOperand().getUnderlyingValue() } } diff --git a/javascript/ql/src/LanguageFeatures/BadTypeof.ql b/javascript/ql/src/LanguageFeatures/BadTypeof.ql index e5db8bdc50e8..16deb3f5e7be 100644 --- a/javascript/ql/src/LanguageFeatures/BadTypeof.ql +++ b/javascript/ql/src/LanguageFeatures/BadTypeof.ql @@ -47,7 +47,7 @@ class EqOrSwitch extends ASTNode { } from EqOrSwitch et, TypeofExpr typeof, ConstantString str -where typeof = et.getAnOperand().stripParens() and - str = et.getAnOperand().stripParens() and +where typeof = et.getAnOperand().getUnderlyingValue() and + str = et.getAnOperand().getUnderlyingValue() and not str.getStringValue().regexpMatch("undefined|boolean|number|string|object|function|symbol|unknown|date|bigint") select typeof, "The result of this 'typeof' expression is compared to '$@', but the two can never be equal.", str, str.getStringValue() diff --git a/javascript/ql/src/Statements/ImplicitReturn.ql b/javascript/ql/src/Statements/ImplicitReturn.ql index 1c3096a57131..e6f964344694 100644 --- a/javascript/ql/src/Statements/ImplicitReturn.ql +++ b/javascript/ql/src/Statements/ImplicitReturn.ql @@ -56,7 +56,7 @@ int numRet(Function f) { predicate isDualUseConstructor(Function f) { numRet(f) = 1 and exists (ReturnStmt ret, DataFlow::NewNode new | ret.getContainer() = f | - new.asExpr() = ret.getExpr().stripParens() and + new.asExpr() = ret.getExpr().getUnderlyingValue() and new.getACallee() = f ) } diff --git a/javascript/ql/src/Statements/SuspiciousUnusedLoopIterationVariable.ql b/javascript/ql/src/Statements/SuspiciousUnusedLoopIterationVariable.ql index e9d5c5bb7487..0936cbc30f66 100644 --- a/javascript/ql/src/Statements/SuspiciousUnusedLoopIterationVariable.ql +++ b/javascript/ql/src/Statements/SuspiciousUnusedLoopIterationVariable.ql @@ -26,7 +26,7 @@ class IncrementExpr extends Expr { // x = x + e exists (AssignExpr assgn, Variable v | assgn = this | assgn.getTarget() = v.getAnAccess() and - assgn.getRhs().(AddExpr).getAnOperand().stripParens() = v.getAnAccess() + assgn.getRhs().(AddExpr).getAnOperand().getUnderlyingReference() = v.getAnAccess() ) } } diff --git a/javascript/ql/src/Statements/UselessConditional.ql b/javascript/ql/src/Statements/UselessConditional.ql index 94e44c556429..6e71d6827134 100644 --- a/javascript/ql/src/Statements/UselessConditional.ql +++ b/javascript/ql/src/Statements/UselessConditional.ql @@ -28,13 +28,13 @@ import semmle.javascript.dataflow.Refinements */ predicate isDefensiveInit(VarAccess va) { exists (LogOrExpr o, VarRef va2 | - va = o.getLeftOperand().stripParens() and va2.getVariable() = va.getVariable() | + va = o.getLeftOperand().getUnderlyingReference() and va2.getVariable() = va.getVariable() | exists (AssignExpr assgn | va2 = assgn.getTarget() | assgn = o.getRightOperand().stripParens() or - o = assgn.getRhs().stripParens() + o = assgn.getRhs().getUnderlyingValue() ) or exists (VariableDeclarator vd | va2 = vd.getBindingPattern() | - o = vd.getInit().stripParens() + o = vd.getInit().getUnderlyingValue() ) ) } diff --git a/javascript/ql/src/definitions.ql b/javascript/ql/src/definitions.ql index 0331b394b6bd..a31bf79d4bad 100644 --- a/javascript/ql/src/definitions.ql +++ b/javascript/ql/src/definitions.ql @@ -19,7 +19,7 @@ private import Declarations.Declarations * `x` has kind `"V"`. */ string refKind(RefExpr r) { - if exists(InvokeExpr invk | r = invk.getCallee().stripParens()) then + if exists(InvokeExpr invk | r = invk.getCallee().getUnderlyingReference()) then result = "M" else result = "V" @@ -143,7 +143,7 @@ predicate typedInvokeLookup(ASTNode ref, ASTNode decl, string kind) { not variableDefLookup(ref, decl, _) and not propertyLookup(ref, decl, _) and exists (InvokeExpr invoke, Expr callee | - callee = invoke.getCallee().stripParens() and + callee = invoke.getCallee().getUnderlyingReference() and (ref = callee.(Identifier) or ref = callee.(DotExpr).getPropertyNameExpr()) and decl = invoke.getResolvedCallee() and kind = "M") diff --git a/javascript/ql/src/semmle/javascript/AMD.qll b/javascript/ql/src/semmle/javascript/AMD.qll index 0d622b16cf3f..e142cb39e962 100644 --- a/javascript/ql/src/semmle/javascript/AMD.qll +++ b/javascript/ql/src/semmle/javascript/AMD.qll @@ -172,7 +172,7 @@ class AMDModuleDefinition extends CallExpr { * Gets a call to `require` inside this module. */ CallExpr getARequireCall() { - result.getCallee().stripParens() = getRequireVariable().getAnAccess() + result.getCallee().getUnderlyingValue() = getRequireVariable().getAnAccess() } } diff --git a/javascript/ql/src/semmle/javascript/Classes.qll b/javascript/ql/src/semmle/javascript/Classes.qll index 6624bb99067b..637f828beff7 100644 --- a/javascript/ql/src/semmle/javascript/Classes.qll +++ b/javascript/ql/src/semmle/javascript/Classes.qll @@ -291,7 +291,7 @@ class SuperExpr extends @superexpr, Expr { */ class SuperCall extends CallExpr { SuperCall() { - getCallee().stripParens() instanceof SuperExpr + getCallee().getUnderlyingValue() instanceof SuperExpr } /** @@ -299,7 +299,7 @@ class SuperCall extends CallExpr { * which is the nearest enclosing non-arrow function. */ Function getBinder() { - result = getCallee().stripParens().(SuperExpr).getBinder() + result = getCallee().getUnderlyingValue().(SuperExpr).getBinder() } } @@ -308,7 +308,7 @@ class SuperCall extends CallExpr { */ class SuperPropAccess extends PropAccess { SuperPropAccess() { - getBase().stripParens() instanceof SuperExpr + getBase().getUnderlyingValue() instanceof SuperExpr } } diff --git a/javascript/ql/src/semmle/javascript/DefUse.qll b/javascript/ql/src/semmle/javascript/DefUse.qll index 1b691174254d..11e6346c2a5c 100644 --- a/javascript/ql/src/semmle/javascript/DefUse.qll +++ b/javascript/ql/src/semmle/javascript/DefUse.qll @@ -71,7 +71,7 @@ private predicate defn(ControlFlowNode def, Expr lhs, AST::ValueNode rhs) { private predicate defn(ControlFlowNode def, Expr lhs) { defn(def, lhs, _) or lhs = def.(CompoundAssignExpr).getTarget() or - lhs = def.(UpdateExpr).getOperand().stripParens() or + lhs = def.(UpdateExpr).getOperand().getUnderlyingReference() or lhs = def.(ImportSpecifier).getLocal() or exists (EnhancedForLoop efl | def = efl.getIteratorExpr() | lhs = def.(Expr).stripParens() or @@ -143,7 +143,7 @@ class RValue extends RefExpr { not this instanceof LValue and not this instanceof VarDecl or // in `x++` and `x += 1`, `x` is both RValue and LValue this = any(CompoundAssignExpr a).getTarget() or - this = any(UpdateExpr u).getOperand().stripParens() or + this = any(UpdateExpr u).getOperand().getUnderlyingReference() or this = any(NamespaceDeclaration decl).getId() } } diff --git a/javascript/ql/src/semmle/javascript/Expr.qll b/javascript/ql/src/semmle/javascript/Expr.qll index 297b6480cfee..a5ebb5d6b607 100644 --- a/javascript/ql/src/semmle/javascript/Expr.qll +++ b/javascript/ql/src/semmle/javascript/Expr.qll @@ -710,7 +710,7 @@ class InvokeExpr extends @invokeexpr, Expr { /** Gets the name of the function or method being invoked, if it can be determined. */ string getCalleeName() { - exists (Expr callee | callee = getCallee().stripParens() | + exists (Expr callee | callee = getCallee().getUnderlyingValue() | result = ((Identifier)callee).getName() or result = ((PropAccess)callee).getPropertyName() ) @@ -1690,10 +1690,10 @@ class ImmediatelyInvokedFunctionExpr extends Function { ImmediatelyInvokedFunctionExpr() { // direct call - this = invk.getCallee().stripParens() and kind = "direct" or + this = invk.getCallee().getUnderlyingValue() and kind = "direct" or // reflective call exists (MethodCallExpr mce | mce = invk | - this = mce.getReceiver().stripParens() and + this = mce.getReceiver().getUnderlyingValue() and kind = mce.getMethodName() and (kind = "call" or kind = "apply") ) diff --git a/javascript/ql/src/semmle/javascript/Variables.qll b/javascript/ql/src/semmle/javascript/Variables.qll index 37128213192a..fd7f0d853744 100644 --- a/javascript/ql/src/semmle/javascript/Variables.qll +++ b/javascript/ql/src/semmle/javascript/Variables.qll @@ -319,7 +319,7 @@ class VarAccess extends @varaccess, VarRef, LexicalAccess { override predicate isLValue() { exists (Assignment assgn | assgn.getTarget() = this) or - exists (UpdateExpr upd | upd.getOperand().stripParens() = this) or + exists (UpdateExpr upd | upd.getOperand().getUnderlyingReference() = this) or exists (EnhancedForLoop efl | efl.getIterator() = this) or exists (BindingPattern p | this = p.getABindingVarRef() and p.isLValue()) } diff --git a/javascript/ql/src/semmle/javascript/dataflow/Sources.qll b/javascript/ql/src/semmle/javascript/dataflow/Sources.qll index bc7a4b1fbd2f..d9ba96706d10 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/Sources.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/Sources.qll @@ -125,7 +125,7 @@ abstract class SourceNode extends DataFlow::Node { */ DataFlow::CallNode getAMethodCall(string methodName) { exists (PropAccess pacc | - pacc = result.getCalleeNode().asExpr().stripParens() and + pacc = result.getCalleeNode().asExpr().getUnderlyingReference() and flowsToExpr(pacc.getBase()) and pacc.getPropertyName() = methodName ) diff --git a/javascript/ql/src/semmle/javascript/dataflow/internal/BasicExprTypeInference.qll b/javascript/ql/src/semmle/javascript/dataflow/internal/BasicExprTypeInference.qll index 51a95ccb9461..17fc893239f2 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/internal/BasicExprTypeInference.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/internal/BasicExprTypeInference.qll @@ -159,7 +159,7 @@ private class AnalyzedJSXEmptyExpression extends DataFlow::AnalyzedValueNode{ */ private class AnalyzedSuperCall extends DataFlow::AnalyzedValueNode { AnalyzedSuperCall() { - astNode = any(SuperCall sc).getCallee().stripParens() + astNode = any(SuperCall sc).getCallee().getUnderlyingValue() } override AbstractValue getALocalValue() { diff --git a/javascript/ql/src/semmle/javascript/frameworks/Bundling.qll b/javascript/ql/src/semmle/javascript/frameworks/Bundling.qll index 0adab311f6e3..f75ec87b69e9 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/Bundling.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/Bundling.qll @@ -36,7 +36,7 @@ predicate isBrowserifyBundle(ObjectExpr oe) { isBrowserifyBundledModule(p) ) and // the whole object must be passed to the module loader function - exists (CallExpr ce | ce.getCallee().stripParens() instanceof Function | + exists (CallExpr ce | ce.getCallee().getUnderlyingValue() instanceof Function | // the module loader function always has three arguments ce.getNumArgument() = 3 and // the first of which is the bundle @@ -140,10 +140,10 @@ private predicate isWebpackModule(FunctionExpr m) { */ predicate isWebpackBundle(ArrayExpr ae) { // ensure that there is at least one bundled module - isWebpackModule(ae.getAnElement().stripParens()) + isWebpackModule(ae.getAnElement().getUnderlyingValue()) and // furthermore, every element is either - forall (Expr elt | elt = ae.getAnElement().stripParens() | + forall (Expr elt | elt = ae.getAnElement().getUnderlyingValue() | // (1) a module isWebpackModule(elt) or @@ -158,7 +158,7 @@ predicate isWebpackBundle(ArrayExpr ae) { ) and // the whole array must be passed to a module loader function - exists (CallExpr ce | ce.getCallee().stripParens() instanceof Function | + exists (CallExpr ce | ce.getCallee().getUnderlyingValue() instanceof Function | // which is the bundle ce.getArgument(0) = ae ) diff --git a/javascript/ql/src/semmle/javascript/heuristics/SyntacticHeuristics.qll b/javascript/ql/src/semmle/javascript/heuristics/SyntacticHeuristics.qll index 50392a8cdf13..be6e212ec62e 100644 --- a/javascript/ql/src/semmle/javascript/heuristics/SyntacticHeuristics.qll +++ b/javascript/ql/src/semmle/javascript/heuristics/SyntacticHeuristics.qll @@ -16,10 +16,10 @@ import javascript bindingset[regexp] predicate isReadFrom(DataFlow::Node read, string regexp) { exists (DataFlow::Node actualRead | - actualRead = read.asExpr().stripParens().(LogOrExpr).getAnOperand().flow() or // unfold `x || y` once + actualRead = read.asExpr().getUnderlyingValue().(LogOrExpr).getAnOperand().flow() or // unfold `x || y` once actualRead = read | exists (string name | name.regexpMatch(regexp) | - actualRead.asExpr().stripParens().(VarAccess).getName() = name or + actualRead.asExpr().getUnderlyingValue().(VarAccess).getName() = name or actualRead.(DataFlow::PropRead).getPropertyName() = name or actualRead.(DataFlow::InvokeNode).getCalleeName() = "get" + name )