mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Consolidate all InlineFlowTest libraries in the dataflow qlpack
This commit is contained in:
@@ -3,20 +3,6 @@
|
||||
* See `shared/util/codeql/util/test/InlineExpectationsTest.qll`
|
||||
*/
|
||||
|
||||
private import codeql.ruby.AST as R
|
||||
private import codeql.util.test.InlineExpectationsTest
|
||||
|
||||
private module Impl implements InlineExpectationsTestSig {
|
||||
private import codeql.ruby.ast.internal.TreeSitter
|
||||
|
||||
/**
|
||||
* A class representing line comments in Ruby.
|
||||
*/
|
||||
class ExpectationComment extends Ruby::Comment {
|
||||
string getContents() { result = this.getValue().suffix(1) }
|
||||
}
|
||||
|
||||
class Location = R::Location;
|
||||
}
|
||||
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import Make<Impl>
|
||||
|
||||
@@ -1,96 +1,21 @@
|
||||
/**
|
||||
* Provides a simple base test for flow-related tests using inline expectations.
|
||||
*
|
||||
* Example for a test.ql:
|
||||
* ```ql
|
||||
* import TestUtilities.InlineFlowTest
|
||||
* import DefaultFlowTest
|
||||
* import PathGraph
|
||||
*
|
||||
* from PathNode source, PathNode sink
|
||||
* where flowPath(source, sink)
|
||||
* select sink, source, sink, "$@", source, source.toString()
|
||||
* ```
|
||||
*
|
||||
* To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files.
|
||||
* Example of the corresponding test file, e.g. test.rb
|
||||
* ```rb
|
||||
* s = source(1)
|
||||
* sink(s); // $ hasValueFlow=1
|
||||
* t = "foo" + taint(2);
|
||||
* sink(t); // $ hasTaintFlow=2
|
||||
* ```
|
||||
*
|
||||
* If you are only interested in value flow, then instead of importing `DefaultFlowTest`, you can import
|
||||
* `ValueFlowTest<DefaultFlowConfig>`. Similarly, if you are only interested in taint flow, then instead of
|
||||
* importing `DefaultFlowTest`, you can import `TaintFlowTest<DefaultFlowConfig>`. In both cases
|
||||
* `DefaultFlowConfig` can be replaced by another implementation of `DataFlow::ConfigSig`.
|
||||
*
|
||||
* If you need more fine-grained tuning, consider implementing a test using `InlineExpectationsTest`.
|
||||
* Inline flow tests for Ruby.
|
||||
* See `shared/util/codeql/dataflow/test/InlineFlowTest.qll`
|
||||
*/
|
||||
|
||||
import codeql.ruby.AST
|
||||
import codeql.ruby.DataFlow
|
||||
import codeql.ruby.TaintTracking
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import TestUtilities.InlineFlowTestUtil
|
||||
import ruby
|
||||
private import codeql.dataflow.test.InlineFlowTest
|
||||
private import codeql.ruby.dataflow.internal.DataFlowImplSpecific
|
||||
private import codeql.ruby.dataflow.internal.TaintTrackingImplSpecific
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
|
||||
module DefaultFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { defaultSource(source) }
|
||||
private module FlowTestImpl implements InputSig<RubyDataFlow> {
|
||||
import TestUtilities.InlineFlowTestUtil
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { defaultSink(sink) }
|
||||
|
||||
int fieldFlowBranchLimit() { result = 1000 }
|
||||
}
|
||||
|
||||
private module NoFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { none() }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFlowConfig> {
|
||||
module ValueFlow = DataFlow::Global<ValueFlowConfig>;
|
||||
|
||||
module TaintFlow = TaintTracking::Global<TaintFlowConfig>;
|
||||
|
||||
private module InlineTest implements TestSig {
|
||||
string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasValueFlow" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink | ValueFlow::flow(src, sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
)
|
||||
or
|
||||
tag = "hasTaintFlow" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
TaintFlow::flow(src, sink) and not ValueFlow::flow(src, sink)
|
||||
|
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<InlineTest>
|
||||
import DataFlow::MergePathGraph<ValueFlow::PathNode, TaintFlow::PathNode, ValueFlow::PathGraph, TaintFlow::PathGraph>
|
||||
|
||||
predicate flowPath(PathNode source, PathNode sink) {
|
||||
ValueFlow::flowPath(source.asPathNode1(), sink.asPathNode1()) or
|
||||
TaintFlow::flowPath(source.asPathNode2(), sink.asPathNode2())
|
||||
string getArgString(DataFlow::Node src, DataFlow::Node sink) {
|
||||
(if exists(getSourceArgString(src)) then result = getSourceArgString(src) else result = "") and
|
||||
exists(sink)
|
||||
}
|
||||
}
|
||||
|
||||
module DefaultFlowTest = FlowTest<DefaultFlowConfig, DefaultFlowConfig>;
|
||||
|
||||
module ValueFlowTest<DataFlow::ConfigSig ValueFlowConfig> {
|
||||
import FlowTest<ValueFlowConfig, NoFlowConfig>
|
||||
}
|
||||
|
||||
module TaintFlowTest<DataFlow::ConfigSig TaintFlowConfig> {
|
||||
import FlowTest<NoFlowConfig, TaintFlowConfig>
|
||||
}
|
||||
import InlineFlowTestMake<RubyDataFlow, RubyTaintTracking, Impl, FlowTestImpl>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
private import codeql.ruby.AST as R
|
||||
private import codeql.util.test.InlineExpectationsTest
|
||||
|
||||
module Impl implements InlineExpectationsTestSig {
|
||||
private import codeql.ruby.ast.internal.TreeSitter
|
||||
|
||||
/**
|
||||
* A class representing line comments in Ruby.
|
||||
*/
|
||||
class ExpectationComment extends Ruby::Comment {
|
||||
string getContents() { result = this.getValue().suffix(1) }
|
||||
}
|
||||
|
||||
class Location = R::Location;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| array_flow.rb:2:5:2:5 | a [element 0] | array_flow.rb:3:10:3:10 | a [element 0] |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| call_sensitivity.rb:9:7:9:13 | call to taint | call_sensitivity.rb:9:6:9:14 | ( ... ) |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| semantics.rb:2:5:2:5 | a | semantics.rb:3:9:3:9 | a |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| captured_variables.rb:1:24:1:24 | x | captured_variables.rb:2:20:2:20 | x |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| hash_flow.rb:10:5:10:8 | hash [element 0] | hash_flow.rb:30:10:30:13 | hash [element 0] |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| local_dataflow.rb:78:3:78:3 | z | local_dataflow.rb:89:8:89:8 | z |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| params_flow.rb:9:16:9:17 | p1 | params_flow.rb:10:10:10:11 | p1 |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| pathname_flow.rb:4:5:4:6 | pn | pathname_flow.rb:5:10:5:11 | pn |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| ssa_flow.rb:12:9:12:9 | [post] a [element 0] | ssa_flow.rb:16:10:16:10 | a [element 0] |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
| string_flow.rb:85:10:85:10 | a | Unexpected result: hasValueFlow=a |
|
||||
| string_flow.rb:227:10:227:10 | a | Unexpected result: hasValueFlow=a |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| summaries.rb:1:1:1:7 | tainted | summaries.rb:2:6:2:12 | tainted |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
| filter_flow.rb:21:10:21:13 | @foo | Unexpected result: hasTaintFlow= |
|
||||
| filter_flow.rb:38:10:38:13 | @foo | Unexpected result: hasTaintFlow= |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| mailer.rb:3:10:3:15 | call to params | mailer.rb:3:10:3:21 | ...[...] |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
| hash_extensions.rb:126:10:126:19 | call to sole | Unexpected result: hasValueFlow=b |
|
||||
edges
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
#select
|
||||
| arel.rb:3:8:3:18 | call to sql | arel.rb:2:7:2:14 | call to source | arel.rb:3:8:3:18 | call to sql | $@ | arel.rb:2:7:2:14 | call to source | call to source |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
edges
|
||||
| json.rb:1:17:1:26 | call to source | json.rb:1:6:1:27 | call to parse |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
failures
|
||||
testFailures
|
||||
| views/index.erb:2:10:2:12 | call to foo | Unexpected result: hasTaintFlow= |
|
||||
edges
|
||||
|
||||
Reference in New Issue
Block a user