Skip to content

Commit f051702

Browse files
authored
Merge pull request github#13496 from asgerf/rb/tracking-on-demand
Ruby: overhaul API graphs
2 parents 7c59f5a + 39789d4 commit f051702

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2339
-1195
lines changed

python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,9 @@ private module Cached {
5555
)
5656
}
5757

58-
pragma[nomagic]
59-
private TypeTracker noContentTypeTracker(boolean hasCall) {
60-
result = MkTypeTracker(hasCall, noContent())
61-
}
58+
/** Gets a type tracker with no content and the call bit set to the given value. */
59+
cached
60+
TypeTracker noContentTypeTracker(boolean hasCall) { result = MkTypeTracker(hasCall, noContent()) }
6261

6362
/** Gets the summary resulting from appending `step` to type-tracking summary `tt`. */
6463
cached
@@ -340,6 +339,8 @@ class StepSummary extends TStepSummary {
340339

341340
/** Provides predicates for updating step summaries (`StepSummary`s). */
342341
module StepSummary {
342+
predicate append = Cached::append/2;
343+
343344
/**
344345
* Gets the summary that corresponds to having taken a forwards
345346
* inter-procedural step from `nodeFrom` to `nodeTo`.
@@ -400,6 +401,35 @@ module StepSummary {
400401
}
401402

402403
deprecated predicate localSourceStoreStep = flowsToStoreStep/3;
404+
405+
/** Gets the step summary for a level step. */
406+
StepSummary levelStep() { result = LevelStep() }
407+
408+
/** Gets the step summary for a call step. */
409+
StepSummary callStep() { result = CallStep() }
410+
411+
/** Gets the step summary for a return step. */
412+
StepSummary returnStep() { result = ReturnStep() }
413+
414+
/** Gets the step summary for storing into `content`. */
415+
StepSummary storeStep(TypeTrackerContent content) { result = StoreStep(content) }
416+
417+
/** Gets the step summary for loading from `content`. */
418+
StepSummary loadStep(TypeTrackerContent content) { result = LoadStep(content) }
419+
420+
/** Gets the step summary for loading from `load` and then storing into `store`. */
421+
StepSummary loadStoreStep(TypeTrackerContent load, TypeTrackerContent store) {
422+
result = LoadStoreStep(load, store)
423+
}
424+
425+
/** Gets the step summary for a step that only permits contents matched by `filter`. */
426+
StepSummary withContent(ContentFilter filter) { result = WithContent(filter) }
427+
428+
/** Gets the step summary for a step that blocks contents matched by `filter`. */
429+
StepSummary withoutContent(ContentFilter filter) { result = WithoutContent(filter) }
430+
431+
/** Gets the step summary for a jump step. */
432+
StepSummary jumpStep() { result = JumpStep() }
403433
}
404434

405435
/**
@@ -545,6 +575,13 @@ module TypeTracker {
545575
* Gets a valid end point of type tracking.
546576
*/
547577
TypeTracker end() { result.end() }
578+
579+
/**
580+
* INTERNAL USE ONLY.
581+
*
582+
* Gets a valid end point of type tracking with the call bit set to the given value.
583+
*/
584+
predicate end = Cached::noContentTypeTracker/1;
548585
}
549586

550587
pragma[nomagic]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
category: majorAnalysis
3+
---
4+
* The API graph library (`codeql.ruby.ApiGraphs`) has been significantly improved, with better support for inheritance,
5+
and data-flow nodes can now be converted to API nodes by calling `.track()` or `.backtrack()` on the node.
6+
API graphs allow for efficient modelling of how a given value is used by the code base, or how values produced by the code base
7+
are consumed by a library. See the documentation for `API::Node` for details and examples.

0 commit comments

Comments
 (0)