New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Javascript escaping invalid, generates SyntaxError: expected expression, got '&' #940
Comments
This is intentional, not a bug. You should fix template like this (using data attribute) railsadminteam/rails_admin#2870 or disable HTML escape globally. Haml::Template.options[:escape_html] = false |
Okay, a pitty, but I can do this.
However, the code giving me this problem is like:
:javascript
var my_var=Array( #{ruby_array});
In the HAML Reference file it says: "Currently, filters ignore the :escape_html <http://haml.info/docs/yardoc/Haml/Options.html#escape_html-instance_method> option. This means that #{} interpolation within filters is never HTML-escaped."
Does this mean that the documentation is outdated?
… Op 10 jul. 2017, om 12:32 heeft Takashi Kokubun ***@***.***> het volgende geschreven:
This is intentional, not a bug. You should fix template like this (using data attribute) railsadminteam/rails_admin#2870 <railsadminteam/rails_admin#2870> or disable HTML escape globally.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub <#940 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAWNNxsf8SSP4RAh8kH8Srbd_cux4Kixks5sMf20gaJpZM4OPiE8>.
|
Yes, definitely. I fixed it 965e66e. Thank you for reporting it. |
@k0kubun is it possible to set the :javascript{ escape_html: false } Just looking to keep the same behavior as before. |
No, as said in #770.
In Rails, you can call html_safe to value. Otherwise no idea. |
I still don't understand how this works, or why it was introduced. What could previously be done with: :javascript
var array = #{@user.all.to_json} ...now results in a broken JSON output. Even if we ignore the why, I still don't know how to use :javascript{ escape_html: false }
var array = #{@user.all.to_json} Or does |
It seems that you use ActiveRecord and it's likely that you can use :javascript
var array = #{@user.all.to_json.html_safe}
Haml::Template.options[:escape_html] = false This would also solve your problem if you're using Rails.
That's because there are possibly vulnerable cases in some string interpolation. Following code can generate unexpected code in Haml 4, but not in Haml 5 with escape_html: true. - foo = "null;</script> ANY HTML HERE <script>"
:javascript
var array = #{foo} Does it make sense? |
The way I solved it, is to set somewhere in your config:
Haml::Template.options[:escape_html] = false
This will give you the ‘old way’.
… Op 31 jul. 2017, om 13:32 heeft Darth Praxeum ***@***.***> het volgende geschreven:
I still don't understand how this works, or why it was introduced. What could previously be done with:
:javascript
var array = ***@***.***_json}
...now results in a broken JSON output. Even if we ignore the why, I still don't know how to use :escape_html? Should it be used like in the above comment, i.e:
:javascript{ escape_html: false }
var array = ***@***.***_json}
Or does :escape_html go somewhere else?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub <#940 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAWNN8d3Gf55g5mrpnDYU9Ol-HEzeNFVks5sTbtpgaJpZM4OPiE8>.
|
Ah nice, yeah that makes sense. Although :javascript
var array = #{@available_shifts.to_json(:include => { :ward => {:include => :location} })} If I add :javascript
var array = #{@available_shifts.to_json.html_safe(:include => { :ward => {:include => :location} })} ...I get a I'll use the |
Please try one of followings if your application is on production: :javascript
var array = #{@available_shifts.to_json(:include => { :ward => {:include => :location} }).html_safe} :javascript
var array = #{raw @available_shifts.to_json(:include => { :ward => {:include => :location} })} |
Tried both of those and no difference. Adding |
Hmm, it sounds like another issue. Let me check. |
Also worth noting that I can't actually just put var array = #{@available_shifts.to_json(:include => { :ward => {:include => :location} })} I have to wrap the Rails section in quotes for it to do anything, i.e var array = "#{@available_shifts.to_json(:include => { :ward => {:include => :location} })}" |
You need string in :javascript
var array = #{@available_shifts.to_json(:include => { :ward => {:include => :location} }).dump.html_safe}; Anyway, I tried Haml 5.0.1 and |
Ok thanks, I'll take another look. |
New to Haml... TL;DR - in 'production' haml/template.rb forces :escape_html = true, so setting it false in the initializer doesn't work! After hours of trying to work out how to get a Ruby hash into a JavaScript object within a :javascript block (because should be easy, right?), and then, with reluctance, setting the global :escape_html option (because, outside of a few places, like :javascript, encoding to entities makes sense, right?) I finally had hashes in objects - or so I thought... Deploy to the server, and all the So anyway, a long while later of running production locally with breakpoints to narrow down what was going on - it turns out that, during initialization, in production, there's a line towards the end of :-/ But, fortunately, in this thread, (checking closed issues to see if it had been reported previously) I have learn't of 'html_safe' - something not mentioned as far as I can tell anywhere in the docs? [I know it's not a Haml feature] And now I know that, in a ...please add a mention of hash.to_json.html_safe in a couple of places, e.g. This example in the Ruby Interpolation: #{} section of the reference:
... perhaps the FAQ, and also mention html_safe in the [Escaping HTML] section of the docs, to make it easier for the noobs who come after me... :-) |
What about non rails users that don't have raw or html_safe?? |
Use data attribute. I've never experienced the case that data attribute couldn't be used for just injecting JSON from Ruby world. |
example please |
What if i want it as a js variable? |
var variable = document.getElementById("foo").getAttribute("data-bar");
// or possibly
var variable = JSON.parse(document.getElementById("foo").getAttribute("data-bar")); |
So the suggested solution is something like:
jiiikes |
Yes. Sorry for taking your time to migrate code in that way. |
I second @Justin-Maxwell's suggestion of documentation updates. This hit us with an update to For Rails apps and JSON, using
|
Following up on #940 (comment):
I managed to reproduce this consistently, and it actually seems like a subtle change in behavior introduced in Haml 5 that did not behave the same in Haml 4. I'm not sure this change in behavior is intentional, and this subtle difference can be quite dangerous considering its production-environment-specific behavior. I will follow-up on this in a linked issue. |
For others still facing migration pains related to this issue, I've opened a PR #984 that adds an |
More info here: haml/haml#940
+1 |
I wrote a little script to help us find cases of interpolation inside of HAML require 'haml'
# Couldn't get `Haml::Util.handle_interpolation` to work *shrug*
def scan_for_escape(t)
scanner = StringScanner.new(t)
yield scanner while scanner.scan_until(/#\{/)
end
def check(node, fname)
if node.type == :filter && node.value[:name] == "javascript"
interpolations = []
scan_for_escape(node.value[:text]) do |scanner|
start_pos = scanner.pos
Haml::Util.balance(scanner, '{', '}', 1)
end_pos = scanner.pos
matching = scanner.string[start_pos...end_pos]
interpolations << matching
end
not_safe = interpolations.reject { |i| i.match /.to_json.html_safe\s*}\z/ }
unless not_safe.empty?
puts "#{fname}:#{node.line}:"
not_safe.each do |b|
puts " #{b}"
end
end
else
node.children.each do |n|
check(n, fname)
end
end
end
ARGV.each do |fname|
file_contents = File.read(fname)
node = Haml::Parser.new({}).call(file_contents)
check(node, fname)
end run as something like In our case, we wanted to make sure every interpolation ended with |
The 5.0.0 release notes refers to:
However, I have (Haml 5.0.1):
In the browser this results into:
The browsers runs into an error on line 4 (list2) and 5 (hash2):
The text was updated successfully, but these errors were encountered: