Skip to content

Commit 06dfc88

Browse files
committed
Fixed handling of escaped slashes in json.decode
1 parent 5555f60 commit 06dfc88

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

trunk/json/json.lua

+17-2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ local decode_scanObject
5454
local decode_scanString
5555
local decode_scanWhitespace
5656
local encodeString
57+
local decodeString
5758
local isArray
5859
local isEncodable
5960

@@ -141,6 +142,16 @@ function encodeString(s)
141142
return tostring(s):gsub('["\\\r\n\t]',qrep)
142143
end
143144

145+
--- Decodes a given JSON string back to a Lua string
146+
-- The characters, escapable in JSON (see above function) are automatically
147+
-- escaped by Lua. Nevertheless, the "/" (slash) character CAN be escaped in
148+
-- JSON but CANNOT be escaped in Lua.
149+
-- @param s The string to return as proper Lua string
150+
-- @return A JSON encoded string
151+
function decodeString(s)
152+
return (base.load("return " .. tostring(s):gsub("\\/", "/"))) ()
153+
end
154+
144155
-- Determines whether the given Lua type is an array or a table / dictionary.
145156
-- We consider any table an array if it has indexes 1..n for its n items, and no
146157
-- other data in the table.
@@ -253,8 +264,8 @@ do
253264
--escapechar[i] = "\\" .. string.char(i)
254265
end
255266

267+
charstounescape = "\"\'\\bfnrt/"
256268
--[[
257-
charstounescape = "\"\'\\bfnrt/";
258269
unescapechars = "\"'\\\b\f\n\r\t\/";
259270
for i=1,#charstounescape do
260271
escapechar[ charstounescape:byte(i) ] = unescapechars:sub(i,i)
@@ -383,11 +394,15 @@ do
383394
if t == c_esc then
384395
--table.insert(returnString, js_string:sub(start, pos-2))
385396
--table.insert(returnString, escapechar[ js_string:byte(pos) ])
397+
local c = js_string:sub(pos, pos)
398+
if (not charstounescape:find(c)) then
399+
error("invalid escape sequence '\\"..c.."' ("..location()..")")
400+
end
386401
pos = pos + 1
387402
--start = pos
388403
end -- jump over escaped chars, no matter what
389404
until t == true
390-
return (base.loadstring("return " .. js_string:sub(start-1, pos-1) ) ())
405+
return decodeString(js_string:sub(start-1, pos-1))
391406

392407
-- We consider the situation where no escaped chars were encountered separately,
393408
-- and use the fastest possible return in this case.

0 commit comments

Comments
 (0)