lib/raven/okjson.rb in sentry-raven-0.12.0 vs lib/raven/okjson.rb in sentry-raven-0.12.1

- old
+ new

@@ -26,13 +26,12 @@ # Some parts adapted from # http://golang.org/src/pkg/json/decode.go and # http://golang.org/src/pkg/utf8/utf8.go module Raven - module OkJson - Upstream = '42' + Upstream = '43' extend self # Decodes a json document in string s and # returns the corresponding ruby value. @@ -60,32 +59,31 @@ # be raised if x contains any other value, such as # Nan, Infinity, Symbol, and Proc, or if a Hash key # is not a String. # Strings contained in x must be valid UTF-8. def encode(x) - visited = [] case x - when Hash then objenc(x, visited) - when Array then arrenc(x, visited) + when Hash then objenc(x) + when Array then arrenc(x) else raise Error, 'root value must be an Array or a Hash' end end - def valenc(x, visited) + def valenc(x) case x - when Hash then objenc(x, visited) - when Array then arrenc(x, visited) + when Hash then objenc(x) + when Array then arrenc(x) when String then strenc(x) when Symbol then strenc(x.to_s) when Numeric then numenc(x) when true then "true" when false then "false" when nil then "null" else - strenc((x.inspect rescue $!.to_s)) + raise Error, "cannot encode #{x.class}: #{x.inspect}" end end private @@ -132,10 +130,14 @@ # Returns the parsed value and any trailing tokens. def objparse(ts) ts = eat('{', ts) obj = {} + unless ts[0] + raise Error, "unexpected end of object" + end + if ts[0][0] == '}' return obj, ts[1..-1] end k, v, ts = pairparse(ts) @@ -175,10 +177,14 @@ # Returns the parsed value and any trailing tokens. def arrparse(ts) ts = eat('[', ts) arr = [] + unless ts[0] + raise Error, "unexpected end of array" + end + if ts[0][0] == ']' return arr, ts[1..-1] end v, ts = valparse(ts) @@ -425,31 +431,26 @@ raise Error, "invalid hex code #{c}" end end - def objenc(x, visited) - return '"{...}"' if visited.include?(x.__id__) - visited += [x.__id__] - '{' + x.map{|k,v| keyenc(k) + ':' + valenc(v, visited)}.join(',') + '}' + def objenc(x) + '{' + x.map{|k,v| keyenc(k) + ':' + valenc(v)}.join(',') + '}' end - def arrenc(a, visited) - return '"[...]"' if visited.include?(a.__id__) - visited += [a.__id__] - - '[' + a.map{|x| valenc(x, visited)}.join(',') + ']' + def arrenc(a) + '[' + a.map{|x| valenc(x)}.join(',') + ']' end def keyenc(k) case k when String then strenc(k) when Symbol then strenc(k.to_s) else - strenc(k.inspect) + raise Error, "Hash key is not a string: #{k.inspect}" end end def strenc(s) @@ -469,15 +470,20 @@ else c = s[r] # In ruby >= 1.9, s[r] is a codepoint, not a byte. if rubydoesenc? begin - c.ord # will raise an error if c is invalid UTF-8 + # c.ord will raise an error if c is invalid UTF-8 + if c.ord < Spc.ord + c = "\\u%04x" % [c.ord] + end t.write(c) rescue t.write(Ustrerr) end + elsif c < Spc + t.write("\\u%04x" % c) elsif Spc <= c && c <= ?~ t.putc(c) else n = ucharcopy(t, s, r) # ensure valid UTF-8 output r += n - 1 # r is incremented below @@ -489,14 +495,12 @@ t.string end def numenc(x) - if (x.nan? rescue false) - '"NaN"' - elsif (x.infinite? rescue false) - '"Infinite"' + if ((x.nan? || x.infinite?) rescue false) + raise Error, "Numeric cannot be represented: #{x}" end "#{x}" end @@ -603,7 +607,6 @@ Usurr3 = 0xe000 Spc = ' '[0] Unesc = {?b=>?\b, ?f=>?\f, ?n=>?\n, ?r=>?\r, ?t=>?\t} end - -end +end \ No newline at end of file