Merge pull request #424 from esben-semmle/js/syntactic-nullOrUndefined

Approved by asger-semmle
This commit is contained in:
semmle-qlci
2018-11-08 10:52:44 +00:00
committed by GitHub
19 changed files with 37 additions and 37 deletions

View File

@@ -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()
)
}

View File

@@ -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())
}
/**

View File

@@ -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() |

View File

@@ -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)

View File

@@ -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()
}
}

View File

@@ -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()

View File

@@ -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
)
}

View File

@@ -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()
)
}
}

View File

@@ -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()
)
)
}

View File

@@ -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")

View File

@@ -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()
}
}

View File

@@ -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
}
}

View File

@@ -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()
}
}

View File

@@ -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")
)

View File

@@ -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())
}

View File

@@ -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
)

View File

@@ -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() {

View File

@@ -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
)

View File

@@ -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
)