Skip to content

Commit 923aff2

Browse files
committed
JS: Fixed false positive on manual string interpolation.
1 parent bafe7e6 commit 923aff2

File tree

3 files changed

+27
-5
lines changed

3 files changed

+27
-5
lines changed

javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,36 @@ VarDecl getDeclIn(Variable v, Scope scope, string name, CandidateTopLevel tl) {
9595
result.getTopLevel() = tl
9696
}
9797

98+
/**
99+
* Tracks data flow from a string literal that may flow to a replace operation.
100+
*/
101+
DataFlow::SourceNode trackString(CandidateStringLiteral lit, DataFlow::TypeTracker t) {
102+
t.start() and result = lit.flow()
103+
or
104+
exists(DataFlow::TypeTracker t2 | result = trackString(lit, t2).track(t2, t))
105+
}
106+
107+
/**
108+
* Gets a string literal that flows to a replace operation.
109+
*/
110+
DataFlow::SourceNode trackString(CandidateStringLiteral lit) {
111+
result = trackString(lit, DataFlow::TypeTracker::end())
112+
}
113+
114+
/**
115+
* Holds if the string literal flows to a replace method call.
116+
*/
117+
predicate hasReplaceMethodCall(CandidateStringLiteral lit) {
118+
trackString(lit).getAMethodCall() instanceof StringReplaceCall
119+
}
120+
98121
from CandidateStringLiteral lit, Variable v, Scope s, string name, VarDecl decl
99122
where
100123
decl = getDeclIn(v, s, name, lit.getTopLevel()) and
101124
lit.getAReferencedVariable() = name and
102125
lit.isInScope(s) and
103126
not hasObjectProvidingTemplateVariables(lit) and
104-
not lit.getStringValue() = "${" + name + "}"
127+
not lit.getStringValue() = "${" + name + "}" and
128+
not hasReplaceMethodCall(lit)
105129
select lit, "This string is not a template literal, but appears to reference the variable $@.",
106130
decl, v.getName()

javascript/ql/test/query-tests/LanguageFeatures/TemplateSyntaxInStringLiteral/TemplateSyntaxInStringLiteral.expected

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,3 @@
33
| 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 |
44
| 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 |
55
| 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 |
6-
| 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 |
7-
| 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 |

javascript/ql/test/query-tests/LanguageFeatures/TemplateSyntaxInStringLiteral/TemplateSyntaxInStringLiteral.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ function replacerAll(str, name) {
5959
}
6060

6161
function manualInterpolation(name) {
62-
let str = "Name: ${name}"; // $SPURIOUS:Alert
62+
let str = "Name: ${name}";
6363
let result1 = replacer(str, name);
6464
console.log(result1);
6565

66-
str = "Name: ${name} and again: ${name}"; // $SPURIOUS:Alert
66+
str = "Name: ${name} and again: ${name}";
6767
let result2 = replacerAll(str, name);
6868
console.log(result2);
6969
}

0 commit comments

Comments
 (0)