add support for the promise polyfill

This commit is contained in:
Erik Krogh Kristensen
2021-06-18 16:06:39 +02:00
parent 967ccfef0c
commit f095e190a9
4 changed files with 34 additions and 7 deletions

View File

@@ -58,6 +58,22 @@ private predicate hasHandler(DataFlow::InvokeNode promise, string m, int i) {
exists(promise.getAMethodCall(m).getCallback(i))
}
/**
* Gets a reference to the `Promise` object.
* Either from the standard library, a polyfill import, or a polyfill that defines the global `Promise` variable.
*/
private DataFlow::SourceNode getAPromiseObject() {
// Standard library, or polyfills like [es6-shim](https://npmjs.org/package/es6-shim).
result = DataFlow::globalVarRef("Promise")
or
// polyfills from the [`promise`](https://npmjs.org/package/promise) library.
result =
DataFlow::moduleImport([
"promise", "promise/domains", "promise/setimmediate", "promise/lib/es6-extensions",
"promise/domains/es6-extensions", "promise/setimmediate/es6-extensions"
])
}
/**
* A call that looks like a Promise.
*
@@ -75,7 +91,7 @@ class PromiseCandidate extends DataFlow::InvokeNode {
* A promise object created by the standard ECMAScript 2015 `Promise` constructor.
*/
private class ES2015PromiseDefinition extends PromiseDefinition, DataFlow::NewNode {
ES2015PromiseDefinition() { this = DataFlow::globalVarRef("Promise").getAnInstantiation() }
ES2015PromiseDefinition() { this = getAPromiseObject().getAnInstantiation() }
override DataFlow::FunctionNode getExecutor() { result = getCallback(0) }
}
@@ -109,9 +125,7 @@ abstract class PromiseAllCreation extends PromiseCreationCall {
* A resolved promise created by the standard ECMAScript 2015 `Promise.resolve` function.
*/
class ResolvedES2015PromiseDefinition extends ResolvedPromiseDefinition {
ResolvedES2015PromiseDefinition() {
this = DataFlow::globalVarRef("Promise").getAMemberCall("resolve")
}
ResolvedES2015PromiseDefinition() { this = getAPromiseObject().getAMemberCall("resolve") }
override DataFlow::Node getValue() { result = getArgument(0) }
}
@@ -121,8 +135,7 @@ class ResolvedES2015PromiseDefinition extends ResolvedPromiseDefinition {
*/
class AggregateES2015PromiseDefinition extends PromiseCreationCall {
AggregateES2015PromiseDefinition() {
exists(string m | m = "all" or m = "race" or m = "any" |
this = DataFlow::globalVarRef("Promise").getAMemberCall(m)
this = getAPromiseObject().getAMemberCall(m)
)
}