mirror of
https://github.com/github/codeql.git
synced 2026-04-21 23:14:03 +02:00
Merge branch 'main' into tutorial/library-pack
This commit is contained in:
277
ruby/ql/docs/flow_summaries.md
Normal file
277
ruby/ql/docs/flow_summaries.md
Normal file
@@ -0,0 +1,277 @@
|
||||
# Flow summaries
|
||||
|
||||
Flow summaries describe how data flows through methods whose definition is not
|
||||
included in the database. For example, methods in the standard library or a gem.
|
||||
|
||||
Say we have the following code:
|
||||
|
||||
```rb
|
||||
x = gets
|
||||
y = x.chomp
|
||||
system(y)
|
||||
```
|
||||
|
||||
This code reads a line from STDIN, strips any trailing newlines, and executes it
|
||||
as a shell command. Assuming `x` is considered tainted, we want the argument `y`
|
||||
to be tainted in the call to `system`.
|
||||
|
||||
`chomp` is a standard library method in the `String` class for which we
|
||||
have no source code, so we include a flow summary for it:
|
||||
|
||||
```ql
|
||||
private class ChompSummary extends SimpleSummarizedCallable {
|
||||
ChompSummary() { this = "chomp" }
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = "Argument[self]" and
|
||||
output = "ReturnValue" and
|
||||
preservesValue = false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The shared dataflow library will use this summary to construct a fake definition
|
||||
for `chomp`. The behaviour of this definition depends on the body of
|
||||
`propagatesFlowExt`. In this case, the method will propagate taint flow from the
|
||||
`self` argument (i.e. the receiver) to the return value.
|
||||
|
||||
If `preservesValue = true` then value flow is propagated. If it is `false` then
|
||||
only taint flow is propagated.
|
||||
|
||||
Any call to `chomp` in the database will be translated, in the dataflow graph,
|
||||
to a call to this fake definition.
|
||||
|
||||
`input` and `output` define the "from" and "to" locations in the flow summary.
|
||||
They use a custom string-based syntax which is similar to that used in `path`
|
||||
column in the Models as Data format. These strings are often referred to as
|
||||
access paths.
|
||||
|
||||
Note: The behaviour documented below is tested in
|
||||
`dataflow/flow-summaries/behaviour.ql`. Where specific quirks exist, we may
|
||||
reference a particular test case in this file which demonstrates the quirk.
|
||||
|
||||
# Syntax
|
||||
|
||||
Access paths consist of zero or more components separated by dots (`.`). The
|
||||
permitted components differ for input and output paths. The meaning of each
|
||||
component is defined relative to the implicit context of the component as
|
||||
defined by the preceding access path. For example,
|
||||
|
||||
```
|
||||
Argument[0].Element[1].ReturnValue
|
||||
```
|
||||
|
||||
refers to the return value of the element at index 1 in the array at argument 0
|
||||
of the method call.
|
||||
|
||||
## `Argument` and `Parameter`
|
||||
|
||||
The `Argument` and `Parameter` components refer respectively to an argument to a
|
||||
call or a parameter of a callable. They contain one or more _specifiers_[^1] which
|
||||
constrain the range of arguments/parameters that the component refers to. For
|
||||
example, `Argument[0]` refers to the first argument.
|
||||
|
||||
If multiple specifiers are given then the result is a disjunction, meaning that
|
||||
the component refers to any argument/parameter that satisfies at least one of
|
||||
the specifiers. For example, `Argument[0, 1]` refers to the first and second
|
||||
arguments.
|
||||
|
||||
### Specifiers
|
||||
|
||||
#### `self`
|
||||
The receiver of the call.
|
||||
|
||||
#### `<integer>`
|
||||
The argument to the method call at the position given by the integer. For
|
||||
example, `Argument[0]` refers to the first argument to the call.
|
||||
|
||||
#### `<integer>..`
|
||||
An argument to the call at a position greater or equal to the integer. For
|
||||
example, `Argument[1..]` refers to all arguments except the first one. This
|
||||
specifier is not available on `Parameter` components.
|
||||
|
||||
#### `<string>:`
|
||||
A keyword argument to the call with the given name. For example,
|
||||
`Argument[foo:]` refers to the keyword argument `foo:` in the call.
|
||||
|
||||
#### `block`
|
||||
The block argument passed to the call, if any.
|
||||
|
||||
#### `any`
|
||||
Any argument to the call, except `self` or `block` arguments.
|
||||
|
||||
#### `any-named`
|
||||
Any keyword argument to the call.
|
||||
|
||||
#### `hash-splat`
|
||||
The special "hash splat" argument/parameter, which is written as `**args`.
|
||||
When used in an `Argument` component, this specifier refers to special dataflow
|
||||
node which is constructed at the call site, containing any elements in a hash
|
||||
splat argument (`**args`) along with any explicit keyword arguments (`foo:
|
||||
bar`). The node behaves like a normal dataflow node for a hash, meaning that you
|
||||
can access specific elements of it using the `Element` component.
|
||||
|
||||
For example, the following flow summary states that values flow from any keyword
|
||||
arguments (including those in a hash splat) to the return value:
|
||||
|
||||
```ql
|
||||
input = "Argument[hash-splat].Element[any]" and
|
||||
output = "ReturnValue" and
|
||||
preservesValue = true
|
||||
```
|
||||
|
||||
Assuming this summary is for a global method `foo`, the following test will pass:
|
||||
|
||||
```rb
|
||||
a = source "a"
|
||||
b = source "b"
|
||||
|
||||
h = {a: a}
|
||||
|
||||
x = foo(b: b, **h)
|
||||
|
||||
sink x # $ hasValueFlow=a hasValueFlow=b
|
||||
```
|
||||
|
||||
If the method returns the hash itself, you will need to use `WithElement` in
|
||||
order to preserve taint/value in its elements. For example:
|
||||
|
||||
```ql
|
||||
input = "Argument[hash-splat].WithElement[any]" and
|
||||
output = "ReturnValue" and
|
||||
preservesValue = true
|
||||
```
|
||||
```rb
|
||||
a = source "a"
|
||||
x = foo(a: a)
|
||||
sink x[:a] # $ hasValueFlow=a
|
||||
```
|
||||
|
||||
## `ReturnValue`
|
||||
`ReturnValue` refers to the return value of the element identified in the
|
||||
preceding access path. For example, `Argument[0].ReturnValue` refers to the
|
||||
return value of the first argument. Of course this only makes sense if the first
|
||||
argument is a callable.
|
||||
|
||||
## `Element`
|
||||
This component refers to elements inside a collection of some sort. Typically
|
||||
this is an Array or Hash. Elements are considered to have an index, which is an
|
||||
integer in arrays and a symbol or string in hashes (even though hashes can have
|
||||
arbitrary objects as keys). Elements can also have an unknown index, which means
|
||||
we know the element exists in the collection but we don't know where.
|
||||
|
||||
Many of the specifiers have an optional suffix `!`. If this suffix is used then
|
||||
the specifier excludes elements at unknown indices. Otherwise, these are
|
||||
included by default.
|
||||
|
||||
### Specifiers
|
||||
|
||||
#### `?`
|
||||
If used in an input path: an element at an unknown index. If used in an output
|
||||
path: an element at any known or unkown index. In other words, `?` in an output
|
||||
path means the same as `any`.
|
||||
|
||||
#### `any`
|
||||
An element at any known or unknown index.
|
||||
|
||||
#### `<integer>`, `<integer>!`
|
||||
An element at the index given by the integer.
|
||||
|
||||
#### `<integer>..`, `<integer>..!`
|
||||
Any element at a known index greater or equal to the integer.
|
||||
|
||||
#### `<string>`, `<string>!`
|
||||
An element at the index given by string. The string should match the result of
|
||||
`serialize()` on the `ConstantValue` that represents the index. For a string
|
||||
with contents `foo` this is `"foo"` and for a symbol `:foo` it is `:foo`. The
|
||||
Ruby values `true`, `false` and `nil` can be written verbatim. See tests 31-33
|
||||
for examples.
|
||||
|
||||
## `Field`
|
||||
A "field" in the object. In practice this refers to a value stored in an
|
||||
instance variable in the object. The only valid specifier is `@<string>`, where
|
||||
`<string>` is the name of the instance variable. Currently we assume that a
|
||||
setter call such as `x.foo = bar` means there is a field `foo` in `x`, backed by
|
||||
an instance variable `@foo`.
|
||||
|
||||
For example, the access path `Argument[0].Field[@foo]` would refer to the value `"foo"` in
|
||||
|
||||
```rb
|
||||
x = SomeClass.new
|
||||
x.foo = "foo"
|
||||
some_call(x)
|
||||
```
|
||||
|
||||
## `WithElement`
|
||||
This component restricts the set of elements that are included in the preceding
|
||||
access path to to those at a specific set of indices. The specifiers are the
|
||||
same as those for `Element`. It is only valid in an input path.
|
||||
|
||||
This component has the effect of copying all relevant elements from the input to
|
||||
the output. For example, in the following summary:
|
||||
|
||||
```ql
|
||||
input = "Argument[0].WithElement[1, 2]" and
|
||||
output = "ReturnValue"
|
||||
```
|
||||
|
||||
any data in indices 1 and 2 of the first argument will be copied to indices 1
|
||||
and 2 of the return value. We use this in many Hash summaries that return the
|
||||
receiver, in order to preserve any data stored in it. For example, the summary
|
||||
for `Hash#to_h` is
|
||||
|
||||
```ql
|
||||
input = "Argument[self].WithElement[any]" and
|
||||
output = "ReturnValue" and
|
||||
preservesValue = true
|
||||
```
|
||||
|
||||
## `WithoutElement`
|
||||
This component is used to exclude certain elements from the set included in the
|
||||
preceding access path. It takes the same specifiers as `WithElement` and
|
||||
`Element`. It is only valid in an input path.
|
||||
|
||||
This component has the effect of excluding the relevant elements when copying
|
||||
from input to output. It is useful for modelling methods that remove elements
|
||||
from a collection. For example to model a method that removes the first element
|
||||
from the receiver, we can do so like this:
|
||||
|
||||
```ql
|
||||
input = "Argument[self].WithoutElement[0]" and
|
||||
output = "Argument[self]"
|
||||
```
|
||||
|
||||
Note that both the input and output refer to the receiver. The effect of this
|
||||
summary is that use-use flow between the receiver in the method call and a
|
||||
subsequent use of the same receiver will be blocked:
|
||||
|
||||
```ruby
|
||||
a[0] = source 0
|
||||
a[1] = source 1
|
||||
|
||||
a.remove_first # use-use flow from `a` on this line to `a` below will be blocked.
|
||||
# there will still be flow from `[post-update] a` to `a` below.
|
||||
|
||||
sink a[0]
|
||||
sink a[1] # $ hasValueFlow=1
|
||||
```
|
||||
|
||||
It is also important to note that in a summary such as
|
||||
|
||||
```ql
|
||||
input = "Argument[self].WithoutElement[0]" and
|
||||
output = "ReturnValue"
|
||||
```
|
||||
|
||||
if `Argument[self]` contains data, it will be copied to `ReturnValue`. If you only want to copy data in elements, and not in the container itself, add `WithElement[any]` to the input path:
|
||||
|
||||
```ql
|
||||
input = "Argument[self].WithoutElement[0].WithElement[any]" and
|
||||
output = "ReturnValue"
|
||||
```
|
||||
|
||||
See tests 53 and 54 for examples of this behaviour.
|
||||
|
||||
|
||||
|
||||
[^1]: I've chosen this name to avoid overloading the word "argument".
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/**
|
||||
* CodeQL library for Ruby
|
||||
* Automatically generated from the tree-sitter grammar; do not edit
|
||||
*/
|
||||
|
||||
@@ -260,6 +260,12 @@ module Public {
|
||||
* Holds if the neutral is auto generated.
|
||||
*/
|
||||
predicate isAutoGenerated() { neutralElement(this, true) }
|
||||
|
||||
/**
|
||||
* Holds if the neutral has the given provenance where `true` is
|
||||
* `generated` and `false` is `manual`.
|
||||
*/
|
||||
predicate hasProvenance(boolean generated) { neutralElement(this, generated) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -474,9 +474,6 @@ private class TransformKeysBangSummary extends SimpleSummarizedCallable {
|
||||
(
|
||||
input = "Argument[self].Element[any]" and
|
||||
output = "Argument[self].Element[?]"
|
||||
or
|
||||
input = "Argument[self].WithoutElement[any]" and
|
||||
output = "Argument[self]"
|
||||
) and
|
||||
preservesValue = true
|
||||
}
|
||||
|
||||
@@ -5,23 +5,25 @@
|
||||
* @id rb/alert-suppression
|
||||
*/
|
||||
|
||||
private import codeql.suppression.AlertSuppression as AS
|
||||
private import codeql.util.suppression.AlertSuppression as AS
|
||||
private import codeql.ruby.ast.internal.TreeSitter
|
||||
|
||||
class SingleLineComment extends Ruby::Comment {
|
||||
SingleLineComment() {
|
||||
// suppression comments must be single-line
|
||||
this.getLocation().getStartLine() = this.getLocation().getEndLine()
|
||||
}
|
||||
|
||||
class AstNode extends Ruby::Token {
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
class SingleLineComment extends Ruby::Comment, AstNode {
|
||||
SingleLineComment() {
|
||||
// suppression comments must be single-line
|
||||
this.getLocation().getStartLine() = this.getLocation().getEndLine()
|
||||
}
|
||||
|
||||
/** Gets the suppression annotation in this comment. */
|
||||
string getText() { result = this.getValue().suffix(1) }
|
||||
}
|
||||
|
||||
import AS::Make<SingleLineComment>
|
||||
import AS::Make<AstNode, SingleLineComment>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `AlertSuppression.ql` query has been updated to support the new `# codeql[query-id]` supression comments. These comments can be used to suppress an alert and must be placed on a blank line before the alert. In addition the legacy `# lgtm` and `# lgtm[query-id]` comments can now also be place on the line before an alert.
|
||||
File diff suppressed because it is too large
Load Diff
588
ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.ql
Normal file
588
ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.ql
Normal file
@@ -0,0 +1,588 @@
|
||||
/**
|
||||
* @kind path-problem
|
||||
* This file tests that flow summaries behave as described in `ql/docs/flow-summaries.md`.
|
||||
*/
|
||||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import PathGraph
|
||||
private import codeql.ruby.dataflow.FlowSummary
|
||||
|
||||
/**
|
||||
* A convenience class for defining value (c.f. taint) flow summaries.
|
||||
*/
|
||||
abstract private class Summary extends SimpleSummarizedCallable {
|
||||
bindingset[this]
|
||||
Summary() { any() }
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
this.propagates(input, output) and preservesValue = true
|
||||
}
|
||||
|
||||
abstract predicate propagates(string input, string output);
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[self]` (input)
|
||||
*/
|
||||
private class S1 extends Summary {
|
||||
S1() { this = "s1" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[self]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[self]` (output)
|
||||
*/
|
||||
private class S2 extends Summary {
|
||||
S2() { this = "s2" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "Argument[self]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[<integer>]` (input, output)
|
||||
*/
|
||||
private class S3 extends Summary {
|
||||
S3() { this = "s3" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "Argument[1]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[<integer>..]` (input)
|
||||
*/
|
||||
private class S4 extends Summary {
|
||||
S4() { this = "s4" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[1..]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[<integer>..]` (output)
|
||||
*/
|
||||
private class S5 extends Summary {
|
||||
S5() { this = "s5" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "Argument[2..]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[<string>]` (input)
|
||||
*/
|
||||
private class S6 extends Summary {
|
||||
S6() { this = "s6" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[foo:]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[<string>]` (output)
|
||||
*/
|
||||
private class S7 extends Summary {
|
||||
S7() { this = "s7" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "Argument[foo:]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[block]` (input)
|
||||
*/
|
||||
private class S8 extends Summary {
|
||||
S8() { this = "s8" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[block].ReturnValue" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[block]` (output)
|
||||
*/
|
||||
private class S9 extends Summary {
|
||||
S9() { this = "s9" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "Argument[block].Parameter[0]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[any]` (input) 1
|
||||
*/
|
||||
private class S10 extends Summary {
|
||||
S10() { this = "s10" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[any]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[any]` (input) 2
|
||||
* This tests that access paths using `Argument[any]` do not match blocks.
|
||||
* Test 10 contains an edge case example where blocks are matched, but this does
|
||||
* not appear to work in general.
|
||||
*/
|
||||
private class S11 extends Summary {
|
||||
S11() { this = "s11" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[any].ReturnValue" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[any]` (output)
|
||||
*/
|
||||
private class S12 extends Summary {
|
||||
S12() { this = "s12" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[self]" and output = "Argument[any]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[any-named]` (input)
|
||||
*/
|
||||
private class S13 extends Summary {
|
||||
S13() { this = "s13" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[any-named]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[any-named]` (output)
|
||||
*/
|
||||
private class S14 extends Summary {
|
||||
S14() { this = "s14" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[self]" and output = "Argument[any-named]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[hash-splat]` (input) 1
|
||||
*/
|
||||
private class S15 extends Summary {
|
||||
S15() { this = "s15" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[hash-splat]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[hash-splat]` (input) 2
|
||||
*/
|
||||
private class S16 extends Summary {
|
||||
S16() { this = "s16" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[hash-splat].Element[any]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[hash-splat]` (output) 1
|
||||
*/
|
||||
private class S17 extends Summary {
|
||||
S17() { this = "s17" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "Argument[hash-splat]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Argument[hash-splat]` (output) 2
|
||||
*/
|
||||
private class S18 extends Summary {
|
||||
S18() { this = "s18" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "Argument[hash-splat].Element[:foo]"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[?]` (input) */
|
||||
private class S19 extends Summary {
|
||||
S19() { this = "s19" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].Element[?]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[?]` (output) */
|
||||
private class S20 extends Summary {
|
||||
S20() { this = "s20" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "ReturnValue.Element[?]"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[any]` (input) */
|
||||
private class S21 extends Summary {
|
||||
S21() { this = "s21" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].Element[any]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[any]` (output) */
|
||||
private class S22 extends Summary {
|
||||
S22() { this = "s22" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "ReturnValue.Element[any]"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[<integer>]` (input) */
|
||||
private class S23 extends Summary {
|
||||
S23() { this = "s23" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].Element[0]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[<integer>]` (output) */
|
||||
private class S24 extends Summary {
|
||||
S24() { this = "s24" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "ReturnValue.Element[0]"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[<integer>!]` (input) */
|
||||
private class S25 extends Summary {
|
||||
S25() { this = "s25" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].Element[0!]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[<integer>!]` (output) */
|
||||
private class S26 extends Summary {
|
||||
S26() { this = "s26" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "ReturnValue.Element[0!]"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[<integer>..]` (input) */
|
||||
private class S27 extends Summary {
|
||||
S27() { this = "s27" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].Element[1..]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[<integer>..]` (output) */
|
||||
private class S28 extends Summary {
|
||||
S28() { this = "s28" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "ReturnValue.Element[1..]"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[<integer>..!]` (input) */
|
||||
private class S29 extends Summary {
|
||||
S29() { this = "s29" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].Element[1..!]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[<integer>..!]` (output) */
|
||||
private class S30 extends Summary {
|
||||
S30() { this = "s30" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "ReturnValue.Element[1..!]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Element[<string>]` (input) 1
|
||||
*
|
||||
* In general, the key format must match the output of `ConstantValue::serialize/0`.
|
||||
* For example, symbol keys must be prefixed by `:`.
|
||||
*/
|
||||
private class S31 extends Summary {
|
||||
S31() { this = "s31" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].Element[:foo]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Element[<string>]` (input) 2
|
||||
*
|
||||
* String keys must be wrapped double quotes.
|
||||
*/
|
||||
private class S32 extends Summary {
|
||||
S32() { this = "s32" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].Element[\"foo\"]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Element[<string>]` (input) 3
|
||||
*
|
||||
* `nil`, `true` and `false` keys can be written verbatim.
|
||||
*/
|
||||
private class S33 extends Summary {
|
||||
S33() { this = "s33" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].Element[nil,true,false]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[<string>]` (output) 1 */
|
||||
private class S35 extends Summary {
|
||||
S35() { this = "s35" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "ReturnValue.Element[:foo]"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[<string>]` (output) 2 */
|
||||
private class S36 extends Summary {
|
||||
S36() { this = "s36" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "ReturnValue.Element[\"foo\"]"
|
||||
}
|
||||
}
|
||||
|
||||
/** `Element[<string>]` (output) 3 */
|
||||
private class S37 extends Summary {
|
||||
S37() { this = "s37" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "ReturnValue.Element[true]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Element[<string>!]` (input)
|
||||
*/
|
||||
private class S38 extends Summary {
|
||||
S38() { this = "s38" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].Element[\"foo\"!]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Element[<string>!]` (output)
|
||||
*/
|
||||
private class S39 extends Summary {
|
||||
S39() { this = "s39" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "ReturnValue.Element[:foo!]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Field[@<string>]` (input)
|
||||
*/
|
||||
private class S40 extends Summary {
|
||||
S40() { this = "s40" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].Field[@foo]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `Field[@<string>]` (output)
|
||||
*/
|
||||
private class S41 extends Summary {
|
||||
S41() { this = "s41" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0]" and output = "ReturnValue.Field[@foo]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithElement`
|
||||
*/
|
||||
private class S42 extends Summary {
|
||||
S42() { this = "s42" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].WithElement[0]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithElement[!]`
|
||||
*/
|
||||
private class S43 extends Summary {
|
||||
S43() { this = "s43" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].WithElement[0!]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithoutElement` 1
|
||||
*/
|
||||
private class S44 extends Summary {
|
||||
S44() { this = "s44" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].WithoutElement[0]" and output = "Argument[0]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithoutElement` 2
|
||||
*/
|
||||
private class S45 extends Summary {
|
||||
S45() { this = "s45" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].WithoutElement[0!]" and output = "Argument[0]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithoutElement` 3
|
||||
*/
|
||||
private class S46 extends Summary {
|
||||
S46() { this = "s46" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].WithoutElement[0]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithoutElement` 4
|
||||
*/
|
||||
private class S47 extends Summary {
|
||||
S47() { this = "s47" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].WithoutElement[:foo].WithElement[any]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithoutElement` 5
|
||||
*/
|
||||
private class S48 extends Summary {
|
||||
S48() { this = "s48" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].WithoutElement[:foo]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithoutElement` 6
|
||||
*/
|
||||
private class S49 extends Summary {
|
||||
S49() { this = "s49" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].WithoutElement[:foo!]" and output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithoutElement` 7
|
||||
*/
|
||||
private class S50 extends Summary {
|
||||
S50() { this = "s50" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].WithoutElement[:foo]" and output = "Argument[0]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithoutElement` 8
|
||||
*/
|
||||
private class S51 extends Summary {
|
||||
S51() { this = "s51" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[0].WithoutElement[:foo!]" and output = "Argument[0]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithoutElement` 9
|
||||
*/
|
||||
private class S52 extends Summary {
|
||||
S52() { this = "s52" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[self].WithoutElement[:foo]" and output = "Argument[self]"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithoutElement` 10
|
||||
*/
|
||||
private class S53 extends Summary {
|
||||
S53() { this = "s53" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[self].WithoutElement[:foo]" and
|
||||
output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `WithoutElement` 11
|
||||
*/
|
||||
private class S54 extends Summary {
|
||||
S54() { this = "s54" }
|
||||
|
||||
override predicate propagates(string input, string output) {
|
||||
input = "Argument[self].WithoutElement[:foo].WithElement[any]" and
|
||||
output = "ReturnValue"
|
||||
}
|
||||
}
|
||||
518
ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.rb
Normal file
518
ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.rb
Normal file
@@ -0,0 +1,518 @@
|
||||
def m1
|
||||
a = source "a"
|
||||
x = a.s1()
|
||||
sink x # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m2(x)
|
||||
a = source "a"
|
||||
x.s2(a)
|
||||
sink x # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m3(x)
|
||||
a = source "a"
|
||||
s3(a, x)
|
||||
sink x # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m4
|
||||
sink s4("a", "b", "c")
|
||||
sink s4(source "a", "b", "c")
|
||||
sink s4("a", source "b", "c") # $ hasValueFlow=b SPURIOUS: hasValueFlow=c
|
||||
sink s4("a", "b", source "c") # $ hasValueFlow=c
|
||||
sink s4(source "a", source "b", source "c") # hasValueFlow=b hasValueFlow=c
|
||||
end
|
||||
|
||||
def m5(x, y, z)
|
||||
a = source "a"
|
||||
s5(a, x, y, z)
|
||||
sink x
|
||||
sink y # $ hasValueFlow=a
|
||||
sink z # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m6
|
||||
sink s6(foo: source "a", bar: source "b") # $ MISSING: hasValueFlow=a
|
||||
end
|
||||
|
||||
def m7(x)
|
||||
a = source "a"
|
||||
s7(a, foo: x)
|
||||
sink x # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m8
|
||||
sink(s8 { source "a" }) # $ hasValueFlow=a
|
||||
sink(s8 do # $hasValueFlow=a
|
||||
source "a"
|
||||
end)
|
||||
end
|
||||
|
||||
def m9
|
||||
s9(source "a") { |x| sink x } # $ hasValueFlow=a
|
||||
s9(source "a") do |x|
|
||||
sink x # $ hasValueFlow=a
|
||||
end
|
||||
end
|
||||
|
||||
def m10
|
||||
a = source "a"
|
||||
sink s10(a) # $ hasValueFlow=a
|
||||
sink s10(0, a) # $ hasValueFlow=a
|
||||
sink s10(foo: a) # $ hasValueFlow=a
|
||||
sink s10(foo: 0, bar: a) # $ hasValueFlow=a
|
||||
sink (a).s10
|
||||
sink s10(&a) # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m11
|
||||
a = source "a"
|
||||
sink(s11 { a })
|
||||
sink(s11 do
|
||||
a
|
||||
end)
|
||||
f = ->() { a }
|
||||
sink s10(&f)
|
||||
end
|
||||
|
||||
def m12(x, y, z, &blk)
|
||||
a = source "a"
|
||||
a.s12(x, y, foo: z, &blk)
|
||||
sink x # $ hasValueFlow=a
|
||||
sink y # $ hasValueFlow=a
|
||||
sink z # $ hasValueFlow=a
|
||||
sink blk
|
||||
end
|
||||
|
||||
def m13
|
||||
a = source "a"
|
||||
sink s13(a)
|
||||
sink s13(foo: a) # $ hasValueFlow=a
|
||||
sink s13(foo: 0, bar: a) # $ hasValueFlow=a
|
||||
sink a.s13
|
||||
end
|
||||
|
||||
def m14(w, x, y, z)
|
||||
a = source "a"
|
||||
a.s14(w, foo: x)
|
||||
a.s14(foo: y, bar: z)
|
||||
sink w
|
||||
sink x # $ hasValueFlow=a
|
||||
sink y # $ hasValueFlow=a
|
||||
sink z # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m15
|
||||
a = source "a"
|
||||
b = source "b"
|
||||
sink s15(**a) # $ SPURIOUS: hasTaintFlow=a MISSING: hasValueFlow=a
|
||||
sink s15(0, 1, foo: b, **a) # $ SPURIOUS: hasTaintFlow=a MISSING: hasValueFlow=a
|
||||
end
|
||||
|
||||
def m16
|
||||
a = source "a"
|
||||
b = source "b"
|
||||
h = { a: a, b: 1 }
|
||||
sink s16(**h) # $ hasValueFlow=a
|
||||
sink s16(a)
|
||||
sink s16(a: a) # $ hasValueFlow=a
|
||||
sink s16(b: 1)
|
||||
sink s16(b: b, **h) # $ hasValueFlow=a hasValueFlow=b
|
||||
end
|
||||
|
||||
def m17(h, x)
|
||||
a = source "a"
|
||||
s17(a, **h, foo: x)
|
||||
sink h # $ hasValueFlow=a
|
||||
sink x
|
||||
end
|
||||
|
||||
def m18(x)
|
||||
a = source "a"
|
||||
s18(a, **h, foo: x)
|
||||
sink h
|
||||
sink h[:foo] # $ MISSING: hasValueFlow=a
|
||||
sink x # $ MISSING: hasValueFlow=a
|
||||
end
|
||||
|
||||
def m19(i)
|
||||
a = source "a"
|
||||
b = source "b"
|
||||
|
||||
h = {}
|
||||
h[0] = a
|
||||
h[i] = b
|
||||
|
||||
sink s19(h) # $ hasValueFlow=b
|
||||
end
|
||||
|
||||
def m20(i)
|
||||
a = source "a"
|
||||
x = s20(a)
|
||||
sink x[0] # $ hasValueFlow=a
|
||||
sink x[i] # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m21(i)
|
||||
a = source "a"
|
||||
b = source "b"
|
||||
|
||||
h = {}
|
||||
h[0] = a
|
||||
h[i] = b
|
||||
|
||||
sink s21(h) # $ hasValueFlow=a hasValueFlow=b
|
||||
end
|
||||
|
||||
def m22
|
||||
a = source "a"
|
||||
x = s22(a)
|
||||
sink x[0] # $ hasValueFlow=a
|
||||
sink x[i] # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m23(i)
|
||||
a = source "a"
|
||||
b = source "b"
|
||||
h = []
|
||||
h[0] = a
|
||||
h[1] = b
|
||||
sink s23(h) # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m24(i)
|
||||
a = source "a"
|
||||
x = s24(a)
|
||||
sink x[0] # $ hasValueFlow=a
|
||||
sink x[1]
|
||||
sink x[i] # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m25(i)
|
||||
a = source "a"
|
||||
b = source "b"
|
||||
h = []
|
||||
h[0] = a
|
||||
h[1] = b
|
||||
sink s25(h) # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m26(i)
|
||||
a = source "a"
|
||||
x = s26(a)
|
||||
sink x[0] # $ hasValueFlow=a
|
||||
sink x[1]
|
||||
sink x[i] # $ SPURIOUS: hasValueFlow=a
|
||||
end
|
||||
|
||||
def m27(i)
|
||||
a = source "a"
|
||||
b = source "b"
|
||||
c = source "c"
|
||||
d = source "d"
|
||||
|
||||
h = []
|
||||
h[0] = a
|
||||
h[1] = b
|
||||
h[2] = c
|
||||
h[i] = d
|
||||
|
||||
sink s27(h) # $ hasValueFlow=b hasValueFlow=c hasValueFlow=d
|
||||
end
|
||||
|
||||
def m28(i)
|
||||
a = source "a"
|
||||
x = s28(a)
|
||||
sink x[0]
|
||||
sink x[1] # $ MISSING: hasValueFlow=a
|
||||
sink x[2] # $ MISSING: hasValueFlow=a
|
||||
sink x[i] # $ MISSING: hasValueFlow=a
|
||||
end
|
||||
|
||||
def m29(i)
|
||||
a = source "a"
|
||||
b = source "b"
|
||||
c = source "c"
|
||||
|
||||
h = []
|
||||
h[0] = a
|
||||
h[1] = b
|
||||
h[2] = c
|
||||
h[i] = d
|
||||
|
||||
sink s29(h) # $ hasValueFlow=b hasValueFlow=c
|
||||
end
|
||||
|
||||
def m30(i)
|
||||
a = source "a"
|
||||
x = s30(a)
|
||||
sink x[0] # $ SPURIOUS: hasValueFlow=a
|
||||
sink x[1] # $ hasValueFlow=a
|
||||
sink x[2] # $ hasValueFlow=a
|
||||
sink x[i] # $ SPURIOUS: hasValueFlow=a
|
||||
end
|
||||
|
||||
def m31(h, i)
|
||||
h[:foo] = source("a")
|
||||
h[:bar] = source("b")
|
||||
h[1] = source("c")
|
||||
h[i] = source("d")
|
||||
|
||||
sink s31(h) # $ hasValueFlow=a hasValueFlow=d
|
||||
end
|
||||
|
||||
def m32(h, i)
|
||||
h[:foo] = source("a")
|
||||
h["foo"] = source("b")
|
||||
h[:bar] = source("c")
|
||||
h[1] = source("d")
|
||||
h[i] = source("e")
|
||||
|
||||
sink s32(h) # $ hasValueFlow=b hasValueFlow=e
|
||||
end
|
||||
|
||||
def m33(h, i)
|
||||
h[:foo] = source("a")
|
||||
h["foo"] = source("b")
|
||||
h[:bar] = source("c")
|
||||
h[1] = source("d")
|
||||
h[i] = source("e")
|
||||
h[nil] = source("f")
|
||||
h[true] = source("g")
|
||||
h[false] = source("h")
|
||||
|
||||
sink s33(h) # $ hasValueFlow=e hasValueFlow=f hasValueFlow=g hasValueFlow=h
|
||||
end
|
||||
|
||||
def m35(h, i)
|
||||
x = s35(source("a"))
|
||||
sink x[:foo] # $ hasValueFlow=a
|
||||
sink x[:bar]
|
||||
sink x[i] # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m36(h, i)
|
||||
x = s36(source("a"))
|
||||
sink x[:foo]
|
||||
sink x["foo"] # $ hasValueFlow=a
|
||||
sink x[:bar]
|
||||
sink x[i] # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m37(h, i)
|
||||
x = s37(source("a"))
|
||||
sink x[:foo]
|
||||
sink x[true] # $ hasValueFlow=a
|
||||
sink x[:bar]
|
||||
sink x[i] # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m38(h, i)
|
||||
h["foo"] = source("a")
|
||||
h[i] = source("b")
|
||||
|
||||
sink s38(h) # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m39(i)
|
||||
x = s39(source("a"))
|
||||
|
||||
sink x[:foo] # $ hasValueFlow=a
|
||||
sink x[i] # $ SPURIOUS: hasValueFlow=a
|
||||
end
|
||||
|
||||
def m40
|
||||
x = A.new
|
||||
x.foo = source("a")
|
||||
x.bar = source("b")
|
||||
sink s40(x) # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m41
|
||||
x = s41(source("a"))
|
||||
sink x.foo # $ hasValueFlow=a
|
||||
sink x.bar
|
||||
end
|
||||
|
||||
def m42(i, h)
|
||||
h[0] = source("a")
|
||||
h[i] = source("b")
|
||||
|
||||
x = s42(h)
|
||||
|
||||
sink x[0] # $ hasValueFlow=a hasValueFlow=b
|
||||
sink x[1] # $ hasValueFlow=b
|
||||
sink x[i] # $ hasValueFlow=a hasValueFlow=b
|
||||
end
|
||||
|
||||
def m43(i, h)
|
||||
h[0] = source("a")
|
||||
h[i] = source("b")
|
||||
|
||||
x = s43(h)
|
||||
|
||||
sink x[0] # $ hasValueFlow=a
|
||||
sink x[1]
|
||||
sink x[i] # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m44(i, h)
|
||||
h[0] = source("a")
|
||||
h[1] = source("b")
|
||||
h[i] = source("c")
|
||||
|
||||
s44(h)
|
||||
|
||||
sink h[0]
|
||||
sink h[1] # $ hasValueFlow=b
|
||||
sink h[i] # $ hasValueFlow=b
|
||||
end
|
||||
|
||||
def m45(i, h)
|
||||
h[0] = source("a")
|
||||
h[1] = source("b")
|
||||
h[i] = source("c")
|
||||
|
||||
sink h[0] # $ hasValueFlow=a hasValueFlow=c
|
||||
sink h[1] # $ hasValueFlow=b hasValueFlow=c
|
||||
sink h[i] # $ hasValueFlow=a hasValueFlow=b hasValueFlow=c
|
||||
|
||||
s45(h)
|
||||
|
||||
sink h[0] # $ hasValueFlow=c
|
||||
sink h[1] # $ hasValueFlow=b hasValueFlow=c
|
||||
sink h[i] # $ hasValueFlow=b hasValueFlow=c
|
||||
end
|
||||
|
||||
def m46(i, h)
|
||||
h[0] = source("a")
|
||||
h[1] = source("b")
|
||||
h[i] = source("c")
|
||||
|
||||
sink h[0] # $ hasValueFlow=a hasValueFlow=c
|
||||
sink h[1] # $ hasValueFlow=b hasValueFlow=c
|
||||
sink h[i] # $ hasValueFlow=a hasValueFlow=b hasValueFlow=c
|
||||
|
||||
x = s46(h)
|
||||
|
||||
sink x[0]
|
||||
sink x[1] # $ hasValueFlow=b
|
||||
sink x[i] # $ hasValueFlow=b
|
||||
end
|
||||
|
||||
def m47(i, h)
|
||||
h[:foo] = source("a")
|
||||
h[:bar] = source("b")
|
||||
h[i] = source("c")
|
||||
|
||||
sink h[:foo] # $ hasValueFlow=a hasValueFlow=c
|
||||
sink h[:bar] # $ hasValueFlow=b hasValueFlow=c
|
||||
|
||||
x = s47(h)
|
||||
|
||||
sink x[:foo]
|
||||
sink x[:bar] # $ hasValueFlow=b
|
||||
end
|
||||
|
||||
def m48(i, h)
|
||||
h[:foo] = source("a")
|
||||
h[:bar] = source("b")
|
||||
h[i] = source("c")
|
||||
|
||||
sink h[:foo] # $ hasValueFlow=a hasValueFlow=c
|
||||
sink h[:bar] # $ hasValueFlow=b hasValueFlow=c
|
||||
|
||||
x = s48(h)
|
||||
|
||||
sink x[:foo]
|
||||
sink x[:bar] # $ hasValueFlow=b
|
||||
end
|
||||
|
||||
def m49(i, h)
|
||||
h[:foo] = source("a")
|
||||
h[:bar] = source("b")
|
||||
h[i] = source("c")
|
||||
|
||||
sink h[:foo] # $ hasValueFlow=a hasValueFlow=c
|
||||
sink h[:bar] # $ hasValueFlow=b hasValueFlow=c
|
||||
|
||||
x = s49(h)
|
||||
|
||||
sink x[:foo] # $ hasValueFlow=c
|
||||
sink x[:bar] # $ hasValueFlow=b hasValueFlow=c
|
||||
end
|
||||
|
||||
def m50(i, h)
|
||||
h[:foo] = source("a")
|
||||
h[:bar] = source("b")
|
||||
h[i] = source("c")
|
||||
|
||||
sink h[:foo] # $ hasValueFlow=a hasValueFlow=c
|
||||
sink h[:bar] # $ hasValueFlow=b hasValueFlow=c
|
||||
|
||||
s50(h)
|
||||
|
||||
sink h[:foo]
|
||||
sink h[:bar] # $ hasValueFlow=b
|
||||
end
|
||||
|
||||
def m51(i, h)
|
||||
h[:foo] = source("a")
|
||||
h[:bar] = source("b")
|
||||
h[i] = source("c")
|
||||
|
||||
sink h[:foo] # $ hasValueFlow=a hasValueFlow=c
|
||||
sink h[:bar] # $ hasValueFlow=b hasValueFlow=c
|
||||
|
||||
s51(h)
|
||||
|
||||
sink h[:foo] # $ hasValueFlow=c
|
||||
sink h[:bar] # $ hasValueFlow=b hasValueFlow=c
|
||||
end
|
||||
|
||||
def m52(i, h)
|
||||
h[:foo] = source("a")
|
||||
h[:bar] = source("b")
|
||||
h[i] = source("c")
|
||||
|
||||
sink h[:foo] # $ hasValueFlow=a hasValueFlow=c
|
||||
sink h[:bar] # $ hasValueFlow=b hasValueFlow=c
|
||||
|
||||
h.s52
|
||||
|
||||
sink h[:foo]
|
||||
sink h[:bar] # $ hasValueFlow=b
|
||||
end
|
||||
|
||||
def m53(i, h)
|
||||
h[:foo] = source("a")
|
||||
h[:bar] = source("b")
|
||||
h[i] = source("c")
|
||||
|
||||
sink h[:foo] # $ hasValueFlow=a hasValueFlow=c
|
||||
sink h[:bar] # $ hasValueFlow=b hasValueFlow=c
|
||||
|
||||
x = h.s53()
|
||||
|
||||
sink x[:foo]
|
||||
sink x[:bar] # $ hasValueFlow=b
|
||||
|
||||
sink(source("d").s53()) # $ hasValueFlow=d
|
||||
end
|
||||
|
||||
def m54(i, h)
|
||||
h[:foo] = source("a")
|
||||
h[:bar] = source("b")
|
||||
h[i] = source("c")
|
||||
|
||||
sink h[:foo] # $ hasValueFlow=a hasValueFlow=c
|
||||
sink h[:bar] # $ hasValueFlow=b hasValueFlow=c
|
||||
|
||||
x = h.s54()
|
||||
|
||||
sink x[:foo]
|
||||
sink x[:bar] # $ hasValueFlow=b
|
||||
|
||||
sink(source("d").s54())
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -628,19 +628,21 @@ end
|
||||
|
||||
m38()
|
||||
|
||||
def m39()
|
||||
def m39(x)
|
||||
hash = {
|
||||
:a => taint(39.1),
|
||||
:b => 1,
|
||||
:c => taint(39.2)
|
||||
}
|
||||
hash[x] = taint(39.3)
|
||||
|
||||
hash.transform_keys! {|key| key.to_s }
|
||||
sink (hash["a"]) # $ hasValueFlow=39.1 $ hasValueFlow=39.2
|
||||
sink (hash["b"]) # $ hasValueFlow=39.1 $ hasValueFlow=39.2
|
||||
sink (hash["c"]) # $ hasValueFlow=39.1 $ hasValueFlow=39.2
|
||||
sink (hash["a"]) # $ hasValueFlow=39.1 $ hasValueFlow=39.2 $ hasValueFlow=39.3
|
||||
sink (hash["b"]) # $ hasValueFlow=39.1 $ hasValueFlow=39.2 $ hasValueFlow=39.3
|
||||
sink (hash["c"]) # $ hasValueFlow=39.1 $ hasValueFlow=39.2 $ hasValueFlow=39.3
|
||||
end
|
||||
|
||||
m39()
|
||||
m39(:d)
|
||||
|
||||
def m40()
|
||||
hash = {
|
||||
|
||||
@@ -21,19 +21,19 @@
|
||||
| hash_flow.rb:571:18:571:38 | # $ hasValueFlow=35.1 | Missing result:hasValueFlow=35.1 |
|
||||
| hash_flow.rb:591:20:591:60 | # $ hasValueFlow=36.1 $ hasValueFlow=36.2 | Missing result:hasValueFlow=36.1 |
|
||||
| hash_flow.rb:591:20:591:60 | # $ hasValueFlow=36.1 $ hasValueFlow=36.2 | Missing result:hasValueFlow=36.2 |
|
||||
| hash_flow.rb:668:14:668:18 | value | Unexpected result: hasValueFlow=41.3 |
|
||||
| hash_flow.rb:671:10:671:19 | ( ... ) | Unexpected result: hasValueFlow=41.1 |
|
||||
| hash_flow.rb:702:22:702:42 | # $ hasValueFlow=42.3 | Missing result:hasValueFlow=42.3 |
|
||||
| hash_flow.rb:704:22:704:42 | # $ hasValueFlow=42.4 | Missing result:hasValueFlow=42.4 |
|
||||
| hash_flow.rb:774:10:774:14 | ...[...] | Unexpected result: hasValueFlow=46.1 |
|
||||
| hash_flow.rb:777:10:777:14 | ...[...] | Unexpected result: hasValueFlow=46.3 |
|
||||
| hash_flow.rb:779:10:779:17 | ...[...] | Unexpected result: hasValueFlow=46.1 |
|
||||
| hash_flow.rb:782:10:782:17 | ...[...] | Unexpected result: hasValueFlow=46.3 |
|
||||
| hash_flow.rb:839:22:839:42 | # $ hasValueFlow=48.3 | Missing result:hasValueFlow=48.3 |
|
||||
| hash_flow.rb:841:22:841:42 | # $ hasValueFlow=48.4 | Missing result:hasValueFlow=48.4 |
|
||||
| hash_flow.rb:901:22:901:42 | # $ hasValueFlow=50.3 | Missing result:hasValueFlow=50.3 |
|
||||
| hash_flow.rb:903:22:903:42 | # $ hasValueFlow=50.4 | Missing result:hasValueFlow=50.4 |
|
||||
| hash_flow.rb:931:22:931:42 | # $ hasValueFlow=51.3 | Missing result:hasValueFlow=51.3 |
|
||||
| hash_flow.rb:933:22:933:42 | # $ hasValueFlow=51.4 | Missing result:hasValueFlow=51.4 |
|
||||
| hash_flow.rb:961:22:961:42 | # $ hasValueFlow=52.3 | Missing result:hasValueFlow=52.3 |
|
||||
| hash_flow.rb:963:22:963:42 | # $ hasValueFlow=52.4 | Missing result:hasValueFlow=52.4 |
|
||||
| hash_flow.rb:670:14:670:18 | value | Unexpected result: hasValueFlow=41.3 |
|
||||
| hash_flow.rb:673:10:673:19 | ( ... ) | Unexpected result: hasValueFlow=41.1 |
|
||||
| hash_flow.rb:704:22:704:42 | # $ hasValueFlow=42.3 | Missing result:hasValueFlow=42.3 |
|
||||
| hash_flow.rb:706:22:706:42 | # $ hasValueFlow=42.4 | Missing result:hasValueFlow=42.4 |
|
||||
| hash_flow.rb:776:10:776:14 | ...[...] | Unexpected result: hasValueFlow=46.1 |
|
||||
| hash_flow.rb:779:10:779:14 | ...[...] | Unexpected result: hasValueFlow=46.3 |
|
||||
| hash_flow.rb:781:10:781:17 | ...[...] | Unexpected result: hasValueFlow=46.1 |
|
||||
| hash_flow.rb:784:10:784:17 | ...[...] | Unexpected result: hasValueFlow=46.3 |
|
||||
| hash_flow.rb:841:22:841:42 | # $ hasValueFlow=48.3 | Missing result:hasValueFlow=48.3 |
|
||||
| hash_flow.rb:843:22:843:42 | # $ hasValueFlow=48.4 | Missing result:hasValueFlow=48.4 |
|
||||
| hash_flow.rb:903:22:903:42 | # $ hasValueFlow=50.3 | Missing result:hasValueFlow=50.3 |
|
||||
| hash_flow.rb:905:22:905:42 | # $ hasValueFlow=50.4 | Missing result:hasValueFlow=50.4 |
|
||||
| hash_flow.rb:933:22:933:42 | # $ hasValueFlow=51.3 | Missing result:hasValueFlow=51.3 |
|
||||
| hash_flow.rb:935:22:935:42 | # $ hasValueFlow=51.4 | Missing result:hasValueFlow=51.4 |
|
||||
| hash_flow.rb:963:22:963:42 | # $ hasValueFlow=52.3 | Missing result:hasValueFlow=52.3 |
|
||||
| hash_flow.rb:965:22:965:42 | # $ hasValueFlow=52.4 | Missing result:hasValueFlow=52.4 |
|
||||
|
||||
@@ -1,48 +1,100 @@
|
||||
| Test.rb:1:16:1:21 | # lgtm | lgtm | lgtm | Test.rb:1:1:1:21 | suppression range |
|
||||
| Test.rb:2:1:2:32 | # lgtm[rb/confusing-method-name] | lgtm[rb/confusing-method-name] | lgtm[rb/confusing-method-name] | Test.rb:2:1:2:32 | suppression range |
|
||||
| Test.rb:2:1:2:32 | # lgtm[rb/confusing-method-name] | lgtm[rb/confusing-method-name] | lgtm[rb/confusing-method-name] | Test.rb:3:0:3:0 | suppression range |
|
||||
| Test.rb:3:1:3:65 | # lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation] | Test.rb:3:1:3:65 | suppression range |
|
||||
| Test.rb:3:1:3:65 | # lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation] | Test.rb:4:0:4:0 | suppression range |
|
||||
| Test.rb:4:1:4:23 | # lgtm[@tag:exceptions] | lgtm[@tag:exceptions] | lgtm[@tag:exceptions] | Test.rb:4:1:4:23 | suppression range |
|
||||
| Test.rb:4:1:4:23 | # lgtm[@tag:exceptions] | lgtm[@tag:exceptions] | lgtm[@tag:exceptions] | Test.rb:5:0:5:0 | suppression range |
|
||||
| Test.rb:5:1:5:48 | # lgtm[@tag:exceptions,rb/confusing-method-name] | lgtm[@tag:exceptions,rb/confusing-method-name] | lgtm[@tag:exceptions,rb/confusing-method-name] | Test.rb:5:1:5:48 | suppression range |
|
||||
| Test.rb:5:1:5:48 | # lgtm[@tag:exceptions,rb/confusing-method-name] | lgtm[@tag:exceptions,rb/confusing-method-name] | lgtm[@tag:exceptions,rb/confusing-method-name] | Test.rb:6:0:6:0 | suppression range |
|
||||
| Test.rb:6:1:6:27 | # lgtm[@expires:2017-06-11] | lgtm[@expires:2017-06-11] | lgtm[@expires:2017-06-11] | Test.rb:6:1:6:27 | suppression range |
|
||||
| Test.rb:6:1:6:27 | # lgtm[@expires:2017-06-11] | lgtm[@expires:2017-06-11] | lgtm[@expires:2017-06-11] | Test.rb:7:0:7:0 | suppression range |
|
||||
| Test.rb:7:1:7:78 | # lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm | lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm | lgtm[rb/confusing-method-name] | Test.rb:7:1:7:78 | suppression range |
|
||||
| Test.rb:7:1:7:78 | # lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm | lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm | lgtm[rb/confusing-method-name] | Test.rb:8:0:8:0 | suppression range |
|
||||
| Test.rb:8:1:8:17 | # lgtm: blah blah | lgtm: blah blah | lgtm | Test.rb:8:1:8:17 | suppression range |
|
||||
| Test.rb:8:1:8:17 | # lgtm: blah blah | lgtm: blah blah | lgtm | Test.rb:9:0:9:0 | suppression range |
|
||||
| Test.rb:9:1:9:31 | # lgtm blah blah #falsepositive | lgtm blah blah #falsepositive | lgtm | Test.rb:9:1:9:31 | suppression range |
|
||||
| Test.rb:9:1:9:31 | # lgtm blah blah #falsepositive | lgtm blah blah #falsepositive | lgtm | Test.rb:10:0:10:0 | suppression range |
|
||||
| Test.rb:10:1:10:33 | #lgtm [rb/confusing-method-name] | lgtm [rb/confusing-method-name] | lgtm [rb/confusing-method-name] | Test.rb:10:1:10:33 | suppression range |
|
||||
| Test.rb:10:1:10:33 | #lgtm [rb/confusing-method-name] | lgtm [rb/confusing-method-name] | lgtm [rb/confusing-method-name] | Test.rb:11:0:11:0 | suppression range |
|
||||
| Test.rb:11:1:11:8 | # lgtm[] | lgtm[] | lgtm[] | Test.rb:11:1:11:8 | suppression range |
|
||||
| Test.rb:11:1:11:8 | # lgtm[] | lgtm[] | lgtm[] | Test.rb:12:0:12:0 | suppression range |
|
||||
| Test.rb:13:1:13:5 | #lgtm | lgtm | lgtm | Test.rb:13:1:13:5 | suppression range |
|
||||
| Test.rb:13:1:13:5 | #lgtm | lgtm | lgtm | Test.rb:14:0:14:0 | suppression range |
|
||||
| Test.rb:14:1:14:6 | #\tlgtm | \tlgtm | lgtm | Test.rb:14:1:14:6 | suppression range |
|
||||
| Test.rb:14:1:14:6 | #\tlgtm | \tlgtm | lgtm | Test.rb:15:0:15:0 | suppression range |
|
||||
| Test.rb:15:1:15:33 | # lgtm\t[rb/confusing-method-name] | lgtm\t[rb/confusing-method-name] | lgtm\t[rb/confusing-method-name] | Test.rb:15:1:15:33 | suppression range |
|
||||
| Test.rb:15:1:15:33 | # lgtm\t[rb/confusing-method-name] | lgtm\t[rb/confusing-method-name] | lgtm\t[rb/confusing-method-name] | Test.rb:16:0:16:0 | suppression range |
|
||||
| Test.rb:18:1:18:11 | # foo; lgtm | foo; lgtm | lgtm | Test.rb:18:1:18:11 | suppression range |
|
||||
| Test.rb:18:1:18:11 | # foo; lgtm | foo; lgtm | lgtm | Test.rb:19:0:19:0 | suppression range |
|
||||
| Test.rb:19:1:19:37 | # foo; lgtm[rb/confusing-method-name] | foo; lgtm[rb/confusing-method-name] | lgtm[rb/confusing-method-name] | Test.rb:19:1:19:37 | suppression range |
|
||||
| Test.rb:19:1:19:37 | # foo; lgtm[rb/confusing-method-name] | foo; lgtm[rb/confusing-method-name] | lgtm[rb/confusing-method-name] | Test.rb:20:0:20:0 | suppression range |
|
||||
| Test.rb:21:1:21:36 | # foo lgtm[rb/confusing-method-name] | foo lgtm[rb/confusing-method-name] | lgtm[rb/confusing-method-name] | Test.rb:21:1:21:36 | suppression range |
|
||||
| Test.rb:21:1:21:36 | # foo lgtm[rb/confusing-method-name] | foo lgtm[rb/confusing-method-name] | lgtm[rb/confusing-method-name] | Test.rb:22:0:22:0 | suppression range |
|
||||
| Test.rb:23:1:23:40 | # foo lgtm[rb/confusing-method-name] bar | foo lgtm[rb/confusing-method-name] bar | lgtm[rb/confusing-method-name] | Test.rb:23:1:23:40 | suppression range |
|
||||
| Test.rb:23:1:23:40 | # foo lgtm[rb/confusing-method-name] bar | foo lgtm[rb/confusing-method-name] bar | lgtm[rb/confusing-method-name] | Test.rb:24:0:24:0 | suppression range |
|
||||
| Test.rb:24:1:24:7 | # LGTM! | LGTM! | LGTM | Test.rb:24:1:24:7 | suppression range |
|
||||
| Test.rb:24:1:24:7 | # LGTM! | LGTM! | LGTM | Test.rb:25:0:25:0 | suppression range |
|
||||
| Test.rb:25:1:25:32 | # LGTM[rb/confusing-method-name] | LGTM[rb/confusing-method-name] | LGTM[rb/confusing-method-name] | Test.rb:25:1:25:32 | suppression range |
|
||||
| Test.rb:25:1:25:32 | # LGTM[rb/confusing-method-name] | LGTM[rb/confusing-method-name] | LGTM[rb/confusing-method-name] | Test.rb:26:0:26:0 | suppression range |
|
||||
| Test.rb:26:1:26:73 | #lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name] | Test.rb:26:1:26:73 | suppression range |
|
||||
| Test.rb:26:1:26:73 | #lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name] | Test.rb:27:0:27:0 | suppression range |
|
||||
| Test.rb:26:1:26:73 | #lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation] | lgtm[rb/non-short-circuit-evaluation] | Test.rb:26:1:26:73 | suppression range |
|
||||
| Test.rb:26:1:26:73 | #lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation] | lgtm[rb/non-short-circuit-evaluation] | Test.rb:27:0:27:0 | suppression range |
|
||||
| Test.rb:27:1:27:37 | #lgtm[rb/confusing-method-name]; lgtm | lgtm[rb/confusing-method-name]; lgtm | lgtm | Test.rb:27:1:27:37 | suppression range |
|
||||
| Test.rb:27:1:27:37 | #lgtm[rb/confusing-method-name]; lgtm | lgtm[rb/confusing-method-name]; lgtm | lgtm | Test.rb:28:0:28:0 | suppression range |
|
||||
| Test.rb:27:1:27:37 | #lgtm[rb/confusing-method-name]; lgtm | lgtm[rb/confusing-method-name]; lgtm | lgtm[rb/confusing-method-name] | Test.rb:27:1:27:37 | suppression range |
|
||||
| Test.rb:27:1:27:37 | #lgtm[rb/confusing-method-name]; lgtm | lgtm[rb/confusing-method-name]; lgtm | lgtm[rb/confusing-method-name] | Test.rb:28:0:28:0 | suppression range |
|
||||
| Test.rb:28:1:28:31 | # codeql[js/debugger-statement] | codeql[js/debugger-statement] | lgtm[js/debugger-statement] | Test.rb:29:0:29:0 | suppression range |
|
||||
| Test.rb:29:1:29:31 | # CODEQL[js/debugger-statement] | CODEQL[js/debugger-statement] | lgtm[js/debugger-statement] | Test.rb:30:0:30:0 | suppression range |
|
||||
| Test.rb:30:1:30:68 | # codeql[js/debugger-statement] -- because I know better than codeql | codeql[js/debugger-statement] -- because I know better than codeql | lgtm[js/debugger-statement] | Test.rb:31:0:31:0 | suppression range |
|
||||
| TestWindows.rb:1:23:1:29 | # lgtm\r | lgtm\r | lgtm | TestWindows.rb:1:1:1:29 | suppression range |
|
||||
| TestWindows.rb:2:1:2:33 | # lgtm[rb/confusing-method-name]\r | lgtm[rb/confusing-method-name]\r | lgtm[rb/confusing-method-name] | TestWindows.rb:2:1:2:33 | suppression range |
|
||||
| TestWindows.rb:2:1:2:33 | # lgtm[rb/confusing-method-name]\r | lgtm[rb/confusing-method-name]\r | lgtm[rb/confusing-method-name] | TestWindows.rb:3:0:3:0 | suppression range |
|
||||
| TestWindows.rb:3:1:3:66 | # lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation] | TestWindows.rb:3:1:3:66 | suppression range |
|
||||
| TestWindows.rb:3:1:3:66 | # lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation] | TestWindows.rb:4:0:4:0 | suppression range |
|
||||
| TestWindows.rb:4:1:4:24 | # lgtm[@tag:exceptions]\r | lgtm[@tag:exceptions]\r | lgtm[@tag:exceptions] | TestWindows.rb:4:1:4:24 | suppression range |
|
||||
| TestWindows.rb:4:1:4:24 | # lgtm[@tag:exceptions]\r | lgtm[@tag:exceptions]\r | lgtm[@tag:exceptions] | TestWindows.rb:5:0:5:0 | suppression range |
|
||||
| TestWindows.rb:5:1:5:49 | # lgtm[@tag:exceptions,rb/confusing-method-name]\r | lgtm[@tag:exceptions,rb/confusing-method-name]\r | lgtm[@tag:exceptions,rb/confusing-method-name] | TestWindows.rb:5:1:5:49 | suppression range |
|
||||
| TestWindows.rb:5:1:5:49 | # lgtm[@tag:exceptions,rb/confusing-method-name]\r | lgtm[@tag:exceptions,rb/confusing-method-name]\r | lgtm[@tag:exceptions,rb/confusing-method-name] | TestWindows.rb:6:0:6:0 | suppression range |
|
||||
| TestWindows.rb:6:1:6:28 | # lgtm[@expires:2017-06-11]\r | lgtm[@expires:2017-06-11]\r | lgtm[@expires:2017-06-11] | TestWindows.rb:6:1:6:28 | suppression range |
|
||||
| TestWindows.rb:6:1:6:28 | # lgtm[@expires:2017-06-11]\r | lgtm[@expires:2017-06-11]\r | lgtm[@expires:2017-06-11] | TestWindows.rb:7:0:7:0 | suppression range |
|
||||
| TestWindows.rb:7:1:7:79 | # lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm\r | lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm\r | lgtm[rb/confusing-method-name] | TestWindows.rb:7:1:7:79 | suppression range |
|
||||
| TestWindows.rb:7:1:7:79 | # lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm\r | lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm\r | lgtm[rb/confusing-method-name] | TestWindows.rb:8:0:8:0 | suppression range |
|
||||
| TestWindows.rb:8:1:8:18 | # lgtm: blah blah\r | lgtm: blah blah\r | lgtm | TestWindows.rb:8:1:8:18 | suppression range |
|
||||
| TestWindows.rb:8:1:8:18 | # lgtm: blah blah\r | lgtm: blah blah\r | lgtm | TestWindows.rb:9:0:9:0 | suppression range |
|
||||
| TestWindows.rb:9:1:9:32 | # lgtm blah blah #falsepositive\r | lgtm blah blah #falsepositive\r | lgtm | TestWindows.rb:9:1:9:32 | suppression range |
|
||||
| TestWindows.rb:9:1:9:32 | # lgtm blah blah #falsepositive\r | lgtm blah blah #falsepositive\r | lgtm | TestWindows.rb:10:0:10:0 | suppression range |
|
||||
| TestWindows.rb:10:1:10:34 | #lgtm [rb/confusing-method-name]\r | lgtm [rb/confusing-method-name]\r | lgtm [rb/confusing-method-name] | TestWindows.rb:10:1:10:34 | suppression range |
|
||||
| TestWindows.rb:10:1:10:34 | #lgtm [rb/confusing-method-name]\r | lgtm [rb/confusing-method-name]\r | lgtm [rb/confusing-method-name] | TestWindows.rb:11:0:11:0 | suppression range |
|
||||
| TestWindows.rb:11:1:11:9 | # lgtm[]\r | lgtm[]\r | lgtm[] | TestWindows.rb:11:1:11:9 | suppression range |
|
||||
| TestWindows.rb:11:1:11:9 | # lgtm[]\r | lgtm[]\r | lgtm[] | TestWindows.rb:12:0:12:0 | suppression range |
|
||||
| TestWindows.rb:13:1:13:6 | #lgtm\r | lgtm\r | lgtm | TestWindows.rb:13:1:13:6 | suppression range |
|
||||
| TestWindows.rb:13:1:13:6 | #lgtm\r | lgtm\r | lgtm | TestWindows.rb:14:0:14:0 | suppression range |
|
||||
| TestWindows.rb:14:1:14:7 | #\tlgtm\r | \tlgtm\r | lgtm | TestWindows.rb:14:1:14:7 | suppression range |
|
||||
| TestWindows.rb:14:1:14:7 | #\tlgtm\r | \tlgtm\r | lgtm | TestWindows.rb:15:0:15:0 | suppression range |
|
||||
| TestWindows.rb:15:1:15:34 | # lgtm\t[rb/confusing-method-name]\r | lgtm\t[rb/confusing-method-name]\r | lgtm\t[rb/confusing-method-name] | TestWindows.rb:15:1:15:34 | suppression range |
|
||||
| TestWindows.rb:15:1:15:34 | # lgtm\t[rb/confusing-method-name]\r | lgtm\t[rb/confusing-method-name]\r | lgtm\t[rb/confusing-method-name] | TestWindows.rb:16:0:16:0 | suppression range |
|
||||
| TestWindows.rb:18:1:18:12 | # foo; lgtm\r | foo; lgtm\r | lgtm | TestWindows.rb:18:1:18:12 | suppression range |
|
||||
| TestWindows.rb:18:1:18:12 | # foo; lgtm\r | foo; lgtm\r | lgtm | TestWindows.rb:19:0:19:0 | suppression range |
|
||||
| TestWindows.rb:19:1:19:38 | # foo; lgtm[rb/confusing-method-name]\r | foo; lgtm[rb/confusing-method-name]\r | lgtm[rb/confusing-method-name] | TestWindows.rb:19:1:19:38 | suppression range |
|
||||
| TestWindows.rb:19:1:19:38 | # foo; lgtm[rb/confusing-method-name]\r | foo; lgtm[rb/confusing-method-name]\r | lgtm[rb/confusing-method-name] | TestWindows.rb:20:0:20:0 | suppression range |
|
||||
| TestWindows.rb:21:1:21:37 | # foo lgtm[rb/confusing-method-name]\r | foo lgtm[rb/confusing-method-name]\r | lgtm[rb/confusing-method-name] | TestWindows.rb:21:1:21:37 | suppression range |
|
||||
| TestWindows.rb:21:1:21:37 | # foo lgtm[rb/confusing-method-name]\r | foo lgtm[rb/confusing-method-name]\r | lgtm[rb/confusing-method-name] | TestWindows.rb:22:0:22:0 | suppression range |
|
||||
| TestWindows.rb:23:1:23:41 | # foo lgtm[rb/confusing-method-name] bar\r | foo lgtm[rb/confusing-method-name] bar\r | lgtm[rb/confusing-method-name] | TestWindows.rb:23:1:23:41 | suppression range |
|
||||
| TestWindows.rb:23:1:23:41 | # foo lgtm[rb/confusing-method-name] bar\r | foo lgtm[rb/confusing-method-name] bar\r | lgtm[rb/confusing-method-name] | TestWindows.rb:24:0:24:0 | suppression range |
|
||||
| TestWindows.rb:24:1:24:8 | # LGTM!\r | LGTM!\r | LGTM | TestWindows.rb:24:1:24:8 | suppression range |
|
||||
| TestWindows.rb:24:1:24:8 | # LGTM!\r | LGTM!\r | LGTM | TestWindows.rb:25:0:25:0 | suppression range |
|
||||
| TestWindows.rb:25:1:25:33 | # LGTM[rb/confusing-method-name]\r | LGTM[rb/confusing-method-name]\r | LGTM[rb/confusing-method-name] | TestWindows.rb:25:1:25:33 | suppression range |
|
||||
| TestWindows.rb:25:1:25:33 | # LGTM[rb/confusing-method-name]\r | LGTM[rb/confusing-method-name]\r | LGTM[rb/confusing-method-name] | TestWindows.rb:26:0:26:0 | suppression range |
|
||||
| TestWindows.rb:26:1:26:74 | #lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name] | TestWindows.rb:26:1:26:74 | suppression range |
|
||||
| TestWindows.rb:26:1:26:74 | #lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name] | TestWindows.rb:27:0:27:0 | suppression range |
|
||||
| TestWindows.rb:26:1:26:74 | #lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]\r | lgtm[rb/non-short-circuit-evaluation] | TestWindows.rb:26:1:26:74 | suppression range |
|
||||
| TestWindows.rb:26:1:26:74 | #lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]\r | lgtm[rb/non-short-circuit-evaluation] | TestWindows.rb:27:0:27:0 | suppression range |
|
||||
| TestWindows.rb:27:1:27:38 | #lgtm[rb/confusing-method-name]; lgtm\r | lgtm[rb/confusing-method-name]; lgtm\r | lgtm | TestWindows.rb:27:1:27:38 | suppression range |
|
||||
| TestWindows.rb:27:1:27:38 | #lgtm[rb/confusing-method-name]; lgtm\r | lgtm[rb/confusing-method-name]; lgtm\r | lgtm | TestWindows.rb:28:0:28:0 | suppression range |
|
||||
| TestWindows.rb:27:1:27:38 | #lgtm[rb/confusing-method-name]; lgtm\r | lgtm[rb/confusing-method-name]; lgtm\r | lgtm[rb/confusing-method-name] | TestWindows.rb:27:1:27:38 | suppression range |
|
||||
| TestWindows.rb:27:1:27:38 | #lgtm[rb/confusing-method-name]; lgtm\r | lgtm[rb/confusing-method-name]; lgtm\r | lgtm[rb/confusing-method-name] | TestWindows.rb:28:0:28:0 | suppression range |
|
||||
| TestWindows.rb:28:1:28:32 | # codeql[js/debugger-statement]\r | codeql[js/debugger-statement]\r | lgtm[js/debugger-statement] | TestWindows.rb:29:0:29:0 | suppression range |
|
||||
| TestWindows.rb:29:1:29:32 | # CODEQL[js/debugger-statement]\r | CODEQL[js/debugger-statement]\r | lgtm[js/debugger-statement] | TestWindows.rb:30:0:30:0 | suppression range |
|
||||
| TestWindows.rb:30:1:30:69 | # codeql[js/debugger-statement] -- because I know better than codeql\r | codeql[js/debugger-statement] -- because I know better than codeql\r | lgtm[js/debugger-statement] | TestWindows.rb:31:0:31:0 | suppression range |
|
||||
|
||||
@@ -25,4 +25,8 @@ class Test end # lgtm
|
||||
# LGTM[rb/confusing-method-name]
|
||||
#lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]
|
||||
#lgtm[rb/confusing-method-name]; lgtm
|
||||
# codeql[js/debugger-statement]
|
||||
# CODEQL[js/debugger-statement]
|
||||
# codeql[js/debugger-statement] -- because I know better than codeql
|
||||
foo # codeql[js/debugger-statement]
|
||||
|
||||
|
||||
@@ -25,4 +25,8 @@ class TestWindows end # lgtm
|
||||
# LGTM[rb/confusing-method-name]
|
||||
#lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]
|
||||
#lgtm[rb/confusing-method-name]; lgtm
|
||||
# codeql[js/debugger-statement]
|
||||
# CODEQL[js/debugger-statement]
|
||||
# codeql[js/debugger-statement] -- because I know better than codeql
|
||||
foo # codeql[js/debugger-statement]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user