Elixir version (elixir -v):
Erlang/OTP 24 [erts-12.0.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]
Elixir 1.12.2 (compiled with Erlang/OTP 24)
Phoenix version (mix deps):
1.6.0-rc.0
Phoenix LiveView version (mix deps):
0.16.3
Operating system:
RHEL 8
Browsers you attempted to reproduce this bug on (the more the merrier):
N/A
Does the problem persist after removing "assets/node_modules" and trying again? Yes/no:
N/A
Actual behavior
Certain invalid template sequences completely break the tokenizer. BASICALLY, my template voodoo interacted with your tokenizer voodoo and exploded.
For example, line 2 of this admittedly horrible no good template code (albeit perfectly valid in EEx)
<%= for {cust, orders} <- @orders_cust do %>
<tr<%= if cust == @cust do %> class="current"<% end %>>
<td><%= Enum.count(orders) %></td>
<td><%= link cust, to: Routes.invoice_path(@conn, :auditable, cust: cust) %></td>
</tr>
<% end %>
Results in:
** (FunctionClauseError) no function clause matching in Phoenix.LiveView.HTMLTokenizer.handle_tag_name/3
The following arguments were given to Phoenix.LiveView.HTMLTokenizer.handle_tag_name/3:
# 1
""
# 2
12
# 3
["r", "t"]
Attempted function clauses (showing 3 out of 3):
defp handle_tag_name(<<c::utf8(), _rest::binary()>>, _column, _buffer = []) when c === 32 or c === 9 or c === 12 or c === 62 or c === 47 or c === 61 or c === 13 or c === 10
defp handle_tag_name(<<c::utf8(), _rest::binary()>> = text, column, buffer) when c === 32 or c === 9 or c === 12 or c === 62 or c === 47 or c === 61 or c === 13 or c === 10
defp handle_tag_name(<<c::utf8(), rest::binary()>>, column, buffer)
(phoenix_live_view 0.16.3) lib/phoenix_live_view/html_tokenizer.ex:170: Phoenix.LiveView.HTMLTokenizer.handle_tag_name/3
(phoenix_live_view 0.16.3) lib/phoenix_live_view/html_tokenizer.ex:126: Phoenix.LiveView.HTMLTokenizer.handle_tag_open/5
(phoenix_live_view 0.16.3) lib/phoenix_live_view/html_engine.ex:89: Phoenix.LiveView.HTMLEngine.handle_text/3
(eex 1.12.2) lib/eex/compiler.ex:48: EEx.Compiler.generate_buffer/4
(eex 1.12.2) lib/eex/compiler.ex:80: EEx.Compiler.generate_buffer/4
(phoenix_view 1.0.0) lib/phoenix/template.ex:371: Phoenix.Template.compile/3
(phoenix_view 1.0.0) lib/phoenix/template.ex:165: anonymous fn/4 in Phoenix.Template."MACRO-__before_compile__"/2
(elixir 1.12.2) lib/enum.ex:2385: Enum."-reduce/3-lists^foldl/2-0-"/3
(phoenix_view 1.0.0) expanding macro: Phoenix.Template.__before_compile__/1
lib/ship_web/views/invoice_view.ex:1: ShipWeb.InvoiceView (module)
(elixir 1.12.2) lib/kernel/parallel_compiler.ex:319: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7
which only points to the parent view file.
Expected behavior
A helpful error message such as happens with old style EEx tags inside of HTML tags (<%= @blah %>):
** (Phoenix.LiveView.HTMLTokenizer.ParseError) lib/proj/templates/invoice/to_audit.html.heex:24:12: expected closing `"` for attribute value
This may happen if there is an EEx interpolation inside a tag,
which is not supported. Instead of
<div <%= @some_attributes %>>
</div>
do
<div {@some_attributes}>
</div>
Where @some_attributes must be a keyword list or a map.
as happens with other similar template areas.
This appears to happen because rather than interpolating the variable directly into an attribute, i'm interpolating the entire attribute expression.
I completely understand this is a problem with my code, and know how to fix it on my side, but perhaps the tokenizer could be improved to be more helpful in cases like this. I suppose valid EEx syntax should also not break HEEx's tokenizer.
Environment
Actual behavior
Certain invalid template sequences completely break the tokenizer. BASICALLY, my template voodoo interacted with your tokenizer voodoo and exploded.
For example, line 2 of this admittedly horrible no good template code (albeit perfectly valid in EEx)
Results in:
which only points to the parent view file.
Expected behavior
A helpful error message such as happens with old style EEx tags inside of HTML tags (
<%= @blah %>
):as happens with other similar template areas.
This appears to happen because rather than interpolating the variable directly into an attribute, i'm interpolating the entire attribute expression.
I completely understand this is a problem with my code, and know how to fix it on my side, but perhaps the tokenizer could be improved to be more helpful in cases like this. I suppose valid EEx syntax should also not break HEEx's tokenizer.