Haml: Unescaped attribute value form rendering a partial (HAML 5.0.1)

Created on 4 May 2017  路  6Comments  路  Source: haml/haml

After I updated HAML from 4.0.7 to 5.0.1 I encountered an issue with rendering a partial in an HTML attribute. I'm using Rails 5.

I have a view with this code:

.pop{ content: render('test') }
  Some view text

and a partial _test.html.haml:

.some-class
  partial content

The result HTML from this is:

<div class='pop' content='<div class='some-class'>
partial content
</div>
'>
Some view text
</div>

As you see the '-s in the content attribute are not escaped and so the HTML is messed up.

With HAML 4.0.7 the result HTML with the same code is:

<div class='pop' content="<div class='some-class'>&#x000A;  partial content&#x000A;</div>">
 Some view text
</div>

The outer quotations for the content attribute are "-s and the inner '

If I interpolate the result from rendering the partial like this:

.pop{ content: "#{render('test')}" }
  Some view text

The result HTML is OK and looks like:

<div class='pop' content='&lt;div class=&#39;some-class&#39;&gt;
partial content
&lt;/div&gt;
'>
Some view text
</div>

Is this a bug with HAML 5 or have I been using an "undocumented feature" in HAML 4? Please tell me if you need more information.

Most helpful comment

Or use .pop{ content: render('test').to_str }. As it's not straight-forward, it might be better to force to escape it after Haml 6...

All 6 comments

Changing quotes automatically is dropped in Haml 5. This behavior itself is intentional. What's wrong here is that you pass html_safe (SafeBuffer) object (any return value from render method will become so) as attribute value (that should be escaped). Suppose the case it has both types of quotes. It'll be broken in Haml 4 too. As you did, you should remove html_safe state.

One extra choice may be changing Haml to always escape it even if it's html_safe. But currently it's not implemented.

Hello. Is it correct that the same code returns different result for rails and pure haml call?

rails 5.1.0

index.html.haml

- attr_html  = capture_haml do                                                                                                                                                                                                                                                  
  %span.capture_haml test                                                                                                                                                                                                                                                       

%div.test_attr{ data: { content: attr_html } } 

returns unescaped html

<div class='test_attr' data-content='<span class='capture_haml'>test</span>
--
聽 | '></div>

haml
haml index.html.haml

returns correct string

<div class='test_attr' data-content='&lt;span class=&#39;capture_haml&#39;&gt;test&lt;/span&gt;
'></div>

Probably intentional https://github.com/haml/haml/blob/1d446b33207ae148f203ca1e5b68dd2428750962/lib/haml/helpers/xss_mods.rb#L62, but I don't know whether it's the case with Haml 4.0 or not.

For SafeBuffer outputs, results can differ between Rails and non-Rails. capture_haml results are likely to be HTML, so if you render like = attr_html, it shouldn't be HTML-escaped, right?

And for attributes, unlike Hamlit, Haml doesn't force to HTML-escape attributes if it's HTML-safe. That's basically for backward compatibility, and all of above things are intentional for now.

Haha, for some parts, I doubly commented the same thing.

@k0kubun, so the solution is to always use string interpolation when rendering partial as attribute value, right?

.pop{ content: "#{render('test')}" }
  Some view text

Or use .pop{ content: render('test').to_str }. As it's not straight-forward, it might be better to force to escape it after Haml 6...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kyletolle picture kyletolle  路  6Comments

noise-machines picture noise-machines  路  4Comments

modsognir picture modsognir  路  6Comments

Arcovion picture Arcovion  路  11Comments

yb66 picture yb66  路  4Comments