Skip to content

Commit 5c07750

Browse files
committed
simplify the heuristic for Deferred promises
1 parent 31009d9 commit 5c07750

File tree

1 file changed

+8
-40
lines changed

1 file changed

+8
-40
lines changed

javascript/ql/src/semmle/javascript/Promises.qll

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -36,59 +36,27 @@ module Bluebird {
3636
* Provides classes for working with various Deferred implementations
3737
*/
3838
module Deferred {
39-
class DeferredClass extends DataFlow::SourceNode {
40-
DeferredClass() {
41-
exists(Variable var |
42-
var.getName() = "Deferred" and
43-
(
44-
var.getADeclaration() instanceof LocalNamespaceDecl or
45-
var.getScope() instanceof GlobalScope
46-
) and
47-
this = DataFlow::valueNode(var.getADefinition())
48-
)
49-
or
50-
this.(DataFlow::ParameterNode).getName() = "Deferred"
51-
or
52-
exists(Function f |
53-
f.getName() = "Deferred" and
54-
this = DataFlow::valueNode(f)
55-
)
56-
or
57-
exists(ClassDefinition c |
58-
c.getName() = "Deferred" and
59-
this = DataFlow::valueNode(c)
60-
)
61-
}
62-
}
63-
6439
class DeferredInstance extends DataFlow::NewNode {
65-
DeferredClass deferredClass;
66-
67-
DeferredInstance() { this = deferredClass.getAnInstantiation() }
40+
// Describes both `new Deferred()`, `new $.Deferred` and other variants.
41+
DeferredInstance() { this.getCalleeName() = "Deferred" }
6842

6943
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
7044
t.start() and
7145
result = this
7246
or
7347
exists(DataFlow::TypeTracker t2 | result = ref(t2).track(t2, t))
7448
}
75-
76-
DeferredClass getDeferredClass() { result = deferredClass }
77-
78-
DataFlow::CallNode getPromiseMemberCall(string methodName) {
79-
result = ref(DataFlow::TypeTracker::end()).getAMemberCall(methodName)
80-
}
49+
50+
DataFlow::SourceNode ref() { result = ref(DataFlow::TypeTracker::end()) }
8151
}
8252

8353
/**
8454
* A promise object created by a Deferred constructor
8555
*/
8656
private class DeferredPromiseDefinition extends PromiseDefinition, DeferredInstance {
87-
DeferredPromiseDefinition() {
88-
this = any(DeferredClass c |
89-
exists(any(DeferredInstance i | i.getDeferredClass() = c).getPromiseMemberCall("resolve")) and
90-
exists(any(DeferredInstance i | i.getDeferredClass() = c).getPromiseMemberCall("reject"))
91-
).getAnInstantiation()
57+
DeferredPromiseDefinition() {
58+
// hardening of the "Deferred" heuristic: a method call to `resolve`.
59+
exists(ref().getAMethodCall("resolve"))
9260
}
9361

9462
override DataFlow::FunctionNode getExecutor() { result = getCallback(0) }
@@ -99,7 +67,7 @@ module Deferred {
9967
*/
10068
class ResolvedDeferredPromiseDefinition extends ResolvedPromiseDefinition {
10169
ResolvedDeferredPromiseDefinition() {
102-
this = any(DeferredPromiseDefinition def).getPromiseMemberCall("resolve")
70+
this = any(DeferredPromiseDefinition def).ref().getAMethodCall("resolve")
10371
}
10472

10573
override DataFlow::Node getValue() { result = getArgument(0) }

0 commit comments

Comments
 (0)