Skip to content

Commit 76214f6

Browse files
committed
JS: Add support for Array.prototype.with
Note: This was authored by Copilot
1 parent 592228b commit 76214f6

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

javascript/ql/lib/semmle/javascript/internal/flow_summaries/Arrays.qll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,25 @@ class ToSpliced extends SummarizedCallable {
544544
}
545545
}
546546

547+
class With extends SummarizedCallable {
548+
With() { this = "Array#with" }
549+
550+
override InstanceCall getACallSimple() { result.getMethodName() = "with" }
551+
552+
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
553+
preservesValue = true and
554+
(
555+
// Copy all elements from the original array to the new array
556+
input = "Argument[this].ArrayElement" and
557+
output = "ReturnValue.ArrayElement"
558+
or
559+
// Replace the value at the specified index
560+
input = "Argument[1]" and
561+
output = "ReturnValue.ArrayElement"
562+
)
563+
}
564+
}
565+
547566
class ArrayCoercionPackage extends FunctionalPackageSummary {
548567
ArrayCoercionPackage() { this = "ArrayCoercionPackage" }
549568

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
function t1() {
2+
const arr = [1, 2, 3];
3+
const newArr = arr.with(1, source('with.1'));
4+
sink(newArr[1]); // $ hasValueFlow=with.1
5+
}
6+
7+
function t2() {
8+
const arr = [source('with.2.1'), 2, source('with.2.3')];
9+
const newArr = arr.with(1, 'replaced');
10+
sink(newArr[0]); // $ hasValueFlow=with.2.1
11+
sink(newArr[2]); // $ hasValueFlow=with.2.3
12+
}
13+
14+
function t3() {
15+
const arr = [1, 2, 3];
16+
const index = source('with.3.index');
17+
const newArr = arr.with(index, 'new value');
18+
// No assertions here as the index is tainted, not the value
19+
}
20+
21+
function t4() {
22+
const arr = [1, 2, 3];
23+
const newArr = arr.with(1, source('with.4'));
24+
sink(arr[1]); // This should NOT have value flow as with() returns a new array
25+
}

0 commit comments

Comments
 (0)