Skip to content

Commit

Permalink
Fix escaped quotes (#48)
Browse files Browse the repository at this point in the history
Co-authored-by: Marc Worrell <[email protected]>
  • Loading branch information
williamthome and mworrell authored Apr 26, 2024
1 parent 845bd16 commit ef201ef
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 19 deletions.
27 changes: 8 additions & 19 deletions src/template_compiler_scanner.erl
Original file line number Diff line number Diff line change
Expand Up @@ -286,41 +286,30 @@ scan(<<"_\'", T/binary>>, Scanned, {SourceRef, Row, Column}, {in_code, Closer})
scan(<<$', T/binary>>, Scanned, {SourceRef, Row, Column}, {in_identifier, Closer}) ->
scan(T, [{string_literal, {SourceRef, Row, Column}, <<>>} | Scanned], {SourceRef, Row, Column + 1}, {in_single_quote, Closer});

scan(<<"`", T/binary>>, Scanned, {SourceRef, Row, Column}, {in_code, Closer}) ->
scan(<<$`, T/binary>>, Scanned, {SourceRef, Row, Column}, {in_code, Closer}) ->
scan(T, [{atom_literal, {SourceRef, Row, Column}, <<>>} | Scanned], {SourceRef, Row, Column + 1}, {in_back_quote, Closer});

scan(<<$`, T/binary>>, Scanned, {SourceRef, Row, Column}, {in_identifier, Closer}) ->
scan(T, [{atom_literal, {SourceRef, Row, Column}, <<>>} | Scanned], {SourceRef, Row, Column + 1}, {in_back_quote, Closer});

scan(<<$\\, $", T/binary>>, Scanned, {SourceRef, Row, Column}, {in_double_quote, Closer}) ->
scan(T, append_char(Scanned, $"), {SourceRef, Row, Column + 1}, {in_double_quote_slash, Closer});

scan(<<H/utf8, T/binary>>, Scanned, {SourceRef, Row, Column}, {in_double_quote_slash, Closer}) ->
scan(T, append_char(Scanned, H), {SourceRef, Row, Column + 1}, {in_double_quote, Closer});
scan(T, append_char(append_char(Scanned, $\\), $"), {SourceRef, Row, Column + 2}, {in_double_quote, Closer});

scan(<<$\\, $', T/binary>>, Scanned, {SourceRef, Row, Column}, {in_single_quote, Closer}) ->
scan(T, append_char(Scanned, $'), {SourceRef, Row, Column + 1}, {in_single_quote_slash, Closer});

scan(<<H/utf8, T/binary>>, Scanned, {SourceRef, Row, Column}, {in_single_quote_slash, Closer}) ->
scan(T, append_char(Scanned, H), {SourceRef, Row, Column + 1}, {in_single_quote, Closer});

scan(<<$\\, T/binary>>, Scanned, {SourceRef, Row, Column}, {in_back_quote, Closer}) ->
scan(T, append_char(Scanned, $\\), {SourceRef, Row, Column + 1}, {in_back_quote_slash, Closer});

scan(<<H/utf8, T/binary>>, Scanned, {SourceRef, Row, Column}, {in_back_quote_slash, Closer}) ->
scan(T, append_char(Scanned, H), {SourceRef, Row, Column + 1}, {in_back_quote, Closer});

scan(T, append_char(append_char(Scanned, $\\), $'), {SourceRef, Row, Column + 2}, {in_single_quote, Closer});

scan(<<$\\, $`, T/binary>>, Scanned, {SourceRef, Row, Column}, {in_back_quote, Closer}) ->
scan(T, append_char(append_char(Scanned, $\\), $`), {SourceRef, Row, Column + 2}, {in_back_quote, Closer});

% end quote
scan(<<"\"", T/binary>>, Scanned, {SourceRef, Row, Column}, {in_double_quote, Closer}) ->
scan(<<$", T/binary>>, Scanned, {SourceRef, Row, Column}, {in_double_quote, Closer}) ->
scan(T, Scanned, {SourceRef, Row, Column + 1}, {in_code, Closer});

% treat single quotes the same as double quotes
scan(<<"\'", T/binary>>, Scanned, {SourceRef, Row, Column}, {in_single_quote, Closer}) ->
scan(<<$', T/binary>>, Scanned, {SourceRef, Row, Column}, {in_single_quote, Closer}) ->
scan(T, Scanned, {SourceRef, Row, Column + 1}, {in_code, Closer});

scan(<<"`", T/binary>>, Scanned, {SourceRef, Row, Column}, {in_back_quote, Closer}) ->
scan(<<$`, T/binary>>, Scanned, {SourceRef, Row, Column}, {in_back_quote, Closer}) ->
scan(T, Scanned, {SourceRef, Row, Column + 1}, {in_code, Closer});

scan(<<H/utf8, T/binary>>, Scanned, {SourceRef, Row, Column}, {in_double_quote, Closer}) ->
Expand Down
75 changes: 75 additions & 0 deletions test/template_compiler_quote_SUITE.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
-module(template_compiler_quote_SUITE).

-include_lib("common_test/include/ct.hrl").

-compile(export_all).


suite() ->
[
{timetrap, {seconds, 30}}
].

all() ->
[
{group, basic}
].

groups() ->
[{basic, [],
[single_quote_test
,single_quote_slash_test
,double_quote_test
,double_quote_slash_test
,back_quote_test
,back_quote_slash_test
]}].

init_per_suite(Config) ->
{ok, _} = application:ensure_all_started(template_compiler),
application:set_env(template_compiler, template_dir, test_data_dir(Config)),
Config.

end_per_suite(_Config) ->
ok.

init_per_group(basic, Config) ->
Config.

end_per_group(basic, _Config) ->
ok.

single_quote_test(_Config) ->
{ok, Bin} = template_compiler:render("quote_single.tpl", #{}, [], undefined),
<<"<pre>&lt;&lt;&quot;foo&quot;&gt;&gt;</pre>'bar'">> = iolist_to_binary(Bin),
ok.

single_quote_slash_test(_Config) ->
{ok, Bin} = template_compiler:render("quote_single_slash.tpl", #{}, [], undefined),
<<"<pre>&lt;&lt;&quot;&#39;foo&#39;&quot;&gt;&gt;</pre>\\'bar\\'">> = iolist_to_binary(Bin),
ok.

double_quote_test(_Config) ->
{ok, Bin} = template_compiler:render("quote_double.tpl", #{}, [], undefined),
<<"<pre>&lt;&lt;&quot;foo&quot;&gt;&gt;</pre>\"bar\"">> = iolist_to_binary(Bin),
ok.

double_quote_slash_test(_Config) ->
{ok, Bin} = template_compiler:render("quote_double_slash.tpl", #{}, [], undefined),
<<"<pre>&lt;&lt;&quot;\\&quot;foo\\&quot;&quot;&gt;&gt;</pre>\\\"bar\\\"">> = iolist_to_binary(Bin),
ok.

back_quote_test(_Config) ->
{ok, Bin} = template_compiler:render("quote_back.tpl", #{}, [], undefined),
<<"<pre>foo</pre>`bar`">> = iolist_to_binary(Bin),
ok.

back_quote_slash_test(_Config) ->
{ok, Bin} = template_compiler:render("quote_back_slash.tpl", #{}, [], undefined),
<<"<pre>&#39;\\\\`foo\\\\`&#39;</pre>\\`bar\\`">> = iolist_to_binary(Bin),
ok.

test_data_dir(Config) ->
filename:join([
filename:dirname(filename:dirname(?config(data_dir, Config))),
"test-data"]).
1 change: 1 addition & 0 deletions test/test-data/quote_back.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% print `foo` %}`bar`
1 change: 1 addition & 0 deletions test/test-data/quote_back_slash.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% print `\`foo\`` %}\`bar\`
1 change: 1 addition & 0 deletions test/test-data/quote_double.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% print "foo" %}"bar"
1 change: 1 addition & 0 deletions test/test-data/quote_double_slash.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% print "\"foo\"" %}\"bar\"
1 change: 1 addition & 0 deletions test/test-data/quote_single.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% print 'foo' %}'bar'
1 change: 1 addition & 0 deletions test/test-data/quote_single_slash.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% print '\'foo\'' %}\'bar\'

0 comments on commit ef201ef

Please sign in to comment.