mirror of
https://github.com/github/codeql.git
synced 2026-01-01 00:27:24 +01:00
69 lines
2.1 KiB
Plaintext
69 lines
2.1 KiB
Plaintext
/**
|
|
* @name Illegal invocation
|
|
* @description Attempting to invoke a method or an arrow function using 'new',
|
|
* or invoking a constructor as a function, will cause a runtime
|
|
* error.
|
|
* @kind problem
|
|
* @problem.severity error
|
|
* @id js/illegal-invocation
|
|
* @tags correctness
|
|
* language-features
|
|
* @precision high
|
|
*/
|
|
|
|
import javascript
|
|
|
|
/**
|
|
* Holds if call site `cs` may invoke function `callee` as specified by `how`.
|
|
*/
|
|
predicate calls(DataFlow::InvokeNode cs, Function callee, string how) {
|
|
callee = cs.getACallee() and
|
|
(
|
|
cs instanceof DataFlow::CallNode and
|
|
not cs.asExpr() instanceof SuperCall and
|
|
how = "as a function"
|
|
or
|
|
cs instanceof DataFlow::NewNode and
|
|
how = "using 'new'"
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Holds if call site `cs` may illegally invoke function `callee` as specified by `how`;
|
|
* `calleeDesc` describes what kind of function `callee` is.
|
|
*/
|
|
predicate illegalInvocation(DataFlow::InvokeNode cs, Function callee, string calleeDesc, string how) {
|
|
calls(cs, callee, how) and
|
|
(
|
|
how = "as a function" and
|
|
callee instanceof Constructor and
|
|
calleeDesc = "a constructor"
|
|
or
|
|
how = "using 'new'" and
|
|
callee.isNonConstructible(calleeDesc)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Holds if `ce` is a call with at least one call target that isn't a constructor.
|
|
*/
|
|
predicate isCallToFunction(DataFlow::InvokeNode ce) {
|
|
ce instanceof DataFlow::CallNode and
|
|
exists(Function f | f = ce.getACallee() | not f instanceof Constructor)
|
|
}
|
|
|
|
from DataFlow::InvokeNode cs, Function callee, string calleeDesc, string how
|
|
where
|
|
illegalInvocation(cs, callee, calleeDesc, how) and
|
|
// filter out some easy cases
|
|
not isCallToFunction(cs) and
|
|
// conservatively only flag call sites where _all_ callees are illegal
|
|
forex(DataFlow::InvokeNode cs2, Function otherCallee |
|
|
cs2.getInvokeExpr() = cs.getInvokeExpr() and otherCallee = cs2.getACallee()
|
|
|
|
|
illegalInvocation(cs, otherCallee, _, _)
|
|
) and
|
|
// require that all callees are known
|
|
not cs.isIncomplete()
|
|
select cs, "Illegal invocation of $@ " + how + ".", callee, calleeDesc
|