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