зеркало из https://github.com/github/codeql.git
implement precise data-flow steps for Promise.all
This commit is contained in:
Родитель
5c9fb2312e
Коммит
e98f794dab
|
@ -251,13 +251,17 @@ private module ArrayDataFlow {
|
|||
/**
|
||||
* A step for creating an array and storing the elements in the array.
|
||||
*/
|
||||
private class ArrayCreationStep extends DataFlow::AdditionalFlowStep, DataFlow::Node {
|
||||
ArrayCreationStep() { this instanceof DataFlow::ArrayCreationNode }
|
||||
|
||||
private class ArrayCreationStep extends DataFlow::AdditionalFlowStep, DataFlow::ArrayCreationNode {
|
||||
override predicate storeStep(DataFlow::Node element, DataFlow::SourceNode obj, string prop) {
|
||||
prop = arrayElement() and
|
||||
element = this.(DataFlow::ArrayCreationNode).getAnElement() and
|
||||
element = this.getAnElement() and
|
||||
obj = this
|
||||
or
|
||||
exists(int i |
|
||||
element = this.getElement(i) and
|
||||
obj = this and
|
||||
prop = i.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ private class ES2015PromiseDefinition extends PromiseDefinition, DataFlow::NewNo
|
|||
*/
|
||||
abstract class PromiseCreationCall extends DataFlow::CallNode {
|
||||
/**
|
||||
* Gets the value this promise is resolved with.
|
||||
* Gets a value this promise is resolved with.
|
||||
*/
|
||||
abstract DataFlow::Node getValue();
|
||||
}
|
||||
|
@ -95,6 +95,16 @@ abstract class PromiseCreationCall extends DataFlow::CallNode {
|
|||
*/
|
||||
abstract class ResolvedPromiseDefinition extends PromiseCreationCall { }
|
||||
|
||||
/**
|
||||
* A promise that is created using a `Promise.all(array)` call.
|
||||
*/
|
||||
abstract class PromiseAllCreation extends PromiseCreationCall {
|
||||
/**
|
||||
* Gets a node for the array of values given to the `Promise.all(array)` call.
|
||||
*/
|
||||
abstract DataFlow::Node getArrayNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* A resolved promise created by the standard ECMAScript 2015 `Promise.resolve` function.
|
||||
*/
|
||||
|
@ -121,6 +131,15 @@ class AggregateES2015PromiseDefinition extends PromiseCreationCall {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An aggregated promise created using `Promise.all()`.
|
||||
*/
|
||||
class ES2015PromiseAllDefinition extends AggregateES2015PromiseDefinition, PromiseAllCreation {
|
||||
ES2015PromiseAllDefinition() { this.getCalleeName() = "all" }
|
||||
|
||||
override DataFlow::Node getArrayNode() { result = getArgument(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Common predicates shared between type-tracking and data-flow for promises.
|
||||
*/
|
||||
|
@ -303,16 +322,28 @@ private module PromiseFlow {
|
|||
CreationStep() { this = promise }
|
||||
|
||||
override predicate store(DataFlow::Node pred, DataFlow::SourceNode succ, string prop) {
|
||||
not promise instanceof PromiseAllCreation and
|
||||
prop = valueProp() and
|
||||
pred = promise.getValue() and
|
||||
succ = this
|
||||
or
|
||||
promise instanceof PromiseAllCreation and
|
||||
prop = valueProp() and
|
||||
pred = promise.(PromiseAllCreation).getArrayNode() and
|
||||
succ = this
|
||||
}
|
||||
|
||||
override predicate loadStore(DataFlow::Node pred, DataFlow::Node succ, string prop) {
|
||||
// Copy the value of a resolved promise to the value of this promise.
|
||||
not promise instanceof PromiseAllCreation and
|
||||
prop = valueProp() and
|
||||
pred = promise.getValue() and
|
||||
succ = this
|
||||
or
|
||||
promise instanceof PromiseAllCreation and
|
||||
prop = valueProp() and
|
||||
pred = promise.(PromiseAllCreation).getArrayNode() and
|
||||
succ = this
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -533,6 +564,15 @@ module Bluebird {
|
|||
result = getArgument(0).getALocalSource().(DataFlow::ArrayCreationNode).getAnElement()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A promise created using `Promise.all`:
|
||||
*/
|
||||
class BluebirdPromiseAllDefinition extends AggregateBluebirdPromiseDefinition, PromiseAllCreation {
|
||||
BluebirdPromiseAllDefinition() { this.getCalleeName() = "all" }
|
||||
|
||||
override DataFlow::Node getArrayNode() { result = getArgument(0) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче