JS: Fixed false positive on manual string interpolation.

This commit is contained in:
Napalys Klicius
2025-06-12 11:35:33 +02:00
parent bafe7e66ad
commit 923aff2439
3 changed files with 27 additions and 5 deletions

View File

@@ -95,12 +95,36 @@ VarDecl getDeclIn(Variable v, Scope scope, string name, CandidateTopLevel tl) {
result.getTopLevel() = tl
}
/**
* Tracks data flow from a string literal that may flow to a replace operation.
*/
DataFlow::SourceNode trackString(CandidateStringLiteral lit, DataFlow::TypeTracker t) {
t.start() and result = lit.flow()
or
exists(DataFlow::TypeTracker t2 | result = trackString(lit, t2).track(t2, t))
}
/**
* Gets a string literal that flows to a replace operation.
*/
DataFlow::SourceNode trackString(CandidateStringLiteral lit) {
result = trackString(lit, DataFlow::TypeTracker::end())
}
/**
* Holds if the string literal flows to a replace method call.
*/
predicate hasReplaceMethodCall(CandidateStringLiteral lit) {
trackString(lit).getAMethodCall() instanceof StringReplaceCall
}
from CandidateStringLiteral lit, Variable v, Scope s, string name, VarDecl decl
where
decl = getDeclIn(v, s, name, lit.getTopLevel()) and
lit.getAReferencedVariable() = name and
lit.isInScope(s) and
not hasObjectProvidingTemplateVariables(lit) and
not lit.getStringValue() = "${" + name + "}"
not lit.getStringValue() = "${" + name + "}" and
not hasReplaceMethodCall(lit)
select lit, "This string is not a template literal, but appears to reference the variable $@.",
decl, v.getName()

View File

@@ -3,5 +3,3 @@
| TemplateSyntaxInStringLiteral.js:19:11:19:36 | 'global ... alVar}' | This string is not a template literal, but appears to reference the variable $@. | TemplateSyntaxInStringLiteral.js:14:5:14:13 | globalVar | globalVar |
| TemplateSyntaxInStringLiteral.js:28:15:28:21 | "${x} " | This string is not a template literal, but appears to reference the variable $@. | TemplateSyntaxInStringLiteral.js:25:14:25:14 | x | x |
| TemplateSyntaxInStringLiteral.js:42:17:42:57 | "Name: ... oobar}" | This string is not a template literal, but appears to reference the variable $@. | TemplateSyntaxInStringLiteral.js:37:11:37:16 | foobar | foobar |
| TemplateSyntaxInStringLiteral.js:62:15:62:29 | "Name: ${name}" | This string is not a template literal, but appears to reference the variable $@. | TemplateSyntaxInStringLiteral.js:61:30:61:33 | name | name |
| TemplateSyntaxInStringLiteral.js:66:11:66:44 | "Name: ... {name}" | This string is not a template literal, but appears to reference the variable $@. | TemplateSyntaxInStringLiteral.js:61:30:61:33 | name | name |

View File

@@ -59,11 +59,11 @@ function replacerAll(str, name) {
}
function manualInterpolation(name) {
let str = "Name: ${name}"; // $SPURIOUS:Alert
let str = "Name: ${name}";
let result1 = replacer(str, name);
console.log(result1);
str = "Name: ${name} and again: ${name}"; // $SPURIOUS:Alert
str = "Name: ${name} and again: ${name}";
let result2 = replacerAll(str, name);
console.log(result2);
}