-
Notifications
You must be signed in to change notification settings - Fork 1.9k
JS: Support Promise.try and Array.prototype.with #20375
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -368,3 +368,29 @@ private class PromiseWithResolversLike extends SummarizedCallable { | |
| ) | ||
| } | ||
| } | ||
|
|
||
| class PromiseTry extends DataFlow::SummarizedCallable { | ||
| PromiseTry() { this = "Promise.try()" } | ||
|
|
||
| override DataFlow::CallNode getACallSimple() { | ||
| result = promiseConstructorRef().getAMemberCall(["try", "attempt"]) | ||
| or | ||
| result = DataFlow::moduleImport(["p-try", "es6-promise-try"]).getACall() | ||
| } | ||
|
|
||
| override predicate propagatesFlow(string input, string output, boolean preservesValue) { | ||
| preservesValue = true and | ||
| ( | ||
| exists(int i | i = getAnArgumentPosition() | | ||
| input = "Argument[" + (i + 1) + "]" and | ||
| output = "Argument[0].Parameter[" + i + "]" | ||
| ) | ||
|
Comment on lines
+384
to
+387
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just a quick question for my understanding. We would not have flow if a lambda would have more then 10 arguments?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct on both accounts |
||
| or | ||
| input = "Argument[0].ReturnValue" and | ||
| output = "ReturnValue.Awaited" | ||
| or | ||
| input = "Argument[0].ReturnValue[exception]" and | ||
| output = "ReturnValue.Awaited[error]" | ||
| ) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| --- | ||
| category: minorAnalysis | ||
| --- | ||
| * Data flow is now tracked through the `Promise.try` and `Array.prototype.with` functions. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| function t1() { | ||
| const arr = [1, 2, 3]; | ||
| const newArr = arr.with(1, source('with.1')); | ||
| sink(newArr[1]); // $ hasValueFlow=with.1 | ||
| } | ||
|
|
||
| function t2() { | ||
| const arr = [source('with.2.1'), 2, source('with.2.3')]; | ||
| const newArr = arr.with(1, 'replaced'); | ||
| sink(newArr[0]); // $ hasValueFlow=with.2.1 | ||
| sink(newArr[2]); // $ hasValueFlow=with.2.3 | ||
| } | ||
|
|
||
| function t3() { | ||
| const arr = [1, 2, 3]; | ||
| const index = source('with.3.index'); | ||
| const newArr = arr.with(index, 'new value'); | ||
| // No assertions here as the index is tainted, not the value | ||
| } | ||
|
|
||
| function t4() { | ||
| const arr = [1, 2, 3]; | ||
| const newArr = arr.with(1, source('with.4')); | ||
| sink(arr[1]); // This should NOT have value flow as with() returns a new array | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| async function t1() { | ||
| const promise = Promise.try(() => { | ||
| return source('try.1'); | ||
| }); | ||
| sink(await promise); // $ hasValueFlow=try.1 | ||
| } | ||
|
|
||
| async function t2() { | ||
| const promise = Promise.try((x) => { | ||
| return x | ||
| }, source('try.2')); | ||
| sink(await promise); // $ hasValueFlow=try.2 | ||
| } | ||
|
|
||
| async function t3() { | ||
| const promise = Promise.try((x) => { | ||
| throw x; | ||
| }, source('try.3')); | ||
| promise.catch(err => { | ||
| sink(err); // $ hasValueFlow=try.3 | ||
| }); | ||
| } | ||
|
|
||
| async function t4() { | ||
| const promise = Promise.try((x, y) => { | ||
| return y; | ||
| }, source('try.4.1'), source('try.4.2')); | ||
| sink(await promise); // $ hasValueFlow=try.4.2 | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.