Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #37 from judofyr/jsonp_u2028

JSONP: Always escape U+2028 and U+2029
  • Loading branch information...
commit 9f5bcddba198f3b8a5d76d83ebb4aa3887b65be5 2 parents 3f004dd + 24f3da1
@mtodd mtodd authored
Showing with 21 additions and 2 deletions.
  1. +11 −1 lib/rack/contrib/jsonp.rb
  2. +10 −1 test/spec_rack_jsonp.rb
View
12 lib/rack/contrib/jsonp.rb
@@ -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')
+ end
+
["#{callback}(#{body})"]
end
View
11 test/spec_rack_jsonp.rb
@@ -51,6 +51,15 @@
headers = Rack::JSONP.new(app).call(request)[1]
headers['Content-Type'].should.equal('application/javascript')
end
+
+ specify "should not allow literal U+2028 or U+2029" do
+ test_body = "{\"bar\":\"\u2028 and \u2029\"}"
+ callback = 'foo'
+ app = lambda { |env| [200, {'Content-Type' => 'application/json'}, [test_body]] }
+ request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
+ body = Rack::JSONP.new(app).call(request).last
+ body.join.should.not.match(/\u2028|\u2029/)
+ end
context "but is empty" do
specify "should " do
@@ -122,4 +131,4 @@ def assert_bad_request(response)
body.should.equal [test_body]
end
-end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.