Merge branch 'main' into js-use-shared-cryptography

This commit is contained in:
Alex Ford
2023-02-15 17:13:53 +00:00
committed by GitHub
774 changed files with 129170 additions and 17057 deletions

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

View File

@@ -0,0 +1,4 @@
description: One-line pattern matching
compatibility: backwards
ruby_match_pattern_def.rel: delete
ruby_test_pattern_def.rel: delete

View File

@@ -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"] }

View File

@@ -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" }

View 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`).

View File

@@ -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.

View File

@@ -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) }

View File

@@ -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.

View File

@@ -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

View File

@@ -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() }
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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)
}
}
}

View File

@@ -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. */

View File

@@ -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()

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 |

View File

@@ -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;

View File

@@ -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;

View File

@@ -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. */

View File

@@ -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()
)
}
}

View File

@@ -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" }

View File

@@ -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

View File

@@ -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",
]
}

View File

@@ -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 }
}
}

View File

@@ -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 }
}

View File

@@ -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.

View File

@@ -9,5 +9,6 @@ dependencies:
codeql/regex: ${workspace}
codeql/ssa: ${workspace}
codeql/tutorial: ${workspace}
codeql/util: ${workspace}
dataExtensions:
- codeql/ruby/frameworks/**/model.yml

View File

@@ -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

View File

@@ -0,0 +1,2 @@
description: One-line pattern matching
compatibility: full

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `rb/polynomial-redos` query now considers the entrypoints of the API of a gem as sources.

View File

@@ -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.

View 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>

View 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"

View File

@@ -0,0 +1,5 @@
def bad(input)
raise "Bad input" unless input =~ /^[0-9]+$/
# ....
end

View File

@@ -0,0 +1,5 @@
def good(input)
raise "Bad input" unless input =~ /\A[0-9]+\z/
# ....
end

View File

@@ -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()

View File

@@ -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

View File

@@ -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 []

View File

@@ -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

View File

@@ -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 |

View File

@@ -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 ... |

View File

@@ -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 |

View File

@@ -155,4 +155,8 @@ case expr
in ^(foo);
in ^(@foo);
in ^(1 + 1);
end
end
expr in [1, 2]
expr => {x: v, y: 1}

View File

@@ -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 |

View File

@@ -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

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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()
}

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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()
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,4 @@
class PhotosController < ApplicationController
def show
end
end

View File

@@ -0,0 +1,10 @@
class PostsController < ApplicationController
def index
end
def show
end
def upvote
end
end

View File

@@ -0,0 +1,2 @@
class TagsController < ActionController::Metal
end

View File

@@ -0,0 +1,6 @@
module Users
class NotificationsController < ApplicationController
def mark_as_read
end
end
end

View File

@@ -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\\"" |

View File

@@ -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" |

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,4 @@
module Resolvers
class Base < GraphQL::Schema::Resolver
end
end

View File

@@ -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