Skip to content

Commit 70bfecc

Browse files
authored
Merge pull request #22272 from github/copilot/add-qltest-documenting-existing-behavior
Ruby: add qltest documenting implicit return dataflow gaps
2 parents 2f2b4c8 + 9251516 commit 70bfecc

3 files changed

Lines changed: 90 additions & 0 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
models
2+
edges
3+
| implicit_return.rb:12:3:12:11 | call to source | implicit_return.rb:15:6:15:11 | call to m_body | provenance | |
4+
nodes
5+
| implicit_return.rb:12:3:12:11 | call to source | semmle.label | call to source |
6+
| implicit_return.rb:15:6:15:11 | call to m_body | semmle.label | call to m_body |
7+
subpaths
8+
testFailures
9+
#select
10+
| implicit_return.rb:15:6:15:11 | call to m_body | implicit_return.rb:12:3:12:11 | call to source | implicit_return.rb:15:6:15:11 | call to m_body | $@ | implicit_return.rb:12:3:12:11 | call to source | call to source |
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* @kind path-problem
3+
*/
4+
5+
import codeql.ruby.AST
6+
import utils.test.InlineFlowTest
7+
import DefaultFlowTest
8+
import ValueFlow::PathGraph
9+
10+
from ValueFlow::PathNode source, ValueFlow::PathNode sink
11+
where ValueFlow::flowPath(source, sink)
12+
select sink, source, sink, "$@", source, source.toString()
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Tests for implicit return steps in Ruby data flow.
2+
#
3+
# An implicit return is when no `return` statement is used; instead the
4+
# last evaluated expression is returned.
5+
#
6+
# The following cases test the behaviour when the returned value is
7+
# in the main body, a `rescue` clause, or an `else` clause,
8+
# with and without an `ensure` clause present.
9+
10+
# Simple implicit return from the method body.
11+
def m_body
12+
source(1)
13+
end
14+
15+
sink(m_body) # $ hasValueFlow=1
16+
17+
# Implicit return from the method body when an `ensure` clause is present.
18+
def m_body_ensure
19+
source(2)
20+
ensure
21+
source(20)
22+
end
23+
24+
sink(m_body_ensure) # $ MISSING: hasValueFlow=2
25+
26+
# Implicit return from a `rescue` clause.
27+
def m_rescue
28+
raise "error"
29+
rescue
30+
source(3)
31+
end
32+
33+
sink(m_rescue) # $ MISSING: hasValueFlow=3
34+
35+
# Implicit return from a `rescue` clause when an `ensure` clause is present.
36+
def m_rescue_ensure
37+
raise "error"
38+
rescue
39+
source(4)
40+
ensure
41+
source(40)
42+
end
43+
44+
sink(m_rescue_ensure) # $ MISSING: hasValueFlow=4
45+
46+
# Implicit return from an `else` clause.
47+
def m_else
48+
source(50)
49+
rescue
50+
nil
51+
else
52+
source(5)
53+
end
54+
55+
sink(m_else) # $ MISSING: hasValueFlow=5
56+
57+
# Implicit return from an `else` clause when an `ensure` clause is present.
58+
def m_else_ensure
59+
source(60)
60+
rescue
61+
nil
62+
else
63+
source(6)
64+
ensure
65+
nil
66+
end
67+
68+
sink(m_else_ensure) # $ MISSING: hasValueFlow=6

0 commit comments

Comments
 (0)