Skip to content

Commit 714b61b

Browse files
committed
Ruby: Add missing flow through self.new constructor calls
1 parent 6ee231f commit 714b61b

File tree

4 files changed

+135
-34
lines changed

4 files changed

+135
-34
lines changed

ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,7 @@ private Callable viableSourceCallableNonInit(RelevantCall call) {
299299
not call.getExpr() instanceof YieldCall // handled by `lambdaCreation`/`lambdaCall`
300300
}
301301

302-
private Callable viableSourceCallableInit(RelevantCall call) {
303-
result = getInitializeTarget(call) and
304-
not isUserDefinedNew(getTarget(call))
305-
}
302+
private Callable viableSourceCallableInit(RelevantCall call) { result = getInitializeTarget(call) }
306303

307304
/** Holds if `call` may resolve to the returned source-code method. */
308305
private Callable viableSourceCallable(RelevantCall call) {
@@ -374,9 +371,14 @@ private module Cached {
374371
*/
375372
cached
376373
Method getInitializeTarget(RelevantCall new) {
377-
exists(Module m |
378-
moduleFlowsToMethodCallReceiver(new, m, "new") and
379-
result = lookupMethod(m, "initialize")
374+
exists(Module m, boolean exact |
375+
isStandardNewCall(new, m, exact) and
376+
result = lookupMethod(m, "initialize", exact) and
377+
// In the case where `exact = false`, we need to check that there is
378+
// no user-defined `new` method in between `m` and the enclosing module
379+
// of the `initialize` method (`isStandardNewCall` already checks that
380+
// there is no user-defined `new` method in `m` or any of `m`'s ancestors)
381+
not hasUserDefinedNew(result.getEnclosingModule().getModule())
380382
)
381383
}
382384

@@ -481,6 +483,35 @@ private predicate hasUserDefinedNew(Module m) {
481483
)
482484
}
483485

486+
/**
487+
* Holds if `new` is a call to `new`, targeting a class of type `m` (or a
488+
* sub class, when `exact = false`), where there is no user-defined
489+
* `self.new` on `m`.
490+
*/
491+
pragma[nomagic]
492+
private predicate isStandardNewCall(RelevantCall new, Module m, boolean exact) {
493+
exists(DataFlow::LocalSourceNode sourceNode |
494+
flowsToMethodCallReceiver(new, sourceNode, "new") and
495+
// `m` should not have a user-defined `self.new` method
496+
not hasUserDefinedNew(m)
497+
|
498+
// `C.new`
499+
sourceNode = trackModuleAccess(m) and
500+
exact = true
501+
or
502+
// `self.new` inside a module
503+
selfInModule(sourceNode.(SsaSelfDefinitionNode).getVariable(), m) and
504+
exact = true
505+
or
506+
// `self.new` inside a singleton method
507+
exists(MethodBase caller |
508+
selfInMethod(sourceNode.(SsaSelfDefinitionNode).getVariable(), caller, m) and
509+
singletonMethod(caller, _, _) and
510+
exact = false
511+
)
512+
)
513+
}
514+
484515
/** Holds if `n` is an instance of type `tp`. */
485516
private predicate isInstance(DataFlow::Node n, Module tp, boolean exact) {
486517
n.asExpr().getExpr() instanceof NilLiteral and
@@ -535,27 +566,7 @@ private predicate isInstance(DataFlow::Node n, Module tp, boolean exact) {
535566
tp = TResolved("Proc") and
536567
exact = true
537568
or
538-
exists(RelevantCall call, DataFlow::LocalSourceNode sourceNode |
539-
flowsToMethodCallReceiver(call, sourceNode, "new") and
540-
n.asExpr() = call and
541-
// `tp` should not have a user-defined `self.new` method
542-
not hasUserDefinedNew(tp)
543-
|
544-
// `C.new`
545-
sourceNode = trackModuleAccess(tp) and
546-
exact = true
547-
or
548-
// `self.new` inside a module
549-
selfInModule(sourceNode.(SsaSelfDefinitionNode).getVariable(), tp) and
550-
exact = true
551-
or
552-
// `self.new` inside a singleton method
553-
exists(MethodBase caller |
554-
selfInMethod(sourceNode.(SsaSelfDefinitionNode).getVariable(), caller, tp) and
555-
singletonMethod(caller, _, _) and
556-
exact = false
557-
)
558-
)
569+
isStandardNewCall(n.asExpr(), tp, exact)
559570
or
560571
// `self` reference in method or top-level (but not in module or singleton method,
561572
// where instance methods cannot be called; only singleton methods)

ruby/ql/test/library-tests/dataflow/call-sensitivity/call-sensitivity.expected

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
failures
2-
| call_sensitivity.rb:51:12:51:202 | # $ hasValueFlow=10 $ hasValueFlow=11 $ hasValueFlow=12 $ hasValueFlow=13 $ hasValueFlow=26 $ hasValueFlow=28 $ hasValueFlow=30 $ hasValueFlow=33 $ hasValueFlow=35 $ SPURIOUS: hasValueFlow=27 | Missing result:hasValueFlow=35 |
3-
| call_sensitivity.rb:105:12:105:84 | # $ hasValueFlow=28 $ hasValueFlow=30 $ hasValueFlow=32 $ hasValueFlow=35 | Missing result:hasValueFlow=35 |
42
edges
53
| call_sensitivity.rb:9:7:9:13 | call to taint : | call_sensitivity.rb:9:6:9:14 | ( ... ) |
64
| call_sensitivity.rb:9:7:9:13 | call to taint : | call_sensitivity.rb:9:6:9:14 | ( ... ) |
@@ -108,14 +106,24 @@ edges
108106
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:105:10:105:10 | x |
109107
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:105:10:105:10 | x |
110108
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:105:10:105:10 | x |
109+
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:105:10:105:10 | x |
110+
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:105:10:105:10 | x |
111+
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:106:13:106:13 | x : |
111112
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:106:13:106:13 | x : |
112113
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:106:13:106:13 | x : |
113114
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:106:13:106:13 | x : |
114115
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:106:13:106:13 | x : |
116+
| call_sensitivity.rb:104:18:104:18 | x : | call_sensitivity.rb:106:13:106:13 | x : |
117+
| call_sensitivity.rb:106:13:106:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
115118
| call_sensitivity.rb:106:13:106:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
116119
| call_sensitivity.rb:106:13:106:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
117120
| call_sensitivity.rb:106:13:106:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
118121
| call_sensitivity.rb:106:13:106:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
122+
| call_sensitivity.rb:106:13:106:13 | x : | call_sensitivity.rb:50:15:50:15 | x : |
123+
| call_sensitivity.rb:109:21:109:21 | x : | call_sensitivity.rb:110:9:110:9 | x : |
124+
| call_sensitivity.rb:109:21:109:21 | x : | call_sensitivity.rb:110:9:110:9 | x : |
125+
| call_sensitivity.rb:110:9:110:9 | x : | call_sensitivity.rb:104:18:104:18 | x : |
126+
| call_sensitivity.rb:110:9:110:9 | x : | call_sensitivity.rb:104:18:104:18 | x : |
119127
| call_sensitivity.rb:114:11:114:20 | ( ... ) : | call_sensitivity.rb:104:18:104:18 | x : |
120128
| call_sensitivity.rb:114:11:114:20 | ( ... ) : | call_sensitivity.rb:104:18:104:18 | x : |
121129
| call_sensitivity.rb:114:12:114:19 | call to taint : | call_sensitivity.rb:114:11:114:20 | ( ... ) : |
@@ -138,6 +146,8 @@ edges
138146
| call_sensitivity.rb:123:24:123:32 | call to taint : | call_sensitivity.rb:96:33:96:33 | y : |
139147
| call_sensitivity.rb:124:26:124:33 | call to taint : | call_sensitivity.rb:100:35:100:35 | x : |
140148
| call_sensitivity.rb:124:26:124:33 | call to taint : | call_sensitivity.rb:100:35:100:35 | x : |
149+
| call_sensitivity.rb:125:12:125:19 | call to taint : | call_sensitivity.rb:109:21:109:21 | x : |
150+
| call_sensitivity.rb:125:12:125:19 | call to taint : | call_sensitivity.rb:109:21:109:21 | x : |
141151
| call_sensitivity.rb:166:14:166:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
142152
| call_sensitivity.rb:166:14:166:22 | call to taint : | call_sensitivity.rb:74:18:74:18 | y : |
143153
| call_sensitivity.rb:174:19:174:19 | x : | call_sensitivity.rb:175:12:175:12 | x : |
@@ -271,12 +281,20 @@ nodes
271281
| call_sensitivity.rb:104:18:104:18 | x : | semmle.label | x : |
272282
| call_sensitivity.rb:104:18:104:18 | x : | semmle.label | x : |
273283
| call_sensitivity.rb:104:18:104:18 | x : | semmle.label | x : |
284+
| call_sensitivity.rb:104:18:104:18 | x : | semmle.label | x : |
285+
| call_sensitivity.rb:104:18:104:18 | x : | semmle.label | x : |
274286
| call_sensitivity.rb:105:10:105:10 | x | semmle.label | x |
275287
| call_sensitivity.rb:105:10:105:10 | x | semmle.label | x |
276288
| call_sensitivity.rb:106:13:106:13 | x : | semmle.label | x : |
277289
| call_sensitivity.rb:106:13:106:13 | x : | semmle.label | x : |
278290
| call_sensitivity.rb:106:13:106:13 | x : | semmle.label | x : |
279291
| call_sensitivity.rb:106:13:106:13 | x : | semmle.label | x : |
292+
| call_sensitivity.rb:106:13:106:13 | x : | semmle.label | x : |
293+
| call_sensitivity.rb:106:13:106:13 | x : | semmle.label | x : |
294+
| call_sensitivity.rb:109:21:109:21 | x : | semmle.label | x : |
295+
| call_sensitivity.rb:109:21:109:21 | x : | semmle.label | x : |
296+
| call_sensitivity.rb:110:9:110:9 | x : | semmle.label | x : |
297+
| call_sensitivity.rb:110:9:110:9 | x : | semmle.label | x : |
280298
| call_sensitivity.rb:114:11:114:20 | ( ... ) : | semmle.label | ( ... ) : |
281299
| call_sensitivity.rb:114:11:114:20 | ( ... ) : | semmle.label | ( ... ) : |
282300
| call_sensitivity.rb:114:12:114:19 | call to taint : | semmle.label | call to taint : |
@@ -299,6 +317,8 @@ nodes
299317
| call_sensitivity.rb:123:24:123:32 | call to taint : | semmle.label | call to taint : |
300318
| call_sensitivity.rb:124:26:124:33 | call to taint : | semmle.label | call to taint : |
301319
| call_sensitivity.rb:124:26:124:33 | call to taint : | semmle.label | call to taint : |
320+
| call_sensitivity.rb:125:12:125:19 | call to taint : | semmle.label | call to taint : |
321+
| call_sensitivity.rb:125:12:125:19 | call to taint : | semmle.label | call to taint : |
302322
| call_sensitivity.rb:166:14:166:22 | call to taint : | semmle.label | call to taint : |
303323
| call_sensitivity.rb:166:14:166:22 | call to taint : | semmle.label | call to taint : |
304324
| call_sensitivity.rb:174:19:174:19 | x : | semmle.label | x : |
@@ -325,13 +345,15 @@ subpaths
325345
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:117:14:117:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:117:14:117:22 | call to taint : | call to taint : |
326346
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:118:16:118:24 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:118:16:118:24 | call to taint : | call to taint : |
327347
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:119:14:119:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:119:14:119:22 | call to taint : | call to taint : |
348+
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:125:12:125:19 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:125:12:125:19 | call to taint : | call to taint : |
328349
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:166:14:166:22 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:166:14:166:22 | call to taint : | call to taint : |
329350
| call_sensitivity.rb:51:10:51:10 | x | call_sensitivity.rb:178:11:178:19 | call to taint : | call_sensitivity.rb:51:10:51:10 | x | $@ | call_sensitivity.rb:178:11:178:19 | call to taint : | call to taint : |
330351
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:121:21:121:28 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:121:21:121:28 | call to taint : | call to taint : |
331352
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:122:26:122:33 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:122:26:122:33 | call to taint : | call to taint : |
332353
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:123:24:123:32 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:123:24:123:32 | call to taint : | call to taint : |
333354
| call_sensitivity.rb:71:10:71:10 | x | call_sensitivity.rb:124:26:124:33 | call to taint : | call_sensitivity.rb:71:10:71:10 | x | $@ | call_sensitivity.rb:124:26:124:33 | call to taint : | call to taint : |
334355
| call_sensitivity.rb:105:10:105:10 | x | call_sensitivity.rb:114:12:114:19 | call to taint : | call_sensitivity.rb:105:10:105:10 | x | $@ | call_sensitivity.rb:114:12:114:19 | call to taint : | call to taint : |
356+
| call_sensitivity.rb:105:10:105:10 | x | call_sensitivity.rb:125:12:125:19 | call to taint : | call_sensitivity.rb:105:10:105:10 | x | $@ | call_sensitivity.rb:125:12:125:19 | call to taint : | call to taint : |
335357
| call_sensitivity.rb:105:10:105:10 | x | call_sensitivity.rb:178:11:178:19 | call to taint : | call_sensitivity.rb:105:10:105:10 | x | $@ | call_sensitivity.rb:178:11:178:19 | call to taint : | call to taint : |
336358
| call_sensitivity.rb:105:10:105:10 | x | call_sensitivity.rb:187:12:187:19 | call to taint : | call_sensitivity.rb:105:10:105:10 | x | $@ | call_sensitivity.rb:187:12:187:19 | call to taint : | call to taint : |
337359
mayBenefitFromCallContext
@@ -389,13 +411,19 @@ viableImplInCallContext
389411
| call_sensitivity.rb:97:5:97:26 | call to singleton_method1 | call_sensitivity.rb:153:5:153:35 | call to singleton_method3 | call_sensitivity.rb:132:3:134:5 | singleton_method1 |
390412
| call_sensitivity.rb:97:5:97:26 | call to singleton_method1 | call_sensitivity.rb:170:1:170:33 | call to singleton_method3 | call_sensitivity.rb:132:3:134:5 | singleton_method1 |
391413
| call_sensitivity.rb:101:5:101:35 | call to singleton_method3 | call_sensitivity.rb:124:1:124:34 | call to call_singleton_method3 | call_sensitivity.rb:96:3:98:5 | singleton_method3 |
414+
| call_sensitivity.rb:105:5:105:10 | call to sink | call_sensitivity.rb:110:5:110:9 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
392415
| call_sensitivity.rb:105:5:105:10 | call to sink | call_sensitivity.rb:114:5:114:20 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
393416
| call_sensitivity.rb:105:5:105:10 | call to sink | call_sensitivity.rb:175:3:175:12 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
394417
| call_sensitivity.rb:105:5:105:10 | call to sink | call_sensitivity.rb:187:5:187:20 | call to new | call_sensitivity.rb:5:1:7:3 | sink |
418+
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:110:5:110:9 | call to new | call_sensitivity.rb:50:3:52:5 | method1 |
419+
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:110:5:110:9 | call to new | call_sensitivity.rb:128:3:130:5 | method1 |
420+
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:110:5:110:9 | call to new | call_sensitivity.rb:182:3:184:5 | method1 |
395421
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:114:5:114:20 | call to new | call_sensitivity.rb:50:3:52:5 | method1 |
396422
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:175:3:175:12 | call to new | call_sensitivity.rb:50:3:52:5 | method1 |
397423
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:175:3:175:12 | call to new | call_sensitivity.rb:128:3:130:5 | method1 |
398424
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:187:5:187:20 | call to new | call_sensitivity.rb:182:3:184:5 | method1 |
425+
| call_sensitivity.rb:110:5:110:9 | call to new | call_sensitivity.rb:125:1:125:20 | call to call_new | call_sensitivity.rb:104:3:107:5 | initialize |
426+
| call_sensitivity.rb:110:5:110:9 | call to new | call_sensitivity.rb:172:1:172:20 | call to call_new | call_sensitivity.rb:156:3:158:5 | initialize |
399427
| call_sensitivity.rb:137:5:137:18 | call to method2 | call_sensitivity.rb:163:1:163:24 | call to call_method2 | call_sensitivity.rb:54:3:56:5 | method2 |
400428
| call_sensitivity.rb:141:5:141:25 | call to method3 | call_sensitivity.rb:165:1:165:25 | call to call_method3 | call_sensitivity.rb:62:3:64:5 | method3 |
401429
| call_sensitivity.rb:149:5:149:28 | call to singleton_method2 | call_sensitivity.rb:169:1:169:34 | call to call_singleton_method2 | call_sensitivity.rb:88:3:90:5 | singleton_method2 |

0 commit comments

Comments
 (0)