Skip to content

Commit fc351fb

Browse files
committed
Ruby: Remove value-flow for name-matched summaries
String summaries that are identified by name only should not specify value-preserving flow as this can cause spurious flow in cases where they are applied to different but identically-named methods.
1 parent 0736991 commit fc351fb

File tree

3 files changed

+18
-80
lines changed

3 files changed

+18
-80
lines changed

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

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,6 @@ private import codeql.ruby.dataflow.internal.DataFlowDispatch
1313
* https://docs.ruby-lang.org/en/3.1/String.html.
1414
*/
1515
module String {
16-
/**
17-
* Value-preserving flow from the receiver to the return value.
18-
*/
19-
private predicate valueIdentityFlow(string input, string output, boolean preservesValue) {
20-
input = "Receiver" and
21-
output = "ReturnValue" and
22-
preservesValue = true
23-
}
24-
2516
/**
2617
* Taint-preserving (but not value-preserving) flow from the receiver to the return value.
2718
*/
@@ -89,7 +80,7 @@ module String {
8980
override MethodCall getACall() { result = mc }
9081

9182
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
92-
valueIdentityFlow(input, output, preservesValue)
83+
taintIdentityFlow(input, output, preservesValue)
9384
}
9485
}
9586

@@ -280,7 +271,7 @@ module String {
280271
FreezeSummary() { this = "freeze" }
281272

282273
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
283-
valueIdentityFlow(input, output, preservesValue)
274+
taintIdentityFlow(input, output, preservesValue)
284275
}
285276
}
286277

@@ -375,7 +366,7 @@ module String {
375366
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
376367
input = "Argument[0]" and
377368
output = ["ReturnValue", "Receiver"] and
378-
preservesValue = true
369+
preservesValue = false
379370
}
380371
// TODO: we should also clear any existing content in Receiver
381372
}
@@ -527,7 +518,7 @@ module String {
527518
ToStrSummary() { this = ["to_str", "to_s"] }
528519

529520
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
530-
valueIdentityFlow(input, output, preservesValue)
521+
taintIdentityFlow(input, output, preservesValue)
531522
}
532523
}
533524

@@ -570,15 +561,15 @@ module String {
570561

571562
// TODO: if second arg ('exclusive') is true, the first arg is excluded
572563
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
573-
valueIdentityFlow(input, output, preservesValue)
564+
taintIdentityFlow(input, output, preservesValue)
574565
or
575566
input = ["Receiver", "Argument[0]"] and
576567
output = "BlockArgument.Parameter[0]" and
577-
preservesValue = true
568+
preservesValue = false
578569
or
579570
input = "BlockArgument.ReturnValue" and
580571
output = "ReturnValue.ArrayElement[?]" and
581-
preservesValue = true
572+
preservesValue = false
582573
}
583574
}
584575

@@ -594,11 +585,11 @@ module String {
594585
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
595586
input = "Receiver" and
596587
output = "BlockArgument.Parameter[0]" and
597-
preservesValue = true
588+
preservesValue = false
598589
or
599590
input = "BlockArgument.ReturnValue" and
600591
output = "ReturnValue.ArrayElement[?]" and
601-
preservesValue = true
592+
preservesValue = false
602593
}
603594
}
604595
}

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

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ edges
2323
| string_flow.rb:31:9:31:18 | call to source : | string_flow.rb:33:10:33:10 | b |
2424
| string_flow.rb:31:9:31:18 | call to source : | string_flow.rb:35:10:35:10 | c |
2525
| string_flow.rb:39:9:39:18 | call to source : | string_flow.rb:40:10:40:10 | a : |
26-
| string_flow.rb:39:9:39:18 | call to source : | string_flow.rb:40:10:40:10 | a : |
27-
| string_flow.rb:40:10:40:10 | a : | string_flow.rb:40:10:40:12 | call to b |
2826
| string_flow.rb:40:10:40:10 | a : | string_flow.rb:40:10:40:12 | call to b |
2927
| string_flow.rb:44:9:44:18 | call to source : | string_flow.rb:45:10:45:10 | a : |
3028
| string_flow.rb:44:9:44:18 | call to source : | string_flow.rb:46:10:46:10 | a : |
@@ -116,8 +114,6 @@ edges
116114
| string_flow.rb:154:9:154:18 | call to source : | string_flow.rb:155:10:155:10 | a : |
117115
| string_flow.rb:155:10:155:10 | a : | string_flow.rb:155:10:155:34 | call to force_encoding |
118116
| string_flow.rb:159:9:159:18 | call to source : | string_flow.rb:160:10:160:10 | a : |
119-
| string_flow.rb:159:9:159:18 | call to source : | string_flow.rb:160:10:160:10 | a : |
120-
| string_flow.rb:160:10:160:10 | a : | string_flow.rb:160:10:160:17 | call to freeze |
121117
| string_flow.rb:160:10:160:10 | a : | string_flow.rb:160:10:160:17 | call to freeze |
122118
| string_flow.rb:164:9:164:18 | call to source : | string_flow.rb:166:10:166:10 | a : |
123119
| string_flow.rb:164:9:164:18 | call to source : | string_flow.rb:167:10:167:10 | a : |
@@ -182,14 +178,11 @@ edges
182178
| string_flow.rb:221:9:221:18 | call to source : | string_flow.rb:223:10:223:10 | a : |
183179
| string_flow.rb:221:9:221:18 | call to source : | string_flow.rb:223:10:223:10 | a : |
184180
| string_flow.rb:222:9:222:18 | call to source : | string_flow.rb:223:20:223:20 | b : |
185-
| string_flow.rb:222:9:222:18 | call to source : | string_flow.rb:223:20:223:20 | b : |
186181
| string_flow.rb:223:10:223:10 | [post] a : | string_flow.rb:225:10:225:10 | a |
187182
| string_flow.rb:223:10:223:10 | [post] a : | string_flow.rb:225:10:225:10 | a |
188183
| string_flow.rb:223:10:223:10 | a : | string_flow.rb:223:10:223:10 | [post] a : |
189184
| string_flow.rb:223:10:223:10 | a : | string_flow.rb:223:10:223:10 | [post] a : |
190185
| string_flow.rb:223:20:223:20 | b : | string_flow.rb:223:10:223:10 | [post] a : |
191-
| string_flow.rb:223:20:223:20 | b : | string_flow.rb:223:10:223:10 | [post] a : |
192-
| string_flow.rb:223:20:223:20 | b : | string_flow.rb:223:10:223:21 | call to replace |
193186
| string_flow.rb:223:20:223:20 | b : | string_flow.rb:223:10:223:21 | call to replace |
194187
| string_flow.rb:229:9:229:18 | call to source : | string_flow.rb:230:10:230:10 | a : |
195188
| string_flow.rb:230:10:230:10 | a : | string_flow.rb:230:10:230:18 | call to reverse |
@@ -279,12 +272,8 @@ edges
279272
| string_flow.rb:289:10:289:10 | a : | string_flow.rb:289:10:289:19 | call to squeeze! |
280273
| string_flow.rb:290:10:290:10 | a : | string_flow.rb:290:10:290:24 | call to squeeze! |
281274
| string_flow.rb:294:9:294:18 | call to source : | string_flow.rb:295:10:295:10 | a : |
282-
| string_flow.rb:294:9:294:18 | call to source : | string_flow.rb:295:10:295:10 | a : |
283-
| string_flow.rb:294:9:294:18 | call to source : | string_flow.rb:296:10:296:10 | a : |
284275
| string_flow.rb:294:9:294:18 | call to source : | string_flow.rb:296:10:296:10 | a : |
285276
| string_flow.rb:295:10:295:10 | a : | string_flow.rb:295:10:295:17 | call to to_str |
286-
| string_flow.rb:295:10:295:10 | a : | string_flow.rb:295:10:295:17 | call to to_str |
287-
| string_flow.rb:296:10:296:10 | a : | string_flow.rb:296:10:296:15 | call to to_s |
288277
| string_flow.rb:296:10:296:10 | a : | string_flow.rb:296:10:296:15 | call to to_s |
289278
| string_flow.rb:300:9:300:18 | call to source : | string_flow.rb:301:10:301:10 | a : |
290279
| string_flow.rb:300:9:300:18 | call to source : | string_flow.rb:302:22:302:22 | a : |
@@ -303,23 +292,14 @@ edges
303292
| string_flow.rb:307:10:307:10 | a : | string_flow.rb:307:10:307:26 | call to tr_s! |
304293
| string_flow.rb:308:25:308:25 | a : | string_flow.rb:308:10:308:26 | call to tr_s! |
305294
| string_flow.rb:312:9:312:18 | call to source : | string_flow.rb:313:5:313:5 | a : |
306-
| string_flow.rb:312:9:312:18 | call to source : | string_flow.rb:313:5:313:5 | a : |
307-
| string_flow.rb:312:9:312:18 | call to source : | string_flow.rb:314:5:314:5 | a : |
308295
| string_flow.rb:312:9:312:18 | call to source : | string_flow.rb:314:5:314:5 | a : |
309296
| string_flow.rb:312:9:312:18 | call to source : | string_flow.rb:315:14:315:14 | a : |
310-
| string_flow.rb:312:9:312:18 | call to source : | string_flow.rb:315:14:315:14 | a : |
311297
| string_flow.rb:313:5:313:5 | a : | string_flow.rb:313:20:313:20 | x : |
312-
| string_flow.rb:313:5:313:5 | a : | string_flow.rb:313:20:313:20 | x : |
313-
| string_flow.rb:313:20:313:20 | x : | string_flow.rb:313:28:313:28 | x |
314298
| string_flow.rb:313:20:313:20 | x : | string_flow.rb:313:28:313:28 | x |
315299
| string_flow.rb:314:5:314:5 | a : | string_flow.rb:314:26:314:26 | x : |
316-
| string_flow.rb:314:5:314:5 | a : | string_flow.rb:314:26:314:26 | x : |
317300
| string_flow.rb:314:26:314:26 | x : | string_flow.rb:314:34:314:34 | x |
318-
| string_flow.rb:314:26:314:26 | x : | string_flow.rb:314:34:314:34 | x |
319-
| string_flow.rb:315:14:315:14 | a : | string_flow.rb:315:20:315:20 | x : |
320301
| string_flow.rb:315:14:315:14 | a : | string_flow.rb:315:20:315:20 | x : |
321302
| string_flow.rb:315:20:315:20 | x : | string_flow.rb:315:28:315:28 | x |
322-
| string_flow.rb:315:20:315:20 | x : | string_flow.rb:315:28:315:28 | x |
323303
nodes
324304
| string_flow.rb:2:9:2:18 | call to source : | semmle.label | call to source : |
325305
| string_flow.rb:2:9:2:18 | call to source : | semmle.label | call to source : |
@@ -348,11 +328,8 @@ nodes
348328
| string_flow.rb:33:10:33:10 | b | semmle.label | b |
349329
| string_flow.rb:35:10:35:10 | c | semmle.label | c |
350330
| string_flow.rb:39:9:39:18 | call to source : | semmle.label | call to source : |
351-
| string_flow.rb:39:9:39:18 | call to source : | semmle.label | call to source : |
352-
| string_flow.rb:40:10:40:10 | a : | semmle.label | a : |
353331
| string_flow.rb:40:10:40:10 | a : | semmle.label | a : |
354332
| string_flow.rb:40:10:40:12 | call to b | semmle.label | call to b |
355-
| string_flow.rb:40:10:40:12 | call to b | semmle.label | call to b |
356333
| string_flow.rb:44:9:44:18 | call to source : | semmle.label | call to source : |
357334
| string_flow.rb:45:10:45:10 | a : | semmle.label | a : |
358335
| string_flow.rb:45:10:45:23 | call to byteslice | semmle.label | call to byteslice |
@@ -457,11 +434,8 @@ nodes
457434
| string_flow.rb:155:10:155:10 | a : | semmle.label | a : |
458435
| string_flow.rb:155:10:155:34 | call to force_encoding | semmle.label | call to force_encoding |
459436
| string_flow.rb:159:9:159:18 | call to source : | semmle.label | call to source : |
460-
| string_flow.rb:159:9:159:18 | call to source : | semmle.label | call to source : |
461-
| string_flow.rb:160:10:160:10 | a : | semmle.label | a : |
462437
| string_flow.rb:160:10:160:10 | a : | semmle.label | a : |
463438
| string_flow.rb:160:10:160:17 | call to freeze | semmle.label | call to freeze |
464-
| string_flow.rb:160:10:160:17 | call to freeze | semmle.label | call to freeze |
465439
| string_flow.rb:164:9:164:18 | call to source : | semmle.label | call to source : |
466440
| string_flow.rb:165:9:165:18 | call to source : | semmle.label | call to source : |
467441
| string_flow.rb:166:10:166:10 | a : | semmle.label | a : |
@@ -529,14 +503,11 @@ nodes
529503
| string_flow.rb:221:9:221:18 | call to source : | semmle.label | call to source : |
530504
| string_flow.rb:221:9:221:18 | call to source : | semmle.label | call to source : |
531505
| string_flow.rb:222:9:222:18 | call to source : | semmle.label | call to source : |
532-
| string_flow.rb:222:9:222:18 | call to source : | semmle.label | call to source : |
533506
| string_flow.rb:223:10:223:10 | [post] a : | semmle.label | [post] a : |
534507
| string_flow.rb:223:10:223:10 | [post] a : | semmle.label | [post] a : |
535508
| string_flow.rb:223:10:223:10 | a : | semmle.label | a : |
536509
| string_flow.rb:223:10:223:10 | a : | semmle.label | a : |
537510
| string_flow.rb:223:10:223:21 | call to replace | semmle.label | call to replace |
538-
| string_flow.rb:223:10:223:21 | call to replace | semmle.label | call to replace |
539-
| string_flow.rb:223:20:223:20 | b : | semmle.label | b : |
540511
| string_flow.rb:223:20:223:20 | b : | semmle.label | b : |
541512
| string_flow.rb:225:10:225:10 | a | semmle.label | a |
542513
| string_flow.rb:225:10:225:10 | a | semmle.label | a |
@@ -628,15 +599,10 @@ nodes
628599
| string_flow.rb:290:10:290:10 | a : | semmle.label | a : |
629600
| string_flow.rb:290:10:290:24 | call to squeeze! | semmle.label | call to squeeze! |
630601
| string_flow.rb:294:9:294:18 | call to source : | semmle.label | call to source : |
631-
| string_flow.rb:294:9:294:18 | call to source : | semmle.label | call to source : |
632-
| string_flow.rb:295:10:295:10 | a : | semmle.label | a : |
633602
| string_flow.rb:295:10:295:10 | a : | semmle.label | a : |
634603
| string_flow.rb:295:10:295:17 | call to to_str | semmle.label | call to to_str |
635-
| string_flow.rb:295:10:295:17 | call to to_str | semmle.label | call to to_str |
636-
| string_flow.rb:296:10:296:10 | a : | semmle.label | a : |
637604
| string_flow.rb:296:10:296:10 | a : | semmle.label | a : |
638605
| string_flow.rb:296:10:296:15 | call to to_s | semmle.label | call to to_s |
639-
| string_flow.rb:296:10:296:15 | call to to_s | semmle.label | call to to_s |
640606
| string_flow.rb:300:9:300:18 | call to source : | semmle.label | call to source : |
641607
| string_flow.rb:301:10:301:10 | a : | semmle.label | a : |
642608
| string_flow.rb:301:10:301:23 | call to tr | semmle.label | call to tr |
@@ -655,37 +621,18 @@ nodes
655621
| string_flow.rb:308:10:308:26 | call to tr_s! | semmle.label | call to tr_s! |
656622
| string_flow.rb:308:25:308:25 | a : | semmle.label | a : |
657623
| string_flow.rb:312:9:312:18 | call to source : | semmle.label | call to source : |
658-
| string_flow.rb:312:9:312:18 | call to source : | semmle.label | call to source : |
659-
| string_flow.rb:313:5:313:5 | a : | semmle.label | a : |
660624
| string_flow.rb:313:5:313:5 | a : | semmle.label | a : |
661625
| string_flow.rb:313:20:313:20 | x : | semmle.label | x : |
662-
| string_flow.rb:313:20:313:20 | x : | semmle.label | x : |
663-
| string_flow.rb:313:28:313:28 | x | semmle.label | x |
664626
| string_flow.rb:313:28:313:28 | x | semmle.label | x |
665627
| string_flow.rb:314:5:314:5 | a : | semmle.label | a : |
666-
| string_flow.rb:314:5:314:5 | a : | semmle.label | a : |
667628
| string_flow.rb:314:26:314:26 | x : | semmle.label | x : |
668-
| string_flow.rb:314:26:314:26 | x : | semmle.label | x : |
669-
| string_flow.rb:314:34:314:34 | x | semmle.label | x |
670629
| string_flow.rb:314:34:314:34 | x | semmle.label | x |
671630
| string_flow.rb:315:14:315:14 | a : | semmle.label | a : |
672-
| string_flow.rb:315:14:315:14 | a : | semmle.label | a : |
673631
| string_flow.rb:315:20:315:20 | x : | semmle.label | x : |
674-
| string_flow.rb:315:20:315:20 | x : | semmle.label | x : |
675-
| string_flow.rb:315:28:315:28 | x | semmle.label | x |
676632
| string_flow.rb:315:28:315:28 | x | semmle.label | x |
677633
subpaths
678634
#select
679635
| 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 : |
680636
| string_flow.rb:8:10:8:30 | call to try_convert | string_flow.rb:7:9:7:18 | call to source : | string_flow.rb:8:10:8:30 | call to try_convert | $@ | string_flow.rb:7:9:7:18 | call to source : | call to source : |
681-
| string_flow.rb:40:10:40:12 | call to b | string_flow.rb:39:9:39:18 | call to source : | string_flow.rb:40:10:40:12 | call to b | $@ | string_flow.rb:39:9:39:18 | call to source : | call to source : |
682637
| string_flow.rb:83:10:83:10 | a | string_flow.rb:81:9:81:18 | call to source : | string_flow.rb:83:10:83:10 | a | $@ | string_flow.rb:81:9:81:18 | call to source : | call to source : |
683-
| string_flow.rb:160:10:160:17 | call to freeze | string_flow.rb:159:9:159:18 | call to source : | string_flow.rb:160:10:160:17 | call to freeze | $@ | string_flow.rb:159:9:159:18 | call to source : | call to source : |
684-
| string_flow.rb:223:10:223:21 | call to replace | string_flow.rb:222:9:222:18 | call to source : | string_flow.rb:223:10:223:21 | call to replace | $@ | string_flow.rb:222:9:222:18 | call to source : | call to source : |
685638
| string_flow.rb:225:10:225:10 | a | string_flow.rb:221:9:221:18 | call to source : | string_flow.rb:225:10:225:10 | a | $@ | string_flow.rb:221:9:221:18 | call to source : | call to source : |
686-
| string_flow.rb:225:10:225:10 | a | string_flow.rb:222:9:222:18 | call to source : | string_flow.rb:225:10:225:10 | a | $@ | string_flow.rb:222:9:222:18 | call to source : | call to source : |
687-
| string_flow.rb:295:10:295:17 | call to to_str | string_flow.rb:294:9:294:18 | call to source : | string_flow.rb:295:10:295:17 | call to to_str | $@ | string_flow.rb:294:9:294:18 | call to source : | call to source : |
688-
| string_flow.rb:296:10:296:15 | call to to_s | string_flow.rb:294:9:294:18 | call to source : | string_flow.rb:296:10:296:15 | call to to_s | $@ | string_flow.rb:294:9:294:18 | call to source : | call to source : |
689-
| string_flow.rb:313:28:313:28 | x | string_flow.rb:312:9:312:18 | call to source : | string_flow.rb:313:28:313:28 | x | $@ | string_flow.rb:312:9:312:18 | call to source : | call to source : |
690-
| string_flow.rb:314:34:314:34 | x | string_flow.rb:312:9:312:18 | call to source : | string_flow.rb:314:34:314:34 | x | $@ | string_flow.rb:312:9:312:18 | call to source : | call to source : |
691-
| string_flow.rb:315:28:315:28 | x | string_flow.rb:312:9:312:18 | call to source : | string_flow.rb:315:28:315:28 | x | $@ | string_flow.rb:312:9:312:18 | call to source : | call to source : |

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def m_push
3737

3838
def m_b
3939
a = source "a"
40-
sink a.b # $ hasValueFlow=a
40+
sink a.b # $ hasTaintFlow=a
4141
end
4242

4343
def m_byteslice
@@ -157,7 +157,7 @@ def m_force_encoding
157157

158158
def m_freeze
159159
a = source "a"
160-
sink a.freeze # $ hasValueFlow=a
160+
sink a.freeze # $ hasTaintFlow=a
161161
end
162162

163163
def m_gsub
@@ -220,9 +220,9 @@ def m_partition
220220
def m_replace
221221
a = source "a"
222222
b = source "b"
223-
sink a.replace(b) # $ hasValueFlow=b
223+
sink a.replace(b) # $ hasTaintFlow=b
224224
# TODO: currently we get value flow for a, because we don't clear content
225-
sink a # $ hasValueFlow=b
225+
sink a # $ hasTaintFlow=b
226226
end
227227

228228
def m_reverse
@@ -292,8 +292,8 @@ def m_squeeze
292292

293293
def m_to_str
294294
a = source "a"
295-
sink a.to_str # $ hasValueFlow=a
296-
sink a.to_s # $ hasValueFlow=a
295+
sink a.to_str # $ hasTaintFlow=a
296+
sink a.to_s # $ hasTaintFlow=a
297297
end
298298

299299
def m_tr
@@ -310,8 +310,8 @@ def m_tr
310310

311311
def m_upto(i)
312312
a = source "a"
313-
a.upto("b") { |x| sink x } # $ hasValueFlow=a
314-
a.upto("b", true) { |x| sink x } # $ hasValueFlow=a
315-
"b".upto(a) { |x| sink x } # $ hasValueFlow=a
313+
a.upto("b") { |x| sink x } # $ hasTaintFlow=a
314+
a.upto("b", true) { |x| sink x } # $ hasTaintFlow=a
315+
"b".upto(a) { |x| sink x } # $ hasTaintFlow=a
316316
"b".upto(a, true) { |x| sink x }
317317
end

0 commit comments

Comments
 (0)