Skip to content

JavaScript: Teach API graphs about (some) promisification and bound arguments.#4706

Merged
codeql-ci merged 6 commits into
github:mainfrom
max-schaefer:issue-247
Jan 25, 2021
Merged

JavaScript: Teach API graphs about (some) promisification and bound arguments.#4706
codeql-ci merged 6 commits into
github:mainfrom
max-schaefer:issue-247

Conversation

@max-schaefer
Copy link
Copy Markdown
Contributor

The first commit is an implementation of @asgerf's excellent suggestion for how to deal with util.promisify and friends (though not promisifyAll yet) with an eye towards removing some ad-hoc handling in the NoSQL library. That turned out to also need a model of bound arguments, which is added in the second commit.

On the whole, this is a somewhat ambitious set of changes, which will need a careful evaluation. I also know of several other improvements to the API-graphs library that are currently in flight; I'm happy to rebase this over those changes.

@github-actions github-actions Bot added the JS label Nov 23, 2020
@max-schaefer
Copy link
Copy Markdown
Contributor Author

Evaluation showed a mild overall slowdown; for details see internal issue.

I'll leave this in draft state until we've decided what to do about the BDD issue.

boundArgs = 0
or
exists(DataFlow::CallNode promisify |
promisify = API::moduleImport(["util", "bluebird"]).getMember("promisify").getACall()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, double recursion through API::moduleImport().getMember().getACall() and trackUseNode. Seems safer to just use local data flow to recognize promisify calls.

exists(DataFlow::PartialInvokeNode pin, DataFlow::Node pred, int predBoundArgs |
trackUseNode(nd, promisified, predBoundArgs, t.continue()).flowsTo(pred) and
result = pin.getBoundFunction(pred, boundArgs - predBoundArgs) and
boundArgs <= 10
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a lower bound as well, just to be safe.

BindPartialCall currently sets boundArgs like this,

boundArgs = getNumArgument() - 1

which can in principle be negative. We could try to enforce that getBoundFunction never holds for a negative boundArgs value but it seems more robust to check it here.


private DataFlow::SourceNode awaited(DataFlow::InvokeNode call, DataFlow::TypeTracker t) {
t.startInPromise() and
exists(MkSyntheticCallbackArg(_, _, call))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

result is not bound here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😱

@max-schaefer max-schaefer force-pushed the issue-247 branch 2 times, most recently from 1ce199f to 40183b1 Compare December 3, 2020 12:03
Max Schaefer added 6 commits January 11, 2021 13:53
Following a suggestion by Asger, we track use nodes through calls to `promisify`. When we see a call to a promisified function, we introduce a new synthetic API-graph node representing the callback argument synthesised by the promisification, and track the result of the call to an `await` (or other promise resolution), which is then considered to be a use of the first parameter of the synthetic callback (the zeroth parameter being an error code, which we do not model yet).
@max-schaefer
Copy link
Copy Markdown
Contributor Author

Rebased; let's see if the recent CodeQL improvements have fixed the BDD-node exhaustion problem. If so, I'll set off another performance evaluation.

@max-schaefer max-schaefer marked this pull request as ready for review January 13, 2021 13:39
@max-schaefer max-schaefer requested a review from a team as a code owner January 13, 2021 13:39
@max-schaefer
Copy link
Copy Markdown
Contributor Author

Performance looks reasonable (internal link).

As discussed, I'm happy to wait for this PR to be merged until more critical ones have gone in, just to make sure we still have enough breathing room in terms of BDD nodes.

@asgerf
Copy link
Copy Markdown
Contributor

asgerf commented Jan 25, 2021

@max-schaefer happy to merge as is.

If you're referring to #4772 I'd like to hold on to that a bit, since it's not currently clear if it's helping.

@max-schaefer
Copy link
Copy Markdown
Contributor Author

If you're referring to #4772 (...)

To be honest, I've lost context a bit, so I don't remember exactly which other PRs I was afraid of conflicting with. I trust your judgement on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants