Skip to content

Commit de4b655

Browse files
authored
Merge pull request #7327 from asgerf/js/handlebars-more-raw-interpolation
Approved by erik-krogh
2 parents 39ec713 + 8977542 commit de4b655

File tree

8 files changed

+141
-79
lines changed

8 files changed

+141
-79
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
lgtm,codescanning
2+
* Support for handlebars templates has improved. Raw interpolation tags of the form `{{& ... }}` are now recognized,
3+
as well as whitespace-trimming tags like `{{~ ... }}`.

javascript/extractor/src/com/semmle/js/extractor/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class Main {
4343
* A version identifier that should be updated every time the extractor changes in such a way that
4444
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
4545
*/
46-
public static final String EXTRACTOR_VERSION = "2021-11-23";
46+
public static final String EXTRACTOR_VERSION = "2021-12-17";
4747

4848
public static final Pattern NEWLINE = Pattern.compile("\n");
4949

javascript/extractor/src/com/semmle/js/extractor/TemplateEngines.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import com.semmle.util.trap.TrapWriter.Label;
88

99
public class TemplateEngines {
10-
private static final String MUSTACHE_TAG_TRIPLE = "\\{\\{\\{(.*?)\\}\\}\\}"; // {{{ x }}}
11-
private static final String MUSTACHE_TAG_DOUBLE = "\\{\\{(?!\\{)(.*?)\\}\\}"; // {{ x }}}
10+
private static final String MUSTACHE_TAG_TRIPLE = "\\{\\{\\{[~]?(.*?)[~]?\\}\\}\\}"; // {{{ x }}}
11+
private static final String MUSTACHE_TAG_DOUBLE = "\\{\\{(?!\\{)[~&]?(.*?)[~]?\\}\\}"; // {{ x }}}
1212
private static final String MUSTACHE_TAG_PERCENT = "\\{%(?!>)(.*?)%\\}"; // {% x %}
1313
private static final String EJS_TAG = "<%(?![%<>}])[-=]?(.*?)[_-]?%>"; // <% x %>
1414

@@ -22,7 +22,7 @@ public class TemplateEngines {
2222
public static final Pattern TEMPLATE_TAGS =
2323
Pattern.compile(
2424
StringUtil.glue(
25-
"|", TemplateEngines.MUSTACHE_TAG_DOUBLE, MUSTACHE_TAG_TRIPLE, MUSTACHE_TAG_PERCENT, EJS_TAG),
25+
"|", MUSTACHE_TAG_DOUBLE, MUSTACHE_TAG_TRIPLE, MUSTACHE_TAG_PERCENT, EJS_TAG),
2626
Pattern.DOTALL);
2727

2828
/**

javascript/ql/lib/semmle/javascript/frameworks/Templating.qll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,9 +551,11 @@ module Templating {
551551
private class MustacheStyleSyntax extends TemplateSyntax {
552552
MustacheStyleSyntax() { this = "mustache" }
553553

554-
override string getRawInterpolationRegexp() { result = "(?s)\\{\\{\\{(.*?)\\}\\}\\}" }
554+
override string getRawInterpolationRegexp() {
555+
result = "(?s)\\{\\{\\{(.*?)\\}\\}\\}|\\{\\{&(.*?)\\}\\}"
556+
}
555557

556-
override string getEscapingInterpolationRegexp() { result = "(?s)\\{\\{[^{](.*?)\\}\\}" }
558+
override string getEscapingInterpolationRegexp() { result = "(?s)\\{\\{[^{&](.*?)\\}\\}" }
557559

558560
override string getAFileExtension() { result = ["hbs", "njk"] }
559561

javascript/ql/test/library-tests/frameworks/Templating/CodeInjection.expected

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ nodes
4848
| views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> |
4949
| views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> |
5050
| views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString |
51-
| views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} |
52-
| views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} |
53-
| views/hbs_sinks.hbs:13:42:13:60 | dataInGeneratedCode |
54-
| views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} |
55-
| views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} |
56-
| views/hbs_sinks.hbs:16:22:16:35 | backslashSink1 |
57-
| views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} |
58-
| views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} |
59-
| views/hbs_sinks.hbs:21:42:21:65 | dataInE ... rString |
51+
| views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} |
52+
| views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} |
53+
| views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode |
54+
| views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} |
55+
| views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} |
56+
| views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 |
57+
| views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} |
58+
| views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} |
59+
| views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString |
6060
| views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} |
6161
| views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} |
6262
| views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode |
@@ -86,12 +86,12 @@ edges
8686
| app.js:17:25:17:48 | req.que ... shSink1 | views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 |
8787
| app.js:19:35:19:68 | req.que ... rString | views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString |
8888
| app.js:19:35:19:68 | req.que ... rString | views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString |
89-
| app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:13:42:13:60 | dataInGeneratedCode |
90-
| app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:13:42:13:60 | dataInGeneratedCode |
91-
| app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:16:22:16:35 | backslashSink1 |
92-
| app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:16:22:16:35 | backslashSink1 |
93-
| app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:21:42:21:65 | dataInE ... rString |
94-
| app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:21:42:21:65 | dataInE ... rString |
89+
| app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode |
90+
| app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode |
91+
| app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 |
92+
| app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 |
93+
| app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString |
94+
| app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString |
9595
| app.js:53:30:53:58 | req.que ... tedCode | views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode |
9696
| app.js:53:30:53:58 | req.que ... tedCode | views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode |
9797
| app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw |
@@ -126,12 +126,12 @@ edges
126126
| views/ejs_sinks.ejs:16:23:16:36 | backslashSink1 | views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> |
127127
| views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> |
128128
| views/ejs_sinks.ejs:21:43:21:66 | dataInE ... rString | views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> |
129-
| views/hbs_sinks.hbs:13:42:13:60 | dataInGeneratedCode | views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} |
130-
| views/hbs_sinks.hbs:13:42:13:60 | dataInGeneratedCode | views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} |
131-
| views/hbs_sinks.hbs:16:22:16:35 | backslashSink1 | views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} |
132-
| views/hbs_sinks.hbs:16:22:16:35 | backslashSink1 | views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} |
133-
| views/hbs_sinks.hbs:21:42:21:65 | dataInE ... rString | views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} |
134-
| views/hbs_sinks.hbs:21:42:21:65 | dataInE ... rString | views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} |
129+
| views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode | views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} |
130+
| views/hbs_sinks.hbs:25:42:25:60 | dataInGeneratedCode | views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} |
131+
| views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 | views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} |
132+
| views/hbs_sinks.hbs:28:22:28:35 | backslashSink1 | views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} |
133+
| views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString | views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} |
134+
| views/hbs_sinks.hbs:33:42:33:65 | dataInE ... rString | views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} |
135135
| views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} |
136136
| views/njk_sinks.njk:13:42:13:60 | dataInGeneratedCode | views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} |
137137
| views/njk_sinks.njk:14:45:14:66 | dataInG ... CodeRaw | views/njk_sinks.njk:14:45:14:73 | dataInG ... \| safe |
@@ -156,9 +156,9 @@ edges
156156
| views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> | app.js:15:30:15:58 | req.que ... tedCode | views/ejs_sinks.ejs:13:39:13:64 | <%= dataInGeneratedCode %> | $@ flows to here and is interpreted as code. | app.js:15:30:15:58 | req.que ... tedCode | User-provided value |
157157
| views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> | app.js:17:25:17:48 | req.que ... shSink1 | views/ejs_sinks.ejs:16:19:16:39 | <%= backslashSink1 %> | $@ flows to here and is interpreted as code. | app.js:17:25:17:48 | req.que ... shSink1 | User-provided value |
158158
| views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> | app.js:19:35:19:68 | req.que ... rString | views/ejs_sinks.ejs:21:39:21:69 | <%= dataInEventHandlerString %> | $@ flows to here and is interpreted as code. | app.js:19:35:19:68 | req.que ... rString | User-provided value |
159-
| views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} | app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:13:39:13:63 | {{ dataInGeneratedCode }} | $@ flows to here and is interpreted as code. | app.js:34:30:34:58 | req.que ... tedCode | User-provided value |
160-
| views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} | app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:16:19:16:38 | {{ backslashSink1 }} | $@ flows to here and is interpreted as code. | app.js:36:25:36:48 | req.que ... shSink1 | User-provided value |
161-
| views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} | app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:21:39:21:68 | {{ dataInEventHandlerString }} | $@ flows to here and is interpreted as code. | app.js:38:35:38:68 | req.que ... rString | User-provided value |
159+
| views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} | app.js:34:30:34:58 | req.que ... tedCode | views/hbs_sinks.hbs:25:39:25:63 | {{ dataInGeneratedCode }} | $@ flows to here and is interpreted as code. | app.js:34:30:34:58 | req.que ... tedCode | User-provided value |
160+
| views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} | app.js:36:25:36:48 | req.que ... shSink1 | views/hbs_sinks.hbs:28:19:28:38 | {{ backslashSink1 }} | $@ flows to here and is interpreted as code. | app.js:36:25:36:48 | req.que ... shSink1 | User-provided value |
161+
| views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} | app.js:38:35:38:68 | req.que ... rString | views/hbs_sinks.hbs:33:39:33:68 | {{ dataInEventHandlerString }} | $@ flows to here and is interpreted as code. | app.js:38:35:38:68 | req.que ... rString | User-provided value |
162162
| views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} | app.js:53:30:53:58 | req.que ... tedCode | views/njk_sinks.njk:13:39:13:63 | {{ dataInGeneratedCode }} | $@ flows to here and is interpreted as code. | app.js:53:30:53:58 | req.que ... tedCode | User-provided value |
163163
| views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} | app.js:54:33:54:64 | req.que ... CodeRaw | views/njk_sinks.njk:14:42:14:76 | {{ dataInGeneratedCodeRaw \| safe }} | $@ flows to here and is interpreted as code. | app.js:54:33:54:64 | req.que ... CodeRaw | User-provided value |
164164
| views/njk_sinks.njk:15:46:15:91 | {{ dataInGeneratedCodeJsonRaw \| json \| safe }} | app.js:55:37:55:72 | req.que ... JsonRaw | views/njk_sinks.njk:15:46:15:91 | {{ dataInGeneratedCodeJsonRaw \| json \| safe }} | $@ flows to here and is interpreted as code. | app.js:55:37:55:72 | req.que ... JsonRaw | User-provided value |

0 commit comments

Comments
 (0)