Ruby: Extract isArrayConstant

This predicate might be useful elsewhere.
This commit is contained in:
Harry Maclean
2022-05-23 13:34:06 +01:00
parent 301914d80c
commit b5a3d3c488
2 changed files with 22 additions and 13 deletions

View File

@@ -509,3 +509,23 @@ private module Cached {
}
import Cached
/**
* Holds if `e` is an array constructed from an array literal.
* Example:
* ```rb
* [1, 2, 3]
* C = [1, 2, 3]; C
* x = [1, 2, 3]; x
* ```
*/
predicate isArrayConstant(ExprCfgNode e, ArrayLiteralCfgNode arr) {
// [...]
e = arr
or
// C = [...]; C
e.(ExprNodes::ConstantReadAccessCfgNode).getExpr().getValue().getDesugared() = arr.getExpr()
or
// x = [...]; x
exists(Ssa::WriteDefinition def | def.getARead() = e and def.assigns(arr))
}

View File

@@ -5,6 +5,7 @@ private import codeql.ruby.DataFlow
private import codeql.ruby.CFG
private import codeql.ruby.controlflow.CfgNodes
private import codeql.ruby.dataflow.SSA
private import codeql.ruby.ast.internal.Constant
private predicate stringConstCompare(CfgNodes::ExprCfgNode g, CfgNode e, boolean branch) {
exists(CfgNodes::ExprNodes::ComparisonOperationCfgNode c |
@@ -137,19 +138,7 @@ deprecated class StringConstArrayInclusionCall extends DataFlow::BarrierGuard,
StringConstArrayInclusionCall() {
this.getMethodName() = "include?" and
this.getArgument(0) = checkedNode and
exists(ExprNodes::ArrayLiteralCfgNode arr |
// [...].include?
this.getReceiver() = arr
or
// C = [...]
// C.include?
this.getReceiver().(ExprNodes::ConstantReadAccessCfgNode).getExpr().getValue().getDesugared() =
arr.getExpr()
or
// x = [...]
// x.include?
exists(Ssa::WriteDefinition def | def.getARead() = this.getReceiver() and def.assigns(arr))
|
exists(ExprNodes::ArrayLiteralCfgNode arr | isArrayConstant(this.getReceiver(), arr) |
forall(ExprCfgNode elem | elem = arr.getAnArgument() |
elem instanceof ExprNodes::StringLiteralCfgNode
)