Skip to content

JS: Better type-tracking through Promise.all() #19412

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 30, 2025

Conversation

asgerf
Copy link
Contributor

@asgerf asgerf commented Apr 29, 2025

Adds explicit type-tracking steps through common uses of Promise.all:

In the following example, we'd generate a read step from promise1 -> val1 reading the promise-content, and likewise for promise2 -> val2:

const [ val1, val2 ] = await Promise.all([ promise1, promise2 ]);

Evaluation looks good, showing 15 new call edges, 18 new sinks, and 11 new threat model sources.

@github-actions github-actions bot added the JS label Apr 29, 2025
@asgerf asgerf marked this pull request as ready for review April 30, 2025 10:00
@Copilot Copilot AI review requested due to automatic review settings April 30, 2025 10:00
@asgerf asgerf requested a review from a team as a code owner April 30, 2025 10:00
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR improves type-tracking through explicit handling of Promise.all() calls by introducing new classes and refactoring existing steps used in the dataflow analysis. Key changes include the addition of PromiseAllCall and PromiseAllStep classes in Promises.qll, an update to use SharedTypeTrackingStep in ApiGraphs.qll, and a minor documentation update under change-notes.

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
javascript/ql/src/change-notes/2025-04-30-promise-all.md Adds change notes explaining the improved type propagation through Promise.all() calls.
javascript/ql/lib/semmle/javascript/internal/flow_summaries/Promises.qll Introduces PromiseAllCall and PromiseAllStep classes to enable explicit type tracking through Promise.all().
javascript/ql/lib/semmle/javascript/ApiGraphs.qll Refactors step calls to use SharedTypeTrackingStep for consistency with the new type-tracking implementation.


/** Gets the `n`th output */
DataFlow::SourceNode getNthOutput(int n) {
exists(string prop |
Copy link
Preview

Copilot AI Apr 30, 2025

Choose a reason for hiding this comment

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

[nitpick] Consider adding an inline comment clarifying that the property names read from the output array are expected to be numeric strings, which justifies the conversion using toInt().

Suggested change
exists(string prop |
exists(string prop |
// The property names read from the output array are expected to be numeric strings,
// which justifies the conversion using toInt().

Copilot uses AI. Check for mistakes.

this.flowsToExpr(await.getOperand()) and
result = await.flow()
)
or
Copy link
Preview

Copilot AI Apr 30, 2025

Choose a reason for hiding this comment

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

[nitpick] Consider adding a comment to explain that this fallback branch captures the Promise resolution callback when an AwaitExpr is not present, which aids future maintainability.

Suggested change
or
or
// Fallback: Captures the Promise resolution callback when an AwaitExpr is not present.

Copilot uses AI. Check for mistakes.

Copy link
Contributor

@Napalys Napalys left a comment

Choose a reason for hiding this comment

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

Nice 🫶

@asgerf asgerf merged commit 8ebbfb1 into github:main Apr 30, 2025
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants