22-- json.lua
33--
44-- Copyright (c) 2020 rxi
5- -- https://github.com/rxi/json.lua
6- --
7- -- 2023-02-08: Modified by RStudio, PBC to make encoding more robust under the
8- -- following example: encode(decode("[null, 'test']"))
95--
106-- Permission is hereby granted, free of charge, to any person obtaining a copy of
117-- this software and associated documentation files (the "Software"), to deal in
@@ -59,9 +55,6 @@ local function encode_nil(val)
5955 return " null"
6056end
6157
62- local function encode_string (val )
63- return ' "' .. val :gsub (' [%z\1 -\31 \\ "]' , escape_char ) .. ' "'
64- end
6558
6659local function encode_table (val , stack )
6760 local res = {}
@@ -72,45 +65,44 @@ local function encode_table(val, stack)
7265
7366 stack [val ] = true
7467
75- local n = 0
76- local types = {}
77-
78- for k in pairs (val ) do
79- types [type (k )] = true
80- end
81-
82- if # types > 1 then
83- error (" invalid table: mixed or invalid key types" )
84- elseif types [" number" ] then
85- -- Treat as array
86- local max_key = 0
68+ if rawget (val , 1 ) ~= nil or next (val ) == nil then
69+ -- Treat as array -- check keys are valid and it is not sparse
70+ local n = 0
8771 for k in pairs (val ) do
88- if k > max_key then
89- max_key = k
72+ if type ( k ) ~= " number " then
73+ error ( " invalid table: mixed or invalid key types " )
9074 end
75+ n = n + 1
9176 end
92- for i = 1 , max_key do
93- if val [i ] == nil then
94- table.insert (res , " null" )
95- else
96- local v = encode (val [i ], stack )
97- table.insert (res , v )
98- end
77+ if n ~= # val then
78+ error (" invalid table: sparse array" )
79+ end
80+ -- Encode
81+ for i , v in ipairs (val ) do
82+ table.insert (res , encode (v , stack ))
9983 end
10084 stack [val ] = nil
10185 return " [" .. table.concat (res , " ," ) .. " ]"
102- elseif types [" string" ] then
103- -- Treat as object
104- for k , v in _quarto .utils .table .sortedPairs (val ) do
105- table.insert (res , encode_string (k ) .. " :" .. encode (v , stack ))
86+
87+ else
88+ -- Treat as an object
89+ for k , v in pairs (val ) do
90+ if type (k ) ~= " string" then
91+ error (" invalid table: mixed or invalid key types" )
92+ end
93+ table.insert (res , encode (k , stack ) .. " :" .. encode (v , stack ))
10694 end
10795 stack [val ] = nil
10896 return " {" .. table.concat (res , " ," ) .. " }"
109- else
110- return " []"
11197 end
11298end
11399
100+
101+ local function encode_string (val )
102+ return ' "' .. val :gsub (' [%z\1 -\31 \\ "]' , escape_char ) .. ' "'
103+ end
104+
105+
114106local function encode_number (val )
115107 -- Check for NaN, -inf and inf
116108 if val ~= val or val <= - math.huge or val >= math.huge then
@@ -139,7 +131,7 @@ encode = function(val, stack)
139131end
140132
141133
142- local function jsonEncode (val )
134+ function json . encode (val )
143135 return ( encode (val ) )
144136end
145137
@@ -205,7 +197,7 @@ local function codepoint_to_utf8(n)
205197 return string.char (f (n / 4096 ) + 224 , f (n % 4096 / 64 ) + 128 , n % 64 + 128 )
206198 elseif n <= 0x10ffff then
207199 return string.char (f (n / 262144 ) + 240 , f (n % 262144 / 4096 ) + 128 ,
208- f (n % 4096 / 64 ) + 128 , n % 64 + 128 )
200+ f (n % 4096 / 64 ) + 128 , n % 64 + 128 )
209201 end
210202 error ( string.format (" invalid unicode codepoint '%x'" , n ) )
211203end
214206local function parse_unicode_escape (s )
215207 local n1 = tonumber ( s :sub (1 , 4 ), 16 )
216208 local n2 = tonumber ( s :sub (7 , 10 ), 16 )
217- -- Surrogate pair?
209+ -- Surrogate pair?
218210 if n2 then
219211 return codepoint_to_utf8 ((n1 - 0xd800 ) * 0x400 + (n2 - 0xdc00 ) + 0x10000 )
220212 else
@@ -240,8 +232,8 @@ local function parse_string(str, i)
240232 local c = str :sub (j , j )
241233 if c == " u" then
242234 local hex = str :match (" ^[dD][89aAbB]%x%x\\ u%x%x%x%x" , j + 1 )
243- or str :match (" ^%x%x%x%x" , j + 1 )
244- or decode_error (str , j - 1 , " invalid unicode escape in string" )
235+ or str :match (" ^%x%x%x%x" , j + 1 )
236+ or decode_error (str , j - 1 , " invalid unicode escape in string" )
245237 res = res .. parse_unicode_escape (hex )
246238 j = j + # hex
247239 else
@@ -380,7 +372,7 @@ parse = function(str, idx)
380372end
381373
382374
383- local function jsonDecode (str )
375+ function json . decode (str )
384376 if type (str ) ~= " string" then
385377 error (" expected argument of type string, got " .. type (str ))
386378 end
@@ -393,7 +385,4 @@ local function jsonDecode(str)
393385end
394386
395387
396- return {
397- encode = jsonEncode ,
398- decode = jsonDecode
399- }
388+ return json
0 commit comments