-
Notifications
You must be signed in to change notification settings - Fork 222
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
JSONP: Always escape U+2028 and U+2029 #37
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,7 +75,17 @@ def valid_callback?(callback) | |
# since JSON is returned as a full string. | ||
# | ||
def pad(callback, response, body = "") | ||
response.each{ |s| body << s.to_s } | ||
response.each do |s| | ||
# U+2028 and U+2029 are allowed inside strings in JSON (as all literal | ||
# Unicode characters) but JavaScript defines them as newline | ||
# seperators. Because no literal newlines are allowed in a string, this | ||
# causes a ParseError in the browser. We work around this issue by | ||
# replacing them with the escaped version. This should be safe because | ||
# according to the JSON spec, these characters are *only* valid inside | ||
# a string and should therefore not be present any other places. | ||
body << s.to_s.gsub("\u2028", '\u2028').gsub("\u2029", '\u2029') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be cool to summarize why this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In Ruby
JSON specifies that
In Ruby the response isn't actually a string; it's something you can iterate. The reason for this is so you can create lazy/streaming responses (so you don't have to put everything into memory at the same time). This code on the other hand will put everything in memory at the same time, but it's quite simple to change it to a streaming version. So far, nobody has requested that, and it only matters if you serve huge JSONP responses. |
||
end | ||
|
||
["#{callback}(#{body})"] | ||
end | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job commenting this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just about to commit this (without comments) when I said to myself: "WTF is this? It doesn't make any sense at all? What's so special about U+2028/9?" Then I wrote the comment and all was good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha, and it clarified why escaping made the most sense (when my initial thought was to reject it instead). :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically, it's not really a 400 Bad Request either. The request from the client is perfectly fine, it's the response from the server that's wrong…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course, but it's only obvious when those UTF-8 characters are explained :)