Skip to content

Commit d719a1e

Browse files
authored
Merge pull request github#6114 from erik-krogh/promisify
Approved by esbena
2 parents bde1bb4 + 062502f commit d719a1e

File tree

6 files changed

+253
-13
lines changed

6 files changed

+253
-13
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
lgtm,codescanning
2+
* Support for libraries modeling `promisify` and `promisifyAll` functions have been improved.
3+
Affected packages are
4+
[pify](https://www.npmjs.com/package/pify),
5+
[util.promisify](https://www.npmjs.com/package/util.promisify),
6+
[thenify](https://www.npmjs.com/package/thenify)

javascript/ql/src/semmle/javascript/ApiGraphs.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -686,9 +686,7 @@ module API {
686686
promisified = false and
687687
boundArgs = 0
688688
or
689-
exists(DataFlow::CallNode promisify |
690-
promisify = DataFlow::moduleImport(["util", "bluebird"]).getAMemberCall("promisify")
691-
|
689+
exists(Promisify::PromisifyCall promisify |
692690
trackUseNode(nd, false, boundArgs, t.continue()).flowsTo(promisify.getArgument(0)) and
693691
promisified = true and
694692
result = promisify

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,3 +659,39 @@ private module DynamicImportSteps {
659659
}
660660
}
661661
}
662+
663+
/**
664+
* Provides classes modeling libraries implementing `promisify` functions.
665+
* That is, functions that convert callback style functions to functions that return a promise.
666+
*/
667+
module Promisify {
668+
/**
669+
* Gets a call to a `promisifyAll` function.
670+
* E.g. `require("bluebird").promisifyAll(...)`.
671+
*/
672+
class PromisifyAllCall extends DataFlow::CallNode {
673+
PromisifyAllCall() {
674+
this =
675+
[
676+
DataFlow::moduleMember("bluebird", "promisifyAll"),
677+
DataFlow::moduleImport(["util-promisifyall", "pify"])
678+
].getACall()
679+
}
680+
}
681+
682+
/**
683+
* Gets a call to a `promisify` function.
684+
* E.g. `require("util").promisify(...)`.
685+
*/
686+
class PromisifyCall extends DataFlow::CallNode {
687+
PromisifyCall() {
688+
this = DataFlow::moduleImport(["util", "bluebird"]).getAMemberCall("promisify")
689+
or
690+
this = DataFlow::moduleImport(["pify", "util.promisify"]).getACall()
691+
or
692+
this = DataFlow::moduleImport("thenify").getACall()
693+
or
694+
this = DataFlow::moduleMember("thenify", "withCallback").getACall()
695+
}
696+
}
697+
}

javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -472,14 +472,9 @@ module NodeJSLib {
472472
result = pred.track(t2, t)
473473
or
474474
t.continue() = t2 and
475-
exists(DataFlow::CallNode promisifyAllCall |
475+
exists(Promisify::PromisifyAllCall promisifyAllCall |
476476
result = promisifyAllCall and
477-
pred.flowsTo(promisifyAllCall.getArgument(0)) and
478-
promisifyAllCall =
479-
[
480-
DataFlow::moduleMember("bluebird", "promisifyAll"),
481-
DataFlow::moduleImport("util-promisifyall")
482-
].getACall()
477+
pred.flowsTo(promisifyAllCall.getArgument(0))
483478
)
484479
or
485480
// const fs = require('fs');
@@ -648,9 +643,7 @@ module NodeJSLib {
648643
private DataFlow::SourceNode maybePromisified(DataFlow::SourceNode callback) {
649644
result = callback
650645
or
651-
exists(DataFlow::CallNode promisify |
652-
promisify = DataFlow::moduleMember(["util", "bluebird"], "promisify").getACall()
653-
|
646+
exists(Promisify::PromisifyCall promisify |
654647
result = promisify and promisify.getArgument(0).getALocalSource() = callback
655648
)
656649
}

0 commit comments

Comments
 (0)