Skip to content

Commit

Permalink
Merge pull request #15760 from asgerf/js/summarised-tt-store-steps
Browse files Browse the repository at this point in the history
JS: Summarise store steps for type tracking
  • Loading branch information
asgerf authored Mar 8, 2024
2 parents a9bab18 + fc5b9e2 commit 245cd5c
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ private module Cached {
CopyStep(PropertyName prop) or
LoadStoreStep(PropertyName fromProp, PropertyName toProp) {
SharedTypeTrackingStep::loadStoreStep(_, _, fromProp, toProp)
or
summarizedLoadStoreStep(_, _, fromProp, toProp)
} or
WithoutPropStep(PropertySet props) { SharedTypeTrackingStep::withoutPropStep(_, _, props) }
}
Expand All @@ -69,6 +71,26 @@ private module Cached {
AccessPath::isAssignedInUniqueFile(global)
}

bindingset[fun]
pragma[inline_late]
private DataFlow::PropRead getStoredPropRead(DataFlow::FunctionNode fun, string storeProp) {
result = fun.getAReturn().getALocalSource().getAPropertySource(storeProp)
}

/**
* Holds if `loadProp` of `param` is stored in the `storeProp` property of the return value of `fun`.
*/
pragma[nomagic]
private predicate summarizedLoadStoreStep(
DataFlow::ParameterNode param, DataFlow::FunctionNode fun, string loadProp, string storeProp
) {
exists(DataFlow::PropRead read |
read = getStoredPropRead(fun, storeProp) and
read.getBase().getALocalSource() = param and
read.getPropertyName() = loadProp
)
}

/**
* INTERNAL: Use `TypeBackTracker.smallstep()` instead.
*/
Expand Down Expand Up @@ -156,6 +178,14 @@ private module Cached {
exists(string prop |
param.getAPropertyRead(prop).flowsTo(fun.getAReturn()) and
summary = LoadStep(prop)
or
fun.getAReturn().getALocalSource().getAPropertySource(prop) = param and
summary = StoreStep(prop)
)
or
exists(string loadProp, string storeProp |
summarizedLoadStoreStep(param, fun, loadProp, storeProp) and
summary = LoadStoreStep(loadProp, storeProp)
)
) and
if param = fun.getAParameter()
Expand Down
41 changes: 41 additions & 0 deletions javascript/ql/test/library-tests/TypeTracking/summarize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import 'dummy';

function identity(x) {
return x;
}
function load(x) {
return x.loadProp;
}
function store(x) {
return { storeProp: x };
}
function loadStore(x) {
return { storeProp: x.loadProp };
}
function loadStore2(x) {
let mid = x.loadProp;
return { storeProp: mid };
}

identity({});
load({});
store({});
loadStore({});
loadStore2({});

const obj = {}; // name: obj

let x = identity(obj);
x; // track: obj

x = load({ loadProp: obj });
x; // track: obj

x = store(obj);
x.storeProp; // track: obj

x = loadStore({ loadProp: obj });
x.storeProp; // track: obj

x = loadStore2({ loadProp: obj });
x.storeProp; // track: obj

0 comments on commit 245cd5c

Please sign in to comment.