Skip to content

Commit c9c3698

Browse files
committed
Ruby: address review comments
1 parent ab6e488 commit c9c3698

File tree

3 files changed

+7
-142
lines changed

3 files changed

+7
-142
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,7 @@ private module Cached {
366366

367367
cached
368368
predicate isLocalSourceNode(Node n) {
369-
n instanceof ParameterNode and
370-
not n instanceof SynthHashSplatParameterNode
369+
n instanceof ParameterNode
371370
or
372371
// Expressions that can't be reached from another entry definition or expression
373372
n instanceof ExprNode and

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/** Provides flow summaries for the `Hash` class. */
22

33
private import codeql.ruby.AST
4-
private import codeql.ruby.CFG as Cfg
54
private import codeql.ruby.ApiGraphs
65
private import codeql.ruby.DataFlow
76
private import codeql.ruby.dataflow.FlowSummary

ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll

Lines changed: 6 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,7 @@ private predicate summarizedLocalStep(Node nodeFrom, Node nodeTo) {
102102
}
103103

104104
/** Holds if there is a level step from `nodeFrom` to `nodeTo`. */
105-
predicate levelStep(Node nodeFrom, Node nodeTo) {
106-
summarizedLocalStep(nodeFrom, nodeTo)
107-
or
108-
TypeTrackingStep::step(nodeFrom, nodeTo)
109-
}
105+
predicate levelStep(Node nodeFrom, Node nodeTo) { summarizedLocalStep(nodeFrom, nodeTo) }
110106

111107
pragma[noinline]
112108
private predicate argumentPositionMatch(
@@ -221,8 +217,6 @@ predicate basicStoreStep(Node nodeFrom, Node nodeTo, DataFlow::ContentSet conten
221217
nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and
222218
nodeTo = evaluateSummaryComponentStackLocal(callable, call, output)
223219
)
224-
or
225-
TypeTrackingStep::storeStep(nodeFrom, nodeTo, contents)
226220
}
227221

228222
/**
@@ -265,8 +259,6 @@ predicate basicLoadStep(Node nodeFrom, Node nodeTo, DataFlow::ContentSet content
265259
nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and
266260
nodeTo = evaluateSummaryComponentStackLocal(callable, call, output)
267261
)
268-
or
269-
TypeTrackingStep::loadStep(nodeFrom, nodeTo, contents)
270262
}
271263

272264
/**
@@ -285,8 +277,6 @@ predicate basicLoadStoreStep(
285277
nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and
286278
nodeTo = evaluateSummaryComponentStackLocal(callable, call, output)
287279
)
288-
or
289-
TypeTrackingStep::loadStoreStep(nodeFrom, nodeTo, loadContent, storeContent)
290280
}
291281

292282
/**
@@ -303,8 +293,6 @@ predicate basicWithoutContentStep(Node nodeFrom, Node nodeTo, ContentFilter filt
303293
nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and
304294
nodeTo = evaluateSummaryComponentStackLocal(callable, call, output)
305295
)
306-
or
307-
TypeTrackingStep::withoutContentStep(nodeFrom, nodeTo, filter)
308296
}
309297

310298
/**
@@ -321,8 +309,6 @@ predicate basicWithContentStep(Node nodeFrom, Node nodeTo, ContentFilter filter)
321309
nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and
322310
nodeTo = evaluateSummaryComponentStackLocal(callable, call, output)
323311
)
324-
or
325-
TypeTrackingStep::withContentStep(nodeFrom, nodeTo, filter)
326312
}
327313

328314
/**
@@ -339,7 +325,6 @@ private predicate hasStoreSummary(
339325
SummarizedCallable callable, DataFlow::ContentSet contents, SummaryComponentStack input,
340326
SummaryComponentStack output
341327
) {
342-
not TypeTrackingStep::suppressSummary(callable) and
343328
callable.propagatesFlow(input, push(SummaryComponent::content(contents), output), true) and
344329
not isNonLocal(input.head()) and
345330
not isNonLocal(output.head())
@@ -350,7 +335,6 @@ private predicate hasLoadSummary(
350335
SummarizedCallable callable, DataFlow::ContentSet contents, SummaryComponentStack input,
351336
SummaryComponentStack output
352337
) {
353-
not TypeTrackingStep::suppressSummary(callable) and
354338
callable.propagatesFlow(push(SummaryComponent::content(contents), input), output, true) and
355339
not isNonLocal(input.head()) and
356340
not isNonLocal(output.head())
@@ -361,7 +345,6 @@ private predicate hasLoadStoreSummary(
361345
SummarizedCallable callable, DataFlow::ContentSet loadContents,
362346
DataFlow::ContentSet storeContents, SummaryComponentStack input, SummaryComponentStack output
363347
) {
364-
not TypeTrackingStep::suppressSummary(callable) and
365348
callable
366349
.propagatesFlow(push(SummaryComponent::content(loadContents), input),
367350
push(SummaryComponent::content(storeContents), output), true) and
@@ -394,7 +377,6 @@ private predicate hasWithoutContentSummary(
394377
SummaryComponentStack output
395378
) {
396379
exists(DataFlow::ContentSet content |
397-
not TypeTrackingStep::suppressSummary(callable) and
398380
callable.propagatesFlow(push(SummaryComponent::withoutContent(content), input), output, true) and
399381
filter = getFilterFromWithoutContentStep(content) and
400382
not isNonLocal(input.head()) and
@@ -404,12 +386,12 @@ private predicate hasWithoutContentSummary(
404386
}
405387

406388
/**
407-
* Gets a content filter to use for a `WithoutContent[content]` step, or has no result if
408-
* the step should be treated as ordinary flow.
389+
* Gets a content filter to use for a `WithContent[content]` step, or has no result if
390+
* the step cannot be handled by type-tracking.
409391
*
410-
* `WithoutContent` is often used to perform strong updates on individual collection elements, but for
411-
* type-tracking this is rarely beneficial and quite expensive. However, `WithoutContent` can be quite useful
412-
* for restricting the type of an object, and in these cases we translate it to a filter.
392+
* `WithContent` is often used to perform strong updates on individual collection elements (or rather
393+
* to preserve those that didn't get updated). But for type-tracking this is rarely beneficial and quite expensive.
394+
* However, `WithContent` can be quite useful for restricting the type of an object, and in these cases we translate it to a filter.
413395
*/
414396
private ContentFilter getFilterFromWithContentStep(DataFlow::ContentSet content) {
415397
(
@@ -430,7 +412,6 @@ private predicate hasWithContentSummary(
430412
SummaryComponentStack output
431413
) {
432414
exists(DataFlow::ContentSet content |
433-
not TypeTrackingStep::suppressSummary(callable) and
434415
callable.propagatesFlow(push(SummaryComponent::withContent(content), input), output, true) and
435416
filter = getFilterFromWithContentStep(content) and
436417
not isNonLocal(input.head()) and
@@ -475,7 +456,6 @@ private predicate dependsOnSummaryComponentStack(
475456
SummarizedCallable callable, SummaryComponentStack stack
476457
) {
477458
exists(callable.getACallSimple()) and
478-
not TypeTrackingStep::suppressSummary(callable) and
479459
(
480460
callable.propagatesFlow(stack, _, true)
481461
or
@@ -544,116 +524,3 @@ private DataFlow::Node evaluateSummaryComponentStackLocal(
544524
)
545525
)
546526
}
547-
548-
private newtype TUnit = MkUnit()
549-
550-
/**
551-
* A data flow edge that should be followed by type tracking.
552-
*
553-
* This type of edge does not affect the local data flow graph, and is not used by data-flow configurations.
554-
*
555-
* Note: For performance reasons, all subclasses of this class should be part
556-
* of the standard library, and their implementations may not depend on API graphs.
557-
* For query-specific steps, consider including the custom steps in the type-tracking predicate itself.
558-
*/
559-
class TypeTrackingStep extends TUnit {
560-
/** Gets the string `"unit"`. */
561-
string toString() { result = "unit" }
562-
563-
/**
564-
* Holds if type-tracking should not attempt to derive steps from (simple) calls to `callable`.
565-
*
566-
* This can be done to manually control how steps are generated from such calls.
567-
*/
568-
predicate suppressSummary(SummarizedCallable callable) { none() }
569-
570-
/**
571-
* Holds if type-tracking should step from `pred` to `succ`.
572-
*/
573-
predicate step(Node pred, Node succ) { none() }
574-
575-
/**
576-
* Holds if type-tracking should step from `pred` into the `content` of `succ`.
577-
*/
578-
predicate storeStep(Node pred, TypeTrackingNode succ, TypeTrackerContent content) { none() }
579-
580-
/**
581-
* Holds if type-tracking should step from the `content` of `pred` to `succ`.
582-
*/
583-
predicate loadStep(Node pred, Node succ, TypeTrackerContent content) { none() }
584-
585-
/**
586-
* Holds if type-tracking should step from the `loadContent` of `pred` to the `storeContent` in `succ`.
587-
*/
588-
predicate loadStoreStep(
589-
Node pred, TypeTrackingNode succ, TypeTrackerContent loadContent,
590-
TypeTrackerContent storeContent
591-
) {
592-
none()
593-
}
594-
595-
/**
596-
* Holds if type-tracking should step from `pred` to `succ` but block flow of contents matched by `filter` through here.
597-
*/
598-
predicate withoutContentStep(Node pred, Node succ, ContentFilter filter) { none() }
599-
600-
/**
601-
* Holds if type-tracking should step from `pred` to `succ` if inside a content matched by `filter`.
602-
*/
603-
predicate withContentStep(Node pred, Node succ, ContentFilter filter) { none() }
604-
}
605-
606-
/** Provides access to the steps contributed by subclasses of `SharedTypeTrackingStep`. */
607-
module TypeTrackingStep {
608-
/**
609-
* Holds if type-tracking should not attempt to derive steps from (simple) calls to `callable`.
610-
*
611-
* This can be done to manually control how steps are generated from such calls.
612-
*/
613-
predicate suppressSummary(SummarizedCallable callable) {
614-
any(TypeTrackingStep st).suppressSummary(callable)
615-
}
616-
617-
/**
618-
* Holds if type-tracking should step from `pred` to `succ`.
619-
*/
620-
predicate step(Node pred, Node succ) { any(TypeTrackingStep st).step(pred, succ) }
621-
622-
/**
623-
* Holds if type-tracking should step from `pred` into the `content` of `succ`.
624-
*/
625-
predicate storeStep(Node pred, TypeTrackingNode succ, TypeTrackerContent content) {
626-
any(TypeTrackingStep st).storeStep(pred, succ, content)
627-
}
628-
629-
/**
630-
* Holds if type-tracking should step from the `content` of `pred` to `succ`.
631-
*/
632-
predicate loadStep(Node pred, Node succ, TypeTrackerContent content) {
633-
any(TypeTrackingStep st).loadStep(pred, succ, content)
634-
}
635-
636-
/**
637-
* Holds if type-tracking should step from the `loadContent` of `pred` to the `storeContent` in `succ`.
638-
*/
639-
predicate loadStoreStep(
640-
Node pred, TypeTrackingNode succ, TypeTrackerContent loadContent,
641-
TypeTrackerContent storeContent
642-
) {
643-
any(TypeTrackingStep st).loadStoreStep(pred, succ, loadContent, storeContent)
644-
}
645-
646-
/**
647-
* Holds if type-tracking should step from `pred` to `succ` but block flow of contents matched by `filter` through here.
648-
*/
649-
predicate withoutContentStep(Node pred, Node succ, ContentFilter filter) {
650-
any(TypeTrackingStep st).withoutContentStep(pred, succ, filter)
651-
}
652-
653-
/**
654-
* Holds if type-tracking should step from `pred` to `succ` if inside a content matched by `filter`.
655-
*/
656-
predicate withContentStep(Node pred, Node succ, ContentFilter filter) {
657-
any(TypeTrackingStep st).withContentStep(pred, succ, filter)
658-
}
659-
}

0 commit comments

Comments
 (0)