JS: Model Array#toString

This commit is contained in:
Asger F
2025-02-17 11:10:51 +01:00
parent e8d1703224
commit d87534c7d0
2 changed files with 19 additions and 2 deletions

View File

@@ -24,6 +24,7 @@
private import javascript
private import semmle.javascript.dataflow.internal.DataFlowNode
private import semmle.javascript.dataflow.FlowSummary
private import Arrays
private import FlowSummaryUtil
class At extends SummarizedCallable {
@@ -41,15 +42,18 @@ class At extends SummarizedCallable {
}
class Concat extends SummarizedCallable {
Concat() { this = "Array#concat / String#concat" }
Concat() { this = "Array#concat / String#concat / Buffer.concat" }
override InstanceCall getACallSimple() { result.getMethodName() = "concat" }
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
// Array#concat.
// Also models Buffer.concat as this happens to out work well with our toString() model.
preservesValue = true and
input = "Argument[this,0..].ArrayElement" and
output = "ReturnValue.ArrayElement"
or
// String#concat
preservesValue = false and
input = "Argument[this,0..]" and
output = "ReturnValue"
@@ -149,3 +153,16 @@ class Values extends SummarizedCallable {
output = "ReturnValue.IteratorElement"
}
}
class ToString extends SummarizedCallable {
ToString() { this = "Object#toString / Array#toString" }
override DataFlow::MethodCallNode getACallSimple() { result.getMethodName() = "toString" }
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
preservesValue = false and
// Arrays stringify their contents and joins by ","
input = "Argument[this].ArrayElementDeep" and
output = "ReturnValue"
}
}

View File

@@ -3,5 +3,5 @@ import 'dummy';
function t1() {
const b1 = Buffer.from(source("t1.1"));
const b2 = Buffer.from(source("t1.2"));
sink(Buffer.concat([b1, b2]).toString("utf8")); // $ MISSING: hasTaintFlow=t1.1 hasTaintFlow=t1.2
sink(Buffer.concat([b1, b2]).toString("utf8")); // $ hasTaintFlow=t1.1 hasTaintFlow=t1.2
}