From 0f0acc0428fd1e7fc16ce5223939c5a305c121a2 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 20 Mar 2024 08:52:14 +0100 Subject: [PATCH] Ruby: Add barrier guard flow tests --- .../barrier-guards/barrier-flow.expected | 47 +++++++++++ .../dataflow/barrier-guards/barrier-flow.ql | 23 ++++++ .../barrier-guards/barrier-guards.expected | 28 +++++++ .../dataflow/barrier-guards/barrier_flow.rb | 79 +++++++++++++++++++ 4 files changed, 177 insertions(+) create mode 100644 ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-flow.expected create mode 100644 ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-flow.ql create mode 100644 ruby/ql/test/library-tests/dataflow/barrier-guards/barrier_flow.rb diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-flow.expected b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-flow.expected new file mode 100644 index 000000000000..d3d53177f66c --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-flow.expected @@ -0,0 +1,47 @@ +testFailures +edges +| barrier_flow.rb:2:5:2:5 | x | barrier_flow.rb:4:10:4:10 | x | provenance | | +| barrier_flow.rb:2:9:2:17 | call to source | barrier_flow.rb:2:5:2:5 | x | provenance | | +| barrier_flow.rb:8:5:8:5 | x | barrier_flow.rb:11:14:11:14 | x | provenance | | +| barrier_flow.rb:8:9:8:17 | call to source | barrier_flow.rb:8:5:8:5 | x | provenance | | +| barrier_flow.rb:24:5:24:5 | x | barrier_flow.rb:26:10:26:10 | x | provenance | | +| barrier_flow.rb:24:9:24:17 | call to source | barrier_flow.rb:24:5:24:5 | x | provenance | | +| barrier_flow.rb:36:5:36:5 | x | barrier_flow.rb:42:10:42:10 | x | provenance | | +| barrier_flow.rb:36:9:36:17 | call to source | barrier_flow.rb:36:5:36:5 | x | provenance | | +| barrier_flow.rb:46:5:46:5 | x | barrier_flow.rb:50:10:50:10 | x | provenance | | +| barrier_flow.rb:46:9:46:17 | call to source | barrier_flow.rb:46:5:46:5 | x | provenance | | +| barrier_flow.rb:54:5:54:5 | x | barrier_flow.rb:62:10:62:10 | x | provenance | | +| barrier_flow.rb:54:9:54:17 | call to source | barrier_flow.rb:54:5:54:5 | x | provenance | | +| barrier_flow.rb:66:5:66:5 | x | barrier_flow.rb:78:10:78:10 | x | provenance | | +| barrier_flow.rb:66:9:66:17 | call to source | barrier_flow.rb:66:5:66:5 | x | provenance | | +nodes +| barrier_flow.rb:2:5:2:5 | x | semmle.label | x | +| barrier_flow.rb:2:9:2:17 | call to source | semmle.label | call to source | +| barrier_flow.rb:4:10:4:10 | x | semmle.label | x | +| barrier_flow.rb:8:5:8:5 | x | semmle.label | x | +| barrier_flow.rb:8:9:8:17 | call to source | semmle.label | call to source | +| barrier_flow.rb:11:14:11:14 | x | semmle.label | x | +| barrier_flow.rb:24:5:24:5 | x | semmle.label | x | +| barrier_flow.rb:24:9:24:17 | call to source | semmle.label | call to source | +| barrier_flow.rb:26:10:26:10 | x | semmle.label | x | +| barrier_flow.rb:36:5:36:5 | x | semmle.label | x | +| barrier_flow.rb:36:9:36:17 | call to source | semmle.label | call to source | +| barrier_flow.rb:42:10:42:10 | x | semmle.label | x | +| barrier_flow.rb:46:5:46:5 | x | semmle.label | x | +| barrier_flow.rb:46:9:46:17 | call to source | semmle.label | call to source | +| barrier_flow.rb:50:10:50:10 | x | semmle.label | x | +| barrier_flow.rb:54:5:54:5 | x | semmle.label | x | +| barrier_flow.rb:54:9:54:17 | call to source | semmle.label | call to source | +| barrier_flow.rb:62:10:62:10 | x | semmle.label | x | +| barrier_flow.rb:66:5:66:5 | x | semmle.label | x | +| barrier_flow.rb:66:9:66:17 | call to source | semmle.label | call to source | +| barrier_flow.rb:78:10:78:10 | x | semmle.label | x | +subpaths +#select +| barrier_flow.rb:4:10:4:10 | x | barrier_flow.rb:2:9:2:17 | call to source | barrier_flow.rb:4:10:4:10 | x | $@ | barrier_flow.rb:2:9:2:17 | call to source | call to source | +| barrier_flow.rb:11:14:11:14 | x | barrier_flow.rb:8:9:8:17 | call to source | barrier_flow.rb:11:14:11:14 | x | $@ | barrier_flow.rb:8:9:8:17 | call to source | call to source | +| barrier_flow.rb:26:10:26:10 | x | barrier_flow.rb:24:9:24:17 | call to source | barrier_flow.rb:26:10:26:10 | x | $@ | barrier_flow.rb:24:9:24:17 | call to source | call to source | +| barrier_flow.rb:42:10:42:10 | x | barrier_flow.rb:36:9:36:17 | call to source | barrier_flow.rb:42:10:42:10 | x | $@ | barrier_flow.rb:36:9:36:17 | call to source | call to source | +| barrier_flow.rb:50:10:50:10 | x | barrier_flow.rb:46:9:46:17 | call to source | barrier_flow.rb:50:10:50:10 | x | $@ | barrier_flow.rb:46:9:46:17 | call to source | call to source | +| barrier_flow.rb:62:10:62:10 | x | barrier_flow.rb:54:9:54:17 | call to source | barrier_flow.rb:62:10:62:10 | x | $@ | barrier_flow.rb:54:9:54:17 | call to source | call to source | +| barrier_flow.rb:78:10:78:10 | x | barrier_flow.rb:66:9:66:17 | call to source | barrier_flow.rb:78:10:78:10 | x | $@ | barrier_flow.rb:66:9:66:17 | call to source | call to source | diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-flow.ql b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-flow.ql new file mode 100644 index 000000000000..55bc8c9e529f --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-flow.ql @@ -0,0 +1,23 @@ +/** + * @kind path-problem + */ + +import codeql.ruby.AST +import codeql.ruby.CFG +import TestUtilities.InlineFlowTest +import codeql.ruby.dataflow.BarrierGuards +import PathGraph + +module FlowConfig implements DataFlow::ConfigSig { + predicate isSource = DefaultFlowConfig::isSource/1; + + predicate isSink = DefaultFlowConfig::isSink/1; + + predicate isBarrier(DataFlow::Node n) { n instanceof StringConstCompareBarrier } +} + +import ValueFlowTest + +from PathNode source, PathNode sink +where flowPath(source, sink) +select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected index 798f7c3e3a3f..cc96a29852c0 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected @@ -36,6 +36,8 @@ newStyleBarrierGuards | barrier-guards.rb:276:5:276:7 | foo | | barrier-guards.rb:282:5:282:7 | foo | | barrier-guards.rb:292:5:292:7 | foo | +| barrier_flow.rb:19:14:19:14 | x | +| barrier_flow.rb:32:10:32:10 | x | controls | barrier-guards.rb:3:4:3:15 | ... == ... | barrier-guards.rb:4:5:4:7 | foo | true | | barrier-guards.rb:3:4:3:15 | ... == ... | barrier-guards.rb:6:5:6:7 | foo | false | @@ -331,3 +333,29 @@ controls | barrier-guards.rb:291:6:291:6 | g | barrier-guards.rb:291:1:292:19 | [no-match] when ... | no-match | | barrier-guards.rb:291:6:291:6 | g | barrier-guards.rb:292:5:292:7 | foo | match | | barrier-guards.rb:291:6:291:6 | g | barrier-guards.rb:294:5:294:7 | foo | no-match | +| barrier_flow.rb:10:8:10:18 | ... != ... | barrier_flow.rb:11:9:11:14 | self | true | +| barrier_flow.rb:18:8:18:18 | ... == ... | barrier_flow.rb:19:9:19:14 | self | true | +| barrier_flow.rb:26:19:26:29 | ... == ... | barrier_flow.rb:26:5:26:10 | self | false | +| barrier_flow.rb:32:19:32:29 | ... != ... | barrier_flow.rb:32:5:32:10 | self | false | +| barrier_flow.rb:38:8:38:18 | ... != ... | barrier_flow.rb:39:9:39:9 | x | true | +| barrier_flow.rb:48:23:48:33 | ... == ... | barrier_flow.rb:48:5:48:5 | x | false | +| barrier_flow.rb:56:8:56:8 | b | barrier_flow.rb:57:9:57:14 | return | true | +| barrier_flow.rb:56:8:56:8 | b | barrier_flow.rb:57:9:57:34 | ... unless ... | true | +| barrier_flow.rb:56:8:56:8 | b | barrier_flow.rb:57:23:57:23 | x | true | +| barrier_flow.rb:56:8:56:8 | b | barrier_flow.rb:59:9:59:14 | return | false | +| barrier_flow.rb:56:8:56:8 | b | barrier_flow.rb:59:9:59:34 | ... unless ... | false | +| barrier_flow.rb:56:8:56:8 | b | barrier_flow.rb:59:23:59:23 | x | false | +| barrier_flow.rb:57:23:57:34 | ... == ... | barrier_flow.rb:57:9:57:14 | return | false | +| barrier_flow.rb:57:23:57:34 | ... == ... | barrier_flow.rb:57:9:57:34 | ... unless ... | true | +| barrier_flow.rb:59:23:59:34 | ... == ... | barrier_flow.rb:59:9:59:14 | return | false | +| barrier_flow.rb:59:23:59:34 | ... == ... | barrier_flow.rb:59:9:59:34 | ... unless ... | true | +| barrier_flow.rb:68:8:68:8 | b | barrier_flow.rb:69:9:71:11 | if ... | true | +| barrier_flow.rb:68:8:68:8 | b | barrier_flow.rb:69:12:69:12 | x | true | +| barrier_flow.rb:68:8:68:8 | b | barrier_flow.rb:70:13:70:18 | return | true | +| barrier_flow.rb:68:8:68:8 | b | barrier_flow.rb:73:9:75:11 | if ... | false | +| barrier_flow.rb:68:8:68:8 | b | barrier_flow.rb:73:12:73:12 | x | false | +| barrier_flow.rb:68:8:68:8 | b | barrier_flow.rb:74:13:74:18 | return | false | +| barrier_flow.rb:69:12:69:23 | ... != ... | barrier_flow.rb:69:9:71:11 | if ... | false | +| barrier_flow.rb:69:12:69:23 | ... != ... | barrier_flow.rb:70:13:70:18 | return | true | +| barrier_flow.rb:73:12:73:23 | ... != ... | barrier_flow.rb:73:9:75:11 | if ... | false | +| barrier_flow.rb:73:12:73:23 | ... != ... | barrier_flow.rb:74:13:74:18 | return | true | diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier_flow.rb b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier_flow.rb new file mode 100644 index 000000000000..afd23176bda7 --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier_flow.rb @@ -0,0 +1,79 @@ +def m1 + x = source(1) + + sink x # $ hasValueFlow=1 +end + +def m2 + x = source(2) + + if x != "safe" then + sink x # $ hasValueFlow=2 + end +end + +def m3 + x = source(3) + + if x == "safe" then + sink x # $ guarded + end +end + +def m4 + x = source(4) + + sink x unless x == "safe" # $ hasValueFlow=4 +end + +def m5 + x = source(5) + + sink x unless x != "safe" # $ guarded +end + +def m6 + x = source(6) + + if x != "safe" then + x = "safe" + end + + sink x # $ SPURIOUS hasValueFlow=6 +end + +def m7 + x = source(7) + + x = "safe" unless x == "safe" + + sink x # $ SPURIOUS hasValueFlow=7 +end + +def m8(b) + x = source(8) + + if b then + return unless x == "safe1" + else + return unless x == "safe2" + end + + sink x # $ SPURIOUS hasValueFlow=8 +end + +def m9(b) + x = source(9) + + if b then + if x != "safe1" then + return + end + else + if x != "safe2" then + return + end + end + + sink x # $ SPURIOUS hasValueFlow=9 +end