99private import javascript
1010private import internal.FlowSteps
1111private import internal.StepSummary
12+ private import internal.Unit
1213private import semmle.javascript.internal.CachedStages
1314
1415private newtype TTypeTracker = MkTypeTracker ( Boolean hasCall , OptionalPropertyName prop )
@@ -328,6 +329,71 @@ module TypeBackTracker {
328329}
329330
330331/**
332+ * A data flow edge that should be followed by type tracking.
333+ *
334+ * Unlike `SharedFlowStep`, this type of edge does not affect
335+ * the local data flow graph, and is not used by data-flow configurations.
336+ *
337+ * Note: For performance reasons, all subclasses of this class should be part
338+ * of the standard library. For query-specific steps, consider including the
339+ * custom steps in the type-tracking predicate itself.
340+ */
341+ class SharedTypeTrackingStep extends Unit {
342+ /**
343+ * Holds if type-tracking should step from `pred` to `succ`.
344+ */
345+ predicate step ( DataFlow:: Node pred , DataFlow:: Node succ ) { none ( ) }
346+
347+ /**
348+ * Holds if type-tracking should step from `pred` into the `prop` property of `succ`.
349+ */
350+ predicate storeStep ( DataFlow:: Node pred , DataFlow:: SourceNode succ , string prop ) { none ( ) }
351+
352+ /**
353+ * Holds if type-tracking should step from the `prop` property of `pred` to `succ`.
354+ */
355+ predicate loadStep ( DataFlow:: Node pred , DataFlow:: Node succ , string prop ) { none ( ) }
356+
357+ /**
358+ * Holds if type-tracking should step from the `prop` property of `pred` to the same property in `succ`.
359+ */
360+ predicate loadStoreStep ( DataFlow:: Node pred , DataFlow:: SourceNode succ , string prop ) { none ( ) }
361+ }
362+
363+ /** Provides access to the steps contributed by subclasses of `SharedTypeTrackingStep`. */
364+ module SharedTypeTrackingStep {
365+ /**
366+ * Holds if type-tracking should step from `pred` to `succ`.
367+ */
368+ predicate step ( DataFlow:: Node pred , DataFlow:: Node succ ) {
369+ any ( SharedTypeTrackingStep s ) .step ( pred , succ )
370+ }
371+
372+ /**
373+ * Holds if type-tracking should step from `pred` into the `prop` property of `succ`.
374+ */
375+ predicate storeStep ( DataFlow:: Node pred , DataFlow:: SourceNode succ , string prop ) {
376+ any ( SharedTypeTrackingStep s ) .storeStep ( pred , succ , prop )
377+ }
378+
379+ /**
380+ * Holds if type-tracking should step from the `prop` property of `pred` to `succ`.
381+ */
382+ predicate loadStep ( DataFlow:: Node pred , DataFlow:: Node succ , string prop ) {
383+ any ( SharedTypeTrackingStep s ) .loadStep ( pred , succ , prop )
384+ }
385+
386+ /**
387+ * Holds if type-tracking should step from the `prop` property of `pred` to the same property in `succ`.
388+ */
389+ predicate loadStoreStep ( DataFlow:: Node pred , DataFlow:: SourceNode succ , string prop ) {
390+ any ( SharedTypeTrackingStep s ) .loadStoreStep ( pred , succ , prop )
391+ }
392+ }
393+
394+ /**
395+ * DEPRECATED. Use `SharedTypeTrackingStep` instead.
396+ *
331397 * A data flow edge that should be followed by type tracking.
332398 *
333399 * Unlike `AdditionalFlowStep`, this type of edge does not affect
@@ -337,7 +403,10 @@ module TypeBackTracker {
337403 * of the standard library. For query-specific steps, consider including the
338404 * custom steps in the type-tracking predicate itself.
339405 */
340- abstract class AdditionalTypeTrackingStep extends DataFlow:: Node {
406+ deprecated class AdditionalTypeTrackingStep = LegacyTypeTrackingStep ;
407+
408+ // Internal version of AdditionalTypeTrackingStep that we can reference without deprecation warnings.
409+ abstract private class LegacyTypeTrackingStep extends DataFlow:: Node {
341410 /**
342411 * Holds if type-tracking should step from `pred` to `succ`.
343412 */
@@ -358,3 +427,21 @@ abstract class AdditionalTypeTrackingStep extends DataFlow::Node {
358427 */
359428 predicate loadStoreStep ( DataFlow:: Node pred , DataFlow:: SourceNode succ , string prop ) { none ( ) }
360429}
430+
431+ private class LegacyStepAsSharedTypeTrackingStep extends SharedTypeTrackingStep {
432+ override predicate step ( DataFlow:: Node pred , DataFlow:: Node succ ) {
433+ any ( LegacyTypeTrackingStep s ) .step ( pred , succ )
434+ }
435+
436+ override predicate storeStep ( DataFlow:: Node pred , DataFlow:: SourceNode succ , string prop ) {
437+ any ( LegacyTypeTrackingStep s ) .storeStep ( pred , succ , prop )
438+ }
439+
440+ override predicate loadStep ( DataFlow:: Node pred , DataFlow:: Node succ , string prop ) {
441+ any ( LegacyTypeTrackingStep s ) .loadStep ( pred , succ , prop )
442+ }
443+
444+ override predicate loadStoreStep ( DataFlow:: Node pred , DataFlow:: SourceNode succ , string prop ) {
445+ any ( LegacyTypeTrackingStep s ) .loadStoreStep ( pred , succ , prop )
446+ }
447+ }
0 commit comments