diff --git a/javascript/ql/src/Statements/IgnoreConcatReturn.qhelp b/javascript/ql/src/Statements/IgnoreArrayResult.qhelp similarity index 50% rename from javascript/ql/src/Statements/IgnoreConcatReturn.qhelp rename to javascript/ql/src/Statements/IgnoreArrayResult.qhelp index 1b69a61b3a9..b70ff1f1b32 100644 --- a/javascript/ql/src/Statements/IgnoreConcatReturn.qhelp +++ b/javascript/ql/src/Statements/IgnoreArrayResult.qhelp @@ -4,16 +4,18 @@

-The concat 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 concat. +The concat, join and slice 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.

-Use the returned value from the call to concat. +Use the returned value from the calls to concat, join +or slice.

@@ -26,19 +28,21 @@ function uses the concat method to add elements to the effect as the return value from concat is ignored.

- +

Assigning the returned value from the call to concat to the arr variable fixes the error.

- +
  • Mozilla Developer Network: Array concat.
  • +
  • Mozilla Developer Network: Array slice.
  • +
  • Mozilla Developer Network: Array join.
  • diff --git a/javascript/ql/src/Statements/IgnoreArrayResult.ql b/javascript/ql/src/Statements/IgnoreArrayResult.ql new file mode 100644 index 00000000000..b3703c6992d --- /dev/null +++ b/javascript/ql/src/Statements/IgnoreArrayResult.ql @@ -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." diff --git a/javascript/ql/src/Statements/IgnoreConcatReturn.ql b/javascript/ql/src/Statements/IgnoreConcatReturn.ql deleted file mode 100644 index 65c379b3437..00000000000 --- a/javascript/ql/src/Statements/IgnoreConcatReturn.ql +++ /dev/null @@ -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." diff --git a/javascript/ql/src/Statements/examples/IgnoreConcat.js b/javascript/ql/src/Statements/examples/IgnoreArrayResult.js similarity index 100% rename from javascript/ql/src/Statements/examples/IgnoreConcat.js rename to javascript/ql/src/Statements/examples/IgnoreArrayResult.js diff --git a/javascript/ql/src/Statements/examples/IgnoreConcatFixed.js b/javascript/ql/src/Statements/examples/IgnoreArrayResultFixed.js similarity index 100% rename from javascript/ql/src/Statements/examples/IgnoreConcatFixed.js rename to javascript/ql/src/Statements/examples/IgnoreArrayResultFixed.js diff --git a/javascript/ql/test/query-tests/Statements/IgnoreConcatReturn/IgnoreConcatReturn.expected b/javascript/ql/test/query-tests/Statements/IgnoreArrayResult/IgnoreArrayResult.expected similarity index 100% rename from javascript/ql/test/query-tests/Statements/IgnoreConcatReturn/IgnoreConcatReturn.expected rename to javascript/ql/test/query-tests/Statements/IgnoreArrayResult/IgnoreArrayResult.expected diff --git a/javascript/ql/test/query-tests/Statements/IgnoreConcatReturn/IgnoreConcatReturn.qlref b/javascript/ql/test/query-tests/Statements/IgnoreArrayResult/IgnoreArrayResult.qlref similarity index 100% rename from javascript/ql/test/query-tests/Statements/IgnoreConcatReturn/IgnoreConcatReturn.qlref rename to javascript/ql/test/query-tests/Statements/IgnoreArrayResult/IgnoreArrayResult.qlref diff --git a/javascript/ql/test/query-tests/Statements/IgnoreConcatReturn/tst.js b/javascript/ql/test/query-tests/Statements/IgnoreArrayResult/tst.js similarity index 100% rename from javascript/ql/test/query-tests/Statements/IgnoreConcatReturn/tst.js rename to javascript/ql/test/query-tests/Statements/IgnoreArrayResult/tst.js