24
24
private import javascript
25
25
private import semmle.javascript.dataflow.internal.DataFlowNode
26
26
private import semmle.javascript.dataflow.FlowSummary
27
+ private import Arrays
27
28
private import FlowSummaryUtil
28
29
29
30
class At extends SummarizedCallable {
@@ -41,15 +42,18 @@ class At extends SummarizedCallable {
41
42
}
42
43
43
44
class Concat extends SummarizedCallable {
44
- Concat ( ) { this = "Array#concat / String#concat" }
45
+ Concat ( ) { this = "Array#concat / String#concat / Buffer.concat " }
45
46
46
47
override InstanceCall getACallSimple ( ) { result .getMethodName ( ) = "concat" }
47
48
48
49
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.
49
52
preservesValue = true and
50
53
input = "Argument[this,0..].ArrayElement" and
51
54
output = "ReturnValue.ArrayElement"
52
55
or
56
+ // String#concat
53
57
preservesValue = false and
54
58
input = "Argument[this,0..]" and
55
59
output = "ReturnValue"
@@ -149,3 +153,16 @@ class Values extends SummarizedCallable {
149
153
output = "ReturnValue.IteratorElement"
150
154
}
151
155
}
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
+ }
0 commit comments