Introduce Expr::getValueText

This commit is contained in:
Tom Hvitved
2021-10-01 11:00:51 +02:00
parent 0ea228e86f
commit 08225181c8
6 changed files with 639 additions and 3 deletions

View File

@@ -139,6 +139,8 @@ class ConstantReadAccess extends ConstantAccess {
result = lookupConst(resolveScopeExpr(this.getScopeExpr()), this.getName())
}
override string getValueText() { result = this.getValue().getValueText() }
final override string getAPrimaryQlClass() { result = "ConstantReadAccess" }
}

View File

@@ -1,4 +1,5 @@
private import codeql.ruby.AST
private import codeql.ruby.CFG
private import internal.AST
private import internal.TreeSitter
@@ -7,7 +8,12 @@ private import internal.TreeSitter
*
* This is the root QL class for all expressions.
*/
class Expr extends Stmt, TExpr { }
class Expr extends Stmt, TExpr {
/** Gets the textual (constant) value of this expression, if any. */
string getValueText() {
forex(CfgNodes::ExprCfgNode n | n = this.getAControlFlowNode() | result = n.getValueText())
}
}
/**
* A reference to the current object. For example:

View File

@@ -16,7 +16,7 @@ class Literal extends Expr, TLiteral {
* For complex literals, such as arrays, hashes, and strings with
* interpolations, this predicate has no result.
*/
string getValueText() { none() }
override string getValueText() { none() }
}
/**

View File

@@ -2,6 +2,7 @@
private import codeql.ruby.AST
private import codeql.ruby.controlflow.BasicBlocks
private import codeql.ruby.dataflow.SSA
private import ControlFlowGraph
private import internal.ControlFlowGraphImpl
private import internal.Splitting
@@ -98,6 +99,16 @@ class ExprCfgNode extends AstCfgNode {
/** Gets the underlying expression. */
Expr getExpr() { result = e }
private ExprCfgNode getSource() {
exists(Ssa::WriteDefinition def |
def.assigns(result) and
this = def.getARead()
)
}
/** Gets the textual (constant) value of this expression, if any. */
string getValueText() { result = this.getSource().getValueText() }
}
/** A control-flow node that wraps a return-like statement. */
@@ -164,7 +175,19 @@ abstract private class ExprChildMapping extends Expr {
/** Provides classes for control-flow nodes that wrap AST expressions. */
module ExprNodes {
// TODO: Add more classes
private class LiteralChildMapping extends ExprChildMapping, Literal {
override predicate relevantChild(Expr e) { none() }
}
/** A control-flow node that wraps an `ArrayLiteral` AST expression. */
class LiteralCfgNode extends ExprCfgNode {
override LiteralChildMapping e;
override Literal getExpr() { result = super.getExpr() }
override string getValueText() { result = e.getValueText() }
}
private class AssignExprChildMapping extends ExprChildMapping, AssignExpr {
override predicate relevantChild(Expr e) { e = this.getAnOperand() }
}
@@ -209,6 +232,49 @@ module ExprNodes {
/** Gets the right operand of this binary operation. */
final ExprCfgNode getRightOperand() { e.hasCfgChild(bo.getRightOperand(), this, result) }
final override string getValueText() {
exists(string left, string right, string op |
left = this.getLeftOperand().getValueText() and
right = this.getRightOperand().getValueText() and
op = this.getExpr().getOperator()
|
op = "+" and
(
result = (left.toInt() + right.toInt()).toString()
or
not (exists(left.toInt()) and exists(right.toInt())) and
result = (left.toFloat() + right.toFloat()).toString()
or
not (exists(left.toFloat()) and exists(right.toFloat())) and
result = left + right
)
or
op = "-" and
(
result = (left.toInt() - right.toInt()).toString()
or
not (exists(left.toInt()) and exists(right.toInt())) and
result = (left.toFloat() - right.toFloat()).toString()
)
or
op = "*" and
(
result = (left.toInt() * right.toInt()).toString()
or
not (exists(left.toInt()) and exists(right.toInt())) and
result = (left.toFloat() * right.toFloat()).toString()
)
or
op = "/" and
(
result = (left.toInt() / right.toInt()).toString()
or
not (exists(left.toInt()) and exists(right.toInt())) and
result = (left.toFloat() / right.toFloat()).toString()
)
)
}
}
private class BlockArgumentChildMapping extends ExprChildMapping, BlockArgument {