mirror of
https://github.com/github/codeql.git
synced 2026-05-03 12:45:27 +02:00
Merge branch 'main' into js-use-shared-cryptography
This commit is contained in:
BIN
ruby/Cargo.lock
generated
BIN
ruby/Cargo.lock
generated
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: One-line pattern matching
|
||||
compatibility: backwards
|
||||
ruby_match_pattern_def.rel: delete
|
||||
ruby_test_pattern_def.rel: delete
|
||||
@@ -11,7 +11,7 @@ flate2 = "1.0"
|
||||
node-types = { path = "../node-types" }
|
||||
tree-sitter = "0.20"
|
||||
tree-sitter-embedded-template = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template.git", rev = "a13085849cf69e2401ec44e38cffc3d73f22f3df" }
|
||||
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "7a1921bcfd90e3a04c1ad011059087aaf0168dd4" }
|
||||
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "206c7077164372c596ffa8eaadb9435c28941364" }
|
||||
clap = "3.0"
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3.3", features = ["env-filter"] }
|
||||
|
||||
@@ -12,4 +12,4 @@ node-types = { path = "../node-types" }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3.3", features = ["env-filter"] }
|
||||
tree-sitter-embedded-template = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template.git", rev = "a13085849cf69e2401ec44e38cffc3d73f22f3df" }
|
||||
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "7a1921bcfd90e3a04c1ad011059087aaf0168dd4" }
|
||||
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "206c7077164372c596ffa8eaadb9435c28941364" }
|
||||
|
||||
4
ruby/ql/lib/change-notes/2023-02-06-one-line-matches.md
Normal file
4
ruby/ql/lib/change-notes/2023-02-06-one-line-matches.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Ruby 3.1: one-line pattern matches are now supported. The AST nodes are named `TestPattern` (`expr in pattern`) and `MatchPattern` (`expr => pattern`).
|
||||
@@ -2,6 +2,15 @@
|
||||
|
||||
import files.FileSystem
|
||||
|
||||
bindingset[loc]
|
||||
pragma[inline_late]
|
||||
private string locationToString(Location loc) {
|
||||
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
|
||||
loc.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
|
||||
result = filepath + "@" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A location as given by a file, a start line, a start column,
|
||||
* an end line, and an end column.
|
||||
@@ -28,12 +37,8 @@ class Location extends @location {
|
||||
int getNumLines() { result = this.getEndLine() - this.getStartLine() + 1 }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() {
|
||||
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
|
||||
this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
|
||||
result = filepath + "@" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
pragma[inline]
|
||||
string toString() { result = locationToString(this) }
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
/**
|
||||
* Provides predicates for working with numeric values and their string
|
||||
* representations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets the integer value of `binary` when interpreted as binary. `binary` must
|
||||
* contain only the digits 0 and 1. For values greater than
|
||||
* 01111111111111111111111111111111 (2^31-1, the maximum value that `int` can
|
||||
* represent), there is no result.
|
||||
*
|
||||
* ```
|
||||
* "0" => 0
|
||||
* "01" => 1
|
||||
* "1010101" => 85
|
||||
* ```
|
||||
*/
|
||||
bindingset[binary]
|
||||
int parseBinaryInt(string binary) {
|
||||
exists(string stripped | stripped = stripLeadingZeros(binary) |
|
||||
stripped.length() <= 31 and
|
||||
result >= 0 and
|
||||
result =
|
||||
sum(int index, string c, int digit |
|
||||
c = stripped.charAt(index) and
|
||||
digit = "01".indexOf(c)
|
||||
|
|
||||
twoToThe(stripped.length() - 1 - index) * digit
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the integer value of `hex` when interpreted as hex. `hex` must be a
|
||||
* valid hexadecimal string. For values greater than 7FFFFFFF (2^31-1, the
|
||||
* maximum value that `int` can represent), there is no result.
|
||||
*
|
||||
* ```
|
||||
* "0" => 0
|
||||
* "FF" => 255
|
||||
* "f00d" => 61453
|
||||
* ```
|
||||
*/
|
||||
bindingset[hex]
|
||||
int parseHexInt(string hex) {
|
||||
exists(string stripped | stripped = stripLeadingZeros(hex) |
|
||||
stripped.length() <= 8 and
|
||||
result >= 0 and
|
||||
result =
|
||||
sum(int index, string c |
|
||||
c = stripped.charAt(index)
|
||||
|
|
||||
sixteenToThe(stripped.length() - 1 - index) * toHex(c)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the integer value of `octal` when interpreted as octal. `octal` must be
|
||||
* a valid octal string containing only the digits 0-7. For values greater than
|
||||
* 17777777777 (2^31-1, the maximum value that `int` can represent), there is no
|
||||
* result.
|
||||
*
|
||||
* ```
|
||||
* "0" => 0
|
||||
* "77" => 63
|
||||
* "76543210" => 16434824
|
||||
* ```
|
||||
*/
|
||||
bindingset[octal]
|
||||
int parseOctalInt(string octal) {
|
||||
exists(string stripped | stripped = stripLeadingZeros(octal) |
|
||||
stripped.length() <= 11 and
|
||||
result >= 0 and
|
||||
result =
|
||||
sum(int index, string c, int digit |
|
||||
c = stripped.charAt(index) and
|
||||
digit = "01234567".indexOf(c)
|
||||
|
|
||||
eightToThe(stripped.length() - 1 - index) * digit
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the integer value of the `hex` char. */
|
||||
private int toHex(string hex) {
|
||||
hex = [0 .. 9].toString() and
|
||||
result = hex.toInt()
|
||||
or
|
||||
result = 10 and hex = ["a", "A"]
|
||||
or
|
||||
result = 11 and hex = ["b", "B"]
|
||||
or
|
||||
result = 12 and hex = ["c", "C"]
|
||||
or
|
||||
result = 13 and hex = ["d", "D"]
|
||||
or
|
||||
result = 14 and hex = ["e", "E"]
|
||||
or
|
||||
result = 15 and hex = ["f", "F"]
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of 16 to the power of `n`. Holds only for `n` in the range
|
||||
* 0..7 (inclusive).
|
||||
*/
|
||||
int sixteenToThe(int n) {
|
||||
// 16**7 is the largest power of 16 that fits in an int.
|
||||
n in [0 .. 7] and result = 1.bitShiftLeft(4 * n)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of 8 to the power of `n`. Holds only for `n` in the range
|
||||
* 0..10 (inclusive).
|
||||
*/
|
||||
int eightToThe(int n) {
|
||||
// 8**10 is the largest power of 8 that fits in an int.
|
||||
n in [0 .. 10] and result = 1.bitShiftLeft(3 * n)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of 2 to the power of `n`. Holds only for `n` in the range
|
||||
* 0..30 (inclusive).
|
||||
*/
|
||||
int twoToThe(int n) { n in [0 .. 30] and result = 1.bitShiftLeft(n) }
|
||||
|
||||
/** Gets `s` with any leading "0" characters removed. */
|
||||
bindingset[s]
|
||||
private string stripLeadingZeros(string s) { result = s.regexpCapture("0*(.*)", 1) }
|
||||
@@ -478,15 +478,11 @@ class WhenClause extends AstNode, TWhenClause {
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class InClause extends AstNode, TInClause {
|
||||
private Ruby::InClause g;
|
||||
|
||||
InClause() { this = TInClause(g) }
|
||||
|
||||
class InClause extends AstNode instanceof InClauseImpl {
|
||||
final override string getAPrimaryQlClass() { result = "InClause" }
|
||||
|
||||
/** Gets the body of this case-in expression. */
|
||||
final Stmt getBody() { toGenerated(result) = g.getBody() }
|
||||
final Stmt getBody() { result = super.getBody() }
|
||||
|
||||
/**
|
||||
* Gets the pattern in this case-in expression. In the
|
||||
@@ -498,7 +494,7 @@ class InClause extends AstNode, TInClause {
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
final CasePattern getPattern() { toGenerated(result) = g.getPattern() }
|
||||
final CasePattern getPattern() { result = super.getPattern() }
|
||||
|
||||
/**
|
||||
* Gets the pattern guard condition in this case-in expression. In the
|
||||
@@ -510,7 +506,7 @@ class InClause extends AstNode, TInClause {
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
final Expr getCondition() { toGenerated(result) = g.getGuard().getAFieldOrChild() }
|
||||
final Expr getCondition() { result = super.getCondition() }
|
||||
|
||||
/**
|
||||
* Holds if the pattern guard in this case-in expression is an `if` condition. For example:
|
||||
@@ -520,7 +516,7 @@ class InClause extends AstNode, TInClause {
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
predicate hasIfCondition() { g.getGuard() instanceof Ruby::IfGuard }
|
||||
predicate hasIfCondition() { super.hasIfCondition() }
|
||||
|
||||
/**
|
||||
* Holds if the pattern guard in this case-in expression is an `unless` condition. For example:
|
||||
@@ -530,12 +526,12 @@ class InClause extends AstNode, TInClause {
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
predicate hasUnlessCondition() { g.getGuard() instanceof Ruby::UnlessGuard }
|
||||
predicate hasUnlessCondition() { super.hasUnlessCondition() }
|
||||
|
||||
final override string toString() { result = "in ... then ..." }
|
||||
|
||||
final override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
result = AstNode.super.getAChild(pred)
|
||||
or
|
||||
pred = "getBody" and result = this.getBody()
|
||||
or
|
||||
@@ -545,6 +541,88 @@ class InClause extends AstNode, TInClause {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A one-line pattern match using the `=>` operator. For example:
|
||||
* ```rb
|
||||
* foo => Point{ x:, y: }
|
||||
* ```
|
||||
*/
|
||||
class MatchPattern extends Expr, TMatchPattern {
|
||||
private Ruby::MatchPattern g;
|
||||
|
||||
MatchPattern() { this = TMatchPattern(g) }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "MatchPattern" }
|
||||
|
||||
/**
|
||||
* Gets the expression being compared. For example, `foo` in the following example.
|
||||
* ```rb
|
||||
* foo => Point{ x:, y: }
|
||||
* ```
|
||||
*/
|
||||
final Expr getValue() { toGenerated(result) = g.getValue() }
|
||||
|
||||
/**
|
||||
* Gets the pattern in this `=>` expression. In the
|
||||
* following example, the pattern is `Point{ x:, y: }`.
|
||||
* ```rb
|
||||
* foo => Point{ x:, y: }
|
||||
* ```
|
||||
*/
|
||||
final CasePattern getPattern() { toGenerated(result) = g.getPattern() }
|
||||
|
||||
final override string toString() { result = "... => ..." }
|
||||
|
||||
final override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = "getPattern" and result = this.getPattern()
|
||||
or
|
||||
pred = "getValue" and result = this.getValue()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A one-line pattern match using the `in` operator. For example:
|
||||
* ```rb
|
||||
* foo in Point{ x:, y: }
|
||||
* ```
|
||||
*/
|
||||
class TestPattern extends Expr, TTestPattern {
|
||||
private Ruby::TestPattern g;
|
||||
|
||||
TestPattern() { this = TTestPattern(g) }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "TestPattern" }
|
||||
|
||||
/**
|
||||
* Gets the expression being compared. For example, `foo` in the following example.
|
||||
* ```rb
|
||||
* foo in Point{ x:, y: }
|
||||
* ```
|
||||
*/
|
||||
final Expr getValue() { toGenerated(result) = g.getValue() }
|
||||
|
||||
/**
|
||||
* Gets the pattern in this `in` expression. In the
|
||||
* following example, the pattern is `Point{ x:, y: }`.
|
||||
* ```rb
|
||||
* foo in Point{ x:, y: }
|
||||
* ```
|
||||
*/
|
||||
final CasePattern getPattern() { toGenerated(result) = g.getPattern() }
|
||||
|
||||
final override string toString() { result = "... in ..." }
|
||||
|
||||
final override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = "getPattern" and result = this.getPattern()
|
||||
or
|
||||
pred = "getValue" and result = this.getValue()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A loop. That is, a `for` loop, a `while` or `until` loop, or their
|
||||
* expression-modifier variants.
|
||||
|
||||
@@ -97,12 +97,16 @@ private module Cached {
|
||||
} or
|
||||
TBlockArgument(Ruby::BlockArgument g) or
|
||||
TBlockParameter(Ruby::BlockParameter g) or
|
||||
TBooleanLiteralSynth(Ast::AstNode parent, int i, boolean value) {
|
||||
mkSynthChild(BooleanLiteralKind(value), parent, i)
|
||||
} or
|
||||
TBraceBlockSynth(Ast::AstNode parent, int i) { mkSynthChild(BraceBlockKind(), parent, i) } or
|
||||
TBraceBlockReal(Ruby::Block g) { not g.getParent() instanceof Ruby::Lambda } or
|
||||
TBreakStmt(Ruby::Break g) or
|
||||
TCaseEqExpr(Ruby::Binary g) { g instanceof @ruby_binary_equalequalequal } or
|
||||
TCaseExpr(Ruby::Case g) or
|
||||
TCaseMatch(Ruby::CaseMatch g) or
|
||||
TCaseMatchReal(Ruby::CaseMatch g) or
|
||||
TCaseMatchSynth(Ast::AstNode parent, int i) { mkSynthChild(CaseMatchKind(), parent, i) } or
|
||||
TCharacterLiteral(Ruby::Character g) or
|
||||
TClassDeclaration(Ruby::Class g) or
|
||||
TClassVariableAccessReal(Ruby::ClassVariable g, Ast::ClassVariable v) {
|
||||
@@ -129,7 +133,8 @@ private module Cached {
|
||||
TDo(Ruby::Do g) or
|
||||
TDoBlock(Ruby::DoBlock g) { not g.getParent() instanceof Ruby::Lambda } or
|
||||
TElementReference(Ruby::ElementReference g) or
|
||||
TElse(Ruby::Else g) or
|
||||
TElseReal(Ruby::Else g) or
|
||||
TElseSynth(Ast::AstNode parent, int i) { mkSynthChild(ElseKind(), parent, i) } or
|
||||
TElsif(Ruby::Elsif g) or
|
||||
TEmptyStmt(Ruby::EmptyStatement g) or
|
||||
TEncoding(Ruby::Encoding g) or
|
||||
@@ -168,7 +173,8 @@ private module Cached {
|
||||
TIfReal(Ruby::If g) or
|
||||
TIfSynth(Ast::AstNode parent, int i) { mkSynthChild(IfKind(), parent, i) } or
|
||||
TIfModifierExpr(Ruby::IfModifier g) or
|
||||
TInClause(Ruby::InClause g) or
|
||||
TInClauseReal(Ruby::InClause g) or
|
||||
TInClauseSynth(Ast::AstNode parent, int i) { mkSynthChild(InClauseKind(), parent, i) } or
|
||||
TInstanceVariableAccessReal(Ruby::InstanceVariable g, Ast::InstanceVariable v) {
|
||||
InstanceVariableAccess::range(g, v)
|
||||
} or
|
||||
@@ -207,6 +213,7 @@ private module Cached {
|
||||
g instanceof @ruby_binary_or or g instanceof @ruby_binary_pipepipe
|
||||
} or
|
||||
TLogicalOrExprSynth(Ast::AstNode parent, int i) { mkSynthChild(LogicalOrExprKind(), parent, i) } or
|
||||
TMatchPattern(Ruby::MatchPattern g) or
|
||||
TMethod(Ruby::Method g) or
|
||||
TMethodCallSynth(Ast::AstNode parent, int i, string name, boolean setter, int arity) {
|
||||
mkSynthChild(MethodCallKind(name, setter, arity), parent, i)
|
||||
@@ -305,6 +312,7 @@ private module Cached {
|
||||
TSubshellLiteral(Ruby::Subshell g) or
|
||||
TSymbolArrayLiteral(Ruby::SymbolArray g) or
|
||||
TTernaryIfExpr(Ruby::Conditional g) or
|
||||
TTestPattern(Ruby::TestPattern g) or
|
||||
TThen(Ruby::Then g) or
|
||||
TTokenConstantAccess(Ruby::Constant g) {
|
||||
// A tree-sitter `constant` token is a read of that constant in any context
|
||||
@@ -344,45 +352,45 @@ private module Cached {
|
||||
TAssignMulExpr or TAssignRShiftExpr or TAssignSubExpr or TBareStringLiteral or
|
||||
TBareSymbolLiteral or TBeginBlock or TBeginExpr or TBitwiseAndExprReal or
|
||||
TBitwiseOrExprReal or TBitwiseXorExprReal or TBlockArgument or TBlockParameter or
|
||||
TBraceBlockReal or TBreakStmt or TCaseEqExpr or TCaseExpr or TCaseMatch or
|
||||
TBraceBlockReal or TBreakStmt or TCaseEqExpr or TCaseExpr or TCaseMatchReal or
|
||||
TCharacterLiteral or TClassDeclaration or TClassVariableAccessReal or TComplementExpr or
|
||||
TComplexLiteral or TDefinedExpr or TDelimitedSymbolLiteral or TDestructuredLeftAssignment or
|
||||
TDestructuredParameter or TDivExprReal or TDo or TDoBlock or TElementReference or TElse or
|
||||
TElsif or TEmptyStmt or TEncoding or TEndBlock or TEnsure or TEqExpr or TExponentExprReal or
|
||||
TFalseLiteral or TFile or TFindPattern or TFloatLiteral or TForExpr or TForwardParameter or
|
||||
TForwardArgument or TGEExpr or TGTExpr or TGlobalVariableAccessReal or
|
||||
TDestructuredParameter or TDivExprReal or TDo or TDoBlock or TElementReference or
|
||||
TElseReal or TElsif or TEmptyStmt or TEncoding or TEndBlock or TEnsure or TEqExpr or
|
||||
TExponentExprReal or TFalseLiteral or TFile or TFindPattern or TFloatLiteral or TForExpr or
|
||||
TForwardParameter or TForwardArgument or TGEExpr or TGTExpr or TGlobalVariableAccessReal or
|
||||
THashKeySymbolLiteral or THashLiteral or THashPattern or THashSplatExpr or
|
||||
THashSplatNilParameter or THashSplatParameter or THereDoc or TIdentifierMethodCall or
|
||||
TIfReal or TIfModifierExpr or TInClause or TInstanceVariableAccessReal or
|
||||
TIfReal or TIfModifierExpr or TInClauseReal or TInstanceVariableAccessReal or
|
||||
TIntegerLiteralReal or TKeywordParameter or TLEExpr or TLShiftExprReal or TLTExpr or
|
||||
TLambda or TLeftAssignmentList or TLine or TLocalVariableAccessReal or
|
||||
TLogicalAndExprReal or TLogicalOrExprReal or TMethod or TModuleDeclaration or
|
||||
TModuloExprReal or TMulExprReal or TNEExpr or TNextStmt or TNilLiteralReal or
|
||||
TNoRegExpMatchExpr or TNotExpr or TOptionalParameter or TPair or TParenthesizedExpr or
|
||||
TParenthesizedPattern or TRShiftExprReal or TRangeLiteralReal or TRationalLiteral or
|
||||
TRedoStmt or TRegExpLiteral or TRegExpMatchExpr or TRegularArrayLiteral or
|
||||
TRegularMethodCall or TRegularStringLiteral or TRegularSuperCall or TRescueClause or
|
||||
TRescueModifierExpr or TRetryStmt or TReturnStmt or TScopeResolutionConstantAccess or
|
||||
TSelfReal or TSimpleParameterReal or TSimpleSymbolLiteral or TSingletonClass or
|
||||
TSingletonMethod or TSpaceshipExpr or TSplatExprReal or TSplatParameter or
|
||||
TStringArrayLiteral or TStringConcatenation or TStringEscapeSequenceComponent or
|
||||
TStringInterpolationComponent or TStringTextComponent or TSubExprReal or TSubshellLiteral or
|
||||
TSymbolArrayLiteral or TTernaryIfExpr or TThen or TTokenConstantAccess or
|
||||
TTokenMethodName or TTokenSuperCall or TToplevel or TTrueLiteral or TUnaryMinusExpr or
|
||||
TUnaryPlusExpr or TUndefStmt or TUnlessExpr or TUnlessModifierExpr or TUntilExpr or
|
||||
TUntilModifierExpr or TReferencePattern or TWhenClause or TWhileExpr or
|
||||
TWhileModifierExpr or TYieldCall;
|
||||
TLogicalAndExprReal or TLogicalOrExprReal or TMethod or TMatchPattern or
|
||||
TModuleDeclaration or TModuloExprReal or TMulExprReal or TNEExpr or TNextStmt or
|
||||
TNilLiteralReal or TNoRegExpMatchExpr or TNotExpr or TOptionalParameter or TPair or
|
||||
TParenthesizedExpr or TParenthesizedPattern or TRShiftExprReal or TRangeLiteralReal or
|
||||
TRationalLiteral or TRedoStmt or TRegExpLiteral or TRegExpMatchExpr or
|
||||
TRegularArrayLiteral or TRegularMethodCall or TRegularStringLiteral or TRegularSuperCall or
|
||||
TRescueClause or TRescueModifierExpr or TRetryStmt or TReturnStmt or
|
||||
TScopeResolutionConstantAccess or TSelfReal or TSimpleParameterReal or
|
||||
TSimpleSymbolLiteral or TSingletonClass or TSingletonMethod or TSpaceshipExpr or
|
||||
TSplatExprReal or TSplatParameter or TStringArrayLiteral or TStringConcatenation or
|
||||
TStringEscapeSequenceComponent or TStringInterpolationComponent or TStringTextComponent or
|
||||
TSubExprReal or TSubshellLiteral or TSymbolArrayLiteral or TTernaryIfExpr or TTestPattern or
|
||||
TThen or TTokenConstantAccess or TTokenMethodName or TTokenSuperCall or TToplevel or
|
||||
TTrueLiteral or TUnaryMinusExpr or TUnaryPlusExpr or TUndefStmt or TUnlessExpr or
|
||||
TUnlessModifierExpr or TUntilExpr or TUntilModifierExpr or TReferencePattern or
|
||||
TWhenClause or TWhileExpr or TWhileModifierExpr or TYieldCall;
|
||||
|
||||
class TAstNodeSynth =
|
||||
TAddExprSynth or TAssignExprSynth or TBitwiseAndExprSynth or TBitwiseOrExprSynth or
|
||||
TBitwiseXorExprSynth or TBraceBlockSynth or TClassVariableAccessSynth or
|
||||
TConstantReadAccessSynth or TConstantWriteAccessSynth or TDivExprSynth or
|
||||
TExponentExprSynth or TGlobalVariableAccessSynth or TIfSynth or
|
||||
TInstanceVariableAccessSynth or TIntegerLiteralSynth or TLShiftExprSynth or
|
||||
TLocalVariableAccessSynth or TLogicalAndExprSynth or TLogicalOrExprSynth or
|
||||
TMethodCallSynth or TModuloExprSynth or TMulExprSynth or TNilLiteralSynth or
|
||||
TRShiftExprSynth or TRangeLiteralSynth or TSelfSynth or TSimpleParameterSynth or
|
||||
TSplatExprSynth or TStmtSequenceSynth or TSubExprSynth;
|
||||
TBitwiseXorExprSynth or TBraceBlockSynth or TBooleanLiteralSynth or TCaseMatchSynth or
|
||||
TClassVariableAccessSynth or TConstantReadAccessSynth or TConstantWriteAccessSynth or
|
||||
TDivExprSynth or TElseSynth or TExponentExprSynth or TGlobalVariableAccessSynth or
|
||||
TIfSynth or TInClauseSynth or TInstanceVariableAccessSynth or TIntegerLiteralSynth or
|
||||
TLShiftExprSynth or TLocalVariableAccessSynth or TLogicalAndExprSynth or
|
||||
TLogicalOrExprSynth or TMethodCallSynth or TModuloExprSynth or TMulExprSynth or
|
||||
TNilLiteralSynth or TRShiftExprSynth or TRangeLiteralSynth or TSelfSynth or
|
||||
TSimpleParameterSynth or TSplatExprSynth or TStmtSequenceSynth or TSubExprSynth;
|
||||
|
||||
/**
|
||||
* Gets the underlying TreeSitter entity for a given AST node. This does not
|
||||
@@ -424,7 +432,7 @@ private module Cached {
|
||||
n = TBreakStmt(result) or
|
||||
n = TCaseEqExpr(result) or
|
||||
n = TCaseExpr(result) or
|
||||
n = TCaseMatch(result) or
|
||||
n = TCaseMatchReal(result) or
|
||||
n = TCharacterLiteral(result) or
|
||||
n = TClassDeclaration(result) or
|
||||
n = TClassVariableAccessReal(result, _) or
|
||||
@@ -437,7 +445,7 @@ private module Cached {
|
||||
n = TDoBlock(result) or
|
||||
n = TDo(result) or
|
||||
n = TElementReference(result) or
|
||||
n = TElse(result) or
|
||||
n = TElseReal(result) or
|
||||
n = TElsif(result) or
|
||||
n = TEmptyStmt(result) or
|
||||
n = TEncoding(result) or
|
||||
@@ -465,7 +473,7 @@ private module Cached {
|
||||
n = TIdentifierMethodCall(result) or
|
||||
n = TIfModifierExpr(result) or
|
||||
n = TIfReal(result) or
|
||||
n = TInClause(result) or
|
||||
n = TInClauseReal(result) or
|
||||
n = TInstanceVariableAccessReal(result, _) or
|
||||
n = TIntegerLiteralReal(result) or
|
||||
n = TKeywordParameter(result) or
|
||||
@@ -478,6 +486,7 @@ private module Cached {
|
||||
n = TLogicalOrExprReal(result) or
|
||||
n = TLShiftExprReal(result) or
|
||||
n = TLTExpr(result) or
|
||||
n = TMatchPattern(result) or
|
||||
n = TMethod(result) or
|
||||
n = TModuleDeclaration(result) or
|
||||
n = TModuloExprReal(result) or
|
||||
@@ -528,6 +537,7 @@ private module Cached {
|
||||
n = TSubshellLiteral(result) or
|
||||
n = TSymbolArrayLiteral(result) or
|
||||
n = TTernaryIfExpr(result) or
|
||||
n = TTestPattern(result) or
|
||||
n = TThen(result) or
|
||||
n = TTokenConstantAccess(result) or
|
||||
n = TTokenMethodName(result) or
|
||||
@@ -563,8 +573,12 @@ private module Cached {
|
||||
or
|
||||
result = TBitwiseXorExprSynth(parent, i)
|
||||
or
|
||||
result = TBooleanLiteralSynth(parent, i, _)
|
||||
or
|
||||
result = TBraceBlockSynth(parent, i)
|
||||
or
|
||||
result = TCaseMatchSynth(parent, i)
|
||||
or
|
||||
result = TClassVariableAccessSynth(parent, i, _)
|
||||
or
|
||||
result = TConstantReadAccessSynth(parent, i, _)
|
||||
@@ -573,12 +587,16 @@ private module Cached {
|
||||
or
|
||||
result = TDivExprSynth(parent, i)
|
||||
or
|
||||
result = TElseSynth(parent, i)
|
||||
or
|
||||
result = TExponentExprSynth(parent, i)
|
||||
or
|
||||
result = TGlobalVariableAccessSynth(parent, i, _)
|
||||
or
|
||||
result = TIfSynth(parent, i)
|
||||
or
|
||||
result = TInClauseSynth(parent, i)
|
||||
or
|
||||
result = TInstanceVariableAccessSynth(parent, i, _)
|
||||
or
|
||||
result = TIntegerLiteralSynth(parent, i, _)
|
||||
@@ -669,8 +687,12 @@ TAstNodeReal fromGenerated(Ruby::AstNode n) { n = toGenerated(result) }
|
||||
|
||||
class TCall = TMethodCall or TYieldCall;
|
||||
|
||||
class TCaseMatch = TCaseMatchReal or TCaseMatchSynth;
|
||||
|
||||
class TCase = TCaseExpr or TCaseMatch;
|
||||
|
||||
class TInClause = TInClauseReal or TInClauseSynth;
|
||||
|
||||
class TMethodCall =
|
||||
TMethodCallSynth or TIdentifierMethodCall or TRegularMethodCall or TElementReference or
|
||||
TSuperCall or TUnaryOperation or TBinaryOperation;
|
||||
@@ -701,10 +723,13 @@ class TDestructuredLhsExpr = TDestructuredLeftAssignment or TLeftAssignmentList;
|
||||
class TExpr =
|
||||
TSelf or TArgumentList or TRescueClause or TRescueModifierExpr or TPair or TStringConcatenation or
|
||||
TCall or TBlockArgument or TConstantAccess or TControlExpr or TLiteral or TCallable or
|
||||
TVariableAccess or TStmtSequence or TOperation or TForwardArgument or TDestructuredLhsExpr;
|
||||
TVariableAccess or TStmtSequence or TOperation or TForwardArgument or TDestructuredLhsExpr or
|
||||
TMatchPattern or TTestPattern;
|
||||
|
||||
class TSplatExpr = TSplatExprReal or TSplatExprSynth;
|
||||
|
||||
class TElse = TElseReal or TElseSynth;
|
||||
|
||||
class TStmtSequence =
|
||||
TBeginBlock or TEndBlock or TThen or TElse or TDo or TEnsure or TStringInterpolationComponent or
|
||||
TBlock or TBodyStmt or TParenthesizedExpr or TStmtSequenceSynth;
|
||||
@@ -722,7 +747,7 @@ class TNumericLiteral = TIntegerLiteral or TFloatLiteral or TRationalLiteral or
|
||||
|
||||
class TIntegerLiteral = TIntegerLiteralReal or TIntegerLiteralSynth;
|
||||
|
||||
class TBooleanLiteral = TTrueLiteral or TFalseLiteral;
|
||||
class TBooleanLiteral = TTrueLiteral or TFalseLiteral or TBooleanLiteralSynth;
|
||||
|
||||
class TStringTextComponentNonRegexp =
|
||||
TStringTextComponentNonRegexpStringOrHeredocContent or
|
||||
|
||||
@@ -21,10 +21,10 @@ class CaseWhenClause extends CaseExprImpl, TCaseExpr {
|
||||
}
|
||||
}
|
||||
|
||||
class CaseMatch extends CaseExprImpl, TCaseMatch {
|
||||
class CaseMatch extends CaseExprImpl, TCaseMatchReal {
|
||||
private Ruby::CaseMatch g;
|
||||
|
||||
CaseMatch() { this = TCaseMatch(g) }
|
||||
CaseMatch() { this = TCaseMatchReal(g) }
|
||||
|
||||
final override Expr getValue() { toGenerated(result) = g.getValue() }
|
||||
|
||||
@@ -34,3 +34,53 @@ class CaseMatch extends CaseExprImpl, TCaseMatch {
|
||||
n = count(g.getClauses(_)) and toGenerated(result) = g.getElse()
|
||||
}
|
||||
}
|
||||
|
||||
class CaseMatchSynth extends CaseExprImpl, TCaseMatchSynth {
|
||||
CaseMatchSynth() { this = TCaseMatchSynth(_, _) }
|
||||
|
||||
final override Expr getValue() { synthChild(this, 0, result) }
|
||||
|
||||
final override AstNode getBranch(int n) { n >= 0 and synthChild(this, n + 1, result) }
|
||||
}
|
||||
|
||||
abstract class InClauseImpl extends AstNode, TInClause {
|
||||
abstract Stmt getBody();
|
||||
|
||||
abstract CasePattern getPattern();
|
||||
|
||||
Expr getCondition() { none() }
|
||||
|
||||
predicate hasIfCondition() { none() }
|
||||
|
||||
predicate hasUnlessCondition() { none() }
|
||||
}
|
||||
|
||||
class InClauseReal extends InClauseImpl, TInClauseReal {
|
||||
private Ruby::InClause g;
|
||||
|
||||
InClauseReal() { this = TInClauseReal(g) }
|
||||
|
||||
final override Stmt getBody() { toGenerated(result) = g.getBody() }
|
||||
|
||||
final override CasePattern getPattern() { toGenerated(result) = g.getPattern() }
|
||||
|
||||
final override Expr getCondition() { toGenerated(result) = g.getGuard().getAFieldOrChild() }
|
||||
|
||||
final override predicate hasIfCondition() { g.getGuard() instanceof Ruby::IfGuard }
|
||||
|
||||
final override predicate hasUnlessCondition() { g.getGuard() instanceof Ruby::UnlessGuard }
|
||||
}
|
||||
|
||||
class InClauseSynth extends InClauseImpl, TInClauseSynth {
|
||||
InClauseSynth() { this = TInClauseSynth(_, _) }
|
||||
|
||||
final override Stmt getBody() { synthChild(this, 1, result) }
|
||||
|
||||
final override CasePattern getPattern() { synthChild(this, 0, result) }
|
||||
|
||||
final override Expr getCondition() { none() }
|
||||
|
||||
final override predicate hasIfCondition() { none() }
|
||||
|
||||
final override predicate hasUnlessCondition() { none() }
|
||||
}
|
||||
|
||||
@@ -19,16 +19,24 @@ class Then extends StmtSequence, TThen {
|
||||
final override string toString() { result = "then ..." }
|
||||
}
|
||||
|
||||
class Else extends StmtSequence, TElse {
|
||||
class Else extends StmtSequence, TElseReal {
|
||||
private Ruby::Else g;
|
||||
|
||||
Else() { this = TElse(g) }
|
||||
Else() { this = TElseReal(g) }
|
||||
|
||||
override Stmt getStmt(int n) { toGenerated(result) = g.getChild(n) }
|
||||
|
||||
final override string toString() { result = "else ..." }
|
||||
}
|
||||
|
||||
class ElseSynth extends StmtSequence, TElseSynth {
|
||||
ElseSynth() { this = TElseSynth(_, _) }
|
||||
|
||||
override Stmt getStmt(int n) { synthChild(this, n, result) }
|
||||
|
||||
final override string toString() { result = "else ..." }
|
||||
}
|
||||
|
||||
class Do extends StmtSequence, TDo {
|
||||
private Ruby::Do g;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ private import Constant
|
||||
private import TreeSitter
|
||||
private import codeql.ruby.ast.internal.Scope
|
||||
private import codeql.ruby.controlflow.CfgNodes
|
||||
private import codeql.NumberUtils
|
||||
private import codeql.util.Numbers
|
||||
|
||||
int parseInteger(Ruby::Integer i) {
|
||||
exists(string s | s = i.getValue().toLowerCase().replaceAll("_", "") |
|
||||
@@ -149,6 +149,12 @@ class FalseLiteral extends BooleanLiteralImpl, TFalseLiteral {
|
||||
final override boolean getValue() { result = false }
|
||||
}
|
||||
|
||||
class BooleanLiteralSynth extends BooleanLiteralImpl, TBooleanLiteralSynth {
|
||||
final override string toString() { result = this.getValue().toString() }
|
||||
|
||||
final override boolean getValue() { this = TBooleanLiteralSynth(_, _, result) }
|
||||
}
|
||||
|
||||
class EncodingLiteralImpl extends Expr, TEncoding {
|
||||
private Ruby::Encoding g;
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@ deprecated class TuplePatternImpl extends Ruby::AstNode {
|
||||
* Holds if `node` is a case pattern.
|
||||
*/
|
||||
predicate casePattern(Ruby::AstNode node) {
|
||||
node = any(Ruby::TestPattern parent).getPattern()
|
||||
or
|
||||
node = any(Ruby::MatchPattern parent).getPattern()
|
||||
or
|
||||
node = any(Ruby::InClause parent).getPattern()
|
||||
or
|
||||
node = any(Ruby::ArrayPattern parent).getChild(_).(Ruby::UnderscorePatternExpr)
|
||||
|
||||
@@ -16,12 +16,16 @@ newtype SynthKind =
|
||||
BitwiseAndExprKind() or
|
||||
BitwiseOrExprKind() or
|
||||
BitwiseXorExprKind() or
|
||||
BooleanLiteralKind(boolean value) { value = true or value = false } or
|
||||
BraceBlockKind() or
|
||||
CaseMatchKind() or
|
||||
ClassVariableAccessKind(ClassVariable v) or
|
||||
DivExprKind() or
|
||||
ElseKind() or
|
||||
ExponentExprKind() or
|
||||
GlobalVariableAccessKind(GlobalVariable v) or
|
||||
IfKind() or
|
||||
InClauseKind() or
|
||||
InstanceVariableAccessKind(InstanceVariable v) or
|
||||
IntegerLiteralKind(int i) { i in [-1000 .. 1000] } or
|
||||
LShiftExprKind() or
|
||||
@@ -1497,3 +1501,102 @@ private module SafeNavigationCallDesugar {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private module TestPatternDesugar {
|
||||
/**
|
||||
* ```rb
|
||||
* expr in pattern
|
||||
* ```
|
||||
* desugars to
|
||||
*
|
||||
* ```rb
|
||||
* case expr
|
||||
* in pattern then true
|
||||
* else false
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate testPatternSynthesis(AstNode parent, int i, Child child) {
|
||||
exists(TestPattern test |
|
||||
parent = test and
|
||||
i = -1 and
|
||||
child = SynthChild(CaseMatchKind())
|
||||
or
|
||||
exists(TCaseMatchSynth case | case = TCaseMatchSynth(test, -1) |
|
||||
parent = case and
|
||||
(
|
||||
child = childRef(test.getValue()) and i = 0
|
||||
or
|
||||
child = SynthChild(InClauseKind()) and i = 1
|
||||
or
|
||||
child = SynthChild(ElseKind()) and i = 2
|
||||
)
|
||||
or
|
||||
parent = TInClauseSynth(case, 1) and
|
||||
(
|
||||
child = childRef(test.getPattern()) and
|
||||
i = 0
|
||||
or
|
||||
child = SynthChild(BooleanLiteralKind(true)) and i = 1
|
||||
)
|
||||
or
|
||||
parent = TElseSynth(case, 2) and
|
||||
child = SynthChild(BooleanLiteralKind(false)) and
|
||||
i = 0
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private class TestPatternSynthesis extends Synthesis {
|
||||
final override predicate child(AstNode parent, int i, Child child) {
|
||||
testPatternSynthesis(parent, i, child)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private module MatchPatternDesugar {
|
||||
/**
|
||||
* ```rb
|
||||
* expr => pattern
|
||||
* ```
|
||||
* desugars to
|
||||
*
|
||||
* ```rb
|
||||
* case expr
|
||||
* in pattern then nil
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate matchPatternSynthesis(AstNode parent, int i, Child child) {
|
||||
exists(MatchPattern test |
|
||||
parent = test and
|
||||
i = -1 and
|
||||
child = SynthChild(CaseMatchKind())
|
||||
or
|
||||
exists(TCaseMatchSynth case | case = TCaseMatchSynth(test, -1) |
|
||||
parent = case and
|
||||
(
|
||||
child = childRef(test.getValue()) and i = 0
|
||||
or
|
||||
child = SynthChild(InClauseKind()) and i = 1
|
||||
)
|
||||
or
|
||||
parent = TInClauseSynth(case, 1) and
|
||||
(
|
||||
child = childRef(test.getPattern()) and
|
||||
i = 0
|
||||
or
|
||||
child = SynthChild(NilLiteralKind()) and i = 1
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private class MatchPatternSynthesis extends Synthesis {
|
||||
final override predicate child(AstNode parent, int i, Child child) {
|
||||
matchPatternSynthesis(parent, i, child)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1125,6 +1125,23 @@ module Ruby {
|
||||
final override string getAPrimaryQlClass() { result = "Line" }
|
||||
}
|
||||
|
||||
/** A class representing `match_pattern` nodes. */
|
||||
class MatchPattern extends @ruby_match_pattern, AstNode {
|
||||
/** Gets the name of the primary QL class for this element. */
|
||||
final override string getAPrimaryQlClass() { result = "MatchPattern" }
|
||||
|
||||
/** Gets the node corresponding to the field `pattern`. */
|
||||
final UnderscorePatternTopExprBody getPattern() { ruby_match_pattern_def(this, result, _) }
|
||||
|
||||
/** Gets the node corresponding to the field `value`. */
|
||||
final UnderscoreArg getValue() { ruby_match_pattern_def(this, _, result) }
|
||||
|
||||
/** Gets a field or child node of this node. */
|
||||
final override AstNode getAFieldOrChild() {
|
||||
ruby_match_pattern_def(this, result, _) or ruby_match_pattern_def(this, _, result)
|
||||
}
|
||||
}
|
||||
|
||||
/** A class representing `method` nodes. */
|
||||
class Method extends @ruby_method, AstNode {
|
||||
/** Gets the name of the primary QL class for this element. */
|
||||
@@ -1662,6 +1679,23 @@ module Ruby {
|
||||
final override AstNode getAFieldOrChild() { ruby_symbol_array_child(this, _, result) }
|
||||
}
|
||||
|
||||
/** A class representing `test_pattern` nodes. */
|
||||
class TestPattern extends @ruby_test_pattern, AstNode {
|
||||
/** Gets the name of the primary QL class for this element. */
|
||||
final override string getAPrimaryQlClass() { result = "TestPattern" }
|
||||
|
||||
/** Gets the node corresponding to the field `pattern`. */
|
||||
final UnderscorePatternTopExprBody getPattern() { ruby_test_pattern_def(this, result, _) }
|
||||
|
||||
/** Gets the node corresponding to the field `value`. */
|
||||
final UnderscoreArg getValue() { ruby_test_pattern_def(this, _, result) }
|
||||
|
||||
/** Gets a field or child node of this node. */
|
||||
final override AstNode getAFieldOrChild() {
|
||||
ruby_test_pattern_def(this, result, _) or ruby_test_pattern_def(this, _, result)
|
||||
}
|
||||
}
|
||||
|
||||
/** A class representing `then` nodes. */
|
||||
class Then extends @ruby_then, AstNode {
|
||||
/** Gets the name of the primary QL class for this element. */
|
||||
|
||||
@@ -247,6 +247,8 @@ private module Cached {
|
||||
or
|
||||
i = any(Ruby::KeywordParameter x).getValue()
|
||||
or
|
||||
i = any(Ruby::MatchPattern x).getValue()
|
||||
or
|
||||
i = any(Ruby::Method x).getBody()
|
||||
or
|
||||
i = any(Ruby::OperatorAssignment x).getRight()
|
||||
@@ -285,6 +287,8 @@ private module Cached {
|
||||
or
|
||||
i = any(Ruby::Superclass x).getChild()
|
||||
or
|
||||
i = any(Ruby::TestPattern x).getValue()
|
||||
or
|
||||
i = any(Ruby::Then x).getChild(_)
|
||||
or
|
||||
i = any(Ruby::Unary x).getOperand()
|
||||
|
||||
@@ -667,23 +667,78 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
fwdFlowIn(_, _, _, node, config) and
|
||||
cc = true
|
||||
or
|
||||
// flow out of a callable
|
||||
fwdFlowOut(_, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
// inline to reduce the number of iterations
|
||||
pragma[inline]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, NodeEx arg, Cc cc, ParamNodeEx p, Configuration config
|
||||
) {
|
||||
// call context cannot help reduce virtual dispatch
|
||||
fwdFlow(arg, cc, config) and
|
||||
viableParamArgEx(call, p, arg) and
|
||||
not fullBarrier(p, config) and
|
||||
(
|
||||
cc = false
|
||||
or
|
||||
cc = true and
|
||||
not reducedViableImplInCallContext(call, _, _)
|
||||
)
|
||||
or
|
||||
// call context may help reduce virtual dispatch
|
||||
exists(DataFlowCallable target |
|
||||
fwdFlowInReducedViableImplInSomeCallContext(call, arg, p, target, config) and
|
||||
target = viableImplInSomeFwdFlowCallContextExt(call, config) and
|
||||
cc = true
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
|
||||
fwdFlowIn(call, _, cc, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowInReducedViableImplInSomeCallContext(
|
||||
DataFlowCall call, NodeEx arg, ParamNodeEx p, DataFlowCallable target, Configuration config
|
||||
) {
|
||||
fwdFlow(arg, true, config) and
|
||||
viableParamArgEx(call, p, arg) and
|
||||
reducedViableImplInCallContext(call, _, _) and
|
||||
target = p.getEnclosingCallable() and
|
||||
not fullBarrier(p, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference,
|
||||
* and to `ctx`s that are reachable in `fwdFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private DataFlowCallable viableImplInSomeFwdFlowCallContextExt(
|
||||
DataFlowCall call, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall ctx |
|
||||
fwdFlowIsEntered(ctx, _, config) and
|
||||
result = viableImplInCallContextExt(call, ctx)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate fwdFlow(NodeEx node, Configuration config) { fwdFlow(node, _, config) }
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -726,7 +781,8 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
// inline to reduce the number of iterations
|
||||
pragma[inline]
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
@@ -740,17 +796,6 @@ private module Stage1 implements StageSig {
|
||||
fwdFlowOut(call, out, true, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
|
||||
exists(ArgNodeEx arg |
|
||||
fwdFlow(arg, cc, config) and
|
||||
viableParamArgEx(call, _, arg)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate stateStepFwd(FlowState state1, FlowState state2, Configuration config) {
|
||||
exists(NodeEx node1 |
|
||||
additionalLocalStateStep(node1, state1, _, state2, config) or
|
||||
@@ -817,13 +862,8 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(DataFlowCall call |
|
||||
revFlowIn(call, node, false, config) and
|
||||
toReturn = false
|
||||
or
|
||||
revFlowInToReturn(call, node, config) and
|
||||
revFlowIsReturned(call, toReturn, config)
|
||||
)
|
||||
revFlowIn(_, node, false, config) and
|
||||
toReturn = false
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(ReturnPosition pos |
|
||||
@@ -831,6 +871,12 @@ private module Stage1 implements StageSig {
|
||||
node.(RetNodeEx).getReturnPosition() = pos and
|
||||
toReturn = true
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call |
|
||||
revFlowInToReturn(call, node, config) and
|
||||
revFlowIsReturned(call, toReturn, config)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -886,11 +932,11 @@ private module Stage1 implements StageSig {
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
fwdFlow(arg, config)
|
||||
fwdFlowIn(call, arg, _, p, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
// inline to reduce the number of iterations
|
||||
pragma[inline]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgNodeEx arg, boolean toReturn, Configuration config
|
||||
) {
|
||||
@@ -1223,7 +1269,16 @@ private module MkStage<StageSig PrevStage> {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail);
|
||||
|
||||
Content getHeadContent(Ap ap);
|
||||
/**
|
||||
* An approximation of `Content` that corresponds to the precision level of
|
||||
* `Ap`, such that the mappings from both `Ap` and `Content` to this type
|
||||
* are functional.
|
||||
*/
|
||||
class ApHeadContent;
|
||||
|
||||
ApHeadContent getHeadContent(Ap ap);
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c);
|
||||
|
||||
class ApOption;
|
||||
|
||||
@@ -1471,34 +1526,32 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
private class ApNonNil instanceof Ap {
|
||||
pragma[nomagic]
|
||||
ApNonNil() { not this instanceof ApNil }
|
||||
|
||||
string toString() { result = "" }
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead0(
|
||||
NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap,
|
||||
Configuration config
|
||||
private predicate readStepCand(
|
||||
NodeEx node1, ApHeadContent apc, Content c, NodeEx node2, Configuration config
|
||||
) {
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, _, _, config)
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
apc = projectToHeadContent(c)
|
||||
}
|
||||
|
||||
bindingset[ap, c]
|
||||
bindingset[node1, apc]
|
||||
pragma[inline_late]
|
||||
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
|
||||
private predicate readStepCand0(
|
||||
NodeEx node1, ApHeadContent apc, Content c, NodeEx node2, Configuration config
|
||||
) {
|
||||
readStepCand(node1, apc, c, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead(
|
||||
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
hasHeadContent(ap, c)
|
||||
exists(ApHeadContent apc |
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
apc = getHeadContent(ap) and
|
||||
readStepCand0(node1, apc, c, node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -2072,8 +2125,12 @@ private module Stage2Param implements MkStage<Stage1>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) }
|
||||
|
||||
class ApHeadContent = Unit;
|
||||
|
||||
pragma[inline]
|
||||
Content getHeadContent(Ap ap) { exists(result) and ap = true }
|
||||
ApHeadContent getHeadContent(Ap ap) { exists(result) and ap = true }
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c) { any() }
|
||||
|
||||
class ApOption = BooleanOption;
|
||||
|
||||
@@ -2337,8 +2394,12 @@ private module Stage3Param implements MkStage<Stage2>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) }
|
||||
|
||||
class ApHeadContent = ContentApprox;
|
||||
|
||||
pragma[noinline]
|
||||
Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() }
|
||||
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
|
||||
predicate projectToHeadContent = getContentApprox/1;
|
||||
|
||||
class ApOption = ApproxAccessPathFrontOption;
|
||||
|
||||
@@ -2413,8 +2474,12 @@ private module Stage4Param implements MkStage<Stage3>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) }
|
||||
|
||||
class ApHeadContent = Content;
|
||||
|
||||
pragma[noinline]
|
||||
Content getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c) { result = c }
|
||||
|
||||
class ApOption = AccessPathFrontOption;
|
||||
|
||||
@@ -2743,8 +2808,12 @@ private module Stage5Param implements MkStage<Stage4>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) }
|
||||
|
||||
class ApHeadContent = Content;
|
||||
|
||||
pragma[noinline]
|
||||
Content getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c) { result = c }
|
||||
|
||||
class ApOption = AccessPathApproxOption;
|
||||
|
||||
|
||||
@@ -667,23 +667,78 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
fwdFlowIn(_, _, _, node, config) and
|
||||
cc = true
|
||||
or
|
||||
// flow out of a callable
|
||||
fwdFlowOut(_, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
// inline to reduce the number of iterations
|
||||
pragma[inline]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, NodeEx arg, Cc cc, ParamNodeEx p, Configuration config
|
||||
) {
|
||||
// call context cannot help reduce virtual dispatch
|
||||
fwdFlow(arg, cc, config) and
|
||||
viableParamArgEx(call, p, arg) and
|
||||
not fullBarrier(p, config) and
|
||||
(
|
||||
cc = false
|
||||
or
|
||||
cc = true and
|
||||
not reducedViableImplInCallContext(call, _, _)
|
||||
)
|
||||
or
|
||||
// call context may help reduce virtual dispatch
|
||||
exists(DataFlowCallable target |
|
||||
fwdFlowInReducedViableImplInSomeCallContext(call, arg, p, target, config) and
|
||||
target = viableImplInSomeFwdFlowCallContextExt(call, config) and
|
||||
cc = true
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
|
||||
fwdFlowIn(call, _, cc, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowInReducedViableImplInSomeCallContext(
|
||||
DataFlowCall call, NodeEx arg, ParamNodeEx p, DataFlowCallable target, Configuration config
|
||||
) {
|
||||
fwdFlow(arg, true, config) and
|
||||
viableParamArgEx(call, p, arg) and
|
||||
reducedViableImplInCallContext(call, _, _) and
|
||||
target = p.getEnclosingCallable() and
|
||||
not fullBarrier(p, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference,
|
||||
* and to `ctx`s that are reachable in `fwdFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private DataFlowCallable viableImplInSomeFwdFlowCallContextExt(
|
||||
DataFlowCall call, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall ctx |
|
||||
fwdFlowIsEntered(ctx, _, config) and
|
||||
result = viableImplInCallContextExt(call, ctx)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate fwdFlow(NodeEx node, Configuration config) { fwdFlow(node, _, config) }
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -726,7 +781,8 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
// inline to reduce the number of iterations
|
||||
pragma[inline]
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
@@ -740,17 +796,6 @@ private module Stage1 implements StageSig {
|
||||
fwdFlowOut(call, out, true, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
|
||||
exists(ArgNodeEx arg |
|
||||
fwdFlow(arg, cc, config) and
|
||||
viableParamArgEx(call, _, arg)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate stateStepFwd(FlowState state1, FlowState state2, Configuration config) {
|
||||
exists(NodeEx node1 |
|
||||
additionalLocalStateStep(node1, state1, _, state2, config) or
|
||||
@@ -817,13 +862,8 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(DataFlowCall call |
|
||||
revFlowIn(call, node, false, config) and
|
||||
toReturn = false
|
||||
or
|
||||
revFlowInToReturn(call, node, config) and
|
||||
revFlowIsReturned(call, toReturn, config)
|
||||
)
|
||||
revFlowIn(_, node, false, config) and
|
||||
toReturn = false
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(ReturnPosition pos |
|
||||
@@ -831,6 +871,12 @@ private module Stage1 implements StageSig {
|
||||
node.(RetNodeEx).getReturnPosition() = pos and
|
||||
toReturn = true
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call |
|
||||
revFlowInToReturn(call, node, config) and
|
||||
revFlowIsReturned(call, toReturn, config)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -886,11 +932,11 @@ private module Stage1 implements StageSig {
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
fwdFlow(arg, config)
|
||||
fwdFlowIn(call, arg, _, p, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
// inline to reduce the number of iterations
|
||||
pragma[inline]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgNodeEx arg, boolean toReturn, Configuration config
|
||||
) {
|
||||
@@ -1223,7 +1269,16 @@ private module MkStage<StageSig PrevStage> {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail);
|
||||
|
||||
Content getHeadContent(Ap ap);
|
||||
/**
|
||||
* An approximation of `Content` that corresponds to the precision level of
|
||||
* `Ap`, such that the mappings from both `Ap` and `Content` to this type
|
||||
* are functional.
|
||||
*/
|
||||
class ApHeadContent;
|
||||
|
||||
ApHeadContent getHeadContent(Ap ap);
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c);
|
||||
|
||||
class ApOption;
|
||||
|
||||
@@ -1471,34 +1526,32 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
private class ApNonNil instanceof Ap {
|
||||
pragma[nomagic]
|
||||
ApNonNil() { not this instanceof ApNil }
|
||||
|
||||
string toString() { result = "" }
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead0(
|
||||
NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap,
|
||||
Configuration config
|
||||
private predicate readStepCand(
|
||||
NodeEx node1, ApHeadContent apc, Content c, NodeEx node2, Configuration config
|
||||
) {
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, _, _, config)
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
apc = projectToHeadContent(c)
|
||||
}
|
||||
|
||||
bindingset[ap, c]
|
||||
bindingset[node1, apc]
|
||||
pragma[inline_late]
|
||||
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
|
||||
private predicate readStepCand0(
|
||||
NodeEx node1, ApHeadContent apc, Content c, NodeEx node2, Configuration config
|
||||
) {
|
||||
readStepCand(node1, apc, c, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead(
|
||||
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
hasHeadContent(ap, c)
|
||||
exists(ApHeadContent apc |
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
apc = getHeadContent(ap) and
|
||||
readStepCand0(node1, apc, c, node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -2072,8 +2125,12 @@ private module Stage2Param implements MkStage<Stage1>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) }
|
||||
|
||||
class ApHeadContent = Unit;
|
||||
|
||||
pragma[inline]
|
||||
Content getHeadContent(Ap ap) { exists(result) and ap = true }
|
||||
ApHeadContent getHeadContent(Ap ap) { exists(result) and ap = true }
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c) { any() }
|
||||
|
||||
class ApOption = BooleanOption;
|
||||
|
||||
@@ -2337,8 +2394,12 @@ private module Stage3Param implements MkStage<Stage2>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) }
|
||||
|
||||
class ApHeadContent = ContentApprox;
|
||||
|
||||
pragma[noinline]
|
||||
Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() }
|
||||
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
|
||||
predicate projectToHeadContent = getContentApprox/1;
|
||||
|
||||
class ApOption = ApproxAccessPathFrontOption;
|
||||
|
||||
@@ -2413,8 +2474,12 @@ private module Stage4Param implements MkStage<Stage3>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) }
|
||||
|
||||
class ApHeadContent = Content;
|
||||
|
||||
pragma[noinline]
|
||||
Content getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c) { result = c }
|
||||
|
||||
class ApOption = AccessPathFrontOption;
|
||||
|
||||
@@ -2743,8 +2808,12 @@ private module Stage5Param implements MkStage<Stage4>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) }
|
||||
|
||||
class ApHeadContent = Content;
|
||||
|
||||
pragma[noinline]
|
||||
Content getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c) { result = c }
|
||||
|
||||
class ApOption = AccessPathApproxOption;
|
||||
|
||||
|
||||
@@ -707,8 +707,8 @@ private module Cached {
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) {
|
||||
cached
|
||||
DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) {
|
||||
result = viableImplInCallContext(call, ctx) and
|
||||
result = viableCallable(call)
|
||||
or
|
||||
@@ -1391,6 +1391,9 @@ class TypedContentApprox extends MkTypedContentApprox {
|
||||
/** Gets a typed content approximated by this value. */
|
||||
TypedContent getATypedContent() { result = getATypedContent(this) }
|
||||
|
||||
/** Gets the content. */
|
||||
ContentApprox getContent() { result = c }
|
||||
|
||||
/** Gets the container type. */
|
||||
DataFlowType getContainerType() { result = t }
|
||||
|
||||
@@ -1408,6 +1411,8 @@ abstract class ApproxAccessPathFront extends TApproxAccessPathFront {
|
||||
|
||||
abstract boolean toBoolNonEmpty();
|
||||
|
||||
TypedContentApprox getHead() { this = TApproxFrontHead(result) }
|
||||
|
||||
pragma[nomagic]
|
||||
TypedContent getAHead() {
|
||||
exists(TypedContentApprox cont |
|
||||
|
||||
@@ -667,23 +667,78 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
fwdFlowIn(_, _, _, node, config) and
|
||||
cc = true
|
||||
or
|
||||
// flow out of a callable
|
||||
fwdFlowOut(_, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
// inline to reduce the number of iterations
|
||||
pragma[inline]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, NodeEx arg, Cc cc, ParamNodeEx p, Configuration config
|
||||
) {
|
||||
// call context cannot help reduce virtual dispatch
|
||||
fwdFlow(arg, cc, config) and
|
||||
viableParamArgEx(call, p, arg) and
|
||||
not fullBarrier(p, config) and
|
||||
(
|
||||
cc = false
|
||||
or
|
||||
cc = true and
|
||||
not reducedViableImplInCallContext(call, _, _)
|
||||
)
|
||||
or
|
||||
// call context may help reduce virtual dispatch
|
||||
exists(DataFlowCallable target |
|
||||
fwdFlowInReducedViableImplInSomeCallContext(call, arg, p, target, config) and
|
||||
target = viableImplInSomeFwdFlowCallContextExt(call, config) and
|
||||
cc = true
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
|
||||
fwdFlowIn(call, _, cc, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowInReducedViableImplInSomeCallContext(
|
||||
DataFlowCall call, NodeEx arg, ParamNodeEx p, DataFlowCallable target, Configuration config
|
||||
) {
|
||||
fwdFlow(arg, true, config) and
|
||||
viableParamArgEx(call, p, arg) and
|
||||
reducedViableImplInCallContext(call, _, _) and
|
||||
target = p.getEnclosingCallable() and
|
||||
not fullBarrier(p, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference,
|
||||
* and to `ctx`s that are reachable in `fwdFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private DataFlowCallable viableImplInSomeFwdFlowCallContextExt(
|
||||
DataFlowCall call, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall ctx |
|
||||
fwdFlowIsEntered(ctx, _, config) and
|
||||
result = viableImplInCallContextExt(call, ctx)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate fwdFlow(NodeEx node, Configuration config) { fwdFlow(node, _, config) }
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -726,7 +781,8 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
// inline to reduce the number of iterations
|
||||
pragma[inline]
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
@@ -740,17 +796,6 @@ private module Stage1 implements StageSig {
|
||||
fwdFlowOut(call, out, true, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
|
||||
exists(ArgNodeEx arg |
|
||||
fwdFlow(arg, cc, config) and
|
||||
viableParamArgEx(call, _, arg)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate stateStepFwd(FlowState state1, FlowState state2, Configuration config) {
|
||||
exists(NodeEx node1 |
|
||||
additionalLocalStateStep(node1, state1, _, state2, config) or
|
||||
@@ -817,13 +862,8 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(DataFlowCall call |
|
||||
revFlowIn(call, node, false, config) and
|
||||
toReturn = false
|
||||
or
|
||||
revFlowInToReturn(call, node, config) and
|
||||
revFlowIsReturned(call, toReturn, config)
|
||||
)
|
||||
revFlowIn(_, node, false, config) and
|
||||
toReturn = false
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(ReturnPosition pos |
|
||||
@@ -831,6 +871,12 @@ private module Stage1 implements StageSig {
|
||||
node.(RetNodeEx).getReturnPosition() = pos and
|
||||
toReturn = true
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call |
|
||||
revFlowInToReturn(call, node, config) and
|
||||
revFlowIsReturned(call, toReturn, config)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -886,11 +932,11 @@ private module Stage1 implements StageSig {
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
fwdFlow(arg, config)
|
||||
fwdFlowIn(call, arg, _, p, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
// inline to reduce the number of iterations
|
||||
pragma[inline]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgNodeEx arg, boolean toReturn, Configuration config
|
||||
) {
|
||||
@@ -1223,7 +1269,16 @@ private module MkStage<StageSig PrevStage> {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail);
|
||||
|
||||
Content getHeadContent(Ap ap);
|
||||
/**
|
||||
* An approximation of `Content` that corresponds to the precision level of
|
||||
* `Ap`, such that the mappings from both `Ap` and `Content` to this type
|
||||
* are functional.
|
||||
*/
|
||||
class ApHeadContent;
|
||||
|
||||
ApHeadContent getHeadContent(Ap ap);
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c);
|
||||
|
||||
class ApOption;
|
||||
|
||||
@@ -1471,34 +1526,32 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
private class ApNonNil instanceof Ap {
|
||||
pragma[nomagic]
|
||||
ApNonNil() { not this instanceof ApNil }
|
||||
|
||||
string toString() { result = "" }
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead0(
|
||||
NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap,
|
||||
Configuration config
|
||||
private predicate readStepCand(
|
||||
NodeEx node1, ApHeadContent apc, Content c, NodeEx node2, Configuration config
|
||||
) {
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, _, _, config)
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
apc = projectToHeadContent(c)
|
||||
}
|
||||
|
||||
bindingset[ap, c]
|
||||
bindingset[node1, apc]
|
||||
pragma[inline_late]
|
||||
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
|
||||
private predicate readStepCand0(
|
||||
NodeEx node1, ApHeadContent apc, Content c, NodeEx node2, Configuration config
|
||||
) {
|
||||
readStepCand(node1, apc, c, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead(
|
||||
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
hasHeadContent(ap, c)
|
||||
exists(ApHeadContent apc |
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
apc = getHeadContent(ap) and
|
||||
readStepCand0(node1, apc, c, node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -2072,8 +2125,12 @@ private module Stage2Param implements MkStage<Stage1>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) }
|
||||
|
||||
class ApHeadContent = Unit;
|
||||
|
||||
pragma[inline]
|
||||
Content getHeadContent(Ap ap) { exists(result) and ap = true }
|
||||
ApHeadContent getHeadContent(Ap ap) { exists(result) and ap = true }
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c) { any() }
|
||||
|
||||
class ApOption = BooleanOption;
|
||||
|
||||
@@ -2337,8 +2394,12 @@ private module Stage3Param implements MkStage<Stage2>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) }
|
||||
|
||||
class ApHeadContent = ContentApprox;
|
||||
|
||||
pragma[noinline]
|
||||
Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() }
|
||||
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
|
||||
predicate projectToHeadContent = getContentApprox/1;
|
||||
|
||||
class ApOption = ApproxAccessPathFrontOption;
|
||||
|
||||
@@ -2413,8 +2474,12 @@ private module Stage4Param implements MkStage<Stage3>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) }
|
||||
|
||||
class ApHeadContent = Content;
|
||||
|
||||
pragma[noinline]
|
||||
Content getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c) { result = c }
|
||||
|
||||
class ApOption = AccessPathFrontOption;
|
||||
|
||||
@@ -2743,8 +2808,12 @@ private module Stage5Param implements MkStage<Stage4>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) }
|
||||
|
||||
class ApHeadContent = Content;
|
||||
|
||||
pragma[noinline]
|
||||
Content getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c) { result = c }
|
||||
|
||||
class ApOption = AccessPathApproxOption;
|
||||
|
||||
|
||||
@@ -667,23 +667,78 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
fwdFlowIn(_, _, _, node, config) and
|
||||
cc = true
|
||||
or
|
||||
// flow out of a callable
|
||||
fwdFlowOut(_, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
// inline to reduce the number of iterations
|
||||
pragma[inline]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, NodeEx arg, Cc cc, ParamNodeEx p, Configuration config
|
||||
) {
|
||||
// call context cannot help reduce virtual dispatch
|
||||
fwdFlow(arg, cc, config) and
|
||||
viableParamArgEx(call, p, arg) and
|
||||
not fullBarrier(p, config) and
|
||||
(
|
||||
cc = false
|
||||
or
|
||||
cc = true and
|
||||
not reducedViableImplInCallContext(call, _, _)
|
||||
)
|
||||
or
|
||||
// call context may help reduce virtual dispatch
|
||||
exists(DataFlowCallable target |
|
||||
fwdFlowInReducedViableImplInSomeCallContext(call, arg, p, target, config) and
|
||||
target = viableImplInSomeFwdFlowCallContextExt(call, config) and
|
||||
cc = true
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
|
||||
fwdFlowIn(call, _, cc, _, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowInReducedViableImplInSomeCallContext(
|
||||
DataFlowCall call, NodeEx arg, ParamNodeEx p, DataFlowCallable target, Configuration config
|
||||
) {
|
||||
fwdFlow(arg, true, config) and
|
||||
viableParamArgEx(call, p, arg) and
|
||||
reducedViableImplInCallContext(call, _, _) and
|
||||
target = p.getEnclosingCallable() and
|
||||
not fullBarrier(p, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference,
|
||||
* and to `ctx`s that are reachable in `fwdFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private DataFlowCallable viableImplInSomeFwdFlowCallContextExt(
|
||||
DataFlowCall call, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall ctx |
|
||||
fwdFlowIsEntered(ctx, _, config) and
|
||||
result = viableImplInCallContextExt(call, ctx)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate fwdFlow(NodeEx node, Configuration config) { fwdFlow(node, _, config) }
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -726,7 +781,8 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
// inline to reduce the number of iterations
|
||||
pragma[inline]
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
@@ -740,17 +796,6 @@ private module Stage1 implements StageSig {
|
||||
fwdFlowOut(call, out, true, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an argument to `call` is reached in the flow covered by `fwdFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
|
||||
exists(ArgNodeEx arg |
|
||||
fwdFlow(arg, cc, config) and
|
||||
viableParamArgEx(call, _, arg)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate stateStepFwd(FlowState state1, FlowState state2, Configuration config) {
|
||||
exists(NodeEx node1 |
|
||||
additionalLocalStateStep(node1, state1, _, state2, config) or
|
||||
@@ -817,13 +862,8 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(DataFlowCall call |
|
||||
revFlowIn(call, node, false, config) and
|
||||
toReturn = false
|
||||
or
|
||||
revFlowInToReturn(call, node, config) and
|
||||
revFlowIsReturned(call, toReturn, config)
|
||||
)
|
||||
revFlowIn(_, node, false, config) and
|
||||
toReturn = false
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(ReturnPosition pos |
|
||||
@@ -831,6 +871,12 @@ private module Stage1 implements StageSig {
|
||||
node.(RetNodeEx).getReturnPosition() = pos and
|
||||
toReturn = true
|
||||
)
|
||||
or
|
||||
// flow through a callable
|
||||
exists(DataFlowCall call |
|
||||
revFlowInToReturn(call, node, config) and
|
||||
revFlowIsReturned(call, toReturn, config)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -886,11 +932,11 @@ private module Stage1 implements StageSig {
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
fwdFlow(arg, config)
|
||||
fwdFlowIn(call, arg, _, p, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
// inline to reduce the number of iterations
|
||||
pragma[inline]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgNodeEx arg, boolean toReturn, Configuration config
|
||||
) {
|
||||
@@ -1223,7 +1269,16 @@ private module MkStage<StageSig PrevStage> {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail);
|
||||
|
||||
Content getHeadContent(Ap ap);
|
||||
/**
|
||||
* An approximation of `Content` that corresponds to the precision level of
|
||||
* `Ap`, such that the mappings from both `Ap` and `Content` to this type
|
||||
* are functional.
|
||||
*/
|
||||
class ApHeadContent;
|
||||
|
||||
ApHeadContent getHeadContent(Ap ap);
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c);
|
||||
|
||||
class ApOption;
|
||||
|
||||
@@ -1471,34 +1526,32 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
private class ApNonNil instanceof Ap {
|
||||
pragma[nomagic]
|
||||
ApNonNil() { not this instanceof ApNil }
|
||||
|
||||
string toString() { result = "" }
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead0(
|
||||
NodeEx node1, FlowState state, Cc cc, ParamNodeOption summaryCtx, ApOption argAp, ApNonNil ap,
|
||||
Configuration config
|
||||
private predicate readStepCand(
|
||||
NodeEx node1, ApHeadContent apc, Content c, NodeEx node2, Configuration config
|
||||
) {
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, _, _, config)
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
apc = projectToHeadContent(c)
|
||||
}
|
||||
|
||||
bindingset[ap, c]
|
||||
bindingset[node1, apc]
|
||||
pragma[inline_late]
|
||||
private predicate hasHeadContent(Ap ap, Content c) { getHeadContent(ap) = c }
|
||||
private predicate readStepCand0(
|
||||
NodeEx node1, ApHeadContent apc, Content c, NodeEx node2, Configuration config
|
||||
) {
|
||||
readStepCand(node1, apc, c, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowRead(
|
||||
Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc,
|
||||
ParamNodeOption summaryCtx, ApOption argAp, Configuration config
|
||||
) {
|
||||
fwdFlowRead0(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
PrevStage::readStepCand(node1, c, node2, config) and
|
||||
hasHeadContent(ap, c)
|
||||
exists(ApHeadContent apc |
|
||||
fwdFlow(node1, state, cc, summaryCtx, argAp, ap, config) and
|
||||
apc = getHeadContent(ap) and
|
||||
readStepCand0(node1, apc, c, node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -2072,8 +2125,12 @@ private module Stage2Param implements MkStage<Stage1>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result = true and exists(tc) and exists(tail) }
|
||||
|
||||
class ApHeadContent = Unit;
|
||||
|
||||
pragma[inline]
|
||||
Content getHeadContent(Ap ap) { exists(result) and ap = true }
|
||||
ApHeadContent getHeadContent(Ap ap) { exists(result) and ap = true }
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c) { any() }
|
||||
|
||||
class ApOption = BooleanOption;
|
||||
|
||||
@@ -2337,8 +2394,12 @@ private module Stage3Param implements MkStage<Stage2>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result.getAHead() = tc and exists(tail) }
|
||||
|
||||
class ApHeadContent = ContentApprox;
|
||||
|
||||
pragma[noinline]
|
||||
Content getHeadContent(Ap ap) { result = ap.getAHead().getContent() }
|
||||
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
|
||||
predicate projectToHeadContent = getContentApprox/1;
|
||||
|
||||
class ApOption = ApproxAccessPathFrontOption;
|
||||
|
||||
@@ -2413,8 +2474,12 @@ private module Stage4Param implements MkStage<Stage3>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result.getHead() = tc and exists(tail) }
|
||||
|
||||
class ApHeadContent = Content;
|
||||
|
||||
pragma[noinline]
|
||||
Content getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c) { result = c }
|
||||
|
||||
class ApOption = AccessPathFrontOption;
|
||||
|
||||
@@ -2743,8 +2808,12 @@ private module Stage5Param implements MkStage<Stage4>::StageParam {
|
||||
bindingset[tc, tail]
|
||||
Ap apCons(TypedContent tc, Ap tail) { result = push(tc, tail) }
|
||||
|
||||
class ApHeadContent = Content;
|
||||
|
||||
pragma[noinline]
|
||||
Content getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
ApHeadContent getHeadContent(Ap ap) { result = ap.getHead().getContent() }
|
||||
|
||||
ApHeadContent projectToHeadContent(Content c) { result = c }
|
||||
|
||||
class ApOption = AccessPathApproxOption;
|
||||
|
||||
|
||||
@@ -303,6 +303,13 @@ private class CookiesSameSiteProtectionSetting extends Settings::NillableStringl
|
||||
}
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isPotentialRenderCall(MethodCall renderCall, Location loc, ErbFile erbFile) {
|
||||
renderCall.getMethodName() = "render" and
|
||||
loc = renderCall.getLocation() and
|
||||
RenderCallUtils::getTemplateFile(renderCall) = erbFile
|
||||
}
|
||||
|
||||
// TODO: initialization hooks, e.g. before_configuration, after_initialize...
|
||||
// TODO: initializers
|
||||
/** A synthetic global to represent the value passed to the `locals` argument of a render call for a specific ERB file. */
|
||||
@@ -313,10 +320,11 @@ private class LocalAssignsHashSyntheticGlobal extends SummaryComponent::Syntheti
|
||||
private MethodCall renderCall;
|
||||
|
||||
LocalAssignsHashSyntheticGlobal() {
|
||||
this = "LocalAssignsHashSyntheticGlobal+" + id and
|
||||
id = erbFile.getRelativePath() + "+" + renderCall.getLocation() and
|
||||
renderCall.getMethodName() = "render" and
|
||||
RenderCallUtils::getTemplateFile(renderCall) = erbFile
|
||||
exists(Location loc |
|
||||
this = "LocalAssignsHashSyntheticGlobal+" + id and
|
||||
isPotentialRenderCall(renderCall, loc, erbFile) and
|
||||
id = erbFile.getRelativePath() + "+" + loc
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the `ErbFile` which this locals hash is accessible from. */
|
||||
|
||||
@@ -85,9 +85,13 @@ module Gem {
|
||||
|
||||
/** Gets a parameter from an exported method, which is an input to this gem. */
|
||||
DataFlow::ParameterNode getAnInputParameter() {
|
||||
exists(MethodBase method | method = getAPublicModule().getAMethod() |
|
||||
result.getParameter() = method.getAParameter() and
|
||||
exists(MethodBase method |
|
||||
method = getAPublicModule().getAMethod() and
|
||||
result.getParameter() = method.getAParameter()
|
||||
|
|
||||
method.isPublic()
|
||||
or
|
||||
method.isProtected()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,14 @@ module Cryptography {
|
||||
* data of arbitrary length using a block encryption algorithm.
|
||||
*/
|
||||
class BlockMode extends string {
|
||||
BlockMode() { this = ["ECB", "CBC", "GCM", "CCM", "CFB", "OFB", "CTR", "OPENPGP"] }
|
||||
BlockMode() {
|
||||
this =
|
||||
[
|
||||
"ECB", "CBC", "GCM", "CCM", "CFB", "OFB", "CTR", "OPENPGP",
|
||||
"XTS", // https://csrc.nist.gov/publications/detail/sp/800-38e/final
|
||||
"EAX" // https://en.wikipedia.org/wiki/EAX_mode
|
||||
]
|
||||
}
|
||||
|
||||
/** Holds if this block mode is considered to be insecure. */
|
||||
predicate isWeak() { this = "ECB" }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** Provides a class hierarchy corresponding to a parse tree of regular expressions. */
|
||||
|
||||
private import internal.ParseRegExp
|
||||
private import codeql.NumberUtils
|
||||
private import codeql.util.Numbers
|
||||
private import codeql.ruby.ast.Literal as Ast
|
||||
private import codeql.Locations
|
||||
private import codeql.regex.nfa.NfaUtils as NfaUtils
|
||||
|
||||
@@ -14,8 +14,20 @@
|
||||
predicate isStrongHashingAlgorithm(string name) {
|
||||
name =
|
||||
[
|
||||
// see https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/#blake2
|
||||
// and https://www.blake2.net/
|
||||
"BLAKE2", "BLAKE2B", "BLAKE2S",
|
||||
// see https://github.com/BLAKE3-team/BLAKE3
|
||||
"BLAKE3",
|
||||
//
|
||||
"DSA", "ED25519", "ES256", "ECDSA256", "ES384", "ECDSA384", "ES512", "ECDSA512", "SHA2",
|
||||
"SHA224", "SHA256", "SHA384", "SHA512", "SHA3", "SHA3224", "SHA3256", "SHA3384", "SHA3512"
|
||||
"SHA224", "SHA256", "SHA384", "SHA512", "SHA3", "SHA3224", "SHA3256", "SHA3384", "SHA3512",
|
||||
// see https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/#cryptography.hazmat.primitives.hashes.SHAKE128
|
||||
"SHAKE128", "SHAKE256",
|
||||
// see https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/#sm3
|
||||
"SM3",
|
||||
// see https://security.stackexchange.com/a/216297
|
||||
"WHIRLPOOL",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for reasoning about
|
||||
* missing full-anchored regular expressions, as well as extension
|
||||
* points for adding your own.
|
||||
*/
|
||||
|
||||
private import ruby
|
||||
private import codeql.ruby.dataflow.RemoteFlowSources
|
||||
private import codeql.ruby.frameworks.core.Gem::Gem as Gem
|
||||
private import codeql.ruby.Regexp as Regexp
|
||||
private import codeql.ruby.security.regexp.HostnameRegexp
|
||||
private import codeql.ruby.Concepts
|
||||
|
||||
private class RegExpTerm = Regexp::RegExpTerm;
|
||||
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting
|
||||
* missing full-anchored regular expressions, as well as extension
|
||||
* points for adding your own.
|
||||
*/
|
||||
module MissingFullAnchor {
|
||||
/** A data flow source for missing full-anchored regular expressions. */
|
||||
abstract class Source extends DataFlow::Node {
|
||||
/** Gets a description of the source. */
|
||||
string describe() { result = "user-provided value" }
|
||||
}
|
||||
|
||||
/** A data flow sink for missing full-anchored regular expressions. */
|
||||
abstract class Sink extends DataFlow::Node {
|
||||
/** Gets the node where the regexp computation happens. */
|
||||
abstract DataFlow::Node getCallNode();
|
||||
|
||||
/** Gets the regular expression term. */
|
||||
abstract RegExpTerm getRegex();
|
||||
}
|
||||
|
||||
/** A sanitizer for missing full-anchored regular expressions. */
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
private class RemoteFlowAsSource extends Source instanceof RemoteFlowSource { }
|
||||
|
||||
private class LibrayInputAsSource extends Source {
|
||||
LibrayInputAsSource() { this = Gem::getALibraryInput() }
|
||||
|
||||
override string describe() { result = "library input" }
|
||||
}
|
||||
|
||||
private RegExpTerm getABadlyAnchoredTerm() {
|
||||
exists(RegExpTerm left | left.getRootTerm() = result |
|
||||
left.(Regexp::RegExpAnchor).getChar() = "^" and
|
||||
isLeftArmTerm(left)
|
||||
) and
|
||||
exists(RegExpTerm right | right.getRootTerm() = result |
|
||||
right.(Regexp::RegExpAnchor).getChar() = "$" and
|
||||
isRightArmTerm(right)
|
||||
)
|
||||
}
|
||||
|
||||
private class DefaultSink extends Sink {
|
||||
RegexExecution exec;
|
||||
RegExpTerm term;
|
||||
|
||||
DefaultSink() {
|
||||
exec.getString() = this and
|
||||
term = Regexp::getTermForExecution(exec) and
|
||||
term = getABadlyAnchoredTerm() and
|
||||
// looks like a sanitizer, not just input transformation
|
||||
exists(Ast::ConditionalExpr ifExpr |
|
||||
[ifExpr.getCondition(), ifExpr.getCondition().(Ast::UnaryLogicalOperation).getOperand()] =
|
||||
exec.asExpr().getExpr() and
|
||||
ifExpr.getBranch(_).(Ast::MethodCall).getMethodName() = "raise"
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getCallNode() { result = exec }
|
||||
|
||||
override RegExpTerm getRegex() { result = term }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Provides a taint tracking configuration for reasoning about
|
||||
* missing full-anchored regular expressions.
|
||||
*
|
||||
* Note, for performance reasons: only import this file if
|
||||
* `MissingFullAnchor::Configuration` is needed, otherwise
|
||||
* `MissingFullAnchorCustomizations` should be imported instead.
|
||||
*/
|
||||
|
||||
import ruby
|
||||
import codeql.ruby.TaintTracking
|
||||
import MissingFullAnchorCustomizations::MissingFullAnchor
|
||||
|
||||
/**
|
||||
* A taint tracking configuration for reasoning about
|
||||
* missing full-anchored regular expressions.
|
||||
*/
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "MissingFullAnchor" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
}
|
||||
@@ -24,7 +24,13 @@ module PolynomialReDoS {
|
||||
/**
|
||||
* A data flow source node for polynomial regular expression denial-of-service vulnerabilities.
|
||||
*/
|
||||
abstract class Source extends DataFlow::Node { }
|
||||
abstract class Source extends DataFlow::Node {
|
||||
/**
|
||||
* Gets a string that describes the source.
|
||||
* For use in the alert message.
|
||||
*/
|
||||
string describe() { result = "user-provided value" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow sink node for polynomial regular expression denial-of-service vulnerabilities.
|
||||
@@ -55,6 +61,15 @@ module PolynomialReDoS {
|
||||
*/
|
||||
class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
|
||||
|
||||
private import codeql.ruby.frameworks.core.Gem::Gem as Gem
|
||||
|
||||
/** A library input, considered as a flow source. */
|
||||
class LibraryInputAsSource extends Source {
|
||||
LibraryInputAsSource() { this = Gem::getALibraryInput() }
|
||||
|
||||
override string describe() { result = "library input" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A regexp match against a superlinear backtracking term, seen as a sink for
|
||||
* polynomial regular expression denial-of-service vulnerabilities.
|
||||
|
||||
@@ -9,5 +9,6 @@ dependencies:
|
||||
codeql/regex: ${workspace}
|
||||
codeql/ssa: ${workspace}
|
||||
codeql/tutorial: ${workspace}
|
||||
codeql/util: ${workspace}
|
||||
dataExtensions:
|
||||
- codeql/ruby/frameworks/**/model.yml
|
||||
|
||||
@@ -54,7 +54,7 @@ case @diagnostic.severity of
|
||||
|
||||
@ruby_underscore_call_operator = @ruby_reserved_word
|
||||
|
||||
@ruby_underscore_expression = @ruby_assignment | @ruby_binary | @ruby_break | @ruby_call | @ruby_next | @ruby_operator_assignment | @ruby_return | @ruby_unary | @ruby_underscore_arg | @ruby_yield
|
||||
@ruby_underscore_expression = @ruby_assignment | @ruby_binary | @ruby_break | @ruby_call | @ruby_match_pattern | @ruby_next | @ruby_operator_assignment | @ruby_return | @ruby_test_pattern | @ruby_unary | @ruby_underscore_arg | @ruby_yield
|
||||
|
||||
@ruby_underscore_lhs = @ruby_call | @ruby_element_reference | @ruby_scope_resolution | @ruby_token_false | @ruby_token_nil | @ruby_token_true | @ruby_underscore_variable
|
||||
|
||||
@@ -815,6 +815,12 @@ ruby_left_assignment_list_def(
|
||||
unique int id: @ruby_left_assignment_list
|
||||
);
|
||||
|
||||
ruby_match_pattern_def(
|
||||
unique int id: @ruby_match_pattern,
|
||||
int pattern: @ruby_underscore_pattern_top_expr_body ref,
|
||||
int value: @ruby_underscore_arg ref
|
||||
);
|
||||
|
||||
@ruby_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg
|
||||
|
||||
ruby_method_body(
|
||||
@@ -1187,6 +1193,12 @@ ruby_symbol_array_def(
|
||||
unique int id: @ruby_symbol_array
|
||||
);
|
||||
|
||||
ruby_test_pattern_def(
|
||||
unique int id: @ruby_test_pattern,
|
||||
int pattern: @ruby_underscore_pattern_top_expr_body ref,
|
||||
int value: @ruby_underscore_arg ref
|
||||
);
|
||||
|
||||
@ruby_then_child_type = @ruby_token_empty_statement | @ruby_underscore_statement
|
||||
|
||||
#keyset[ruby_then, index]
|
||||
@@ -1354,7 +1366,7 @@ case @ruby_token.kind of
|
||||
;
|
||||
|
||||
|
||||
@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_body | @ruby_block_parameter | @ruby_block_parameters | @ruby_body_statement | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_complex | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield
|
||||
@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_body | @ruby_block_parameter | @ruby_block_parameters | @ruby_body_statement | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_complex | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_match_pattern | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_test_pattern | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield
|
||||
|
||||
@ruby_ast_node_parent = @file | @ruby_ast_node
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: One-line pattern matching
|
||||
compatibility: full
|
||||
4
ruby/ql/src/change-notes/2022-10-11-poly-redos-lib.md
Normal file
4
ruby/ql/src/change-notes/2022-10-11-poly-redos-lib.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `rb/polynomial-redos` query now considers the entrypoints of the API of a gem as sources.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* Added a new query, `rb/regex/badly-anchored-regexp`, to detect regular expression validators that use `^` and `$`
|
||||
as anchors and therefore might match only a single line of a multi-line string.
|
||||
45
ruby/ql/src/queries/security/cwe-020/MissingFullAnchor.qhelp
Normal file
45
ruby/ql/src/queries/security/cwe-020/MissingFullAnchor.qhelp
Normal file
@@ -0,0 +1,45 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Regular expressions in Ruby can use anchors to match the beginning and end of a string.
|
||||
However, if the <code>^</code> and <code>$</code> anchors are used,
|
||||
the regular expression can match a single line of a multi-line string.
|
||||
This allows bad actors to bypass your regular expression checks and inject malicious input.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Use the <code>\A</code> and <code>\z</code> anchors since these anchors will always
|
||||
match the beginning and end of the string, even if the string contains newlines.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
|
||||
<p>
|
||||
The following (bad) example code uses a regular expression to check that a string contains only digits.
|
||||
</p>
|
||||
|
||||
<sample src="examples/missing_full_anchor_bad.rb" />
|
||||
|
||||
<p>
|
||||
The regular expression <code>/^[0-9]+$/</code> will match a single line of a multi-line string,
|
||||
which may not be the intended behavior.
|
||||
The following (good) example code uses the regular expression <code>\A[0-9]+\z</code> to match the entire input string.
|
||||
</p>
|
||||
|
||||
<sample src="examples/missing_full_anchor_good.rb" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
Ruby documentation: <a href="https://ruby-doc.org/3.2.0/Regexp.html#class-Regexp-label-Anchors">Anchors</a>
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
21
ruby/ql/src/queries/security/cwe-020/MissingFullAnchor.ql
Normal file
21
ruby/ql/src/queries/security/cwe-020/MissingFullAnchor.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @name Badly anchored regular expression
|
||||
* @description Regular expressions anchored using `^` or `$` are vulnerable to bypassing.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 7.8
|
||||
* @precision high
|
||||
* @id rb/regex/badly-anchored-regexp
|
||||
* @tags correctness
|
||||
* security
|
||||
* external/cwe/cwe-020
|
||||
*/
|
||||
|
||||
import codeql.ruby.security.regexp.MissingFullAnchorQuery
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode
|
||||
where config.hasFlowPath(source, sink) and sink.getNode() = sinkNode
|
||||
select sink, source, sink, "This value depends on $@, and is $@ against a $@.", source.getNode(),
|
||||
source.getNode().(Source).describe(), sinkNode.getCallNode(), "checked", sinkNode.getRegex(),
|
||||
"badly anchored regular expression"
|
||||
@@ -0,0 +1,5 @@
|
||||
def bad(input)
|
||||
raise "Bad input" unless input =~ /^[0-9]+$/
|
||||
|
||||
# ....
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
def good(input)
|
||||
raise "Bad input" unless input =~ /\A[0-9]+\z/
|
||||
|
||||
# ....
|
||||
end
|
||||
@@ -27,4 +27,4 @@ where
|
||||
select sinkNode.getHighlight(), source, sink,
|
||||
"This $@ that depends on a $@ may run slow on strings " + regexp.getPrefixMessage() +
|
||||
"with many repetitions of '" + regexp.getPumpString() + "'.", regexp, "regular expression",
|
||||
source.getNode(), "user-provided value"
|
||||
source.getNode(), source.getNode().(PolynomialReDoS::Source).describe()
|
||||
|
||||
@@ -1259,6 +1259,22 @@ control/cases.rb:
|
||||
# 157| getExpr: [AddExpr] ... + ...
|
||||
# 157| getAnOperand/getLeftOperand/getReceiver: [IntegerLiteral] 1
|
||||
# 157| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1
|
||||
# 160| getStmt: [TestPattern] ... in ...
|
||||
# 160| getValue: [MethodCall] call to expr
|
||||
# 160| getReceiver: [SelfVariableAccess] self
|
||||
# 160| getPattern: [ArrayPattern] [ ..., * ]
|
||||
# 160| getPrefixElement: [IntegerLiteral] 1
|
||||
# 160| getPrefixElement: [IntegerLiteral] 2
|
||||
# 162| getStmt: [MatchPattern] ... => ...
|
||||
# 162| getValue: [MethodCall] call to expr
|
||||
# 162| getReceiver: [SelfVariableAccess] self
|
||||
# 162| getPattern: [HashPattern] { ..., ** }
|
||||
# 162| getKey: [SymbolLiteral] :x
|
||||
# 162| getComponent: [StringTextComponent] x
|
||||
# 162| getValue: [LocalVariableAccess] v
|
||||
# 162| getKey: [SymbolLiteral] :y
|
||||
# 162| getComponent: [StringTextComponent] y
|
||||
# 162| getValue: [IntegerLiteral] 1
|
||||
modules/classes.rb:
|
||||
# 2| [Toplevel] classes.rb
|
||||
# 3| getStmt: [ClassDeclaration] Foo
|
||||
|
||||
@@ -326,6 +326,30 @@ control/cases.rb:
|
||||
# 91| getComponent: [StringTextComponent] foo
|
||||
# 91| getArgument: [SymbolLiteral] :"bar"
|
||||
# 91| getComponent: [StringTextComponent] bar
|
||||
# 160| [TestPattern] ... in ...
|
||||
# 160| getDesugared: [CaseExpr] case ...
|
||||
# 160| getValue: [MethodCall] call to expr
|
||||
# 160| getReceiver: [SelfVariableAccess] self
|
||||
# 160| getBranch: [InClause] in ... then ...
|
||||
# 160| getBody: [BooleanLiteral] true
|
||||
# 160| getPattern: [ArrayPattern] [ ..., * ]
|
||||
# 160| getPrefixElement: [IntegerLiteral] 1
|
||||
# 160| getPrefixElement: [IntegerLiteral] 2
|
||||
# 160| getBranch/getElseBranch: [StmtSequence] else ...
|
||||
# 160| getStmt: [BooleanLiteral] false
|
||||
# 162| [MatchPattern] ... => ...
|
||||
# 162| getDesugared: [CaseExpr] case ...
|
||||
# 162| getValue: [MethodCall] call to expr
|
||||
# 162| getReceiver: [SelfVariableAccess] self
|
||||
# 162| getBranch: [InClause] in ... then ...
|
||||
# 162| getBody: [NilLiteral] nil
|
||||
# 162| getPattern: [HashPattern] { ..., ** }
|
||||
# 162| getKey: [SymbolLiteral] :x
|
||||
# 162| getComponent: [StringTextComponent] x
|
||||
# 162| getValue: [LocalVariableAccess] v
|
||||
# 162| getKey: [SymbolLiteral] :y
|
||||
# 162| getComponent: [StringTextComponent] y
|
||||
# 162| getValue: [IntegerLiteral] 1
|
||||
constants/constants.rb:
|
||||
# 20| [ArrayLiteral] [...]
|
||||
# 20| getDesugared: [MethodCall] call to []
|
||||
|
||||
@@ -2732,6 +2732,30 @@ control/cases.rb:
|
||||
# 157| 3: [ReservedWord] )
|
||||
# 157| 2: [ReservedWord] ;
|
||||
# 158| 5: [ReservedWord] end
|
||||
# 160| 17: [TestPattern] TestPattern
|
||||
# 160| 0: [Identifier] expr
|
||||
# 160| 1: [ReservedWord] in
|
||||
# 160| 2: [ArrayPattern] ArrayPattern
|
||||
# 160| 0: [ReservedWord] [
|
||||
# 160| 1: [Integer] 1
|
||||
# 160| 2: [ReservedWord] ,
|
||||
# 160| 3: [Integer] 2
|
||||
# 160| 4: [ReservedWord] ]
|
||||
# 162| 18: [MatchPattern] MatchPattern
|
||||
# 162| 0: [Identifier] expr
|
||||
# 162| 1: [ReservedWord] =>
|
||||
# 162| 2: [HashPattern] HashPattern
|
||||
# 162| 0: [ReservedWord] {
|
||||
# 162| 1: [KeywordPattern] KeywordPattern
|
||||
# 162| 0: [HashKeySymbol] x
|
||||
# 162| 1: [ReservedWord] :
|
||||
# 162| 2: [Identifier] v
|
||||
# 162| 2: [ReservedWord] ,
|
||||
# 162| 3: [KeywordPattern] KeywordPattern
|
||||
# 162| 0: [HashKeySymbol] y
|
||||
# 162| 1: [ReservedWord] :
|
||||
# 162| 2: [Integer] 1
|
||||
# 162| 4: [ReservedWord] }
|
||||
# 1| [Comment] # Define some variables used below
|
||||
# 7| [Comment] # A case expr with a value and an else branch
|
||||
# 17| [Comment] # A case expr without a value or else branch
|
||||
|
||||
@@ -263,6 +263,14 @@ exprValue
|
||||
| control/cases.rb:157:8:157:8 | 1 | 1 | int |
|
||||
| control/cases.rb:157:8:157:12 | ... + ... | 2 | int |
|
||||
| control/cases.rb:157:12:157:12 | 1 | 1 | int |
|
||||
| control/cases.rb:160:1:160:14 | false | false | boolean |
|
||||
| control/cases.rb:160:1:160:14 | true | true | boolean |
|
||||
| control/cases.rb:160:10:160:10 | 1 | 1 | int |
|
||||
| control/cases.rb:160:13:160:13 | 2 | 2 | int |
|
||||
| control/cases.rb:162:1:162:20 | nil | nil | nil |
|
||||
| control/cases.rb:162:10:162:10 | :x | :x | symbol |
|
||||
| control/cases.rb:162:16:162:16 | :y | :y | symbol |
|
||||
| control/cases.rb:162:19:162:19 | 1 | 1 | int |
|
||||
| control/conditionals.rb:2:5:2:5 | 0 | 0 | int |
|
||||
| control/conditionals.rb:3:5:3:5 | 0 | 0 | int |
|
||||
| control/conditionals.rb:4:5:4:5 | 0 | 0 | int |
|
||||
@@ -1147,6 +1155,12 @@ exprCfgNodeValue
|
||||
| control/cases.rb:157:8:157:8 | 1 | 1 | int |
|
||||
| control/cases.rb:157:8:157:12 | ... + ... | 2 | int |
|
||||
| control/cases.rb:157:12:157:12 | 1 | 1 | int |
|
||||
| control/cases.rb:160:1:160:14 | false | false | boolean |
|
||||
| control/cases.rb:160:1:160:14 | true | true | boolean |
|
||||
| control/cases.rb:160:10:160:10 | 1 | 1 | int |
|
||||
| control/cases.rb:160:13:160:13 | 2 | 2 | int |
|
||||
| control/cases.rb:162:1:162:20 | nil | nil | nil |
|
||||
| control/cases.rb:162:19:162:19 | 1 | 1 | int |
|
||||
| control/conditionals.rb:2:5:2:5 | 0 | 0 | int |
|
||||
| control/conditionals.rb:3:5:3:5 | 0 | 0 | int |
|
||||
| control/conditionals.rb:4:5:4:5 | 0 | 0 | int |
|
||||
|
||||
@@ -10,12 +10,15 @@ caseValues
|
||||
| cases.rb:137:1:145:3 | case ... | cases.rb:137:6:137:9 | call to expr |
|
||||
| cases.rb:147:1:152:3 | case ... | cases.rb:147:6:147:9 | call to expr |
|
||||
| cases.rb:154:1:158:3 | case ... | cases.rb:154:6:154:9 | call to expr |
|
||||
| cases.rb:160:1:160:14 | case ... | cases.rb:160:1:160:4 | call to expr |
|
||||
| cases.rb:162:1:162:20 | case ... | cases.rb:162:1:162:4 | call to expr |
|
||||
caseNoValues
|
||||
| cases.rb:18:1:22:3 | case ... |
|
||||
caseElseBranches
|
||||
| cases.rb:8:1:15:3 | case ... | cases.rb:13:1:14:7 | else ... |
|
||||
| cases.rb:26:1:29:3 | case ... | cases.rb:28:3:28:12 | else ... |
|
||||
| cases.rb:31:1:37:3 | case ... | cases.rb:36:3:36:12 | else ... |
|
||||
| cases.rb:160:1:160:14 | case ... | cases.rb:160:1:160:14 | else ... |
|
||||
caseNoElseBranches
|
||||
| cases.rb:18:1:22:3 | case ... |
|
||||
| cases.rb:39:1:80:3 | case ... |
|
||||
@@ -26,6 +29,7 @@ caseNoElseBranches
|
||||
| cases.rb:137:1:145:3 | case ... |
|
||||
| cases.rb:147:1:152:3 | case ... |
|
||||
| cases.rb:154:1:158:3 | case ... |
|
||||
| cases.rb:162:1:162:20 | case ... |
|
||||
caseWhenBranches
|
||||
| cases.rb:8:1:15:3 | case ... | cases.rb:9:1:10:7 | when ... | 0 | cases.rb:9:6:9:6 | b | cases.rb:9:7:10:7 | then ... |
|
||||
| cases.rb:8:1:15:3 | case ... | cases.rb:11:1:12:7 | when ... | 0 | cases.rb:11:6:11:6 | c | cases.rb:11:10:12:7 | then ... |
|
||||
@@ -132,3 +136,6 @@ caseAllBranches
|
||||
| cases.rb:154:1:158:3 | case ... | 0 | cases.rb:155:3:155:12 | in ... then ... |
|
||||
| cases.rb:154:1:158:3 | case ... | 1 | cases.rb:156:3:156:13 | in ... then ... |
|
||||
| cases.rb:154:1:158:3 | case ... | 2 | cases.rb:157:3:157:14 | in ... then ... |
|
||||
| cases.rb:160:1:160:14 | case ... | 0 | cases.rb:160:1:160:14 | in ... then ... |
|
||||
| cases.rb:160:1:160:14 | case ... | 1 | cases.rb:160:1:160:14 | else ... |
|
||||
| cases.rb:162:1:162:20 | case ... | 0 | cases.rb:162:1:162:20 | in ... then ... |
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
| cases.rb:137:1:145:3 | case ... | CaseExpr |
|
||||
| cases.rb:147:1:152:3 | case ... | CaseExpr |
|
||||
| cases.rb:154:1:158:3 | case ... | CaseExpr |
|
||||
| cases.rb:160:1:160:14 | case ... | CaseExpr |
|
||||
| cases.rb:162:1:162:20 | case ... | CaseExpr |
|
||||
| conditionals.rb:10:1:12:3 | if ... | IfExpr |
|
||||
| conditionals.rb:15:1:19:3 | if ... | IfExpr |
|
||||
| conditionals.rb:22:1:30:3 | if ... | IfExpr |
|
||||
|
||||
@@ -155,4 +155,8 @@ case expr
|
||||
in ^(foo);
|
||||
in ^(@foo);
|
||||
in ^(1 + 1);
|
||||
end
|
||||
end
|
||||
|
||||
expr in [1, 2]
|
||||
|
||||
expr => {x: v, y: 1}
|
||||
@@ -68,78 +68,86 @@ edges
|
||||
| call_sensitivity.rb:74:18:74:18 | y : | call_sensitivity.rb:76:17:76:17 | y : |
|
||||
| call_sensitivity.rb:76:17:76:17 | y : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:76:17:76:17 | y : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:80:30:80:30 | x : | call_sensitivity.rb:81:23:81:23 | x : |
|
||||
| call_sensitivity.rb:80:30:80:30 | x : | call_sensitivity.rb:81:23:81:23 | x : |
|
||||
| call_sensitivity.rb:80:30:80:30 | x : | call_sensitivity.rb:81:23:81:23 | x : |
|
||||
| call_sensitivity.rb:80:30:80:30 | x : | call_sensitivity.rb:81:23:81:23 | x : |
|
||||
| call_sensitivity.rb:81:23:81:23 | x : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:81:23:81:23 | x : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:81:23:81:23 | x : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:81:23:81:23 | x : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:84:35:84:35 | x : | call_sensitivity.rb:85:28:85:28 | x : |
|
||||
| call_sensitivity.rb:84:35:84:35 | x : | call_sensitivity.rb:85:28:85:28 | x : |
|
||||
| call_sensitivity.rb:85:28:85:28 | x : | call_sensitivity.rb:80:30:80:30 | x : |
|
||||
| call_sensitivity.rb:85:28:85:28 | x : | call_sensitivity.rb:80:30:80:30 | x : |
|
||||
| call_sensitivity.rb:88:33:88:33 | y : | call_sensitivity.rb:89:25:89:25 | y : |
|
||||
| call_sensitivity.rb:88:33:88:33 | y : | call_sensitivity.rb:89:25:89:25 | y : |
|
||||
| call_sensitivity.rb:88:33:88:33 | y : | call_sensitivity.rb:89:25:89:25 | y : |
|
||||
| call_sensitivity.rb:88:33:88:33 | y : | call_sensitivity.rb:89:25:89:25 | y : |
|
||||
| call_sensitivity.rb:89:25:89:25 | y : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:89:25:89:25 | y : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:89:25:89:25 | y : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:89:25:89:25 | y : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:92:35:92:35 | x : | call_sensitivity.rb:93:34:93:34 | x : |
|
||||
| call_sensitivity.rb:92:35:92:35 | x : | call_sensitivity.rb:93:34:93:34 | x : |
|
||||
| call_sensitivity.rb:93:34:93:34 | x : | call_sensitivity.rb:88:33:88:33 | y : |
|
||||
| call_sensitivity.rb:93:34:93:34 | x : | call_sensitivity.rb:88:33:88:33 | y : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:97:10:97:10 | x |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:97:10:97:10 | x |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:97:10:97:10 | x |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:97:10:97:10 | x |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:97:10:97:10 | x |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:97:10:97:10 | x |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:98:13:98:13 | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:98:13:98:13 | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:98:13:98:13 | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | call_sensitivity.rb:98:13:98:13 | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:102:11:102:20 | ( ... ) : | call_sensitivity.rb:96:18:96:18 | x : |
|
||||
| call_sensitivity.rb:102:11:102:20 | ( ... ) : | call_sensitivity.rb:96:18:96:18 | x : |
|
||||
| call_sensitivity.rb:102:12:102:19 | call to taint : | call_sensitivity.rb:102:11:102:20 | ( ... ) : |
|
||||
| call_sensitivity.rb:102:12:102:19 | call to taint : | call_sensitivity.rb:102:11:102:20 | ( ... ) : |
|
||||
| call_sensitivity.rb:103:11:103:18 | call to taint : | call_sensitivity.rb:54:15:54:15 | x : |
|
||||
| call_sensitivity.rb:103:11:103:18 | call to taint : | call_sensitivity.rb:54:15:54:15 | x : |
|
||||
| call_sensitivity.rb:104:16:104:23 | call to taint : | call_sensitivity.rb:58:20:58:20 | x : |
|
||||
| call_sensitivity.rb:104:16:104:23 | call to taint : | call_sensitivity.rb:58:20:58:20 | x : |
|
||||
| call_sensitivity.rb:105:14:105:22 | call to taint : | call_sensitivity.rb:62:18:62:18 | y : |
|
||||
| call_sensitivity.rb:105:14:105:22 | call to taint : | call_sensitivity.rb:62:18:62:18 | y : |
|
||||
| call_sensitivity.rb:106:16:106:24 | call to taint : | call_sensitivity.rb:66:20:66:20 | x : |
|
||||
| call_sensitivity.rb:106:16:106:24 | call to taint : | call_sensitivity.rb:66:20:66:20 | x : |
|
||||
| call_sensitivity.rb:107:14:107:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:107:14:107:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:109:21:109:28 | call to taint : | call_sensitivity.rb:80:30:80:30 | x : |
|
||||
| call_sensitivity.rb:109:21:109:28 | call to taint : | call_sensitivity.rb:80:30:80:30 | x : |
|
||||
| call_sensitivity.rb:110:26:110:33 | call to taint : | call_sensitivity.rb:84:35:84:35 | x : |
|
||||
| call_sensitivity.rb:110:26:110:33 | call to taint : | call_sensitivity.rb:84:35:84:35 | x : |
|
||||
| call_sensitivity.rb:111:24:111:32 | call to taint : | call_sensitivity.rb:88:33:88:33 | y : |
|
||||
| call_sensitivity.rb:111:24:111:32 | call to taint : | call_sensitivity.rb:88:33:88:33 | y : |
|
||||
| call_sensitivity.rb:112:26:112:33 | call to taint : | call_sensitivity.rb:92:35:92:35 | x : |
|
||||
| call_sensitivity.rb:112:26:112:33 | call to taint : | call_sensitivity.rb:92:35:92:35 | x : |
|
||||
| call_sensitivity.rb:149:14:149:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:149:14:149:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:156:19:156:19 | x : | call_sensitivity.rb:157:12:157:12 | x : |
|
||||
| call_sensitivity.rb:156:19:156:19 | x : | call_sensitivity.rb:157:12:157:12 | x : |
|
||||
| call_sensitivity.rb:157:12:157:12 | x : | call_sensitivity.rb:96:18:96:18 | x : |
|
||||
| call_sensitivity.rb:157:12:157:12 | x : | call_sensitivity.rb:96:18:96:18 | x : |
|
||||
| call_sensitivity.rb:160:11:160:19 | call to taint : | call_sensitivity.rb:156:19:156:19 | x : |
|
||||
| call_sensitivity.rb:160:11:160:19 | call to taint : | call_sensitivity.rb:156:19:156:19 | x : |
|
||||
| call_sensitivity.rb:169:11:169:20 | ( ... ) : | call_sensitivity.rb:96:18:96:18 | x : |
|
||||
| call_sensitivity.rb:169:11:169:20 | ( ... ) : | call_sensitivity.rb:96:18:96:18 | x : |
|
||||
| call_sensitivity.rb:169:12:169:19 | call to taint : | call_sensitivity.rb:169:11:169:20 | ( ... ) : |
|
||||
| call_sensitivity.rb:169:12:169:19 | call to taint : | call_sensitivity.rb:169:11:169:20 | ( ... ) : |
|
||||
| call_sensitivity.rb:80:15:80:15 | x : | call_sensitivity.rb:81:18:81:18 | x : |
|
||||
| call_sensitivity.rb:80:15:80:15 | x : | call_sensitivity.rb:81:18:81:18 | x : |
|
||||
| call_sensitivity.rb:81:18:81:18 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:81:18:81:18 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:85:18:85:27 | ( ... ) : | call_sensitivity.rb:80:15:80:15 | x : |
|
||||
| call_sensitivity.rb:85:18:85:27 | ( ... ) : | call_sensitivity.rb:80:15:80:15 | x : |
|
||||
| call_sensitivity.rb:85:19:85:26 | call to taint : | call_sensitivity.rb:85:18:85:27 | ( ... ) : |
|
||||
| call_sensitivity.rb:85:19:85:26 | call to taint : | call_sensitivity.rb:85:18:85:27 | ( ... ) : |
|
||||
| call_sensitivity.rb:88:30:88:30 | x : | call_sensitivity.rb:89:23:89:23 | x : |
|
||||
| call_sensitivity.rb:88:30:88:30 | x : | call_sensitivity.rb:89:23:89:23 | x : |
|
||||
| call_sensitivity.rb:88:30:88:30 | x : | call_sensitivity.rb:89:23:89:23 | x : |
|
||||
| call_sensitivity.rb:88:30:88:30 | x : | call_sensitivity.rb:89:23:89:23 | x : |
|
||||
| call_sensitivity.rb:89:23:89:23 | x : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:89:23:89:23 | x : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:89:23:89:23 | x : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:89:23:89:23 | x : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:92:35:92:35 | x : | call_sensitivity.rb:93:28:93:28 | x : |
|
||||
| call_sensitivity.rb:92:35:92:35 | x : | call_sensitivity.rb:93:28:93:28 | x : |
|
||||
| call_sensitivity.rb:93:28:93:28 | x : | call_sensitivity.rb:88:30:88:30 | x : |
|
||||
| call_sensitivity.rb:93:28:93:28 | x : | call_sensitivity.rb:88:30:88:30 | x : |
|
||||
| call_sensitivity.rb:96:33:96:33 | y : | call_sensitivity.rb:97:25:97:25 | y : |
|
||||
| call_sensitivity.rb:96:33:96:33 | y : | call_sensitivity.rb:97:25:97:25 | y : |
|
||||
| call_sensitivity.rb:96:33:96:33 | y : | call_sensitivity.rb:97:25:97:25 | y : |
|
||||
| call_sensitivity.rb:96:33:96:33 | y : | call_sensitivity.rb:97:25:97:25 | y : |
|
||||
| call_sensitivity.rb:97:25:97:25 | y : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:97:25:97:25 | y : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:97:25:97:25 | y : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:97:25:97:25 | y : | call_sensitivity.rb:70:30:70:30 | x : |
|
||||
| call_sensitivity.rb:100:35:100:35 | x : | call_sensitivity.rb:101:34:101:34 | x : |
|
||||
| call_sensitivity.rb:100:35:100:35 | x : | call_sensitivity.rb:101:34:101:34 | x : |
|
||||
| call_sensitivity.rb:101:34:101:34 | x : | call_sensitivity.rb:96:33:96:33 | y : |
|
||||
| call_sensitivity.rb:101:34:101:34 | x : | call_sensitivity.rb:96:33:96:33 | y : |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:105:10:105:10 | x |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:105:10:105:10 | x |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:105:10:105:10 | x |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:105:10:105:10 | x |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:105:10:105:10 | x |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:105:10:105:10 | x |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:106:13:106:13 | x : |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:106:13:106:13 | x : |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:106:13:106:13 | x : |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:106:13:106:13 | x : |
|
||||
| call_sensitivity.rb:106:13:106:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:106:13:106:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:106:13:106:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:106:13:106:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
|
||||
| call_sensitivity.rb:110:11:110:20 | ( ... ) : | call_sensitivity.rb:104:18:104:18 | x : |
|
||||
| call_sensitivity.rb:110:11:110:20 | ( ... ) : | call_sensitivity.rb:104:18:104:18 | x : |
|
||||
| call_sensitivity.rb:110:12:110:19 | call to taint : | call_sensitivity.rb:110:11:110:20 | ( ... ) : |
|
||||
| call_sensitivity.rb:110:12:110:19 | call to taint : | call_sensitivity.rb:110:11:110:20 | ( ... ) : |
|
||||
| call_sensitivity.rb:111:11:111:18 | call to taint : | call_sensitivity.rb:54:15:54:15 | x : |
|
||||
| call_sensitivity.rb:111:11:111:18 | call to taint : | call_sensitivity.rb:54:15:54:15 | x : |
|
||||
| call_sensitivity.rb:112:16:112:23 | call to taint : | call_sensitivity.rb:58:20:58:20 | x : |
|
||||
| call_sensitivity.rb:112:16:112:23 | call to taint : | call_sensitivity.rb:58:20:58:20 | x : |
|
||||
| call_sensitivity.rb:113:14:113:22 | call to taint : | call_sensitivity.rb:62:18:62:18 | y : |
|
||||
| call_sensitivity.rb:113:14:113:22 | call to taint : | call_sensitivity.rb:62:18:62:18 | y : |
|
||||
| call_sensitivity.rb:114:16:114:24 | call to taint : | call_sensitivity.rb:66:20:66:20 | x : |
|
||||
| call_sensitivity.rb:114:16:114:24 | call to taint : | call_sensitivity.rb:66:20:66:20 | x : |
|
||||
| call_sensitivity.rb:115:14:115:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:115:14:115:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:117:21:117:28 | call to taint : | call_sensitivity.rb:88:30:88:30 | x : |
|
||||
| call_sensitivity.rb:117:21:117:28 | call to taint : | call_sensitivity.rb:88:30:88:30 | x : |
|
||||
| call_sensitivity.rb:118:26:118:33 | call to taint : | call_sensitivity.rb:92:35:92:35 | x : |
|
||||
| call_sensitivity.rb:118:26:118:33 | call to taint : | call_sensitivity.rb:92:35:92:35 | x : |
|
||||
| call_sensitivity.rb:119:24:119:32 | call to taint : | call_sensitivity.rb:96:33:96:33 | y : |
|
||||
| call_sensitivity.rb:119:24:119:32 | call to taint : | call_sensitivity.rb:96:33:96:33 | y : |
|
||||
| call_sensitivity.rb:120:26:120:33 | call to taint : | call_sensitivity.rb:100:35:100:35 | x : |
|
||||
| call_sensitivity.rb:120:26:120:33 | call to taint : | call_sensitivity.rb:100:35:100:35 | x : |
|
||||
| call_sensitivity.rb:161:14:161:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:161:14:161:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
|
||||
| call_sensitivity.rb:168:19:168:19 | x : | call_sensitivity.rb:169:12:169:12 | x : |
|
||||
| call_sensitivity.rb:168:19:168:19 | x : | call_sensitivity.rb:169:12:169:12 | x : |
|
||||
| call_sensitivity.rb:169:12:169:12 | x : | call_sensitivity.rb:104:18:104:18 | x : |
|
||||
| call_sensitivity.rb:169:12:169:12 | x : | call_sensitivity.rb:104:18:104:18 | x : |
|
||||
| call_sensitivity.rb:172:11:172:19 | call to taint : | call_sensitivity.rb:168:19:168:19 | x : |
|
||||
| call_sensitivity.rb:172:11:172:19 | call to taint : | call_sensitivity.rb:168:19:168:19 | x : |
|
||||
| call_sensitivity.rb:181:11:181:20 | ( ... ) : | call_sensitivity.rb:104:18:104:18 | x : |
|
||||
| call_sensitivity.rb:181:11:181:20 | ( ... ) : | call_sensitivity.rb:104:18:104:18 | x : |
|
||||
| call_sensitivity.rb:181:12:181:19 | call to taint : | call_sensitivity.rb:181:11:181:20 | ( ... ) : |
|
||||
| call_sensitivity.rb:181:12:181:19 | call to taint : | call_sensitivity.rb:181:11:181:20 | ( ... ) : |
|
||||
nodes
|
||||
| call_sensitivity.rb:9:6:9:14 | ( ... ) | semmle.label | ( ... ) |
|
||||
| call_sensitivity.rb:9:6:9:14 | ( ... ) | semmle.label | ( ... ) |
|
||||
@@ -223,76 +231,84 @@ nodes
|
||||
| call_sensitivity.rb:74:18:74:18 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:76:17:76:17 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:76:17:76:17 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:80:30:80:30 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:80:30:80:30 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:80:30:80:30 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:80:30:80:30 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:81:23:81:23 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:81:23:81:23 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:81:23:81:23 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:81:23:81:23 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:84:35:84:35 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:84:35:84:35 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:85:28:85:28 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:85:28:85:28 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:88:33:88:33 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:88:33:88:33 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:88:33:88:33 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:88:33:88:33 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:89:25:89:25 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:89:25:89:25 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:89:25:89:25 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:89:25:89:25 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:80:15:80:15 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:80:15:80:15 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:81:18:81:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:81:18:81:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:85:18:85:27 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:85:18:85:27 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:85:19:85:26 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:85:19:85:26 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:88:30:88:30 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:88:30:88:30 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:88:30:88:30 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:88:30:88:30 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:89:23:89:23 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:89:23:89:23 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:89:23:89:23 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:89:23:89:23 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:92:35:92:35 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:92:35:92:35 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:93:34:93:34 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:93:34:93:34 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:96:18:96:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:97:10:97:10 | x | semmle.label | x |
|
||||
| call_sensitivity.rb:97:10:97:10 | x | semmle.label | x |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:98:13:98:13 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:102:11:102:20 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:102:11:102:20 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:102:12:102:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:102:12:102:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:103:11:103:18 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:103:11:103:18 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:104:16:104:23 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:104:16:104:23 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:105:14:105:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:105:14:105:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:106:16:106:24 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:106:16:106:24 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:107:14:107:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:107:14:107:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:109:21:109:28 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:109:21:109:28 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:110:26:110:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:110:26:110:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:111:24:111:32 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:111:24:111:32 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:112:26:112:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:112:26:112:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:149:14:149:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:149:14:149:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:156:19:156:19 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:156:19:156:19 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:157:12:157:12 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:157:12:157:12 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:160:11:160:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:160:11:160:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:169:11:169:20 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:169:11:169:20 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:169:12:169:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:169:12:169:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:93:28:93:28 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:93:28:93:28 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:96:33:96:33 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:96:33:96:33 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:96:33:96:33 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:96:33:96:33 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:97:25:97:25 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:97:25:97:25 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:97:25:97:25 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:97:25:97:25 | y : | semmle.label | y : |
|
||||
| call_sensitivity.rb:100:35:100:35 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:100:35:100:35 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:101:34:101:34 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:101:34:101:34 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:104:18:104:18 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:105:10:105:10 | x | semmle.label | x |
|
||||
| call_sensitivity.rb:105:10:105:10 | x | semmle.label | x |
|
||||
| call_sensitivity.rb:106:13:106:13 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:106:13:106:13 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:106:13:106:13 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:106:13:106:13 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:110:11:110:20 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:110:11:110:20 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:110:12:110:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:110:12:110:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:111:11:111:18 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:111:11:111:18 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:112:16:112:23 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:112:16:112:23 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:113:14:113:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:113:14:113:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:114:16:114:24 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:114:16:114:24 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:115:14:115:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:115:14:115:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:117:21:117:28 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:117:21:117:28 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:118:26:118:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:118:26:118:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:119:24:119:32 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:119:24:119:32 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:120:26:120:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:120:26:120:33 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:161:14:161:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:161:14:161:22 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:168:19:168:19 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:168:19:168:19 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:169:12:169:12 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:169:12:169:12 | x : | semmle.label | x : |
|
||||
| call_sensitivity.rb:172:11:172:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:172:11:172:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:181:11:181:20 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:181:11:181:20 | ( ... ) : | semmle.label | ( ... ) : |
|
||||
| call_sensitivity.rb:181:12:181:19 | call to taint : | semmle.label | call to taint : |
|
||||
| call_sensitivity.rb:181:12:181:19 | call to taint : | semmle.label | call to taint : |
|
||||
subpaths
|
||||
#select
|
||||
| call_sensitivity.rb:9:6:9:14 | ( ... ) | call_sensitivity.rb:9:7:9:13 | call to taint : | call_sensitivity.rb:9:6:9:14 | ( ... ) | $@ | call_sensitivity.rb:9:7:9:13 | call to taint : | call to taint : |
|
||||
@@ -300,79 +316,86 @@ subpaths
|
||||
| call_sensitivity.rb:31:27:31:27 | x | call_sensitivity.rb:32:25:32:32 | call to taint : | call_sensitivity.rb:31:27:31:27 | x | $@ | call_sensitivity.rb:32:25:32:32 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:40:31:40:31 | x | call_sensitivity.rb:41:25:41:32 | call to taint : | call_sensitivity.rb:40:31:40:31 | x | $@ | call_sensitivity.rb:41:25:41:32 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:43:32:43:32 | x | call_sensitivity.rb:44:26:44:33 | call to taint : | call_sensitivity.rb:43:32:43:32 | x | $@ | call_sensitivity.rb:44:26:44:33 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:102:12:102:19 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:102:12:102:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:103:11:103:18 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:103:11:103:18 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:104:16:104:23 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:104:16:104:23 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:105:14:105:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:105:14:105:22 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:106:16:106:24 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:106:16:106:24 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:107:14:107:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:107:14:107:22 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:149:14:149:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:149:14:149:22 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:160:11:160:19 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:160:11:160:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:109:21:109:28 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:109:21:109:28 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:110:26:110:33 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:110:26:110:33 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:111:24:111:32 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:111:24:111:32 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:112:26:112:33 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:112:26:112:33 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:97:10:97:10 | x | call_sensitivity.rb:102:12:102:19 | call to taint : | call_sensitivity.rb:97:10:97:10 | x | $@ | call_sensitivity.rb:102:12:102:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:97:10:97:10 | x | call_sensitivity.rb:160:11:160:19 | call to taint : | call_sensitivity.rb:97:10:97:10 | x | $@ | call_sensitivity.rb:160:11:160:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:97:10:97:10 | x | call_sensitivity.rb:169:12:169:19 | call to taint : | call_sensitivity.rb:97:10:97:10 | x | $@ | call_sensitivity.rb:169:12:169:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:85:19:85:26 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:85:19:85:26 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:110:12:110:19 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:110:12:110:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:111:11:111:18 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:111:11:111:18 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:112:16:112:23 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:112:16:112:23 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:113:14:113:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:113:14:113:22 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:114:16:114:24 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:114:16:114:24 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:115:14:115:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:115:14:115:22 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:161:14:161:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:161:14:161:22 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:172:11:172:19 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:172:11:172:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:117:21:117:28 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:117:21:117:28 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:118:26:118:33 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:118:26:118:33 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:119:24:119:32 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:119:24:119:32 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:120:26:120:33 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:120:26:120:33 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:105:10:105:10 | x | call_sensitivity.rb:110:12:110:19 | call to taint : | call_sensitivity.rb:105:10:105:10 | x | $@ | call_sensitivity.rb:110:12:110:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:105:10:105:10 | x | call_sensitivity.rb:172:11:172:19 | call to taint : | call_sensitivity.rb:105:10:105:10 | x | $@ | call_sensitivity.rb:172:11:172:19 | call to taint : | call to taint : |
|
||||
| call_sensitivity.rb:105:10:105:10 | x | call_sensitivity.rb:181:12:181:19 | call to taint : | call_sensitivity.rb:105:10:105:10 | x | $@ | call_sensitivity.rb:181:12:181:19 | call to taint : | call to taint : |
|
||||
mayBenefitFromCallContext
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:54:3:56:5 | method2 |
|
||||
| call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:58:3:60:5 | call_method2 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:62:3:64:5 | method3 |
|
||||
| call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:66:3:68:5 | call_method3 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:80:3:82:5 | singleton_method2 |
|
||||
| call_sensitivity.rb:85:5:85:28 | call to singleton_method2 | call_sensitivity.rb:84:3:86:5 | call_singleton_method2 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:88:3:90:5 | singleton_method3 |
|
||||
| call_sensitivity.rb:93:5:93:35 | call to singleton_method3 | call_sensitivity.rb:92:3:94:5 | call_singleton_method3 |
|
||||
| call_sensitivity.rb:97:5:97:10 | call to sink | call_sensitivity.rb:96:3:99:5 | initialize |
|
||||
| call_sensitivity.rb:98:5:98:13 | call to method1 | call_sensitivity.rb:96:3:99:5 | initialize |
|
||||
| call_sensitivity.rb:124:5:124:18 | call to method2 | call_sensitivity.rb:123:3:125:5 | call_method2 |
|
||||
| call_sensitivity.rb:128:5:128:25 | call to method3 | call_sensitivity.rb:127:3:129:5 | call_method3 |
|
||||
| call_sensitivity.rb:132:5:132:28 | call to singleton_method2 | call_sensitivity.rb:131:3:133:5 | call_singleton_method2 |
|
||||
| call_sensitivity.rb:136:5:136:35 | call to singleton_method3 | call_sensitivity.rb:135:3:137:5 | call_singleton_method3 |
|
||||
| call_sensitivity.rb:157:3:157:12 | call to new | call_sensitivity.rb:156:1:158:3 | create |
|
||||
| call_sensitivity.rb:81:5:81:18 | call to method1 | call_sensitivity.rb:80:3:82:5 | method5 |
|
||||
| call_sensitivity.rb:89:5:89:23 | call to singleton_method1 | call_sensitivity.rb:88:3:90:5 | singleton_method2 |
|
||||
| call_sensitivity.rb:93:5:93:28 | call to singleton_method2 | call_sensitivity.rb:92:3:94:5 | call_singleton_method2 |
|
||||
| call_sensitivity.rb:97:5:97:26 | call to singleton_method1 | call_sensitivity.rb:96:3:98:5 | singleton_method3 |
|
||||
| call_sensitivity.rb:101:5:101:35 | call to singleton_method3 | call_sensitivity.rb:100:3:102:5 | call_singleton_method3 |
|
||||
| call_sensitivity.rb:105:5:105:10 | call to sink | call_sensitivity.rb:104:3:107:5 | initialize |
|
||||
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:104:3:107:5 | initialize |
|
||||
| call_sensitivity.rb:132:5:132:18 | call to method2 | call_sensitivity.rb:131:3:133:5 | call_method2 |
|
||||
| call_sensitivity.rb:136:5:136:25 | call to method3 | call_sensitivity.rb:135:3:137:5 | call_method3 |
|
||||
| call_sensitivity.rb:144:5:144:28 | call to singleton_method2 | call_sensitivity.rb:143:3:145:5 | call_singleton_method2 |
|
||||
| call_sensitivity.rb:148:5:148:35 | call to singleton_method3 | call_sensitivity.rb:147:3:149:5 | call_singleton_method3 |
|
||||
| call_sensitivity.rb:169:3:169:12 | call to new | call_sensitivity.rb:168:1:170:3 | create |
|
||||
viableImplInCallContext
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:76:7:76:18 | call to method1 | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:98:5:98:13 | call to method1 | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:81:5:81:18 | call to method1 | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:164:3:166:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:103:1:103:19 | call to method2 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:124:5:124:18 | call to method2 | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:145:1:145:19 | call to method2 | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:104:1:104:24 | call to call_method2 | call_sensitivity.rb:54:3:56:5 | method2 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:123:3:125:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:176:3:178:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:111:1:111:19 | call to method2 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:132:5:132:18 | call to method2 | call_sensitivity.rb:123:3:125:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:157:1:157:19 | call to method2 | call_sensitivity.rb:123:3:125:5 | method1 |
|
||||
| call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:112:1:112:24 | call to call_method2 | call_sensitivity.rb:54:3:56:5 | method2 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:164:3:166:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:105:1:105:23 | call to method3 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:128:5:128:25 | call to method3 | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:147:1:147:23 | call to method3 | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:106:1:106:25 | call to call_method3 | call_sensitivity.rb:62:3:64:5 | method3 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:85:5:85:28 | call to singleton_method2 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:85:5:85:28 | call to singleton_method2 | call_sensitivity.rb:119:3:121:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:109:1:109:29 | call to singleton_method2 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:132:5:132:28 | call to singleton_method2 | call_sensitivity.rb:119:3:121:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:81:5:81:23 | call to singleton_method1 | call_sensitivity.rb:151:1:151:29 | call to singleton_method2 | call_sensitivity.rb:119:3:121:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:85:5:85:28 | call to singleton_method2 | call_sensitivity.rb:110:1:110:34 | call to call_singleton_method2 | call_sensitivity.rb:80:3:82:5 | singleton_method2 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:93:5:93:35 | call to singleton_method3 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:93:5:93:35 | call to singleton_method3 | call_sensitivity.rb:119:3:121:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:111:1:111:33 | call to singleton_method3 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:136:5:136:35 | call to singleton_method3 | call_sensitivity.rb:119:3:121:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:26 | call to singleton_method1 | call_sensitivity.rb:153:1:153:33 | call to singleton_method3 | call_sensitivity.rb:119:3:121:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:93:5:93:35 | call to singleton_method3 | call_sensitivity.rb:112:1:112:34 | call to call_singleton_method3 | call_sensitivity.rb:88:3:90:5 | singleton_method3 |
|
||||
| call_sensitivity.rb:97:5:97:10 | call to sink | call_sensitivity.rb:102:5:102:20 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:97:5:97:10 | call to sink | call_sensitivity.rb:157:3:157:12 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:97:5:97:10 | call to sink | call_sensitivity.rb:169:5:169:20 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:98:5:98:13 | call to method1 | call_sensitivity.rb:102:5:102:20 | call to new | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:98:5:98:13 | call to method1 | call_sensitivity.rb:157:3:157:12 | call to new | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:98:5:98:13 | call to method1 | call_sensitivity.rb:157:3:157:12 | call to new | call_sensitivity.rb:115:3:117:5 | method1 |
|
||||
| call_sensitivity.rb:98:5:98:13 | call to method1 | call_sensitivity.rb:169:5:169:20 | call to new | call_sensitivity.rb:164:3:166:5 | method1 |
|
||||
| call_sensitivity.rb:124:5:124:18 | call to method2 | call_sensitivity.rb:146:1:146:24 | call to call_method2 | call_sensitivity.rb:54:3:56:5 | method2 |
|
||||
| call_sensitivity.rb:128:5:128:25 | call to method3 | call_sensitivity.rb:148:1:148:25 | call to call_method3 | call_sensitivity.rb:62:3:64:5 | method3 |
|
||||
| call_sensitivity.rb:132:5:132:28 | call to singleton_method2 | call_sensitivity.rb:152:1:152:34 | call to call_singleton_method2 | call_sensitivity.rb:80:3:82:5 | singleton_method2 |
|
||||
| call_sensitivity.rb:136:5:136:35 | call to singleton_method3 | call_sensitivity.rb:154:1:154:34 | call to call_singleton_method3 | call_sensitivity.rb:88:3:90:5 | singleton_method3 |
|
||||
| call_sensitivity.rb:157:3:157:12 | call to new | call_sensitivity.rb:160:1:160:20 | call to create | call_sensitivity.rb:96:3:99:5 | initialize |
|
||||
| call_sensitivity.rb:157:3:157:12 | call to new | call_sensitivity.rb:161:1:161:20 | call to create | call_sensitivity.rb:139:3:141:5 | initialize |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:123:3:125:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:176:3:178:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:113:1:113:23 | call to method3 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:136:5:136:25 | call to method3 | call_sensitivity.rb:123:3:125:5 | method1 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:159:1:159:23 | call to method3 | call_sensitivity.rb:123:3:125:5 | method1 |
|
||||
| call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:114:1:114:25 | call to call_method3 | call_sensitivity.rb:62:3:64:5 | method3 |
|
||||
| call_sensitivity.rb:81:5:81:18 | call to method1 | call_sensitivity.rb:85:5:85:27 | call to method5 | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:81:5:81:18 | call to method1 | call_sensitivity.rb:85:5:85:27 | call to method5 | call_sensitivity.rb:123:3:125:5 | method1 |
|
||||
| call_sensitivity.rb:81:5:81:18 | call to method1 | call_sensitivity.rb:85:5:85:27 | call to method5 | call_sensitivity.rb:176:3:178:5 | method1 |
|
||||
| call_sensitivity.rb:81:5:81:18 | call to method1 | call_sensitivity.rb:140:5:140:27 | call to method5 | call_sensitivity.rb:123:3:125:5 | method1 |
|
||||
| call_sensitivity.rb:89:5:89:23 | call to singleton_method1 | call_sensitivity.rb:93:5:93:28 | call to singleton_method2 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:23 | call to singleton_method1 | call_sensitivity.rb:93:5:93:28 | call to singleton_method2 | call_sensitivity.rb:127:3:129:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:23 | call to singleton_method1 | call_sensitivity.rb:117:1:117:29 | call to singleton_method2 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:23 | call to singleton_method1 | call_sensitivity.rb:144:5:144:28 | call to singleton_method2 | call_sensitivity.rb:127:3:129:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:89:5:89:23 | call to singleton_method1 | call_sensitivity.rb:163:1:163:29 | call to singleton_method2 | call_sensitivity.rb:127:3:129:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:93:5:93:28 | call to singleton_method2 | call_sensitivity.rb:118:1:118:34 | call to call_singleton_method2 | call_sensitivity.rb:88:3:90:5 | singleton_method2 |
|
||||
| call_sensitivity.rb:97:5:97:26 | call to singleton_method1 | call_sensitivity.rb:101:5:101:35 | call to singleton_method3 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:97:5:97:26 | call to singleton_method1 | call_sensitivity.rb:101:5:101:35 | call to singleton_method3 | call_sensitivity.rb:127:3:129:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:97:5:97:26 | call to singleton_method1 | call_sensitivity.rb:119:1:119:33 | call to singleton_method3 | call_sensitivity.rb:70:3:72:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:97:5:97:26 | call to singleton_method1 | call_sensitivity.rb:148:5:148:35 | call to singleton_method3 | call_sensitivity.rb:127:3:129:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:97:5:97:26 | call to singleton_method1 | call_sensitivity.rb:165:1:165:33 | call to singleton_method3 | call_sensitivity.rb:127:3:129:5 | singleton_method1 |
|
||||
| call_sensitivity.rb:101:5:101:35 | call to singleton_method3 | call_sensitivity.rb:120:1:120:34 | call to call_singleton_method3 | call_sensitivity.rb:96:3:98:5 | singleton_method3 |
|
||||
| call_sensitivity.rb:105:5:105:10 | call to sink | call_sensitivity.rb:110:5:110:20 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:105:5:105:10 | call to sink | call_sensitivity.rb:169:3:169:12 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:105:5:105:10 | call to sink | call_sensitivity.rb:181:5:181:20 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:110:5:110:20 | call to new | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:169:3:169:12 | call to new | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:169:3:169:12 | call to new | call_sensitivity.rb:123:3:125:5 | method1 |
|
||||
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:181:5:181:20 | call to new | call_sensitivity.rb:176:3:178:5 | method1 |
|
||||
| call_sensitivity.rb:132:5:132:18 | call to method2 | call_sensitivity.rb:158:1:158:24 | call to call_method2 | call_sensitivity.rb:54:3:56:5 | method2 |
|
||||
| call_sensitivity.rb:136:5:136:25 | call to method3 | call_sensitivity.rb:160:1:160:25 | call to call_method3 | call_sensitivity.rb:62:3:64:5 | method3 |
|
||||
| call_sensitivity.rb:144:5:144:28 | call to singleton_method2 | call_sensitivity.rb:164:1:164:34 | call to call_singleton_method2 | call_sensitivity.rb:88:3:90:5 | singleton_method2 |
|
||||
| call_sensitivity.rb:148:5:148:35 | call to singleton_method3 | call_sensitivity.rb:166:1:166:34 | call to call_singleton_method3 | call_sensitivity.rb:96:3:98:5 | singleton_method3 |
|
||||
| call_sensitivity.rb:169:3:169:12 | call to new | call_sensitivity.rb:172:1:172:20 | call to create | call_sensitivity.rb:104:3:107:5 | initialize |
|
||||
| call_sensitivity.rb:169:3:169:12 | call to new | call_sensitivity.rb:173:1:173:20 | call to create | call_sensitivity.rb:151:3:153:5 | initialize |
|
||||
|
||||
@@ -48,7 +48,7 @@ apply_lambda(MY_LAMBDA2, taint(9))
|
||||
|
||||
class A
|
||||
def method1 x
|
||||
sink x # $ hasValueFlow=10 $ hasValueFlow=11 $ hasValueFlow=12 $ hasValueFlow=13 $ hasValueFlow=26 $ hasValueFlow=28 $ hasValueFlow=30 $ SPURIOUS: hasValueFlow=27
|
||||
sink x # $ hasValueFlow=10 $ hasValueFlow=11 $ hasValueFlow=12 $ hasValueFlow=13 $ hasValueFlow=26 $ hasValueFlow=28 $ hasValueFlow=30 $ hasValueFlow=33 $ SPURIOUS: hasValueFlow=27
|
||||
end
|
||||
|
||||
def method2 x
|
||||
@@ -77,6 +77,14 @@ class A
|
||||
end
|
||||
end
|
||||
|
||||
def method5 x
|
||||
self.method1 x
|
||||
end
|
||||
|
||||
def call_method5
|
||||
self.method5 (taint 33)
|
||||
end
|
||||
|
||||
def self.singleton_method2 x
|
||||
singleton_method1 x
|
||||
end
|
||||
@@ -128,6 +136,10 @@ class B < A
|
||||
self.method3(self, x)
|
||||
end
|
||||
|
||||
def call_method5 x
|
||||
self.method5 (taint 34)
|
||||
end
|
||||
|
||||
def self.call_singleton_method2 x
|
||||
self.singleton_method2 x
|
||||
end
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
actionDispatchRoutes
|
||||
| action_controller/routes.rb:2:5:2:20 | call to resources | delete | users/:id | users | destroy |
|
||||
| action_controller/routes.rb:2:5:2:20 | call to resources | get | users | users | index |
|
||||
| action_controller/routes.rb:2:5:2:20 | call to resources | get | users/:id | users | show |
|
||||
| action_controller/routes.rb:2:5:2:20 | call to resources | get | users/new | users | new |
|
||||
| action_controller/routes.rb:2:5:2:20 | call to resources | get | users:id/edit | users | edit |
|
||||
| action_controller/routes.rb:2:5:2:20 | call to resources | patch | users/:id | users | update |
|
||||
| action_controller/routes.rb:2:5:2:20 | call to resources | post | users | users | create |
|
||||
| action_controller/routes.rb:2:5:2:20 | call to resources | put | users/:id | users | update |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | delete | comments/:id | comments | destroy |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | get | comments | comments | index |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | get | comments/:id | comments | show |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | get | comments/new | comments | new |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | get | comments:id/edit | comments | edit |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | patch | comments/:id | comments | update |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | post | comments | comments | create |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | put | comments/:id | comments | update |
|
||||
| action_controller/routes.rb:4:9:4:32 | call to get | get | comments/:comment_id/photo | comments | photo |
|
||||
| action_controller/routes.rb:6:5:6:21 | call to resources | delete | photos/:id | photos | destroy |
|
||||
| action_controller/routes.rb:6:5:6:21 | call to resources | get | photos | photos | index |
|
||||
| action_controller/routes.rb:6:5:6:21 | call to resources | get | photos/:id | photos | show |
|
||||
| action_controller/routes.rb:6:5:6:21 | call to resources | get | photos/new | photos | new |
|
||||
| action_controller/routes.rb:6:5:6:21 | call to resources | get | photos:id/edit | photos | edit |
|
||||
| action_controller/routes.rb:6:5:6:21 | call to resources | patch | photos/:id | photos | update |
|
||||
| action_controller/routes.rb:6:5:6:21 | call to resources | post | photos | photos | create |
|
||||
| action_controller/routes.rb:6:5:6:21 | call to resources | put | photos/:id | photos | update |
|
||||
| action_controller/routes.rb:7:5:9:7 | call to resources | delete | posts/:id | posts | destroy |
|
||||
| action_controller/routes.rb:7:5:9:7 | call to resources | get | posts | posts | index |
|
||||
| action_controller/routes.rb:7:5:9:7 | call to resources | get | posts/:id | posts | show |
|
||||
| action_controller/routes.rb:7:5:9:7 | call to resources | get | posts/new | posts | new |
|
||||
| action_controller/routes.rb:7:5:9:7 | call to resources | get | posts:id/edit | posts | edit |
|
||||
| action_controller/routes.rb:7:5:9:7 | call to resources | patch | posts/:id | posts | update |
|
||||
| action_controller/routes.rb:7:5:9:7 | call to resources | post | posts | posts | create |
|
||||
| action_controller/routes.rb:7:5:9:7 | call to resources | put | posts/:id | posts | update |
|
||||
| action_controller/routes.rb:8:9:8:34 | call to post | post | posts/:post_id/upvote | posts | upvote |
|
||||
| action_controller/routes.rb:10:5:10:19 | call to resources | delete | tags/:id | tags | destroy |
|
||||
| action_controller/routes.rb:10:5:10:19 | call to resources | get | tags | tags | index |
|
||||
| action_controller/routes.rb:10:5:10:19 | call to resources | get | tags/:id | tags | show |
|
||||
| action_controller/routes.rb:10:5:10:19 | call to resources | get | tags/new | tags | new |
|
||||
| action_controller/routes.rb:10:5:10:19 | call to resources | get | tags:id/edit | tags | edit |
|
||||
| action_controller/routes.rb:10:5:10:19 | call to resources | patch | tags/:id | tags | update |
|
||||
| action_controller/routes.rb:10:5:10:19 | call to resources | post | tags | tags | create |
|
||||
| action_controller/routes.rb:10:5:10:19 | call to resources | put | tags/:id | tags | update |
|
||||
| app/config/routes.rb:2:3:8:5 | call to resources | get | posts | posts | index |
|
||||
| app/config/routes.rb:2:3:8:5 | call to resources | get | posts/:id | posts | show |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | delete | posts/:post_id/comments/:id | comments | destroy |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | get | posts/:post_id/comments | comments | index |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | get | posts/:post_id/comments/:id | comments | show |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | get | posts/:post_id/comments/new | comments | new |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | get | posts/:post_id/comments:id/edit | comments | edit |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | patch | posts/:post_id/comments/:id | comments | update |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | post | posts/:post_id/comments | comments | create |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | put | posts/:post_id/comments/:id | comments | update |
|
||||
| app/config/routes.rb:4:7:4:41 | call to resources | post | posts/:post_id/comments/:comment_id/replies | replies | create |
|
||||
| app/config/routes.rb:5:7:5:28 | call to post | post | posts/:post_id/comments/:comment_id/flag | comments | flag |
|
||||
| app/config/routes.rb:7:5:7:37 | call to post | post | posts/:post_id/upvote | posts | upvote |
|
||||
| app/config/routes.rb:11:5:11:54 | call to post | post | destroy_all_posts | posts | destroy_alll |
|
||||
| app/config/routes.rb:15:5:15:46 | call to get | get | numbers/:number | numbers | show |
|
||||
| app/config/routes.rb:19:5:19:44 | call to get | get | admin/jobs | background_jobs | index |
|
||||
| app/config/routes.rb:23:5:23:64 | call to get | get | admin/secrets | secrets | view_secrets |
|
||||
| app/config/routes.rb:24:5:24:42 | call to delete | delete | admin/:user_id | users | destroy |
|
||||
| app/config/routes.rb:27:3:27:48 | call to match | get | photos/:id | photos | show |
|
||||
| app/config/routes.rb:28:3:28:50 | call to match | get | photos/:id | photos | show |
|
||||
| app/config/routes.rb:29:3:29:69 | call to match | get | photos/:id | photos | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | delete | photos/:id | photos | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | get | photos/:id | photos | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | patch | photos/:id | photos | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | post | photos/:id | photos | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | put | photos/:id | photos | show |
|
||||
| app/config/routes.rb:33:5:33:43 | call to post | post | upgrade | users | start_upgrade |
|
||||
| app/config/routes.rb:37:5:37:31 | call to get | get | current_billing_cycle | billing/enterprise | current_billing_cycle |
|
||||
| app/config/routes.rb:40:3:40:40 | call to resource | get | global_config | global_config | show |
|
||||
| app/config/routes.rb:43:5:45:7 | call to resources | get | foo/bar | foo/bar | index |
|
||||
| app/config/routes.rb:43:5:45:7 | call to resources | get | foo/bar/:id | foo/bar | show |
|
||||
| app/config/routes.rb:44:7:44:39 | call to get | get | foo/bar/:bar_id/show_debug | foo/bar | show_debug |
|
||||
| app/config/routes.rb:49:5:49:95 | call to delete | delete | users/:user/notifications | users/notifications | destroy |
|
||||
| app/config/routes.rb:50:5:50:94 | call to post | post | users/:user/notifications/:notification_id/mark_as_read | users/notifications | mark_as_read |
|
||||
actionDispatchControllerMethods
|
||||
| action_controller/routes.rb:2:5:2:20 | call to resources | action_controller/input_access.rb:2:3:49:5 | index |
|
||||
| action_controller/routes.rb:2:5:2:20 | call to resources | action_controller/logging.rb:2:5:8:7 | index |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:17:3:51:5 | index |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:53:3:54:5 | create |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:56:3:62:5 | show |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:68:3:70:5 | destroy |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | app/controllers/comments_controller.rb:2:3:36:5 | index |
|
||||
| action_controller/routes.rb:3:5:5:7 | call to resources | app/controllers/comments_controller.rb:38:3:39:5 | show |
|
||||
| action_controller/routes.rb:4:9:4:32 | call to get | action_controller/controllers/comments_controller.rb:64:3:66:5 | photo |
|
||||
| action_controller/routes.rb:6:5:6:21 | call to resources | action_controller/controllers/photos_controller.rb:3:3:6:5 | show |
|
||||
| action_controller/routes.rb:6:5:6:21 | call to resources | app/controllers/photos_controller.rb:2:3:3:5 | show |
|
||||
| action_controller/routes.rb:7:5:9:7 | call to resources | action_controller/controllers/posts_controller.rb:12:3:13:5 | index |
|
||||
| action_controller/routes.rb:7:5:9:7 | call to resources | action_controller/controllers/posts_controller.rb:15:3:16:5 | show |
|
||||
| action_controller/routes.rb:7:5:9:7 | call to resources | app/controllers/posts_controller.rb:2:3:3:5 | index |
|
||||
| action_controller/routes.rb:7:5:9:7 | call to resources | app/controllers/posts_controller.rb:5:3:6:5 | show |
|
||||
| action_controller/routes.rb:8:9:8:34 | call to post | action_controller/controllers/posts_controller.rb:18:3:19:5 | upvote |
|
||||
| action_controller/routes.rb:8:9:8:34 | call to post | app/controllers/posts_controller.rb:8:3:9:5 | upvote |
|
||||
| app/config/routes.rb:2:3:8:5 | call to resources | action_controller/controllers/posts_controller.rb:12:3:13:5 | index |
|
||||
| app/config/routes.rb:2:3:8:5 | call to resources | action_controller/controllers/posts_controller.rb:15:3:16:5 | show |
|
||||
| app/config/routes.rb:2:3:8:5 | call to resources | app/controllers/posts_controller.rb:2:3:3:5 | index |
|
||||
| app/config/routes.rb:2:3:8:5 | call to resources | app/controllers/posts_controller.rb:5:3:6:5 | show |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:17:3:51:5 | index |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:53:3:54:5 | create |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:56:3:62:5 | show |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:68:3:70:5 | destroy |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:2:3:36:5 | index |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:38:3:39:5 | show |
|
||||
| app/config/routes.rb:7:5:7:37 | call to post | action_controller/controllers/posts_controller.rb:18:3:19:5 | upvote |
|
||||
| app/config/routes.rb:7:5:7:37 | call to post | app/controllers/posts_controller.rb:8:3:9:5 | upvote |
|
||||
| app/config/routes.rb:27:3:27:48 | call to match | action_controller/controllers/photos_controller.rb:3:3:6:5 | show |
|
||||
| app/config/routes.rb:27:3:27:48 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show |
|
||||
| app/config/routes.rb:28:3:28:50 | call to match | action_controller/controllers/photos_controller.rb:3:3:6:5 | show |
|
||||
| app/config/routes.rb:28:3:28:50 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show |
|
||||
| app/config/routes.rb:29:3:29:69 | call to match | action_controller/controllers/photos_controller.rb:3:3:6:5 | show |
|
||||
| app/config/routes.rb:29:3:29:69 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | action_controller/controllers/photos_controller.rb:3:3:6:5 | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show |
|
||||
| app/config/routes.rb:50:5:50:94 | call to post | action_controller/controllers/users/notifications_controller.rb:3:5:4:7 | mark_as_read |
|
||||
| app/config/routes.rb:50:5:50:94 | call to post | app/controllers/users/notifications_controller.rb:3:5:4:7 | mark_as_read |
|
||||
underscore
|
||||
| Foo | foo |
|
||||
| Foo::Bar | foo/bar |
|
||||
| Foo::Bar::Baz | foo/bar/baz |
|
||||
| Foo::Bar::BazQuux | foo/bar/baz_quux |
|
||||
| FooBar | foo_bar |
|
||||
| FooBar::Baz | foo_bar/baz |
|
||||
| HTTPServerRequest | httpserver_request |
|
||||
| LotsOfCapitalLetters | lots_of_capital_letters |
|
||||
| invalid | invalid |
|
||||
mimeTypeInstances
|
||||
| action_dispatch/mime_type.rb:2:6:2:28 | Use getMember("Mime").getContent(element_text/html) |
|
||||
| action_dispatch/mime_type.rb:3:6:3:32 | Use getMember("Mime").getMember("Type").getMethod("new").getReturn() |
|
||||
| action_dispatch/mime_type.rb:4:6:4:35 | Use getMember("Mime").getMember("Type").getMethod("lookup").getReturn() |
|
||||
| action_dispatch/mime_type.rb:5:6:5:43 | Use getMember("Mime").getMember("Type").getMethod("lookup_by_extension").getReturn() |
|
||||
| action_dispatch/mime_type.rb:6:6:6:47 | Use getMember("Mime").getMember("Type").getMethod("register").getReturn() |
|
||||
| action_dispatch/mime_type.rb:7:6:7:64 | Use getMember("Mime").getMember("Type").getMethod("register_alias").getReturn() |
|
||||
mimeTypeMatchRegExpInterpretations
|
||||
| action_dispatch/mime_type.rb:11:11:11:19 | "foo/bar" |
|
||||
| action_dispatch/mime_type.rb:12:7:12:15 | "foo/bar" |
|
||||
| action_dispatch/mime_type.rb:13:11:13:11 | s |
|
||||
| action_dispatch/mime_type.rb:14:7:14:7 | s |
|
||||
@@ -1,58 +0,0 @@
|
||||
rawCalls
|
||||
| app/views/foo/bars/_widget.html.erb:1:5:1:21 | call to raw |
|
||||
| app/views/foo/bars/_widget.html.erb:2:5:2:20 | call to raw |
|
||||
| app/views/foo/bars/_widget.html.erb:3:5:3:29 | call to raw |
|
||||
| app/views/foo/bars/show.html.erb:1:14:1:29 | call to raw |
|
||||
| app/views/foo/bars/show.html.erb:2:5:2:21 | call to raw |
|
||||
| app/views/foo/bars/show.html.erb:3:5:3:20 | call to raw |
|
||||
| app/views/foo/bars/show.html.erb:4:5:4:29 | call to raw |
|
||||
| app/views/foo/bars/show.html.erb:5:5:5:21 | call to raw |
|
||||
| app/views/foo/bars/show.html.erb:7:5:7:19 | call to raw |
|
||||
renderCalls
|
||||
| action_controller/controllers/comments_controller.rb:60:21:60:64 | call to render |
|
||||
| action_controller/controllers/comments_controller.rb:76:5:76:68 | call to render |
|
||||
| action_controller/controllers/foo/bars_controller.rb:6:5:6:37 | call to render |
|
||||
| action_controller/controllers/foo/bars_controller.rb:23:5:23:76 | call to render |
|
||||
| action_controller/controllers/foo/bars_controller.rb:35:5:35:33 | call to render |
|
||||
| action_controller/controllers/foo/bars_controller.rb:38:5:38:50 | call to render |
|
||||
| action_controller/controllers/foo/bars_controller.rb:44:5:44:17 | call to render |
|
||||
| app/controllers/foo/bars_controller.rb:6:5:6:37 | call to render |
|
||||
| app/controllers/foo/bars_controller.rb:23:5:23:76 | call to render |
|
||||
| app/controllers/foo/bars_controller.rb:35:5:35:33 | call to render |
|
||||
| app/controllers/foo/bars_controller.rb:38:5:38:50 | call to render |
|
||||
| app/controllers/foo/bars_controller.rb:44:5:44:17 | call to render |
|
||||
| app/views/foo/bars/show.html.erb:31:5:31:89 | call to render |
|
||||
renderToCalls
|
||||
| action_controller/controllers/foo/bars_controller.rb:15:16:15:97 | call to render_to_string |
|
||||
| action_controller/controllers/foo/bars_controller.rb:36:12:36:67 | call to render_to_string |
|
||||
| app/controllers/foo/bars_controller.rb:15:16:15:97 | call to render_to_string |
|
||||
| app/controllers/foo/bars_controller.rb:36:12:36:67 | call to render_to_string |
|
||||
linkToCalls
|
||||
| app/views/foo/bars/show.html.erb:33:5:33:41 | call to link_to |
|
||||
httpResponses
|
||||
| action_controller/controllers/comments_controller.rb:26:5:26:17 | call to body= | action_controller/controllers/comments_controller.rb:26:21:26:34 | ... = ... | text/http |
|
||||
| action_controller/controllers/comments_controller.rb:36:5:36:37 | call to send_file | action_controller/controllers/comments_controller.rb:36:24:36:36 | "my-file.ext" | application/octet-stream |
|
||||
| action_controller/controllers/comments_controller.rb:65:5:65:20 | call to send_data | action_controller/controllers/comments_controller.rb:65:15:65:20 | @photo | application/octet-stream |
|
||||
| action_controller/controllers/foo/bars_controller.rb:15:16:15:97 | call to render_to_string | action_controller/controllers/foo/bars_controller.rb:15:33:15:47 | "foo/bars/show" | text/html |
|
||||
| action_controller/controllers/foo/bars_controller.rb:23:5:23:76 | call to render | action_controller/controllers/foo/bars_controller.rb:23:12:23:26 | "foo/bars/show" | text/html |
|
||||
| action_controller/controllers/foo/bars_controller.rb:35:5:35:33 | call to render | action_controller/controllers/foo/bars_controller.rb:35:18:35:33 | call to [] | application/json |
|
||||
| action_controller/controllers/foo/bars_controller.rb:36:12:36:67 | call to render_to_string | action_controller/controllers/foo/bars_controller.rb:36:29:36:33 | @user | application/json |
|
||||
| action_controller/controllers/foo/bars_controller.rb:38:5:38:50 | call to render | action_controller/controllers/foo/bars_controller.rb:38:12:38:22 | call to backtrace | text/plain |
|
||||
| action_controller/controllers/foo/bars_controller.rb:44:5:44:17 | call to render | action_controller/controllers/foo/bars_controller.rb:44:12:44:17 | "show" | text/html |
|
||||
| app/controllers/comments_controller.rb:11:5:11:17 | call to body= | app/controllers/comments_controller.rb:11:21:11:34 | ... = ... | text/http |
|
||||
| app/controllers/comments_controller.rb:21:5:21:37 | call to send_file | app/controllers/comments_controller.rb:21:24:21:36 | "my-file.ext" | application/octet-stream |
|
||||
| app/controllers/foo/bars_controller.rb:15:16:15:97 | call to render_to_string | app/controllers/foo/bars_controller.rb:15:33:15:47 | "foo/bars/show" | text/html |
|
||||
| app/controllers/foo/bars_controller.rb:23:5:23:76 | call to render | app/controllers/foo/bars_controller.rb:23:12:23:26 | "foo/bars/show" | text/html |
|
||||
| app/controllers/foo/bars_controller.rb:35:5:35:33 | call to render | app/controllers/foo/bars_controller.rb:35:18:35:33 | call to [] | application/json |
|
||||
| app/controllers/foo/bars_controller.rb:36:12:36:67 | call to render_to_string | app/controllers/foo/bars_controller.rb:36:29:36:33 | @user | application/json |
|
||||
| app/controllers/foo/bars_controller.rb:38:5:38:50 | call to render | app/controllers/foo/bars_controller.rb:38:12:38:22 | call to backtrace | text/plain |
|
||||
| app/controllers/foo/bars_controller.rb:44:5:44:17 | call to render | app/controllers/foo/bars_controller.rb:44:12:44:17 | "show" | text/html |
|
||||
rawHelperCalls
|
||||
| action_view/helpers.erb:4:1:4:36 | call to simple_format | action_view/helpers.erb:4:15:4:15 | call to x |
|
||||
| action_view/helpers.erb:7:1:7:26 | call to truncate | action_view/helpers.erb:7:10:7:10 | call to x |
|
||||
| action_view/helpers.erb:10:1:10:29 | call to highlight | action_view/helpers.erb:10:11:10:11 | call to x |
|
||||
| action_view/helpers.erb:12:1:12:17 | call to javascript_tag | action_view/helpers.erb:12:16:12:16 | call to x |
|
||||
| action_view/helpers.erb:15:1:15:27 | call to content_tag | action_view/helpers.erb:15:16:15:16 | call to y |
|
||||
| action_view/helpers.erb:18:1:18:19 | call to tag | action_view/helpers.erb:18:5:18:5 | call to x |
|
||||
| action_view/helpers.erb:21:1:21:24 | call to h1 | action_view/helpers.erb:21:8:21:8 | call to x |
|
||||
| action_view/helpers.erb:24:1:24:23 | call to p | action_view/helpers.erb:24:7:24:7 | call to x |
|
||||
@@ -1,21 +0,0 @@
|
||||
private import ruby
|
||||
private import codeql.ruby.AST
|
||||
private import codeql.ruby.frameworks.ActionView
|
||||
private import codeql.ruby.frameworks.Rails
|
||||
private import codeql.ruby.Concepts
|
||||
|
||||
query predicate rawCalls(RawCall c) { any() }
|
||||
|
||||
query predicate renderCalls(Rails::RenderCall c) { any() }
|
||||
|
||||
query predicate renderToCalls(Rails::RenderToCall c) { any() }
|
||||
|
||||
query predicate linkToCalls(LinkToCall c) { any() }
|
||||
|
||||
query predicate httpResponses(Http::Server::HttpResponse r, DataFlow::Node body, string mimeType) {
|
||||
r.getBody() = body and r.getMimetype() = mimeType
|
||||
}
|
||||
|
||||
query predicate rawHelperCalls(ActionView::Helpers::RawHelperCall c, Expr arg) {
|
||||
arg = c.getRawArgument()
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
actionDispatchRoutes
|
||||
| app/config/routes.rb:2:3:8:5 | call to resources | get | posts | posts | index |
|
||||
| app/config/routes.rb:2:3:8:5 | call to resources | get | posts/:id | posts | show |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | delete | posts/:post_id/comments/:id | comments | destroy |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | get | posts/:post_id/comments | comments | index |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | get | posts/:post_id/comments/:id | comments | show |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | get | posts/:post_id/comments/new | comments | new |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | get | posts/:post_id/comments:id/edit | comments | edit |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | patch | posts/:post_id/comments/:id | comments | update |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | post | posts/:post_id/comments | comments | create |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | put | posts/:post_id/comments/:id | comments | update |
|
||||
| app/config/routes.rb:4:7:4:41 | call to resources | post | posts/:post_id/comments/:comment_id/replies | replies | create |
|
||||
| app/config/routes.rb:5:7:5:28 | call to post | post | posts/:post_id/comments/:comment_id/flag | comments | flag |
|
||||
| app/config/routes.rb:7:5:7:37 | call to post | post | posts/:post_id/upvote | posts | upvote |
|
||||
| app/config/routes.rb:11:5:11:54 | call to post | post | destroy_all_posts | posts | destroy_alll |
|
||||
| app/config/routes.rb:15:5:15:46 | call to get | get | numbers/:number | numbers | show |
|
||||
| app/config/routes.rb:19:5:19:44 | call to get | get | admin/jobs | background_jobs | index |
|
||||
| app/config/routes.rb:23:5:23:64 | call to get | get | admin/secrets | secrets | view_secrets |
|
||||
| app/config/routes.rb:24:5:24:42 | call to delete | delete | admin/:user_id | users | destroy |
|
||||
| app/config/routes.rb:27:3:27:48 | call to match | get | photos/:id | photos | show |
|
||||
| app/config/routes.rb:28:3:28:50 | call to match | get | photos/:id | photos | show |
|
||||
| app/config/routes.rb:29:3:29:69 | call to match | get | photos/:id | photos | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | delete | photos/:id | photos | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | get | photos/:id | photos | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | patch | photos/:id | photos | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | post | photos/:id | photos | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | put | photos/:id | photos | show |
|
||||
| app/config/routes.rb:33:5:33:43 | call to post | post | upgrade | users | start_upgrade |
|
||||
| app/config/routes.rb:37:5:37:31 | call to get | get | current_billing_cycle | billing/enterprise | current_billing_cycle |
|
||||
| app/config/routes.rb:40:3:40:40 | call to resource | get | global_config | global_config | show |
|
||||
| app/config/routes.rb:43:5:45:7 | call to resources | get | foo/bar | foo/bar | index |
|
||||
| app/config/routes.rb:43:5:45:7 | call to resources | get | foo/bar/:id | foo/bar | show |
|
||||
| app/config/routes.rb:44:7:44:39 | call to get | get | foo/bar/:bar_id/show_debug | foo/bar | show_debug |
|
||||
| app/config/routes.rb:49:5:49:95 | call to delete | delete | users/:user/notifications | users/notifications | destroy |
|
||||
| app/config/routes.rb:50:5:50:94 | call to post | post | users/:user/notifications/:notification_id/mark_as_read | users/notifications | mark_as_read |
|
||||
actionDispatchControllerMethods
|
||||
| app/config/routes.rb:2:3:8:5 | call to resources | app/controllers/posts_controller.rb:2:3:3:5 | index |
|
||||
| app/config/routes.rb:2:3:8:5 | call to resources | app/controllers/posts_controller.rb:5:3:6:5 | show |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:2:3:36:5 | index |
|
||||
| app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:38:3:39:5 | show |
|
||||
| app/config/routes.rb:7:5:7:37 | call to post | app/controllers/posts_controller.rb:8:3:9:5 | upvote |
|
||||
| app/config/routes.rb:27:3:27:48 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show |
|
||||
| app/config/routes.rb:28:3:28:50 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show |
|
||||
| app/config/routes.rb:29:3:29:69 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show |
|
||||
| app/config/routes.rb:30:3:30:50 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show |
|
||||
| app/config/routes.rb:50:5:50:94 | call to post | app/controllers/users/notifications_controller.rb:3:5:4:7 | mark_as_read |
|
||||
underscore
|
||||
| Foo | foo |
|
||||
| Foo::Bar | foo/bar |
|
||||
| Foo::Bar::Baz | foo/bar/baz |
|
||||
| Foo::Bar::BazQuux | foo/bar/baz_quux |
|
||||
| FooBar | foo_bar |
|
||||
| FooBar::Baz | foo_bar/baz |
|
||||
| HTTPServerRequest | httpserver_request |
|
||||
| LotsOfCapitalLetters | lots_of_capital_letters |
|
||||
| invalid | invalid |
|
||||
mimeTypeInstances
|
||||
| mime_type.rb:2:6:2:28 | Use getMember("Mime").getContent(element_text/html) |
|
||||
| mime_type.rb:3:6:3:32 | Use getMember("Mime").getMember("Type").getMethod("new").getReturn() |
|
||||
| mime_type.rb:4:6:4:35 | Use getMember("Mime").getMember("Type").getMethod("lookup").getReturn() |
|
||||
| mime_type.rb:5:6:5:43 | Use getMember("Mime").getMember("Type").getMethod("lookup_by_extension").getReturn() |
|
||||
| mime_type.rb:6:6:6:47 | Use getMember("Mime").getMember("Type").getMethod("register").getReturn() |
|
||||
| mime_type.rb:7:6:7:64 | Use getMember("Mime").getMember("Type").getMethod("register_alias").getReturn() |
|
||||
mimeTypeMatchRegExpInterpretations
|
||||
| mime_type.rb:11:11:11:19 | "foo/bar" |
|
||||
| mime_type.rb:12:7:12:15 | "foo/bar" |
|
||||
| mime_type.rb:13:11:13:11 | s |
|
||||
| mime_type.rb:14:7:14:7 | s |
|
||||
@@ -1 +1,44 @@
|
||||
fileSystemResolverAccesses
|
||||
| ActionView.rb:5:39:5:92 | call to new | ActionView.rb:5:74:5:82 | view_path |
|
||||
| app/controllers/comments_controller.rb:21:5:21:37 | call to send_file | app/controllers/comments_controller.rb:21:24:21:36 | "my-file.ext" |
|
||||
| app/controllers/foo/bars_controller.rb:1:1:1:14 | call to require | app/controllers/foo/bars_controller.rb:1:9:1:14 | "json" |
|
||||
rawCalls
|
||||
| app/views/foo/bars/_widget.html.erb:1:5:1:21 | call to raw |
|
||||
| app/views/foo/bars/_widget.html.erb:2:5:2:20 | call to raw |
|
||||
| app/views/foo/bars/_widget.html.erb:3:5:3:29 | call to raw |
|
||||
| app/views/foo/bars/show.html.erb:1:14:1:29 | call to raw |
|
||||
| app/views/foo/bars/show.html.erb:2:5:2:21 | call to raw |
|
||||
| app/views/foo/bars/show.html.erb:3:5:3:20 | call to raw |
|
||||
| app/views/foo/bars/show.html.erb:4:5:4:29 | call to raw |
|
||||
| app/views/foo/bars/show.html.erb:5:5:5:21 | call to raw |
|
||||
| app/views/foo/bars/show.html.erb:7:5:7:19 | call to raw |
|
||||
renderCalls
|
||||
| app/controllers/foo/bars_controller.rb:6:5:6:37 | call to render |
|
||||
| app/controllers/foo/bars_controller.rb:23:5:23:76 | call to render |
|
||||
| app/controllers/foo/bars_controller.rb:35:5:35:33 | call to render |
|
||||
| app/controllers/foo/bars_controller.rb:38:5:38:50 | call to render |
|
||||
| app/controllers/foo/bars_controller.rb:44:5:44:17 | call to render |
|
||||
| app/views/foo/bars/show.html.erb:31:5:31:89 | call to render |
|
||||
renderToCalls
|
||||
| app/controllers/foo/bars_controller.rb:15:16:15:97 | call to render_to_string |
|
||||
| app/controllers/foo/bars_controller.rb:36:12:36:67 | call to render_to_string |
|
||||
linkToCalls
|
||||
| app/views/foo/bars/show.html.erb:33:5:33:41 | call to link_to |
|
||||
httpResponses
|
||||
| app/controllers/comments_controller.rb:11:5:11:17 | call to body= | app/controllers/comments_controller.rb:11:21:11:34 | ... = ... | text/http |
|
||||
| app/controllers/comments_controller.rb:21:5:21:37 | call to send_file | app/controllers/comments_controller.rb:21:24:21:36 | "my-file.ext" | application/octet-stream |
|
||||
| app/controllers/foo/bars_controller.rb:15:16:15:97 | call to render_to_string | app/controllers/foo/bars_controller.rb:15:33:15:47 | "foo/bars/show" | text/html |
|
||||
| app/controllers/foo/bars_controller.rb:23:5:23:76 | call to render | app/controllers/foo/bars_controller.rb:23:12:23:26 | "foo/bars/show" | text/html |
|
||||
| app/controllers/foo/bars_controller.rb:35:5:35:33 | call to render | app/controllers/foo/bars_controller.rb:35:18:35:33 | call to [] | application/json |
|
||||
| app/controllers/foo/bars_controller.rb:36:12:36:67 | call to render_to_string | app/controllers/foo/bars_controller.rb:36:29:36:33 | @user | application/json |
|
||||
| app/controllers/foo/bars_controller.rb:38:5:38:50 | call to render | app/controllers/foo/bars_controller.rb:38:12:38:22 | call to backtrace | text/plain |
|
||||
| app/controllers/foo/bars_controller.rb:44:5:44:17 | call to render | app/controllers/foo/bars_controller.rb:44:12:44:17 | "show" | text/html |
|
||||
rawHelperCalls
|
||||
| helpers.erb:4:1:4:36 | call to simple_format | helpers.erb:4:15:4:15 | call to x |
|
||||
| helpers.erb:7:1:7:26 | call to truncate | helpers.erb:7:10:7:10 | call to x |
|
||||
| helpers.erb:10:1:10:29 | call to highlight | helpers.erb:10:11:10:11 | call to x |
|
||||
| helpers.erb:12:1:12:17 | call to javascript_tag | helpers.erb:12:16:12:16 | call to x |
|
||||
| helpers.erb:15:1:15:27 | call to content_tag | helpers.erb:15:16:15:16 | call to y |
|
||||
| helpers.erb:18:1:18:19 | call to tag | helpers.erb:18:5:18:5 | call to x |
|
||||
| helpers.erb:21:1:21:24 | call to h1 | helpers.erb:21:8:21:8 | call to x |
|
||||
| helpers.erb:24:1:24:23 | call to p | helpers.erb:24:7:24:7 | call to x |
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
import codeql.ruby.Concepts
|
||||
import codeql.ruby.DataFlow
|
||||
private import ruby
|
||||
private import codeql.ruby.AST
|
||||
private import codeql.ruby.frameworks.ActionView
|
||||
private import codeql.ruby.frameworks.Rails
|
||||
private import codeql.ruby.Concepts
|
||||
|
||||
query predicate fileSystemResolverAccesses(FileSystemAccess a, DataFlow::Node path) {
|
||||
a.getAPathArgument() = path
|
||||
}
|
||||
|
||||
query predicate rawCalls(RawCall c) { any() }
|
||||
|
||||
query predicate renderCalls(Rails::RenderCall c) { any() }
|
||||
|
||||
query predicate renderToCalls(Rails::RenderToCall c) { any() }
|
||||
|
||||
query predicate linkToCalls(LinkToCall c) { any() }
|
||||
|
||||
query predicate httpResponses(Http::Server::HttpResponse r, DataFlow::Node body, string mimeType) {
|
||||
r.getBody() = body and r.getMimetype() = mimeType
|
||||
}
|
||||
|
||||
query predicate rawHelperCalls(ActionView::Helpers::RawHelperCall c, Expr arg) {
|
||||
arg = c.getRawArgument()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
Rails.application.routes.draw do
|
||||
resources :posts, only: [:show, :index] do
|
||||
resources :comments do
|
||||
resources :replies, only: [:create]
|
||||
post "flag", to: :flag
|
||||
end
|
||||
post "upvote", to: "posts#upvote"
|
||||
end
|
||||
|
||||
if Rails.env.test?
|
||||
post "destroy_all_posts", to: "posts#destroy_alll"
|
||||
end
|
||||
|
||||
constraints(number: /[0-9]+/) do
|
||||
get "/numbers/:number", to: "numbers#show"
|
||||
end
|
||||
|
||||
scope path: "/admin" do
|
||||
get "/jobs", to: "background_jobs#index"
|
||||
end
|
||||
|
||||
scope "/admin" do
|
||||
get "secrets", controller: "secrets", action: "view_secrets"
|
||||
delete ":user_id", to: "users#destroy"
|
||||
end
|
||||
|
||||
match "photos/:id" => "photos#show", via: :get
|
||||
match "photos/:id", to: "photos#show", via: :get
|
||||
match "photos/:id", controller: "photos", action: "show", via: :get
|
||||
match "photos/:id", to: "photos#show", via: :all
|
||||
|
||||
scope controller: "users" do
|
||||
post "upgrade", action: "start_upgrade"
|
||||
end
|
||||
|
||||
scope module: "enterprise", controller: "billing" do
|
||||
get "current_billing_cycle"
|
||||
end
|
||||
|
||||
resource :global_config, only: [:show]
|
||||
|
||||
namespace :foo do
|
||||
resources :bar, only: [:index, :show] do
|
||||
get "show_debug", to: :show_debug
|
||||
end
|
||||
end
|
||||
|
||||
scope "/users/:user" do
|
||||
delete "/notifications", to: "users/notifications#destroy", as: :user_destroy_notifications
|
||||
post "notifications/:notification_id/mark_as_read", to: "users/notifications#mark_as_read"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
class CommentsController < ApplicationController
|
||||
def index
|
||||
request.params
|
||||
request.parameters
|
||||
request.GET
|
||||
request.POST
|
||||
request.query_parameters
|
||||
request.request_parameters
|
||||
request.filtered_parameters
|
||||
|
||||
response.body = "some content"
|
||||
|
||||
response.status = 200
|
||||
|
||||
response.header["Content-Type"] = "text/html"
|
||||
response.set_header("Content-Length", 100)
|
||||
response.headers["X-Custom-Header"] = "hi"
|
||||
response["X-Another-Custom-Header"] = "yes"
|
||||
response.add_header "X-Yet-Another", "indeed"
|
||||
|
||||
response.send_file("my-file.ext")
|
||||
|
||||
response.request
|
||||
|
||||
response.location = "http://..." # relevant for url redirect query
|
||||
response.cache_control = "value"
|
||||
response._cache_control = "value"
|
||||
response.etag = "value"
|
||||
response.charset = "value" # sets the charset part of the content-type header
|
||||
response.content_type = "value" # sets the main part of the content-type header
|
||||
|
||||
response.date = Date.today
|
||||
response.last_modified = Date.yesterday
|
||||
response.weak_etag = "value"
|
||||
response.strong_etag = "value"
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
require 'json'
|
||||
|
||||
class BarsController < ApplicationController
|
||||
|
||||
def index
|
||||
render template: "foo/bars/index"
|
||||
end
|
||||
|
||||
def show_debug
|
||||
user_info = JSON.load cookies[:user_info]
|
||||
puts "User: #{user_info['name']}"
|
||||
|
||||
@user_website = params[:website]
|
||||
dt = params[:text]
|
||||
rendered = render_to_string "foo/bars/show", locals: { display_text: dt, safe_text: "hello" }
|
||||
puts rendered
|
||||
redirect_to action: "show"
|
||||
end
|
||||
|
||||
def show
|
||||
@user_website = params[:website]
|
||||
dt = params[:text]
|
||||
render "foo/bars/show", locals: { display_text: dt, safe_text: "hello" }
|
||||
end
|
||||
|
||||
def go_back
|
||||
redirect_back_or_to action: "index"
|
||||
end
|
||||
|
||||
def go_back_2
|
||||
redirect_back fallback_location: { action: "index" }
|
||||
end
|
||||
|
||||
def show_2
|
||||
render json: { some: "data" }
|
||||
body = render_to_string @user, content_type: "application/json"
|
||||
rescue => e
|
||||
render e.backtrace, content_type: "text/plain"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def unreachable_action
|
||||
render "show"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,4 @@
|
||||
class PhotosController < ApplicationController
|
||||
def show
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
class PostsController < ApplicationController
|
||||
def index
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def upvote
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,2 @@
|
||||
class TagsController < ActionController::Metal
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
module Users
|
||||
class NotificationsController < ApplicationController
|
||||
def mark_as_read
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -38,7 +38,10 @@ kernelSpawnCallExecutions
|
||||
| Kernel.rb:68:1:68:61 | call to spawn |
|
||||
| Kernel.rb:69:1:69:71 | call to spawn |
|
||||
sendCallCodeExecutions
|
||||
| Eval.rb:4:1:4:22 | call to send | Eval.rb:4:6:4:12 | "raise" |
|
||||
| Eval.rb:7:1:7:19 | call to send | Eval.rb:7:8:7:13 | "push" |
|
||||
| Kernel.rb:2:1:2:22 | call to send | Kernel.rb:2:6:2:12 | "raise" |
|
||||
| Kernel.rb:5:1:5:19 | call to send | Kernel.rb:5:8:5:13 | "push" |
|
||||
evalCallCodeExecutions
|
||||
| Eval.rb:3:1:3:43 | call to eval | Eval.rb:3:6:3:22 | "raise \\"error\\"" |
|
||||
| Kernel.rb:1:1:1:43 | call to eval | Kernel.rb:1:6:1:22 | "raise \\"error\\"" |
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
classEvalCallCodeExecutions
|
||||
| Module.rb:29:1:29:47 | call to class_eval | Module.rb:29:16:29:32 | "def foo; 1; end" |
|
||||
moduleEvalCallCodeExecutions
|
||||
| Eval.rb:24:1:24:54 | call to module_eval | Eval.rb:24:17:24:33 | "def bar; 1; end" |
|
||||
| Module.rb:30:1:30:54 | call to module_eval | Module.rb:30:17:30:33 | "def bar; 1; end" |
|
||||
moduleConstGetCallCodeExecutions
|
||||
| Module.rb:1:1:1:24 | call to const_get | Module.rb:1:18:1:23 | "Math" |
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
module Mutations
|
||||
class BaseMutation < GraphQL::Schema::RelayClassicMutation
|
||||
argument_class Types::BaseArgument
|
||||
field_class Types::BaseField
|
||||
input_object_class Types::BaseInputObject
|
||||
object_class Types::BaseObject
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
module Mutations
|
||||
class Dummy < BaseMutation
|
||||
argument :something_id, ID, required: false
|
||||
|
||||
def load_something(id)
|
||||
"Something number #{id}"
|
||||
end
|
||||
|
||||
def resolve(something:)
|
||||
system("echo #{something}")
|
||||
{ success: true }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,4 @@
|
||||
module Resolvers
|
||||
class Base < GraphQL::Schema::Resolver
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
module Resolvers
|
||||
class DummyResolver < Resolvers::Base
|
||||
type String, null: false
|
||||
argument :something_id, ID, required: true
|
||||
|
||||
def load_something(id)
|
||||
"Something number #{id}"
|
||||
end
|
||||
|
||||
def resolve(something:)
|
||||
system("echo #{something}")
|
||||
"true"
|
||||
end
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user