Skip to content

Commit 334c43a

Browse files
committed
Ruby: Add tests for ActiveSupport modelling
1 parent deff24e commit 334c43a

File tree

11 files changed

+427
-11
lines changed

11 files changed

+427
-11
lines changed

ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ module ActiveSupport {
130130
* `ActiveSupport::Logger`
131131
*/
132132
module Logger {
133-
private class ActiveSupportLoggerInstance extends StdlibLogger::LoggerInstance {
134-
ActiveSupportLoggerInstance() {
133+
private class ActiveSupportLoggerInstantiation extends StdlibLogger::LoggerInstantiation {
134+
ActiveSupportLoggerInstantiation() {
135135
this =
136136
API::getTopLevelMember("ActiveSupport")
137137
.getMember(["Logger", "TaggedLogging"])

ruby/ql/lib/codeql/ruby/frameworks/stdlib/Logger.qll

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ private import codeql.ruby.dataflow.internal.DataFlowDispatch
1616
module Logger {
1717
/** A reference to a `Logger` instance */
1818
private DataFlow::Node loggerInstance() {
19-
result = API::getTopLevelMember("Logger").getAnInstantiation()
19+
result instanceof LoggerInstantiation
2020
or
2121
exists(DataFlow::Node inst |
2222
inst = loggerInstance() and
@@ -34,17 +34,21 @@ module Logger {
3434
}
3535

3636
/**
37-
* An instance of a logger that responds to the std lib logging methods.
37+
* An instantiation of a logger that responds to the std lib logging methods.
3838
* This can be extended to recognise additional instances that conform to the
3939
* same interface.
4040
*/
41-
abstract class LoggerInstance extends DataFlow::Node { }
41+
abstract class LoggerInstantiation extends DataFlow::Node { }
4242

4343
/**
44-
* An instance of the std lib `Logger` class.
44+
* An instantiation of the std lib `Logger` class.
4545
*/
46-
private class StdlibLoggerInstance extends LoggerInstance {
47-
StdlibLoggerInstance() { this = loggerInstance() }
46+
private class StdlibLoggerInstantiation extends LoggerInstantiation {
47+
StdlibLoggerInstantiation() { this = API::getTopLevelMember("Logger").getAnInstantiation() }
48+
}
49+
50+
private class LoggerInstance extends DataFlow::Node {
51+
LoggerInstance() { this = loggerInstance() }
4852
}
4953

5054
/**

ruby/ql/test/library-tests/frameworks/active_support.rb

Lines changed: 0 additions & 3 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1+
constantizeCalls
12
| active_support.rb:1:1:1:22 | call to constantize | active_support.rb:1:1:1:10 | "Foo::Bar" |
23
| active_support.rb:3:1:3:13 | call to constantize | active_support.rb:3:1:3:1 | call to a |
4+
loggerInstantiations
5+
| active_support.rb:5:1:5:33 | call to new |
6+
| active_support.rb:6:1:6:40 | call to new |
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import codeql.ruby.frameworks.ActiveSupport
22
import codeql.ruby.DataFlow
3+
import codeql.ruby.frameworks.stdlib.Logger
34

45
query DataFlow::Node constantizeCalls(ActiveSupport::CoreExtensions::String::Constantize c) {
56
result = c.getCode()
67
}
8+
9+
query predicate loggerInstantiations(Logger::LoggerInstantiation l) { any() }

ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected

Lines changed: 252 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @kind path-problem
3+
*/
4+
5+
import ruby
6+
import TestUtilities.InlineFlowTest
7+
import PathGraph
8+
9+
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf
10+
where conf.hasFlowPath(source, sink)
11+
select sink, source, sink, "$@", source, source.toString()
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
"Foo::Bar".constantize
2+
3+
a.constantize
4+
5+
ActiveSupport::Logger.new(STDOUT)
6+
ActiveSupport::TaggedLogging.new(STDOUT)
7+
8+
def m_camelize
9+
x = source "a"
10+
sink x.camelize # $hasTaintFlow=a
11+
end
12+
13+
def m_camelcase
14+
x = source "a"
15+
sink x.camelcase # $hasTaintFlow=a
16+
end
17+
18+
def m_classify
19+
x = source "a"
20+
sink x.classify # $hasTaintFlow=a
21+
end
22+
23+
def m_dasherize
24+
x = source "a"
25+
sink x.dasherize # $hasTaintFlow=a
26+
end
27+
28+
def m_deconstantize
29+
x = source "a"
30+
sink x.deconstantize # $hasTaintFlow=a
31+
end
32+
33+
def m_demodulize
34+
x = source "a"
35+
sink x.demodulize # $hasTaintFlow=a
36+
end
37+
38+
def m_foreign_key
39+
x = source "a"
40+
sink x.foreign_key # $hasTaintFlow=a
41+
end
42+
43+
def m_humanize
44+
x = source "a"
45+
sink x.humanize # $hasTaintFlow=a
46+
end
47+
48+
def m_indent
49+
x = source "a"
50+
sink x.indent(1) # $hasTaintFlow=a
51+
end
52+
53+
def m_parameterize
54+
x = source "a"
55+
sink x.parameterize # $hasTaintFlow=a
56+
end
57+
58+
def m_pluralize
59+
x = source "a"
60+
sink x.pluralize # $hasTaintFlow=a
61+
end
62+
63+
def m_singularize
64+
x = source "a"
65+
sink x.singularize # $hasTaintFlow=a
66+
end
67+
68+
def m_squish
69+
x = source "a"
70+
sink x.squish # $hasTaintFlow=a
71+
end
72+
73+
def m_strip_heredoc
74+
x = source "a"
75+
sink x.strip_heredoc # $hasTaintFlow=a
76+
end
77+
78+
def m_tableize
79+
x = source "a"
80+
sink x.tableize # $hasTaintFlow=a
81+
end
82+
83+
def m_titlecase
84+
x = source "a"
85+
sink x.titlecase # $hasTaintFlow=a
86+
end
87+
88+
def m_titleize
89+
x = source "a"
90+
sink x.titleize # $hasTaintFlow=a
91+
end
92+
93+
def m_underscore
94+
x = source "a"
95+
sink x.underscore # $hasTaintFlow=a
96+
end
97+
98+
def m_upcase_first
99+
x = source "a"
100+
sink x.upcase_first # $hasTaintFlow=a
101+
end
102+
103+
def m_compact_blank
104+
x = [source 1]
105+
y = x.compact_blank
106+
sink y[0] # $hasValueFlow=1
107+
end
108+
109+
def m_excluding
110+
x = [source(1), 2]
111+
y = x.excluding 2
112+
sink y[0] # $hasValueFlow=1
113+
end
114+
115+
def m_without
116+
x = [source(1), 2]
117+
y = x.without 2
118+
sink y[0] # $hasValueFlow=1
119+
end
120+
121+
def m_in_order_of
122+
x = [source(1), 2]
123+
y = x.in_order_of(:itself, [2,1])
124+
sink y[0] # $hasValueFlow=1
125+
end
126+
127+
def m_including
128+
a = [source(1), 2]
129+
b = a.including(source(3), source(4))
130+
sink a[0] # $ hasValueFlow=1
131+
sink a[1]
132+
sink b[0] # $ hasValueFlow=1 $ hasValueFlow=3 $ hasValueFlow=4
133+
sink b[1] # $ hasValueFlow=3 $ hasValueFlow=4
134+
sink b[2] # $ hasValueFlow=3 $ hasValueFlow=4
135+
sink b[3] # $ hasValueFlow=3 $ hasValueFlow=4
136+
end

ruby/ql/test/library-tests/frameworks/stdlib/Logger.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@
2121
| Logging.rb:73:5:73:63 | call to log | Logging.rb:73:36:73:45 | "message1" |
2222
| Logging.rb:74:5:74:76 | call to log | Logging.rb:74:36:74:45 | "message2" |
2323
| Logging.rb:74:5:74:76 | call to log | Logging.rb:74:48:74:58 | "progname2" |
24+
| Logging.rb:81:1:81:21 | call to debug | Logging.rb:81:16:81:20 | "msg" |
25+
| Logging.rb:82:1:82:21 | call to debug | Logging.rb:82:16:82:20 | "msg" |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import codeql.ruby.frameworks.stdlib.Logger::Logger
2+
import codeql.ruby.frameworks.ActiveSupport::ActiveSupport::Logger
23
import codeql.ruby.DataFlow
34

45
query DataFlow::Node loggerLoggingCallInputs(LoggerLoggingCall c) { result = c.getAnInput() }

0 commit comments

Comments
 (0)