Skip to content

Commit 4cc7138

Browse files
authored
Merge pull request #4507 from erik-krogh/template
Approved by asgerf
2 parents 3587235 + 8c44392 commit 4cc7138

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ class CandidateStringLiteral extends StringLiteral {
6262
}
6363

6464
/**
65-
* Holds if `obj` has a property for each template variable in `lit` and they occur as arguments
66-
* to the same call.
65+
* Holds if there exists an object that has a property for each template variable in `lit` and
66+
* they occur as arguments to the same call.
6767
*
6868
* This recognises a typical pattern in which template arguments are passed along with a string,
6969
* for example:
@@ -73,14 +73,14 @@ class CandidateStringLiteral extends StringLiteral {
7373
* { url: url, name: name } );
7474
* ```
7575
*/
76-
predicate providesTemplateVariablesFor(ObjectExpr obj, CandidateStringLiteral lit) {
77-
exists(CallExpr call | call.getAnArgument() = obj and call.getAnArgument() = lit) and
78-
forex(string name | lit.getAReferencedVariable() = name | hasProperty(obj, name))
76+
predicate hasObjectProvidingTemplateVariables(CandidateStringLiteral lit) {
77+
exists(DataFlow::CallNode call, DataFlow::ObjectLiteralNode obj |
78+
call.getAnArgument().getALocalSource() = obj and
79+
call.getAnArgument().asExpr() = lit and
80+
forex(string name | name = lit.getAReferencedVariable() | exists(obj.getAPropertyWrite(name)))
81+
)
7982
}
8083

81-
/** Holds if `object` has a property with the given `name`. */
82-
predicate hasProperty(ObjectExpr object, string name) { name = object.getAProperty().getName() }
83-
8484
/**
8585
* Gets a declaration of variable `v` in `tl`, where `v` has the given `name` and
8686
* belongs to `scope`.
@@ -97,7 +97,7 @@ where
9797
decl = getDeclIn(v, s, name, lit.getTopLevel()) and
9898
lit.getAReferencedVariable() = name and
9999
lit.isInScope(s) and
100-
not exists(ObjectExpr obj | providesTemplateVariablesFor(obj, lit)) and
100+
not hasObjectProvidingTemplateVariables(lit) and
101101
not lit.getStringValue() = "${" + name + "}"
102102
select lit, "This string is not a template literal, but appears to reference the variable $@.",
103103
decl, v.getName()

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
| TemplateSyntaxInStringLiteral.js:17:15:17:40 | 'global ... alVar}' | This string is not a template literal, but appears to reference the variable $@. | TemplateSyntaxInStringLiteral.js:14:5:14:13 | globalVar | globalVar |
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 |
5+
| 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 |

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,16 @@ function baz(x){
2828
log.error("${x} ");
2929
log.error("${y} ");
3030
}
31+
32+
33+
function foo1() {
34+
const aTemplateLitInScope = `Connecting to ${id}`;
35+
const name = 2;
36+
const date = 3;
37+
const foobar = 4;
38+
39+
const data = {name: name, date: date};
40+
writer.emit("Name: ${name}, Date: ${date}.", data); // OK
41+
42+
writer.emit("Name: ${name}, Date: ${date}, ${foobar}", data); // NOT OK - `foobar` is not in `data`.
43+
}

0 commit comments

Comments
 (0)