mirror of
https://github.com/github/codeql.git
synced 2025-12-20 18:56:32 +01:00
introduce backtracking, and also marking join/slice calls
This commit is contained in:
@@ -4,16 +4,18 @@
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
The <code>concat</code> method on is pure and does not modify any of the input
|
||||
arrays. It is therefore generally an error to ignore the return value from a
|
||||
call to <code>concat</code>.
|
||||
The <code>concat</code>, <code>join</code> and <code>slice</code> methods are
|
||||
pure and does not modify any of the inputs or the array the method was called
|
||||
on. It is therefore generally an error to ignore the return value from a call
|
||||
to one of these methods.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Use the returned value from the call to <code>concat</code>.
|
||||
Use the returned value from the calls to <code>concat</code>, <code>join</code>
|
||||
or <code>slice</code>.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
@@ -26,19 +28,21 @@ function uses the <code>concat</code> method to add elements to the
|
||||
effect as the return value from <code>concat</code> is ignored.
|
||||
</p>
|
||||
|
||||
<sample src="examples/IgnoreConcat.js" />
|
||||
<sample src="examples/IgnoreArrayResult.js" />
|
||||
|
||||
<p>
|
||||
Assigning the returned value from the call to <code>concat</code> to the
|
||||
<code>arr</code> variable fixes the error.
|
||||
</p>
|
||||
|
||||
<sample src="examples/IgnoreConcatFixed.js" />
|
||||
<sample src="examples/IgnoreArrayResultFixed.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>Mozilla Developer Network: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat">Array concat</a>.</li>
|
||||
<li>Mozilla Developer Network: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">Array slice</a>.</li>
|
||||
<li>Mozilla Developer Network: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join">Array join</a>.</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
45
javascript/ql/src/Statements/IgnoreArrayResult.ql
Normal file
45
javascript/ql/src/Statements/IgnoreArrayResult.ql
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @name Ignoring result from pure array method
|
||||
* @description The array methods do not modify the array, ignoring the result of such a call is therefore generally an error.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id js/ignore-array-result
|
||||
* @tags maintainability,
|
||||
* correctness
|
||||
* @precision high
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import Expressions.ExprHasNoEffect
|
||||
|
||||
DataFlow::SourceNode callsArray(DataFlow::TypeBackTracker t, DataFlow::MethodCallNode call) {
|
||||
isIgnoredPureArrayCall(call) and
|
||||
(
|
||||
t.start() and
|
||||
result = call.getReceiver()
|
||||
or
|
||||
exists(DataFlow::TypeBackTracker t2 | result = callsArray(t2, call).backtrack(t2, t))
|
||||
)
|
||||
}
|
||||
|
||||
DataFlow::SourceNode callsArray(DataFlow::MethodCallNode call) {
|
||||
result = callsArray(DataFlow::TypeBackTracker::end(), call)
|
||||
}
|
||||
|
||||
predicate isIgnoredPureArrayCall(DataFlow::MethodCallNode call) {
|
||||
inVoidContext(call.asExpr()) and
|
||||
(
|
||||
call.getMethodName() = "concat" and
|
||||
call.getNumArgument() = 1
|
||||
or
|
||||
call.getMethodName() = "join" and
|
||||
call.getNumArgument() < 2
|
||||
or
|
||||
call.getMethodName() = "slice" and
|
||||
call.getNumArgument() < 3
|
||||
)
|
||||
}
|
||||
|
||||
from DataFlow::MethodCallNode call
|
||||
where callsArray(call) instanceof DataFlow::ArrayCreationNode
|
||||
select call, "Result from call to " + call.getMethodName() + " ignored."
|
||||
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* @name Ignoring return from concat
|
||||
* @description The concat method does not modify an array, ignoring the result of a call to concat is therefore generally an error.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id js/ignore-result-from-concat
|
||||
* @tags maintainability,
|
||||
* correctness
|
||||
* @precision high
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import Expressions.ExprHasNoEffect
|
||||
|
||||
DataFlow::SourceNode array(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result instanceof DataFlow::ArrayCreationNode
|
||||
or
|
||||
exists (DataFlow::TypeTracker t2 |
|
||||
result = array(t2).track(t2, t)
|
||||
)
|
||||
}
|
||||
|
||||
DataFlow::SourceNode array() { result = array(DataFlow::TypeTracker::end()) }
|
||||
|
||||
predicate isArrayMethod(DataFlow::MethodCallNode call) {
|
||||
call.getReceiver().getALocalSource() = array()
|
||||
}
|
||||
|
||||
predicate isIncomplete(DataFlow::Node node) {
|
||||
any(DataFlow::Incompleteness cause | node.analyze().getAValue().isIndefinite(cause)) != "global"
|
||||
}
|
||||
|
||||
from DataFlow::CallNode call
|
||||
where
|
||||
isArrayMethod(call) and
|
||||
call.getCalleeName() = "concat" and
|
||||
call.getNumArgument() = 1 and
|
||||
(call.getArgument(0).getALocalSource() = array() or isIncomplete(call.getArgument(0))) and
|
||||
not call.getArgument(0).asExpr().(ArrayExpr).getSize() = 0 and
|
||||
inVoidContext(call.asExpr())
|
||||
select call, "Return value from call to concat ignored."
|
||||
Reference in New Issue
Block a user