Skip to content

Commit f07ae35

Browse files
committed
Ruby: Fix bug with String flow summaries
Split summaries for methods with optional block parmaters into separate classes. Also model the `exclusive` argument to `String#upto`.
1 parent 379de55 commit f07ae35

File tree

3 files changed

+152
-73
lines changed

3 files changed

+152
-73
lines changed

ruby/ql/lib/codeql/ruby/frameworks/core/String.qll

Lines changed: 104 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -224,26 +224,40 @@ module String {
224224

225225
/**
226226
* A flow summary for `String#each_line` and `String#lines`.
227+
* This is split into two summaries below - one for when a block is passed and one for when no block is passed.
227228
*/
228-
private class EachLineSummary extends SummarizedCallable {
229+
abstract private class EachLineSummary extends SummarizedCallable {
229230
MethodCall mc;
230231

231-
EachLineSummary() { this = ["each_line", "lines"] and mc.getMethodName() = this }
232+
bindingset[this]
233+
EachLineSummary() { mc.getMethodName() = ["each_line", "lines"] }
232234

233235
override MethodCall getACall() { result = mc }
236+
}
234237

235-
predicate hasBlock() { exists(Block b | b = mc.getBlock()) }
238+
/**
239+
* A flow summary for `String#each_line` and `String#lines` when a block is passed.
240+
*/
241+
private class EachLineBlockSummary extends EachLineSummary {
242+
EachLineBlockSummary() { this = "each_line_with_block" and exists(mc.getBlock()) }
236243

237244
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
238245
preservesValue = false and
239246
input = "Receiver" and
240-
(
241-
output = "Parameter[0] of BlockArgument"
242-
or
243-
not this.hasBlock() and output = "ArrayElement[?] of ReturnValue"
244-
or
245-
this.hasBlock() and output = "ReturnValue"
246-
)
247+
output = ["Parameter[0] of BlockArgument", "ReturnValue"]
248+
}
249+
}
250+
251+
/**
252+
* A flow summary for `String#each_line` and `String#lines` when no block is passed.
253+
*/
254+
private class EachLineNoBlockSummary extends EachLineSummary {
255+
EachLineNoBlockSummary() { this = "each_line_without_block" and not exists(mc.getBlock()) }
256+
257+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
258+
preservesValue = false and
259+
input = "Receiver" and
260+
output = ["Parameter[0] of BlockArgument", "ArrayElement[?] of ReturnValue"]
247261
}
248262
}
249263

@@ -399,45 +413,61 @@ module String {
399413
/**
400414
* A flow summary for `String#scan`.
401415
*/
402-
private class ScanSummary extends SummarizedCallable {
403-
private MethodCall mc;
416+
abstract private class ScanSummary extends SummarizedCallable {
417+
MethodCall mc;
404418

405-
ScanSummary() { this = "scan" and mc.getMethodName() = this }
419+
bindingset[this]
420+
ScanSummary() { mc.getMethodName() = "scan" }
406421

407422
override MethodCall getACall() { result = mc }
423+
}
408424

409-
private predicate hasBlock() { exists(Block b | b = mc.getBlock()) }
425+
private class ScanBlockSummary extends ScanSummary {
426+
ScanBlockSummary() { this = "scan_with_block" and exists(mc.getBlock()) }
410427

411428
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
412429
input = "Receiver" and
413430
(
414-
// scan(pattern) {|match, ...| block } -> str
415-
not this.hasBlock() and
416-
output = "ArrayElement[?] of ReturnValue" and
417-
preservesValue = false
418-
or
419431
// Parameter[_] doesn't seem to work
420432
output = "Parameter[" + [0 .. 10] + "] of BlockArgument" and preservesValue = false
421433
or
422434
// scan(pattern) -> array
423-
this.hasBlock() and
424435
output = "ReturnValue" and
425436
preservesValue = true
426437
)
427438
}
428439
}
429440

441+
private class ScanNoBlockSummary extends ScanSummary {
442+
ScanNoBlockSummary() { this = "scan_no_block" and not exists(mc.getBlock()) }
443+
444+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
445+
input = "Receiver" and
446+
(
447+
// scan(pattern) {|match, ...| block } -> str
448+
output = "ArrayElement[?] of ReturnValue" and
449+
preservesValue = false
450+
or
451+
// Parameter[_] doesn't seem to work
452+
output = "Parameter[" + [0 .. 10] + "] of BlockArgument" and preservesValue = false
453+
)
454+
}
455+
}
456+
430457
/**
431458
* A flow summary for `String#scrub(!)`.
432459
*/
433-
private class ScrubSummary extends SummarizedCallable {
434-
private MethodCall mc;
460+
abstract private class ScrubSummary extends SummarizedCallable {
461+
MethodCall mc;
435462

436-
ScrubSummary() { this = ["scrub", "scrub!"] and mc.getMethodName() = this }
463+
bindingset[this]
464+
ScrubSummary() { mc.getMethodName() = ["scrub", "scrub!"] }
437465

438466
override MethodCall getACall() { result = mc }
467+
}
439468

440-
private predicate hasBlock() { exists(Block b | b = mc.getBlock()) }
469+
private class ScrubBlockSummary extends ScrubSummary {
470+
ScrubBlockSummary() { this = "scrub_block" and exists(mc.getBlock()) }
441471

442472
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
443473
input = "Receiver" and
@@ -446,7 +476,6 @@ module String {
446476
or
447477
input = "Argument[0]" and output = "ReturnValue" and preservesValue = true
448478
or
449-
this.hasBlock() and
450479
input = "ReturnValue of BlockArgument" and
451480
output = "ReturnValue" and
452481
preservesValue = true
@@ -455,6 +484,20 @@ module String {
455484
}
456485
}
457486

487+
private class ScrubNoBlockSummary extends ScrubSummary {
488+
ScrubNoBlockSummary() { this = "scrub_no_block" and not exists(mc.getBlock()) }
489+
490+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
491+
input = "Receiver" and
492+
output = "Parameter[0] of BlockArgument" and
493+
preservesValue = true
494+
or
495+
input = "Argument[0]" and output = "ReturnValue" and preservesValue = true
496+
or
497+
taintIdentityFlow(input, output, preservesValue)
498+
}
499+
}
500+
458501
// TODO: what do we do about `String#shellescape`?
459502
/**
460503
* A flow summary for `String#shellsplit`.
@@ -515,15 +558,27 @@ module String {
515558

516559
/**
517560
* A flow summary for `String#upto`.
561+
* ```
562+
* String#upto(stop, exclusive=false, &block)
563+
* ```
518564
*/
519-
private class UptoSummary extends SummarizedCallable {
520-
private MethodCall mc;
565+
abstract private class UptoSummary extends SummarizedCallable {
566+
MethodCall mc;
521567

522-
UptoSummary() { this = "upto" and mc.getMethodName() = this }
568+
bindingset[this]
569+
UptoSummary() { mc.getMethodName() = "upto" }
523570

524571
override MethodCall getACall() { result = mc }
572+
}
525573

526-
private predicate hasBlock() { exists(Block b | b = mc.getBlock()) }
574+
/**
575+
* A flow summary for `String#upto`, when `exclusive = false`.
576+
*/
577+
private class UptoInclusiveSummary extends UptoSummary {
578+
UptoInclusiveSummary() {
579+
this = "upto_inclusive" and
580+
(not exists(mc.getArgument(1)) or mc.getArgument(1).getConstantValue().isBoolean(false))
581+
}
527582

528583
// TODO: if second arg ('exclusive') is true, the first arg is excluded
529584
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
@@ -533,7 +588,26 @@ module String {
533588
output = "Parameter[0] of BlockArgument" and
534589
preservesValue = true
535590
or
536-
not this.hasBlock() and
591+
input = "ReturnValue of BlockArgument" and
592+
output = "ArrayElement[?] of ReturnValue" and
593+
preservesValue = true
594+
}
595+
}
596+
597+
/**
598+
* A flow summary for `String#upto`, when `exclusive = true`.
599+
*/
600+
private class UptoExclusiveSummary extends UptoSummary {
601+
UptoExclusiveSummary() {
602+
this = "upto_exclusive" and
603+
mc.getArgument(1).getConstantValue().isBoolean(true)
604+
}
605+
606+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
607+
input = ["Receiver"] and
608+
output = "Parameter[0] of BlockArgument" and
609+
preservesValue = true
610+
or
537611
input = "ReturnValue of BlockArgument" and
538612
output = "ArrayElement[?] of ReturnValue" and
539613
preservesValue = true

ruby/ql/test/library-tests/dataflow/string-flow/string-flow.expected

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -104,19 +104,19 @@ edges
104104
| string_flow.rb:131:9:131:9 | a : | string_flow.rb:131:24:131:27 | line : |
105105
| string_flow.rb:131:9:131:40 | call to each_line : | string_flow.rb:132:10:132:10 | b |
106106
| string_flow.rb:131:24:131:27 | line : | string_flow.rb:131:35:131:38 | line |
107-
| string_flow.rb:133:9:133:9 | a : | string_flow.rb:133:9:133:19 | call to each_line : |
108-
| string_flow.rb:133:9:133:19 | call to each_line : | string_flow.rb:134:10:134:10 | c : |
109-
| string_flow.rb:134:10:134:10 | c : | string_flow.rb:134:10:134:15 | call to to_a : |
110-
| string_flow.rb:134:10:134:15 | call to to_a : | string_flow.rb:134:10:134:18 | ...[...] |
107+
| string_flow.rb:133:9:133:9 | a : | string_flow.rb:133:9:133:19 | call to each_line [array element] : |
108+
| string_flow.rb:133:9:133:19 | call to each_line [array element] : | string_flow.rb:134:10:134:10 | c [array element] : |
109+
| string_flow.rb:134:10:134:10 | c [array element] : | string_flow.rb:134:10:134:15 | call to to_a [array element] : |
110+
| string_flow.rb:134:10:134:15 | call to to_a [array element] : | string_flow.rb:134:10:134:18 | ...[...] |
111111
| string_flow.rb:138:9:138:18 | call to source : | string_flow.rb:139:9:139:9 | a : |
112112
| string_flow.rb:138:9:138:18 | call to source : | string_flow.rb:141:9:141:9 | a : |
113113
| string_flow.rb:139:9:139:9 | a : | string_flow.rb:139:9:139:36 | call to lines : |
114114
| string_flow.rb:139:9:139:9 | a : | string_flow.rb:139:20:139:23 | line : |
115115
| string_flow.rb:139:9:139:36 | call to lines : | string_flow.rb:140:10:140:10 | b |
116116
| string_flow.rb:139:20:139:23 | line : | string_flow.rb:139:31:139:34 | line |
117-
| string_flow.rb:141:9:141:9 | a : | string_flow.rb:141:9:141:15 | call to lines : |
118-
| string_flow.rb:141:9:141:15 | call to lines : | string_flow.rb:142:10:142:10 | c : |
119-
| string_flow.rb:142:10:142:10 | c : | string_flow.rb:142:10:142:13 | ...[...] |
117+
| string_flow.rb:141:9:141:9 | a : | string_flow.rb:141:9:141:15 | call to lines [array element] : |
118+
| string_flow.rb:141:9:141:15 | call to lines [array element] : | string_flow.rb:142:10:142:10 | c [array element] : |
119+
| string_flow.rb:142:10:142:10 | c [array element] : | string_flow.rb:142:10:142:13 | ...[...] |
120120
| string_flow.rb:146:9:146:18 | call to source : | string_flow.rb:147:10:147:10 | a : |
121121
| string_flow.rb:146:9:146:18 | call to source : | string_flow.rb:148:10:148:10 | a : |
122122
| string_flow.rb:146:9:146:18 | call to source : | string_flow.rb:149:10:149:10 | a : |
@@ -233,11 +233,11 @@ edges
233233
| string_flow.rb:236:9:236:37 | call to scan : | string_flow.rb:237:10:237:10 | b |
234234
| string_flow.rb:236:9:236:37 | call to scan : | string_flow.rb:237:10:237:10 | b |
235235
| string_flow.rb:236:27:236:27 | y : | string_flow.rb:236:35:236:35 | y |
236-
| string_flow.rb:238:9:238:9 | a : | string_flow.rb:238:9:238:19 | call to scan : |
237-
| string_flow.rb:238:9:238:19 | call to scan : | string_flow.rb:239:10:239:10 | b : |
238-
| string_flow.rb:238:9:238:19 | call to scan : | string_flow.rb:240:10:240:10 | b : |
239-
| string_flow.rb:239:10:239:10 | b : | string_flow.rb:239:10:239:13 | ...[...] |
240-
| string_flow.rb:240:10:240:10 | b : | string_flow.rb:240:10:240:13 | ...[...] |
236+
| string_flow.rb:238:9:238:9 | a : | string_flow.rb:238:9:238:19 | call to scan [array element] : |
237+
| string_flow.rb:238:9:238:19 | call to scan [array element] : | string_flow.rb:239:10:239:10 | b [array element] : |
238+
| string_flow.rb:238:9:238:19 | call to scan [array element] : | string_flow.rb:240:10:240:10 | b [array element] : |
239+
| string_flow.rb:239:10:239:10 | b [array element] : | string_flow.rb:239:10:239:13 | ...[...] |
240+
| string_flow.rb:240:10:240:10 | b [array element] : | string_flow.rb:240:10:240:13 | ...[...] |
241241
| string_flow.rb:244:5:244:18 | ... = ... : | string_flow.rb:248:26:248:26 | a : |
242242
| string_flow.rb:244:5:244:18 | ... = ... : | string_flow.rb:248:26:248:26 | a : |
243243
| string_flow.rb:244:5:244:18 | ... = ... : | string_flow.rb:256:27:256:27 | a : |
@@ -351,20 +351,22 @@ edges
351351
| string_flow.rb:303:25:303:25 | a : | string_flow.rb:303:10:303:26 | call to tr_s! |
352352
| string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:308:5:308:5 | a : |
353353
| string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:308:5:308:5 | a : |
354-
| string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:309:14:309:14 | a : |
355-
| string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:309:14:309:14 | a : |
356-
| string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:310:9:310:9 | a : |
354+
| string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:309:5:309:5 | a : |
355+
| string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:309:5:309:5 | a : |
356+
| string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:310:14:310:14 | a : |
357+
| string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:310:14:310:14 | a : |
357358
| string_flow.rb:308:5:308:5 | a : | string_flow.rb:308:20:308:20 | x : |
358359
| string_flow.rb:308:5:308:5 | a : | string_flow.rb:308:20:308:20 | x : |
359360
| string_flow.rb:308:20:308:20 | x : | string_flow.rb:308:28:308:28 | x |
360361
| string_flow.rb:308:20:308:20 | x : | string_flow.rb:308:28:308:28 | x |
361-
| string_flow.rb:309:14:309:14 | a : | string_flow.rb:309:20:309:20 | x : |
362-
| string_flow.rb:309:14:309:14 | a : | string_flow.rb:309:20:309:20 | x : |
363-
| string_flow.rb:309:20:309:20 | x : | string_flow.rb:309:28:309:28 | x |
364-
| string_flow.rb:309:20:309:20 | x : | string_flow.rb:309:28:309:28 | x |
365-
| string_flow.rb:310:9:310:9 | a : | string_flow.rb:310:9:310:19 | call to upto : |
366-
| string_flow.rb:310:9:310:19 | call to upto : | string_flow.rb:311:10:311:10 | c : |
367-
| string_flow.rb:311:10:311:10 | c : | string_flow.rb:311:10:311:13 | ...[...] |
362+
| string_flow.rb:309:5:309:5 | a : | string_flow.rb:309:26:309:26 | x : |
363+
| string_flow.rb:309:5:309:5 | a : | string_flow.rb:309:26:309:26 | x : |
364+
| string_flow.rb:309:26:309:26 | x : | string_flow.rb:309:34:309:34 | x |
365+
| string_flow.rb:309:26:309:26 | x : | string_flow.rb:309:34:309:34 | x |
366+
| string_flow.rb:310:14:310:14 | a : | string_flow.rb:310:20:310:20 | x : |
367+
| string_flow.rb:310:14:310:14 | a : | string_flow.rb:310:20:310:20 | x : |
368+
| string_flow.rb:310:20:310:20 | x : | string_flow.rb:310:28:310:28 | x |
369+
| string_flow.rb:310:20:310:20 | x : | string_flow.rb:310:28:310:28 | x |
368370
nodes
369371
| string_flow.rb:2:9:2:18 | call to source : | semmle.label | call to source : |
370372
| string_flow.rb:2:9:2:18 | call to source : | semmle.label | call to source : |
@@ -489,9 +491,9 @@ nodes
489491
| string_flow.rb:131:35:131:38 | line | semmle.label | line |
490492
| string_flow.rb:132:10:132:10 | b | semmle.label | b |
491493
| string_flow.rb:133:9:133:9 | a : | semmle.label | a : |
492-
| string_flow.rb:133:9:133:19 | call to each_line : | semmle.label | call to each_line : |
493-
| string_flow.rb:134:10:134:10 | c : | semmle.label | c : |
494-
| string_flow.rb:134:10:134:15 | call to to_a : | semmle.label | call to to_a : |
494+
| string_flow.rb:133:9:133:19 | call to each_line [array element] : | semmle.label | call to each_line [array element] : |
495+
| string_flow.rb:134:10:134:10 | c [array element] : | semmle.label | c [array element] : |
496+
| string_flow.rb:134:10:134:15 | call to to_a [array element] : | semmle.label | call to to_a [array element] : |
495497
| string_flow.rb:134:10:134:18 | ...[...] | semmle.label | ...[...] |
496498
| string_flow.rb:138:9:138:18 | call to source : | semmle.label | call to source : |
497499
| string_flow.rb:139:9:139:9 | a : | semmle.label | a : |
@@ -500,8 +502,8 @@ nodes
500502
| string_flow.rb:139:31:139:34 | line | semmle.label | line |
501503
| string_flow.rb:140:10:140:10 | b | semmle.label | b |
502504
| string_flow.rb:141:9:141:9 | a : | semmle.label | a : |
503-
| string_flow.rb:141:9:141:15 | call to lines : | semmle.label | call to lines : |
504-
| string_flow.rb:142:10:142:10 | c : | semmle.label | c : |
505+
| string_flow.rb:141:9:141:15 | call to lines [array element] : | semmle.label | call to lines [array element] : |
506+
| string_flow.rb:142:10:142:10 | c [array element] : | semmle.label | c [array element] : |
505507
| string_flow.rb:142:10:142:13 | ...[...] | semmle.label | ...[...] |
506508
| string_flow.rb:146:9:146:18 | call to source : | semmle.label | call to source : |
507509
| string_flow.rb:147:10:147:10 | a : | semmle.label | a : |
@@ -637,10 +639,10 @@ nodes
637639
| string_flow.rb:237:10:237:10 | b | semmle.label | b |
638640
| string_flow.rb:237:10:237:10 | b | semmle.label | b |
639641
| string_flow.rb:238:9:238:9 | a : | semmle.label | a : |
640-
| string_flow.rb:238:9:238:19 | call to scan : | semmle.label | call to scan : |
641-
| string_flow.rb:239:10:239:10 | b : | semmle.label | b : |
642+
| string_flow.rb:238:9:238:19 | call to scan [array element] : | semmle.label | call to scan [array element] : |
643+
| string_flow.rb:239:10:239:10 | b [array element] : | semmle.label | b [array element] : |
642644
| string_flow.rb:239:10:239:13 | ...[...] | semmle.label | ...[...] |
643-
| string_flow.rb:240:10:240:10 | b : | semmle.label | b : |
645+
| string_flow.rb:240:10:240:10 | b [array element] : | semmle.label | b [array element] : |
644646
| string_flow.rb:240:10:240:13 | ...[...] | semmle.label | ...[...] |
645647
| string_flow.rb:244:5:244:18 | ... = ... : | semmle.label | ... = ... : |
646648
| string_flow.rb:244:5:244:18 | ... = ... : | semmle.label | ... = ... : |
@@ -761,16 +763,18 @@ nodes
761763
| string_flow.rb:308:20:308:20 | x : | semmle.label | x : |
762764
| string_flow.rb:308:28:308:28 | x | semmle.label | x |
763765
| string_flow.rb:308:28:308:28 | x | semmle.label | x |
764-
| string_flow.rb:309:14:309:14 | a : | semmle.label | a : |
765-
| string_flow.rb:309:14:309:14 | a : | semmle.label | a : |
766-
| string_flow.rb:309:20:309:20 | x : | semmle.label | x : |
767-
| string_flow.rb:309:20:309:20 | x : | semmle.label | x : |
768-
| string_flow.rb:309:28:309:28 | x | semmle.label | x |
769-
| string_flow.rb:309:28:309:28 | x | semmle.label | x |
770-
| string_flow.rb:310:9:310:9 | a : | semmle.label | a : |
771-
| string_flow.rb:310:9:310:19 | call to upto : | semmle.label | call to upto : |
772-
| string_flow.rb:311:10:311:10 | c : | semmle.label | c : |
773-
| string_flow.rb:311:10:311:13 | ...[...] | semmle.label | ...[...] |
766+
| string_flow.rb:309:5:309:5 | a : | semmle.label | a : |
767+
| string_flow.rb:309:5:309:5 | a : | semmle.label | a : |
768+
| string_flow.rb:309:26:309:26 | x : | semmle.label | x : |
769+
| string_flow.rb:309:26:309:26 | x : | semmle.label | x : |
770+
| string_flow.rb:309:34:309:34 | x | semmle.label | x |
771+
| string_flow.rb:309:34:309:34 | x | semmle.label | x |
772+
| string_flow.rb:310:14:310:14 | a : | semmle.label | a : |
773+
| string_flow.rb:310:14:310:14 | a : | semmle.label | a : |
774+
| string_flow.rb:310:20:310:20 | x : | semmle.label | x : |
775+
| string_flow.rb:310:20:310:20 | x : | semmle.label | x : |
776+
| string_flow.rb:310:28:310:28 | x | semmle.label | x |
777+
| string_flow.rb:310:28:310:28 | x | semmle.label | x |
774778
subpaths
775779
#select
776780
| string_flow.rb:3:10:3:22 | call to new | string_flow.rb:2:9:2:18 | call to source : | string_flow.rb:3:10:3:22 | call to new | $@ | string_flow.rb:2:9:2:18 | call to source : | call to source : |
@@ -809,4 +813,5 @@ subpaths
809813
| string_flow.rb:290:10:290:17 | call to to_str | string_flow.rb:289:9:289:18 | call to source : | string_flow.rb:290:10:290:17 | call to to_str | $@ | string_flow.rb:289:9:289:18 | call to source : | call to source : |
810814
| string_flow.rb:291:10:291:15 | call to to_s | string_flow.rb:289:9:289:18 | call to source : | string_flow.rb:291:10:291:15 | call to to_s | $@ | string_flow.rb:289:9:289:18 | call to source : | call to source : |
811815
| string_flow.rb:308:28:308:28 | x | string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:308:28:308:28 | x | $@ | string_flow.rb:307:9:307:18 | call to source : | call to source : |
812-
| string_flow.rb:309:28:309:28 | x | string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:309:28:309:28 | x | $@ | string_flow.rb:307:9:307:18 | call to source : | call to source : |
816+
| string_flow.rb:309:34:309:34 | x | string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:309:34:309:34 | x | $@ | string_flow.rb:307:9:307:18 | call to source : | call to source : |
817+
| string_flow.rb:310:28:310:28 | x | string_flow.rb:307:9:307:18 | call to source : | string_flow.rb:310:28:310:28 | x | $@ | string_flow.rb:307:9:307:18 | call to source : | call to source : |

ruby/ql/test/library-tests/dataflow/string-flow/string_flow.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ def m_tr
306306
def m_upto(i)
307307
a = source "a"
308308
a.upto("b") { |x| sink x } # $ hasValueFlow=a
309+
a.upto("b", true) { |x| sink x } # $ hasValueFlow=a
309310
"b".upto(a) { |x| sink x } # $ hasValueFlow=a
310-
c = a.upto("b")
311-
sink c[i] # $ hasTaintFlow=a
311+
"b".upto(a, true) { |x| sink x }
312312
end

0 commit comments

Comments
 (0)