Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
hvitved committed Sep 18, 2023
1 parent aa3bafe commit f582dbd
Show file tree
Hide file tree
Showing 6 changed files with 363 additions and 334 deletions.
27 changes: 26 additions & 1 deletion ruby/ql/lib/codeql/ruby/ApiGraphs.qll
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,9 @@ module API {
or
implicitCallEdge(pred, succ)
or
exists(DataFlow::HashLiteralNode splat | hashSplatEdge(splat, pred, succ))
exists(DataFlow::HashLiteralNode literal | hashSplatEdge(literal, pred, succ))

Check warning

Code scanning / CodeQL

Omittable 'exists' variable Warning

This exists variable can be omitted by using a don't-care expression
in this argument
.
or
exists(DataFlow::ArrayLiteralNode literal | splatEdge(literal, pred, succ))

Check warning

Code scanning / CodeQL

Omittable 'exists' variable Warning

This exists variable can be omitted by using a don't-care expression
in this argument
.
}

/**
Expand Down Expand Up @@ -1009,6 +1011,29 @@ module API {
)
}

pragma[nomagic]
private DataFlow::Node getSplatArgument(DataFlow::ArrayLiteralNode literal) {
result = DataFlowPrivate::TSynthSplatArgumentNode(literal.asExpr())
}

/**
* Holds if the epsilon edge `pred -> succ` should be generated to account for the members of an array literal.
*
* This currently exists because array literals are desugared to `Array.[]` calls, whose summary relies on `WithContent`.
* However, `contentEdge` does not currently generate edges for `WithContent` steps.
*/
bindingset[literal]
pragma[inline_late]
private predicate splatEdge(DataFlow::ArrayLiteralNode literal, ApiNode pred, ApiNode succ) {
exists(TypeTracker t |
pred = Impl::MkForwardNode(getALocalSourceStrict(getSplatArgument(literal)), t) and
succ = Impl::MkForwardNode(pragma[only_bind_out](literal), pragma[only_bind_out](t))
or
succ = Impl::MkBackwardNode(getALocalSourceStrict(getSplatArgument(literal)), t) and
pred = Impl::MkBackwardNode(pragma[only_bind_out](literal), pragma[only_bind_out](t))
)
}

pragma[nomagic]
private DataFlow::LocalSourceNode getAModuleReference(DataFlow::ModuleNode mod) {
result = mod.getAnImmediateReference()
Expand Down
11 changes: 7 additions & 4 deletions ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1331,8 +1331,10 @@ module ArgumentNodes {
exists(ArgumentPosition pos, int n |
arg.asExpr().(Argument).isArgumentOf(call_, pos) and
pos.isPositional(n) and
c = getSplatContent(n, false) and
not exists(int i | splatArgumentAt(call_, i) and i < n)
not exists(int i | splatArgumentAt(call_, i) and i < n) and
if call_ instanceof CfgNodes::ExprNodes::ArrayLiteralCfgNode
then c = getArrayContent(n)
else c = getSplatContent(n, false)
)
}

Expand Down Expand Up @@ -1742,7 +1744,7 @@ predicate expectsContent(Node n, ContentSet c) {
private newtype TDataFlowType =
TLambdaDataFlowType(Callable c) { c = any(LambdaSelfReferenceNode n).getCallable() } or
// TSynthHashSplatArgumentType(SynthHashSplatArgumentNode n) or
// TSynthSplatArgumentType(SynthSplatArgumentNode n) or
TSynthSplatArgumentType(SynthSplatArgumentNode n) or
TUnknownDataFlowType()

class DataFlowType extends TDataFlowType {
Expand Down Expand Up @@ -1772,13 +1774,14 @@ DataFlowType getNodeType(Node n) {
result = TLambdaDataFlowType(c)
)
or
// or
// result = TSynthHashSplatArgumentType(n)
// or
// result = TSynthSplatArgumentType(n)
// or
not n instanceof LambdaSelfReferenceNode and
not mustHaveLambdaType(n, _) and
// not n instanceof SynthHashSplatArgumentNode and
// not exists(TSynthSplatArgumentType(n)) and
// not n instanceof SynthSplatArgumentNode and
result = TUnknownDataFlowType()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ SummaryComponent interpretComponentSpecific(AccessPathToken c) {
or
arg = "hash-splat" and
ppos.isHashSplat()
or
arg = "splat" and
ppos.isSynthSplat()
)
or
result = interpretElementArg(c.getAnArgument("Element"))
Expand Down Expand Up @@ -229,6 +232,9 @@ string getParameterPosition(ParameterPosition pos) {
or
pos.isHashSplat() and
result = "hash-splat"
or
pos.isSynthSplat() and
result = "splat"
}

/** Gets the textual representation of an argument position in the format used for flow summaries. */
Expand Down
8 changes: 3 additions & 5 deletions ruby/ql/lib/codeql/ruby/frameworks/core/Array.qll
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,9 @@ module Array {
override MethodCall getACallSimple() { result = getAStaticArrayCall("[]") }

override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
exists(ArrayIndex i |
input = "Argument[" + i + "]" and
output = "ReturnValue.Element[" + i + "]" and
preservesValue = true
)
input = "Argument[splat].WithElement[any]" and
output = "ReturnValue" and
preservesValue = true
}
}

Expand Down
Loading

0 comments on commit f582dbd

Please sign in to comment.