mirror of
https://github.com/github/codeql.git
synced 2026-05-01 19:55:15 +02:00
move deferred model to the query where it is used
This commit is contained in:
@@ -149,6 +149,57 @@ predicate voidArrayCallback(DataFlow::CallNode call, Function func) {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provides classes for working with various Deferred implementations.
|
||||
* It is a heuristic. The heuristic assume that a class is a promise defintion
|
||||
* if the class is called "Deferred" and the method `resolve` is called on an instance.
|
||||
*
|
||||
* Removes some false positives in the js/use-of-returnless-function query.
|
||||
*/
|
||||
module Deferred {
|
||||
/**
|
||||
* An instance of a `Deferred` class.
|
||||
* E.g. the result from `new Deferred()` or `new $.Deferred()`.
|
||||
*/
|
||||
class DeferredInstance extends DataFlow::NewNode {
|
||||
// Describes both `new Deferred()`, `new $.Deferred` and other variants.
|
||||
DeferredInstance() { this.getCalleeName() = "Deferred" }
|
||||
|
||||
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = this
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = ref(t2).track(t2, t))
|
||||
}
|
||||
|
||||
DataFlow::SourceNode ref() { result = ref(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A promise object created by a Deferred constructor
|
||||
*/
|
||||
private class DeferredPromiseDefinition extends PromiseDefinition, DeferredInstance {
|
||||
DeferredPromiseDefinition() {
|
||||
// hardening of the "Deferred" heuristic: a method call to `resolve`.
|
||||
exists(ref().getAMethodCall("resolve"))
|
||||
}
|
||||
|
||||
override DataFlow::FunctionNode getExecutor() { result = getCallback(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A resolved promise created by a `new Deferred().resolve()` call.
|
||||
*/
|
||||
class ResolvedDeferredPromiseDefinition extends ResolvedPromiseDefinition {
|
||||
ResolvedDeferredPromiseDefinition() {
|
||||
this = any(DeferredPromiseDefinition def).ref().getAMethodCall("resolve")
|
||||
}
|
||||
|
||||
override DataFlow::Node getValue() { result = getArgument(0) }
|
||||
}
|
||||
}
|
||||
|
||||
from DataFlow::CallNode call, Function func, string name, string msg
|
||||
where
|
||||
(
|
||||
|
||||
@@ -32,48 +32,6 @@ module Bluebird {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides classes for working with various Deferred implementations
|
||||
*/
|
||||
module Deferred {
|
||||
class DeferredInstance extends DataFlow::NewNode {
|
||||
// Describes both `new Deferred()`, `new $.Deferred` and other variants.
|
||||
DeferredInstance() { this.getCalleeName() = "Deferred" }
|
||||
|
||||
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = this
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = ref(t2).track(t2, t))
|
||||
}
|
||||
|
||||
DataFlow::SourceNode ref() { result = ref(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A promise object created by a Deferred constructor
|
||||
*/
|
||||
private class DeferredPromiseDefinition extends PromiseDefinition, DeferredInstance {
|
||||
DeferredPromiseDefinition() {
|
||||
// hardening of the "Deferred" heuristic: a method call to `resolve`.
|
||||
exists(ref().getAMethodCall("resolve"))
|
||||
}
|
||||
|
||||
override DataFlow::FunctionNode getExecutor() { result = getCallback(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A resolved promise created by a `new Deferred().resolve()` call.
|
||||
*/
|
||||
class ResolvedDeferredPromiseDefinition extends ResolvedPromiseDefinition {
|
||||
ResolvedDeferredPromiseDefinition() {
|
||||
this = any(DeferredPromiseDefinition def).ref().getAMethodCall("resolve")
|
||||
}
|
||||
|
||||
override DataFlow::Node getValue() { result = getArgument(0) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides classes for working with the `q` library (https://github.com/kriskowal/q).
|
||||
*/
|
||||
|
||||
@@ -69,7 +69,6 @@ typeInferenceMismatch
|
||||
| promise.js:5:25:5:32 | source() | promise.js:5:8:5:33 | bluebir ... urce()) |
|
||||
| promise.js:10:24:10:31 | source() | promise.js:10:8:10:32 | Promise ... urce()) |
|
||||
| promise.js:12:20:12:27 | source() | promise.js:13:8:13:23 | resolver.promise |
|
||||
| promise.js:22:23:22:30 | source() | promise.js:22:7:22:31 | promise ... urce()) |
|
||||
| sanitizer-guards.js:2:11:2:18 | source() | sanitizer-guards.js:4:8:4:8 | x |
|
||||
| sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:15:10:15:15 | this.x |
|
||||
| sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:21:14:21:19 | this.x |
|
||||
|
||||
@@ -11,15 +11,4 @@ function closure() {
|
||||
let resolver = Promise.withResolver();
|
||||
resolver.resolve(source());
|
||||
sink(resolver.promise); // NOT OK
|
||||
}
|
||||
|
||||
class Deferred {
|
||||
|
||||
}
|
||||
|
||||
function deferred() {
|
||||
var promise = new Deferred();
|
||||
sink(promise.resolve(source())); // NOT OK
|
||||
|
||||
new Deferred().reject("foo") // <- a reject has to exist.
|
||||
}
|
||||
@@ -82,4 +82,10 @@
|
||||
|
||||
var baz = [1,2,3].filter(n => {n === 3}) // OK
|
||||
console.log(baz);
|
||||
|
||||
class Deferred {
|
||||
|
||||
}
|
||||
|
||||
new Deferred().resolve(onlySideEffects()); // OK
|
||||
})();
|
||||
Reference in New Issue
Block a user