Skip to content

Commit d87534c

Browse files
committed
JS: Model Array#toString
1 parent e8d1703 commit d87534c

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
private import javascript
2525
private import semmle.javascript.dataflow.internal.DataFlowNode
2626
private import semmle.javascript.dataflow.FlowSummary
27+
private import Arrays
2728
private import FlowSummaryUtil
2829

2930
class At extends SummarizedCallable {
@@ -41,15 +42,18 @@ class At extends SummarizedCallable {
4142
}
4243

4344
class Concat extends SummarizedCallable {
44-
Concat() { this = "Array#concat / String#concat" }
45+
Concat() { this = "Array#concat / String#concat / Buffer.concat" }
4546

4647
override InstanceCall getACallSimple() { result.getMethodName() = "concat" }
4748

4849
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
50+
// Array#concat.
51+
// Also models Buffer.concat as this happens to out work well with our toString() model.
4952
preservesValue = true and
5053
input = "Argument[this,0..].ArrayElement" and
5154
output = "ReturnValue.ArrayElement"
5255
or
56+
// String#concat
5357
preservesValue = false and
5458
input = "Argument[this,0..]" and
5559
output = "ReturnValue"
@@ -149,3 +153,16 @@ class Values extends SummarizedCallable {
149153
output = "ReturnValue.IteratorElement"
150154
}
151155
}
156+
157+
class ToString extends SummarizedCallable {
158+
ToString() { this = "Object#toString / Array#toString" }
159+
160+
override DataFlow::MethodCallNode getACallSimple() { result.getMethodName() = "toString" }
161+
162+
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
163+
preservesValue = false and
164+
// Arrays stringify their contents and joins by ","
165+
input = "Argument[this].ArrayElementDeep" and
166+
output = "ReturnValue"
167+
}
168+
}

javascript/ql/test/library-tests/TripleDot/buffer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ import 'dummy';
33
function t1() {
44
const b1 = Buffer.from(source("t1.1"));
55
const b2 = Buffer.from(source("t1.2"));
6-
sink(Buffer.concat([b1, b2]).toString("utf8")); // $ MISSING: hasTaintFlow=t1.1 hasTaintFlow=t1.2
6+
sink(Buffer.concat([b1, b2]).toString("utf8")); // $ hasTaintFlow=t1.1 hasTaintFlow=t1.2
77
}

0 commit comments

Comments
 (0)