webmcp
view libraries/json/json.c @ 178:1a85110cdbe2
Throw error in mondelefant-atom-connector when encountering illegal JSON document
| author | jbe | 
|---|---|
| date | Fri Aug 01 23:08:42 2014 +0200 (2014-08-01) | 
| parents | 20e393d2e6e1 | 
| children | 461e5353ffb1 | 
 line source
     1 #include <lua.h>
     2 #include <lauxlib.h>
     3 #include <stdlib.h>
     4 #include <string.h>
     5 #include <math.h>
     7 // maximum number of nested JSON values (objects and arrays):
     8 // NOTE: The Lua reference states that the stack may typically contain at least
     9 //       "a few thousand elements". Since every nested level consumes
    10 //       3 elements on the Lua stack (the object/array, its shadow table,
    11 //       a string key or a placeholder), we limit the number of nested levels
    12 //       to 500. If a stack overflow would still happen in the import function,
    13 //       this is detected nevertheless and an error is thrown (instead of
    14 //       returning nil and an error string).
    15 #define JSON_MAXDEPTH 500
    17 // generate dummy memory addresses that represents null values:
    18 char json_nullmark;
    19 #define json_isnullmark(L, i) (lua_touserdata((L), (i)) == &json_nullmark)
    20 #define json_pushnullmark(L) lua_pushlightuserdata((L), &json_nullmark)
    22 // macros for usage of Lua registry:
    23 #define JSON_REGENT char
    24 #define JSON_REGPOINTER void *
    25 #define json_regpointer(x) (&json_registry.x)
    26 #define json_regfetchpointer(L, x) lua_rawgetp((L), LUA_REGISTRYINDEX, (x))
    27 #define json_regfetch(L, x) json_regfetchpointer(L, json_regpointer(x))
    28 #define json_regstore(L, x) lua_rawsetp(L, LUA_REGISTRYINDEX, json_regpointer(x))
    30 // generate dummy memory addresses that represent Lua objects
    31 // via lightuserdata keys and LUA_REGISTRYINDEX:
    32 static struct {
    33   JSON_REGENT shadowtbl;  // ephemeron table that maps tables to their corresponding shadow table
    34   JSON_REGENT objectmt;   // metatable for JSON objects
    35   JSON_REGENT arraymt;    // metatable for JSON arrays
    36 } json_registry;
    38 // returns the string "<JSON null marker>":
    39 static int json_nullmark_tostring(lua_State *L) {
    40   lua_pushliteral(L, "<JSON null marker>");
    41   return 1;
    42 }
    44 #define json_convert_source_idx 1
    45 #define json_convert_iterator_idx 2
    46 #define json_convert_output_idx 3
    47 #define json_convert_shadow_idx 4
    48 #define json_convert_iterfun_idx 5
    49 #define json_convert_itertbl_idx 6
    51 // converts a Lua table (or any other iterable value) to a JSON object or JSON array:
    52 // (does never modify the argument, returns an empty object or array if argument is nil)
    53 static int json_convert(lua_State *L, int array) {
    54   int arrayidx = 0;
    55   // determine is argument is given:
    56   if (lua_isnoneornil(L, json_convert_source_idx)) {
    57     // if no argument is given (or if argument is nil),
    58     // create table with shadow table, and leave first table on top of stack:
    59     json_regfetch(L, shadowtbl);
    60     lua_newtable(L);
    61     lua_pushvalue(L, -1);
    62     lua_newtable(L);
    63     lua_rawset(L, -4);
    64   } else {
    65     // if an argument was given,
    66     // push its iterator function on stack position 2 if existent,
    67     // else push null for normal tables:
    68     lua_settop(L, 1);
    69     if (lua_getmetatable(L, json_convert_source_idx)) {
    70       lua_getfield(L, -1, array ? "__ipairs" : "__pairs");
    71       if (lua_isnil(L, -1)) luaL_checktype(L, 1, LUA_TTABLE);
    72       else if (lua_type(L, -1) != LUA_TFUNCTION)
    73         return luaL_error(L, "%s metamethod is not a function", array ? "__ipairs" : "__pairs");
    74       lua_replace(L, -2);
    75     } else {
    76       lua_pushnil(L);
    77     }
    78     // create result table on stack position 3:
    79     lua_newtable(L);
    80     // create shadow table on stack position 4:
    81     json_regfetch(L, shadowtbl);
    82     lua_newtable(L);
    83     lua_pushvalue(L, json_convert_output_idx);
    84     lua_pushvalue(L, -2);
    85     lua_rawset(L, -4);
    86     lua_replace(L, -2);
    87     // check if iterator function exists:
    88     if (lua_isnil(L, json_convert_iterator_idx)) {
    89       // if there is no iterator function,
    90       // distinguish between objects and arrays:
    91       if (array == 0) {
    92         // for an object, copy all string key value pairs to shadow table:
    93         for (lua_pushnil(L); lua_next(L, json_convert_source_idx); lua_pop(L, 1)) {
    94           if (lua_type(L, -2) == LUA_TSTRING) {
    95             lua_pushvalue(L, -2);
    96             lua_pushvalue(L, -2);
    97             lua_rawset(L, json_convert_shadow_idx);
    98           }
    99         }
   100       } else {
   101         // for an array, copy consecutive integer value pairs to shadow table:
   102         while (1) {
   103           // throw error if array would exceed INT_MAX elements:
   104           // TODO: Lua 5.3 may support more elements
   105           if (arrayidx == INT_MAX) {
   106             lua_pushnumber(L, (size_t)INT_MAX+1);
   107             lua_rawget(L, json_convert_source_idx);
   108             if (lua_isnil(L, -1)) break;
   109             return luaL_error(L, "Array exceeded length of %d elements", INT_MAX);
   110           }
   111           // get next array entry:
   112           arrayidx++;
   113           lua_rawgeti(L, json_convert_source_idx, arrayidx);
   114           // break if value is nil:
   115           if (lua_isnil(L, -1)) break;
   116           // store value in shadow table:
   117           lua_rawseti(L, json_convert_shadow_idx, arrayidx);
   118         }
   119       }
   120     } else {
   121       // if there is an iterator function,
   122       // call iterator function with source value (first argument)
   123       // and store 3 result values on stack positions 5 through 7:
   124       lua_pushvalue(L, json_convert_iterator_idx);
   125       lua_pushvalue(L, 1);
   126       lua_call(L, 1, 3);
   127       // iterate through key value pairs and store some of them in shadow table
   128       // while replacing nil values with null-marker:
   129       while (1) {
   130         // call iterfun function:
   131         lua_pushvalue(L, json_convert_iterfun_idx);
   132         lua_pushvalue(L, json_convert_itertbl_idx);
   133         lua_pushvalue(L, -3);
   134         lua_remove(L, -4);
   135         lua_call(L, 2, 2);
   136         // break iteration loop if key is nil:
   137         if (lua_isnil(L, -2)) break;
   138         // store key value pair only if key type is correct:
   139         if (lua_type(L, -2) == (array ? LUA_TNUMBER : LUA_TSTRING)) {
   140           // if key type is correct,
   141           // push key onto stack:
   142           lua_pushvalue(L, -2);
   143           // if value is nil, push null-marker onto stack (as value):
   144           if (lua_isnil(L, -2)) json_pushnullmark(L);
   145           // else push value onto stack:
   146           else lua_pushvalue(L, -2);
   147           // set key value pair in shadow table:
   148           lua_rawset(L, json_convert_shadow_idx);
   149         }
   150         // pop value from stack, but leave key on stack:
   151         lua_pop(L, 1);
   152       }
   153     }
   154     // let result table be on top of stack:
   155     lua_settop(L, json_convert_output_idx);
   156   }
   157   // set metatable (for result table on top of stack):
   158   if (array == 0) json_regfetch(L, objectmt);
   159   else json_regfetch(L, arraymt);
   160   lua_setmetatable(L, -2);
   161   // return table on top of stack:
   162   return 1;
   163 }
   165 // converts a Lua table (or any other iterable value) to a JSON object:
   166 // (does never modify the argument, returns an empty object or array if argument is nil)
   167 static int json_object(lua_State *L) {
   168   return json_convert(L, 0);
   169 }
   171 // converts a Lua table (or any other iterable value) to a JSON array:
   172 // (does never modify the argument, returns an empty object or array if argument is nil)
   173 static int json_array(lua_State *L) {
   174   return json_convert(L, 1);
   175 }
   177 // internal states of JSON parser:
   178 #define JSON_STATE_VALUE 0
   179 #define JSON_STATE_OBJECT_KEY 1
   180 #define JSON_STATE_OBJECT_KEY_TERMINATOR 2
   181 #define JSON_STATE_OBJECT_VALUE 3
   182 #define JSON_STATE_OBJECT_SEPARATOR 4
   183 #define JSON_STATE_ARRAY_VALUE 5
   184 #define JSON_STATE_ARRAY_SEPARATOR 6
   185 #define JSON_STATE_END 7
   187 // special Lua stack indicies for json_import function:
   188 #define json_import_objectmt_idx 2
   189 #define json_import_arraymt_idx 3
   190 #define json_import_shadowtbl_idx 4
   192 // macros for hex decoding:
   193 #define json_utf16_surrogate(x) ((x) >= 0xD800 && (x) <= 0xDFFF)
   194 #define json_utf16_lead(x) ((x) >= 0xD800 && (x) <= 0xDBFF)
   195 #define json_utf16_tail(x) ((x) >= 0xDC00 && (x) <= 0xDFFF)
   196 #define json_import_readhex(x) \
   197   do { \
   198     x = 0; \
   199     for (i=0; i<4; i++) { \
   200       x <<= 4; \
   201       c = str[pos++]; \
   202       if (c >= '0' && c <= '9') x += c - '0'; \
   203       else if (c >= 'A' && c <= 'F') x += c - 'A' + 10; \
   204       else if (c >= 'a' && c <= 'f') x += c - 'a' + 10; \
   205       else if (c == 0) goto json_import_unexpected_eof; \
   206       else goto json_import_unexpected_escape; \
   207     } \
   208   } while (0)
   210 // decodes a JSON document:
   211 static int json_import(lua_State *L) {
   212   int i;             // loop variable
   213   const char *str;   // string to parse
   214   size_t total;      // total length of string to parse
   215   size_t pos = 0;    // current position in string to parse
   216   size_t level = 0;  // nested levels of objects/arrays currently being processed
   217   int mode = JSON_STATE_VALUE;  // state of parser (i.e. "what's expected next?")
   218   unsigned char c;     // variable to store a single character to be processed (unsigned!)
   219   luaL_Buffer luabuf;  // Lua buffer to decode JSON string values
   220   char *cbuf;          // C buffer to decode JSON string values
   221   size_t outlen;       // maximum length or write position of C buffer
   222   long codepoint;      // decoded UTF-16 character or higher codepoint
   223   long utf16tail;      // second decoded UTF-16 character (surrogate tail)
   224   size_t arraylen;     // variable to temporarily store the array length
   225   // require string as argument and convert to C string with length information:
   226   str = luaL_checklstring(L, 1, &total);
   227   // if string contains a NULL byte, this is a syntax error
   228   if (strlen(str) != total) goto json_import_syntax_error;
   229   // stack shall contain one function argument:
   230   lua_settop(L, 1);
   231   // push objectmt onto stack position 2:
   232   json_regfetch(L, objectmt);
   233   // push arraymt onto stack position 3:
   234   json_regfetch(L, arraymt);
   235   // push shadowtbl onto stack position 4:
   236   json_regfetch(L, shadowtbl);
   237   // main loop of parser:
   238   json_import_loop:
   239   // skip whitespace and store next character in variable 'c':
   240   while (c = str[pos],
   241     c == ' ' ||
   242     c == '\f' ||
   243     c == '\n' ||
   244     c == '\r' ||
   245     c == '\t' ||
   246     c == '\v'
   247   ) pos++;
   248   // NOTE: variable c needs to be unsigned in the following code
   249   // switch statement to handle certain (single) characters:
   250   switch (c) {
   251   // handle end of JSON document:
   252   case 0:
   253     // if end of JSON document was expected, then return top element of stack as result:
   254     if (mode == JSON_STATE_END) return 1;
   255     // otherwise, the JSON document was malformed:
   256     if (level == 0) {
   257       lua_pushnil(L);
   258       lua_pushliteral(L, "Empty string");
   259     } else {
   260       json_import_unexpected_eof:
   261       lua_pushnil(L);
   262       lua_pushliteral(L, "Unexpected end of JSON document");
   263     }
   264     return 2;
   265   // new JSON object:
   266   case '{':
   267     // if a JSON object is not expected here, then return an error:
   268     if (
   269       mode != JSON_STATE_VALUE &&
   270       mode != JSON_STATE_OBJECT_VALUE &&
   271       mode != JSON_STATE_ARRAY_VALUE
   272     ) goto json_import_syntax_error;
   273     // create JSON object on stack:
   274     lua_newtable(L);
   275     // set metatable of JSON object:
   276     lua_pushvalue(L, json_import_objectmt_idx);
   277     lua_setmetatable(L, -2);
   278     // create internal shadow table on stack:
   279     lua_newtable(L);
   280     // register internal shadow table:
   281     lua_pushvalue(L, -2);
   282     lua_pushvalue(L, -2);
   283     lua_rawset(L, json_import_shadowtbl_idx);
   284     // expect object key (or end of object) to follow:
   285     mode = JSON_STATE_OBJECT_KEY;
   286     // jump to common code for opening JSON object and JSON array:
   287     goto json_import_open;
   288   // new JSON array:
   289   case '[':
   290     // if a JSON array is not expected here, then return an error:
   291     if (
   292       mode != JSON_STATE_VALUE &&
   293       mode != JSON_STATE_OBJECT_VALUE &&
   294       mode != JSON_STATE_ARRAY_VALUE
   295     ) goto json_import_syntax_error;
   296     // create JSON array on stack:
   297     lua_newtable(L);
   298     // set metatable of JSON array:
   299     lua_pushvalue(L, json_import_arraymt_idx);
   300     lua_setmetatable(L, -2);
   301     // create internal shadow table on stack:
   302     lua_newtable(L);
   303     // register internal shadow table:
   304     lua_pushvalue(L, -2);
   305     lua_pushvalue(L, -2);
   306     lua_rawset(L, json_import_shadowtbl_idx);
   307     // add nil as key (needed to keep stack balance) and as magic to detect arrays:
   308     lua_pushnil(L);
   309     // expect array value (or end of array) to follow:
   310     mode = JSON_STATE_ARRAY_VALUE;
   311     // continue with common code for opening JSON object and JSON array:
   312   // common code for opening JSON object or JSON array:
   313   json_import_open:
   314     // limit nested levels:
   315     if (level >= JSON_MAXDEPTH) {
   316       lua_pushnil(L);
   317       lua_pushfstring(L, "More than %d nested JSON levels", JSON_MAXDEPTH);
   318       return 2;
   319     }
   320     // additional buffer overflow protection:
   321     if (!lua_checkstack(L, LUA_MINSTACK))
   322       return luaL_error(L, "Caught stack overflow in JSON import function (too many nested levels and stack size too small)");
   323     // increment level:
   324     level++;
   325     // consume input character:
   326     pos++;
   327     goto json_import_loop;
   328   // end of JSON object:
   329   case '}':
   330     // if end of JSON object is not expected here, then return an error:
   331     if (
   332       mode != JSON_STATE_OBJECT_KEY &&
   333       mode != JSON_STATE_OBJECT_SEPARATOR
   334     ) goto json_import_syntax_error;
   335     // jump to common code for end of JSON object and JSON array:
   336     goto json_import_close;
   337   // end of JSON array:
   338   case ']':
   339     // if end of JSON array is not expected here, then return an error:
   340     if (
   341       mode != JSON_STATE_ARRAY_VALUE &&
   342       mode != JSON_STATE_ARRAY_SEPARATOR
   343     ) goto json_import_syntax_error;
   344     // pop nil key/magic (that was needed to keep stack balance):
   345     lua_pop(L, 1);
   346     // continue with common code for end of JSON object and JSON array:
   347   // common code for end of JSON object or JSON array:
   348   json_import_close:
   349     // consume input character:
   350     pos++;
   351     // pop shadow table:
   352     lua_pop(L, 1);
   353     // check if nested:
   354     if (--level) {
   355       // if nested,
   356       // check if outer(!) structure is an array or object:
   357       if (lua_isnil(L, -2)) {
   358         // select array value processing:
   359         mode = JSON_STATE_ARRAY_VALUE;
   360       } else {
   361         // select object value processing:
   362         mode = JSON_STATE_OBJECT_VALUE;
   363       }
   364       // store value in outer structure:
   365       goto json_import_process_value;
   366     }
   367     // if not nested, then expect end of JSON document and continue with loop:
   368     mode = JSON_STATE_END;
   369     goto json_import_loop;
   370   // key terminator:
   371   case ':':
   372     // if key terminator is not expected here, then return an error:
   373     if (mode != JSON_STATE_OBJECT_KEY_TERMINATOR)
   374       goto json_import_syntax_error;
   375     // consume input character:
   376     pos++;
   377     // expect object value to follow:
   378     mode = JSON_STATE_OBJECT_VALUE;
   379     // continue with loop:
   380     goto json_import_loop;
   381   // value terminator (NOTE: trailing comma at end of value or key-value list is tolerated by this parser)
   382   case ',':
   383     // branch according to parser state:
   384     if (mode == JSON_STATE_OBJECT_SEPARATOR) {
   385       // expect an object key to follow:
   386       mode = JSON_STATE_OBJECT_KEY;
   387     } else if (mode == JSON_STATE_ARRAY_SEPARATOR) {
   388       // expect an array value to follow:
   389       mode = JSON_STATE_ARRAY_VALUE;
   390     } else {
   391        // if value terminator is not expected here, then return an error:
   392        goto json_import_syntax_error;
   393     }
   394     // consume input character:
   395     pos++;
   396     // continue with loop:
   397     goto json_import_loop;
   398   // string literal:
   399   case '"':
   400     // consume quote character:
   401     pos++;
   402     // find last character in input string:
   403     outlen = pos;
   404     while ((c = str[outlen]) != '"') {
   405       // consume one character:
   406       outlen++;
   407       // handle unexpected end of JSON document:
   408       if (c == 0) goto json_import_unexpected_eof;
   409       // consume one extra character when encountering an escaped quote:
   410       else if (c == '\\' && str[outlen] == '"') outlen++;
   411     }
   412     // determine buffer length:
   413     outlen -= pos;
   414     // check if string is non empty:
   415     if (outlen) {
   416       // prepare buffer to decode string (with maximum possible length) and set write position to zero:
   417       cbuf = luaL_buffinitsize(L, &luabuf, outlen);
   418       outlen = 0;
   419       // loop through the characters until encountering end quote:
   420       while ((c = str[pos++]) != '"') {
   421         // NOTE: unexpected end cannot happen anymore
   422         if (c < 32 || c == 127) {
   423           // do not allow ASCII control characters:
   424           // NOTE: illegal UTF-8 sequences and extended control characters are not sanitized
   425           //       by this parser to allow different encodings than Unicode
   426           lua_pushnil(L);
   427           lua_pushliteral(L, "Unexpected control character in JSON string");
   428           return 2;
   429         } else if (c == '\\') {
   430           // read next char after backslash escape:
   431           c = str[pos++];
   432           switch (c) {
   433           // unexpected end-of-string:
   434           case 0:
   435             goto json_import_unexpected_eof;
   436           // unescaping of quotation mark, slash, and backslash:
   437           case '"':
   438           case '/':
   439           case '\\':
   440             cbuf[outlen++] = c;
   441             break;
   442           // unescaping of backspace:
   443           case 'b': cbuf[outlen++] = '\b'; break;
   444           // unescaping of form-feed:
   445           case 'f': cbuf[outlen++] = '\f'; break;
   446           // unescaping of new-line:
   447           case 'n': cbuf[outlen++] = '\n'; break;
   448           // unescaping of carriage-return:
   449           case 'r': cbuf[outlen++] = '\r'; break;
   450           // unescaping of tabulator:
   451           case 't': cbuf[outlen++] = '\t'; break;
   452           // unescaping of UTF-16 characters
   453           case 'u':
   454             // decode 4 hex nibbles:
   455             json_import_readhex(codepoint);
   456             // handle surrogate character:
   457             if (json_utf16_surrogate(codepoint)) {
   458               // check if first surrogate is in valid range:
   459               if (json_utf16_lead(codepoint)) {
   460                 // require second surrogate:
   461                 if ((c = str[pos++]) != '\\' || (c = str[pos++]) != 'u') {
   462                   if (c == 0) goto json_import_unexpected_eof;
   463                   else goto json_import_wrong_surrogate;
   464                 }
   465                 // read 4 hex nibbles of second surrogate character:
   466                 json_import_readhex(utf16tail);
   467                 // check if second surrogate is in valid range:
   468                 if (!json_utf16_tail(utf16tail)) goto json_import_wrong_surrogate;
   469                 // calculate codepoint:
   470                 codepoint = 0x10000 + (utf16tail - 0xDC00) + (codepoint - 0xD800) * 0x400;
   471               } else {
   472                 // throw error for wrong surrogates:
   473                 json_import_wrong_surrogate:
   474                 lua_pushnil(L);
   475                 lua_pushliteral(L, "Illegal UTF-16 surrogate in JSON string escape sequence");
   476                 return 2;
   477               }
   478             }
   479             // encode as UTF-8:
   480             if (codepoint < 0x80) {
   481               cbuf[outlen++] = (char)codepoint;
   482             } else if (codepoint < 0x800) {
   483               cbuf[outlen++] = (char)(0xc0 | (codepoint >> 6));
   484               cbuf[outlen++] = (char)(0x80 | (codepoint & 0x3f));
   485             } else if (codepoint < 0x10000) {
   486               cbuf[outlen++] = (char)(0xe0 | (codepoint >> 12));
   487               cbuf[outlen++] = (char)(0x80 | ((codepoint >> 6) & 0x3f));
   488               cbuf[outlen++] = (char)(0x80 | (codepoint & 0x3f));
   489             } else {
   490               cbuf[outlen++] = (char)(0xf0 | (codepoint >> 18));
   491               cbuf[outlen++] = (char)(0x80 | ((codepoint >> 12) & 0x3f));
   492               cbuf[outlen++] = (char)(0x80 | ((codepoint >> 6) & 0x3f));
   493               cbuf[outlen++] = (char)(0x80 | (codepoint & 0x3f));
   494             }
   495             break;
   496           // unexpected escape sequence:
   497           default:
   498             json_import_unexpected_escape:
   499             lua_pushnil(L);
   500             lua_pushliteral(L, "Unexpected string escape sequence in JSON document");
   501             return 2;
   502           }
   503         } else {
   504           // normal character:
   505           cbuf[outlen++] = c;
   506         }
   507       }
   508       // process buffer to Lua string:
   509       luaL_pushresultsize(&luabuf, outlen);
   510     } else {
   511       // if JSON string is empty,
   512       // push empty Lua string:
   513       lua_pushliteral(L, "");
   514       // consume closing quote:
   515       pos++;
   516     }
   517     // continue with processing of decoded string:
   518     goto json_import_process_value;
   519   }
   520   // process values whose type is is not deducible from a single character:
   521   if ((c >= '0' && c <= '9') || c == '-' || c == '+') {
   522     // for numbers,
   523     // use strtod() call to parse a (double precision) floating point number:
   524     double numval;
   525     char *endptr;
   526     numval = strtod(str+pos, &endptr);
   527     // catch parsing errors:
   528     if (endptr == str+pos) goto json_import_syntax_error;
   529     // consume characters that were parsed:
   530     pos += endptr - (str+pos);
   531     // push parsed (double precision) floating point number on Lua stack:
   532     lua_pushnumber(L, numval);
   533   } else if (!strncmp(str+pos, "true", 4)) {
   534     // consume 4 input characters for "true":
   535     pos += 4;
   536     // put Lua true value onto stack:
   537     lua_pushboolean(L, 1);
   538   } else if (!strncmp(str+pos, "false", 5)) {
   539     // consume 5 input characters for "false":
   540     pos += 5;
   541     // put Lua false value onto stack:
   542     lua_pushboolean(L, 0);
   543   } else if (!strncmp(str+pos, "null", 4)) {
   544     // consume 4 input characters for "null":
   545     pos += 4;
   546     // different behavor for top-level and sub-levels:
   547     if (level) {
   548       // if sub-level,
   549       // push special null-marker onto stack:
   550       json_pushnullmark(L);
   551     } else {
   552       // if top-level,
   553       // push nil onto stack:
   554       lua_pushnil(L);
   555     }
   556   } else {
   557     // all other cases are a syntax error:
   558     goto json_import_syntax_error;
   559   }
   560   // process a decoded value or key value pair (expected on top of Lua stack):
   561   json_import_process_value:
   562   switch (mode) {
   563   // an object key has been read:
   564   case JSON_STATE_OBJECT_KEY:
   565     // if an object key is not a string, then this is a syntax error:
   566     if (lua_type(L, -1) != LUA_TSTRING) goto json_import_syntax_error;
   567     // expect key terminator to follow:
   568     mode = JSON_STATE_OBJECT_KEY_TERMINATOR;
   569     // continue with loop:
   570     goto json_import_loop;
   571   // a key value pair has been read:
   572   case JSON_STATE_OBJECT_VALUE:
   573     // store key value pair in outer shadow table:
   574     lua_rawset(L, -3);
   575     // expect value terminator (or end of object) to follow:
   576     mode = JSON_STATE_OBJECT_SEPARATOR;
   577     // continue with loop:
   578     goto json_import_loop;
   579   // an array value has been read:
   580   case JSON_STATE_ARRAY_VALUE:
   581     // get current array length:
   582     arraylen = lua_rawlen(L, -3);
   583     // throw error if array would exceed INT_MAX elements:
   584     // TODO: Lua 5.3 may support more elements
   585     if (arraylen >= INT_MAX) {
   586       lua_pushnil(L);
   587       lua_pushfstring(L, "Array exceeded length of %d elements", INT_MAX);
   588     }
   589     // store value in outer shadow table:
   590     lua_rawseti(L, -3, arraylen + 1);
   591     // expect value terminator (or end of object) to follow:
   592     mode = JSON_STATE_ARRAY_SEPARATOR;
   593     // continue with loop
   594     goto json_import_loop;
   595   // a single value has been read:
   596   case JSON_STATE_VALUE:
   597     // leave value on top of stack, expect end of JSON document, and continue with loop:
   598     mode = JSON_STATE_END;
   599     goto json_import_loop;
   600   }
   601   // syntax error handling (reachable by goto statement):
   602   json_import_syntax_error:
   603   lua_pushnil(L);
   604   lua_pushliteral(L, "Syntax error in JSON document");
   605   return 2;
   606 }
   608 // special Lua stack indicies for json_path function:
   609 #define json_path_shadowtbl_idx 1
   611 // stack offset of arguments to json_path function:
   612 #define json_path_idxshift 1
   614 // gets a value or its type from a JSON document (passed as first argument)
   615 // using a path (passed as variable number of keys after the first argument):
   616 static int json_path(lua_State *L, int type_mode) {
   617   int stacktop;                      // stack index of top of stack (after shifting)
   618   int idx = 2 + json_path_idxshift;  // stack index of current argument to process
   619   // require at least one argument:
   620   luaL_checkany(L, 1);
   621   // insert shadowtbl into stack at position 1 (shifting the arguments):
   622   json_regfetch(L, shadowtbl);
   623   lua_insert(L, 1);
   624   // store stack index of top of stack:
   625   stacktop = lua_gettop(L);
   626   // use first argument as "current value" (stored on top of stack):
   627   lua_pushvalue(L, 1 + json_path_idxshift);
   628   // process each "path key" (2nd argument and following arguments):
   629   while (idx <= stacktop) {
   630     // if "current value" (on top of stack) is nil, then the path cannot be walked and nil is returned:
   631     if (lua_isnil(L, -1)) return 1;
   632     // try to get shadow table of "current value":
   633     lua_pushvalue(L, -1);
   634     lua_rawget(L, json_path_shadowtbl_idx);
   635     if (lua_isnil(L, -1)) {
   636       // if no shadow table is found,
   637       if (lua_type(L, -1) == LUA_TTABLE) {
   638         // and if "current value" is a table,
   639         // drop nil from stack:
   640         lua_pop(L, 1);
   641         // get "next value" using the "path key":
   642         lua_pushvalue(L, idx++);
   643         lua_gettable(L, -2);
   644       } else {
   645         // if "current value" is not a table,
   646         // then the path cannot be walked and nil (already on top of stack) is returned:
   647         return 1;
   648       }
   649     } else {
   650       // if a shadow table is found,
   651       // set "current value" to its shadow table:
   652       lua_replace(L, -2);
   653       // get "next value" using the "path key":
   654       lua_pushvalue(L, idx++);
   655       lua_rawget(L, -2);
   656     }
   657     // the "next value" replaces the "current value":
   658     lua_replace(L, -2);
   659   }
   660   if (!type_mode) {
   661     // if a value (and not its type) was requested,
   662     // check if value is the null-marker, and store nil on top of Lua stack in that case:
   663     if (json_isnullmark(L, -1)) lua_pushnil(L);
   664   } else {
   665     // if the type was requested,
   666     // check if value is the null-marker:
   667     if (json_isnullmark(L, -1)) {
   668       // if yes, store string "null" on top of Lua stack:
   669       lua_pushliteral(L, "null");
   670     } else {
   671       // otherwise,
   672       // check if metatable indicates "object" or "array":
   673       if (lua_getmetatable(L, -1)) {
   674         json_regfetch(L, objectmt);
   675         if (lua_rawequal(L, -2, -1)) {
   676           // if value has metatable for JSON objects,
   677           // return string "object":
   678           lua_pushliteral(L, "object");
   679           return 1;
   680         }
   681         json_regfetch(L, arraymt);
   682         if (lua_rawequal(L, -3, -1)) {
   683           // if value has metatable for JSON arrays,
   684           // return string "object":
   685           lua_pushliteral(L, "array");
   686           return 1;
   687         }
   688         // remove 3 metatables (one of the value, two for comparison) from stack:
   689         lua_pop(L, 3);
   690       }
   691       // otherwise, get the Lua type:
   692       lua_pushstring(L, lua_typename(L, lua_type(L, -1)));
   693     }
   694   }
   695   // return the top most value on the Lua stack:
   696   return 1;
   697 }
   699 // gets a value from a JSON document (passed as first argument)
   700 // using a path (passed as variable number of keys after the first argument):
   701 static int json_get(lua_State *L) {
   702   return json_path(L, 0);
   703 }
   705 // gets a value's type from a JSON document (passed as first argument)
   706 // using a path (passed as variable number of keys after first the argument):
   707 static int json_type(lua_State *L) {
   708   return json_path(L, 1);
   709 }
   711 // special Lua stack indicies for json_set function:
   712 #define json_set_shadowtbl_idx 1
   713 #define json_set_objectmt_idx 2
   714 #define json_set_arraymt_idx 3
   716 // stack offset of arguments to json_set function:
   717 #define json_set_idxshift 3
   719 // sets a value (passed as second argument) in a JSON document (passed as first argument)
   720 // using a path (passed as variable number of keys starting at third argument):
   721 static int json_set(lua_State *L) {
   722   int stacktop;   // stack index of top of stack (after shifting)
   723   int idx = 3;    // stack index of current argument to process
   724   // require at least two arguments:
   725   luaL_checkany(L, 1);
   726   luaL_checkany(L, 2);
   727   // insert shadowtbl into stack at position 1 (shifting the arguments):
   728   json_regfetch(L, shadowtbl);
   729   lua_insert(L, 1);
   730   // insert objectmt into stack at position 2 (shifting the arguments):
   731   json_regfetch(L, objectmt);
   732   lua_insert(L, 2);
   733   // insert arraymt into stack at position 3 (shifting the arguments):
   734   json_regfetch(L, arraymt);
   735   lua_insert(L, 3);
   736   // store stack index of top of stack:
   737   stacktop = lua_gettop(L);
   738   // use nil as initial "parent value":
   739   lua_pushnil(L);
   740   // use first argument as "current value":
   741   lua_pushvalue(L, 1 + json_set_idxshift);
   742   // set all necessary values in path:
   743   for (idx = 3 + json_set_idxshift; idx<=stacktop; idx++) {
   744     // push metatable of "current value" onto stack:
   745     if (!lua_getmetatable(L, -1)) lua_pushnil(L);
   746     // distinguish according to type of path key:
   747     switch (lua_type(L, idx)) {
   748     case LUA_TSTRING:
   749       // if path key is a string,
   750       // check if "current value" is a JSON object (or table without metatable):
   751       if (
   752         lua_rawequal(L, -1, json_set_objectmt_idx) ||
   753         (lua_isnil(L, -1) && lua_type(L, -2) == LUA_TTABLE)
   754       ) {
   755         // if "current value" is acceptable,
   756         // pop metatable and leave "current value" on top of stack:
   757         lua_pop(L, 1);
   758       } else {
   759         // if "current value" is not acceptable:
   760         // pop metatable and "current value":
   761         lua_pop(L, 2);
   762         // throw error if parent element does not exist:
   763         if (lua_isnil(L, -1)) return luaL_error(L, "Root element is not a JSON object");
   764         // push new JSON object as "current value" onto stack:
   765         lua_newtable(L);
   766         // create and register shadow table:
   767         lua_pushvalue(L, -1);
   768         lua_newtable(L);
   769         lua_rawset(L, json_set_shadowtbl_idx);
   770         // set metatable of JSON object: 
   771         lua_pushvalue(L, json_set_objectmt_idx);
   772         lua_setmetatable(L, -2);
   773         // set entry in "parent value":
   774         lua_pushvalue(L, idx-1);
   775         lua_pushvalue(L, -2);
   776         lua_settable(L, -4);
   777       }
   778       break;
   779     case LUA_TNUMBER:
   780       // if path key is a number,
   781       // check if "current value" is a JSON array (or table without metatable):
   782       if (
   783         lua_rawequal(L, -1, json_set_arraymt_idx) ||
   784         (lua_isnil(L, -1) && lua_type(L, -2) == LUA_TTABLE)
   785       ) {
   786         // if "current value" is acceptable,
   787         // pop metatable and leave "current value" on top of stack:
   788         lua_pop(L, 1);
   789       } else {
   790         // if "current value" is not acceptable:
   791         // pop metatable and "current value":
   792         lua_pop(L, 2);
   793         // throw error if parent element does not exist:
   794         if (lua_isnil(L, -1)) return luaL_error(L, "Root element is not a JSON array");
   795         // push new JSON array as "current value" onto stack:
   796         lua_newtable(L);
   797         // create and register shadow table:
   798         lua_pushvalue(L, -1);
   799         lua_newtable(L);
   800         lua_rawset(L, json_set_shadowtbl_idx);
   801         // set metatable of JSON array: 
   802         lua_pushvalue(L, json_set_arraymt_idx);
   803         lua_setmetatable(L, -2);
   804         // set entry in "parent value":
   805         lua_pushvalue(L, idx-1);
   806         lua_pushvalue(L, -2);
   807         lua_settable(L, -4);
   808       }
   809       break;
   810     default:
   811       return luaL_error(L, "Invalid path key of type %s", lua_typename(L, lua_type(L, idx)));
   812     }
   813     // check if last path element is being processed:
   814     if (idx == stacktop) {
   815       // if the last path element is being processed,
   816       // set last path value in "current value" container:
   817       lua_pushvalue(L, idx);
   818       lua_pushvalue(L, 2 + json_set_idxshift);
   819       lua_settable(L, -3);
   820     } else {
   821       // if the processed path element is not the last,
   822       // use old "current value" as new "parent value"
   823       lua_remove(L, -2);
   824       // push new "current value" onto stack by performing a lookup:
   825       lua_pushvalue(L, idx);
   826       lua_gettable(L, -2);
   827     }
   828   }
   829   // return first argument for convenience:
   830   lua_settop(L, 1 + json_set_idxshift);
   831   return 1;
   832 }
   834 // returns the length of a JSON array (or zero for a table without numeric keys):
   835 static int json_len(lua_State *L) {
   836   // stack shall contain one function argument:
   837   lua_settop(L, 1);
   838   // try to get corresponding shadow table for first argument:
   839   json_regfetch(L, shadowtbl);
   840   lua_pushvalue(L, 1);
   841   lua_rawget(L, -2);
   842   // if shadow table does not exist, return length of argument, else length of shadow table:
   843   lua_pushnumber(L, lua_rawlen(L, lua_isnil(L, -1) ? 1 : -1));
   844   return 1;
   845 }
   847 // __index metamethod for JSON objects and JSON arrays:
   848 static int json_index(lua_State *L) {
   849   // stack shall contain two function arguments:
   850   lua_settop(L, 2);
   851   // get corresponding shadow table for first argument:
   852   json_regfetch(L, shadowtbl);
   853   lua_pushvalue(L, 1);
   854   lua_rawget(L, -2);
   855   // throw error if no shadow table was found:
   856   if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   857   // use key passed as second argument to lookup value in shadow table:
   858   lua_pushvalue(L, 2);
   859   lua_rawget(L, -2);
   860   // if value is null-marker, then push nil onto stack:
   861   if (json_isnullmark(L, -1)) lua_pushnil(L);
   862   // return either looked up value, or nil
   863   return 1;
   864 }
   866 // __newindex metamethod for JSON objects and JSON arrays:
   867 static int json_newindex(lua_State *L) {
   868   // stack shall contain three function arguments:
   869   lua_settop(L, 3);
   870   // get corresponding shadow table for first argument:
   871   json_regfetch(L, shadowtbl);
   872   lua_pushvalue(L, 1);
   873   lua_rawget(L, -2);
   874   // throw error if no shadow table was found:
   875   if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   876   // replace first argument with shadow table:
   877   lua_replace(L, 1);
   878   // reset stack and use second and third argument to write to shadow table:
   879   lua_settop(L, 3);
   880   lua_rawset(L, 1);
   881   // return nothing:
   882   return 0;
   883 }
   885 // function returned as first value by json_pairs function:
   886 static int json_pairs_iterfunc(lua_State *L) {
   887   // stack shall contain two function arguments:
   888   lua_settop(L, 2);
   889   // get corresponding shadow table for first argument:
   890   json_regfetch(L, shadowtbl);
   891   lua_pushvalue(L, 1);
   892   lua_rawget(L, -2);
   893   // throw error if no shadow table was found:
   894   if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   895   // get next key value pair from shadow table (using previous key from argument 2)
   896   // and return nothing if there is no next pair:
   897   lua_pushvalue(L, 2);
   898   if (!lua_next(L, -2)) return 0;
   899   // replace null-marker with nil:
   900   if (json_isnullmark(L, -1)) {
   901     lua_pop(L, 1);
   902     lua_pushnil(L);
   903   }
   904   // return key and value (or key and nil, if null-marker was found):
   905   return 2;
   906 }
   908 // returns a triple such that 'for key, value in pairs(obj) do ... end'
   909 // iterates through all key value pairs (including JSON null values represented as Lua nil):
   910 static int json_pairs(lua_State *L) {
   911   // require one argument to function
   912   luaL_checkany(L, 1);
   913   // return triple of function json_pairs_iterfunc, first argument, and nil:
   914   lua_pushcfunction(L, json_pairs_iterfunc);
   915   lua_pushvalue(L, 1);
   916   lua_pushnil(L);
   917   return 3;
   918 }
   920 // function returned as first value by json_ipairs function:
   921 static int json_ipairs_iterfunc(lua_State *L) {
   922   lua_Integer idx;
   923   // stack shall contain two function arguments:
   924   lua_settop(L, 2);
   925   // calculate new index by incrementing second argument:
   926   idx = lua_tointeger(L, 2) + 1;
   927   // get corresponding shadow table for first argument:
   928   json_regfetch(L, shadowtbl);
   929   lua_pushvalue(L, 1);
   930   lua_rawget(L, -2);
   931   // throw error if no shadow table was found:
   932   if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   933   // do integer lookup in shadow table:
   934   lua_rawgeti(L, -1, idx);
   935   // return nothing if there was no value:
   936   if (lua_isnil(L, -1)) return 0;
   937   // return new index and
   938   // either the looked up value if it is not equal to the null-marker
   939   // or nil instead of null-marker:
   940   lua_pushinteger(L, idx);
   941   if (json_isnullmark(L, -2)) lua_pushnil(L);
   942   else lua_pushvalue(L, -2);
   943   return 2;
   944 }
   946 // returns a triple such that 'for idx, value in ipairs(ary) do ... end'
   947 // iterates through all values (including JSON null values represented as Lua nil):
   948 static int json_ipairs(lua_State *L) {
   949   // require one argument to function
   950   luaL_checkany(L, 1);
   951   // return triple of function json_ipairs_iterfunc, first argument, and zero:
   952   lua_pushcfunction(L, json_ipairs_iterfunc);
   953   lua_pushvalue(L, 1);
   954   lua_pushinteger(L, 0);
   955   return 3;
   956 }
   958 // datatype representing a table key:
   959 // (used for sorting)
   960 typedef struct {
   961   size_t length;
   962   const char *data;
   963 } json_key_t;
   965 // comparation function for table keys to be passed to qsort function:
   966 static int json_key_cmp(json_key_t *key1, json_key_t *key2) {
   967   size_t pos = 0;
   968   unsigned char c1, c2;
   969   while (1) {
   970     if (key1->length > pos) {
   971       if (key2->length > pos) {
   972         c1 = key1->data[pos];
   973         c2 = key2->data[pos];
   974         if (c1 < c2) return -1;
   975         else if (c1 > c2) return 1;
   976       } else {
   977         return 1;
   978       }
   979     } else {
   980       if (key2->length > pos) {
   981         return -1;
   982       } else {
   983         return 0;
   984       }
   985     }
   986     pos++;
   987   }
   988 }
   990 // constants for type detection of ambiguous tables:
   991 #define JSON_TABLETYPE_UNKNOWN 0
   992 #define JSON_TABLETYPE_OBJECT 1
   993 #define JSON_TABLETYPE_ARRAY 2
   995 // special Lua stack indicies for json_export_internal function:
   996 #define json_export_internal_indentstring_idx 1
   997 #define json_export_internal_level_idx 2
   998 #define json_export_internal_value_idx 3
   999 #define json_export_internal_tmp_idx 4
  1001 // encodes a JSON document (passed as third argument)
  1002 // optionally using indentation (indentation string passed as first argument)
  1003 // for a certain depth level (passed as second argument):
  1004 static int json_export_internal(lua_State *L) {
  1005   int level;        // current depth level
  1006   int pretty;       // pretty printing on? (i.e. printing with indentation)
  1007   int i;            // iteration variable for level dependent repetitions:
  1008   lua_Number num;   // number to encode
  1009   const char *str;  // string to encode
  1010   size_t strlen;    // length of string to encode
  1011   unsigned char c;  // character to encode (unsigned!)
  1012   size_t pos = 0;   // position in string or position of current key (initialized with zero!)
  1013   luaL_Buffer buf;  // Lua buffer to create strings
  1014   char hexcode[7];  // store for unicode hex escape sequence
  1015                     // NOTE: 7 bytes due to backslash, character 'u', 4 hex digits, and terminating NULL byte
  1016   int tabletype = JSON_TABLETYPE_UNKNOWN;  // table type: unknown, JSON object, or JSON array
  1017   int anyelement = 0;         // set to 1 if at least one array element has been processed
  1018   size_t keycount = 0;        // number of string keys in object
  1019   json_key_t *keybuf = NULL;  // temporary buffer to store (and sort) string keys of objects
  1020   lua_Integer arrayidx;       // index to iterate through arrays
  1021   // stack shall contain three function arguments:
  1022   lua_settop(L, json_export_internal_value_idx);
  1023   // if value to encode is the null-marker, then treat it the same as nil:
  1024   if (json_isnullmark(L, json_export_internal_value_idx)) {
  1025     lua_pop(L, 1);
  1026     lua_pushnil(L);
  1027   }
  1028   // distinguish between different Lua types:
  1029   switch (lua_type(L, json_export_internal_value_idx)) {
  1030   // value to encode is nil:
  1031   case LUA_TNIL:
  1032     // return string "null":
  1033     lua_pushliteral(L, "null");
  1034     return 1;
  1035   // value to encode is of type number:
  1036   case LUA_TNUMBER:
  1037     // convert value to double precision number:
  1038     num = lua_tonumber(L, json_export_internal_value_idx);
  1039     // throw error if number is not-a-number:
  1040     if (isnan(num)) return luaL_error(L, "JSON export not possible for NaN value");
  1041     // throw error if number is positive or negative infinity:
  1042     if (isinf(num)) return luaL_error(L, "JSON export not possible for infinite numbers");
  1043     // return Lua's string encoding of the number:
  1044     lua_tostring(L, json_export_internal_value_idx);
  1045     return 1;
  1046   // value to encode is of type boolean:
  1047   case LUA_TBOOLEAN:
  1048     // return string "true" or "false" according to boolean value:
  1049     if (lua_toboolean(L, json_export_internal_value_idx)) {
  1050       lua_pushliteral(L, "true");
  1051     } else {
  1052       lua_pushliteral(L, "false");
  1053     }
  1054     return 1;
  1055   // value to encode is of type string:
  1056   case LUA_TSTRING:
  1057     // quote, escape and return string:
  1058     str = lua_tolstring(L, 3, &strlen);
  1059     luaL_buffinit(L, &buf);
  1060     luaL_addchar(&buf, '"');
  1061     while (pos < strlen) {
  1062       c = str[pos++];
  1063       if (c == '"')       luaL_addstring(&buf, "\\\"");
  1064       else if (c == '\\') luaL_addstring(&buf, "\\\\");
  1065       else if (c == 127)  luaL_addstring(&buf, "\\u007F");
  1066       else if (c >= 32)   luaL_addchar(&buf, c);
  1067       else if (c == '\b') luaL_addstring(&buf, "\\b");
  1068       else if (c == '\f') luaL_addstring(&buf, "\\f");
  1069       else if (c == '\n') luaL_addstring(&buf, "\\n");
  1070       else if (c == '\r') luaL_addstring(&buf, "\\r");
  1071       else if (c == '\t') luaL_addstring(&buf, "\\t");
  1072       else if (c == '\v') luaL_addstring(&buf, "\\v");
  1073       else {
  1074         sprintf(hexcode, "\\u%04X", c);
  1075         luaL_addstring(&buf, hexcode);
  1076       }
  1077     }
  1078     luaL_addchar(&buf, '"');
  1079     luaL_pushresult(&buf);
  1080     return 1;
  1081   // value to encode is of type table (this includes JSON objects and JSON arrays):
  1082   case LUA_TTABLE:
  1083     // use table's metatable to try to determine type of table:
  1084     if (lua_getmetatable(L, json_export_internal_value_idx)) {
  1085       json_regfetch(L, objectmt);
  1086       if (lua_rawequal(L, -2, -1)) {
  1087         tabletype = JSON_TABLETYPE_OBJECT;
  1088       } else {
  1089         json_regfetch(L, arraymt);
  1090         if (lua_rawequal(L, -3, -1)) {
  1091           tabletype = JSON_TABLETYPE_ARRAY;
  1092         } else {
  1093           return luaL_error(L, "JSON export not possible for tables with nonsupported metatable");
  1094         }
  1095       }
  1096     }
  1097     // replace table with its shadow table if existent, and reset stack:
  1098     json_regfetch(L, shadowtbl);
  1099     lua_pushvalue(L, json_export_internal_value_idx);
  1100     lua_rawget(L, -2);
  1101     if (!lua_isnil(L, -1)) lua_replace(L, json_export_internal_value_idx);
  1102     lua_settop(L, json_export_internal_value_idx);
  1103     // check if type of table is still undetermined:
  1104     if (tabletype == JSON_TABLETYPE_UNKNOWN) {
  1105       // if yes, iterate over all keys:
  1106       for (lua_pushnil(L); lua_next(L, json_export_internal_value_idx); lua_pop(L, 1)) {
  1107         switch (lua_type(L, -2)) {
  1108         case LUA_TSTRING:
  1109           // for string keys,
  1110           // increase keycount (may avoid another iteration):
  1111           keycount++;
  1112           // if type of table was unknown, then type of table is a JSON object now:
  1113           if (tabletype == JSON_TABLETYPE_UNKNOWN) tabletype = JSON_TABLETYPE_OBJECT;
  1114           // if type of table was a JSON array, then the type of table is ambiguous now
  1115           // and an error is thrown:
  1116           else if (tabletype == JSON_TABLETYPE_ARRAY) goto json_export_tabletype_error;
  1117           break;
  1118         case LUA_TNUMBER:
  1119           // for numeric keys,
  1120           // if type of table was unknown, then type of table is a JSON array now:
  1121           if (tabletype == JSON_TABLETYPE_UNKNOWN) tabletype = JSON_TABLETYPE_ARRAY;
  1122           // if type of table was a JSON object, then the type of table is ambiguous now
  1123           // and an error is thrown:
  1124           else if (tabletype == JSON_TABLETYPE_OBJECT) goto json_export_tabletype_error;
  1125           break;
  1126         }
  1127       }
  1128     }
  1129     // set pretty variable to 1 if pretty printing (with indentation) is desired:
  1130     pretty = lua_toboolean(L, json_export_internal_indentstring_idx);
  1131     // set level variable to corresponding function argument increased by one:
  1132     level = lua_tointeger(L, json_export_internal_level_idx) + 1;
  1133     // throw error if there are more levels that could be imported by this library:
  1134     if (level > JSON_MAXDEPTH) {
  1135       return luaL_error(L, "More than %d nested JSON levels", JSON_MAXDEPTH);
  1136     }
  1137     // distinguish between JSON objects and JSON arrays:
  1138     switch (tabletype) {
  1139     // JSON object:
  1140     case JSON_TABLETYPE_OBJECT:
  1141       // calculate count of string keys unless it has been calculated before:
  1142       if (!keycount) {
  1143         for (lua_pushnil(L); lua_next(L, json_export_internal_value_idx); lua_pop(L, 1)) {
  1144           if (lua_type(L, -2) == LUA_TSTRING) keycount++;
  1145         }
  1146       }
  1147       // create a sorted list of all string keys in memory:
  1148       if (keycount) {
  1149         // allocate memory for string keys:
  1150         keybuf = calloc(keycount, sizeof(json_key_t));
  1151         // check if memory allocation was successful:
  1152         if (!keybuf) {
  1153           // in case of memory exhaustion, try to collect garbage:
  1154           lua_gc(L, LUA_GCCOLLECT, 0);
  1155           // try to allocate memory again:
  1156           keybuf = calloc(keycount, sizeof(json_key_t));
  1157           // throw error if memory allocation failed again:
  1158           if (!keybuf) {
  1159             return luaL_error(L, "Memory allocation failed in JSON library");
  1160           }
  1161         }
  1162         // copy all string keys to the C array:
  1163         for (lua_pushnil(L); lua_next(L, json_export_internal_value_idx); lua_pop(L, 1)) {
  1164           if (lua_type(L, -2) == LUA_TSTRING) {
  1165             json_key_t *key = keybuf + (pos++);
  1166             key->data = lua_tolstring(L, -2, &key->length);
  1167           }
  1168         }
  1169         // sort C array using quicksort:
  1170         qsort(keybuf, keycount, sizeof(json_key_t), (void *)json_key_cmp);
  1171       }
  1172       // create Lua string buffer:
  1173       luaL_buffinit(L, &buf);
  1174       // add opening bracket to output buffer:
  1175       luaL_addchar(&buf, '{');
  1176       // iterate through all (sorted) string keys:
  1177       for (pos=0; pos<keycount; pos++) {
  1178         json_key_t *key = keybuf + pos;
  1179         // add comma to output buffer unless we process the first key:
  1180         if (pos) luaL_addchar(&buf, ',');
  1181         // handle indentation for pretty results:
  1182         if (pretty) {
  1183           luaL_addchar(&buf, '\n');
  1184           for (i=0; i<level; i++) {
  1185             lua_pushvalue(L, json_export_internal_indentstring_idx);
  1186             luaL_addvalue(&buf);
  1187           }
  1188         }
  1189         // recursive call to encode key:
  1190         lua_pushcfunction(L, json_export_internal);
  1191         lua_pushvalue(L, json_export_internal_indentstring_idx);
  1192         lua_pushinteger(L, level);
  1193         lua_pushlstring(L, key->data, key->length);
  1194         if (lua_pcall(L, 3, 1, 0)) {
  1195           // free memory of sorted string keys on error:
  1196           if (keybuf) free(keybuf);
  1197           // rethrow error:
  1198           return lua_error(L);
  1199         }
  1200         // add encoded key to output buffer:
  1201         luaL_addvalue(&buf);
  1202         // add colon to output buffer:
  1203         luaL_addchar(&buf, ':');
  1204         // handle indentation for pretty results:
  1205         if (pretty) luaL_addchar(&buf, ' ');
  1206         // recursive call to encode value:
  1207         lua_pushcfunction(L, json_export_internal);
  1208         lua_pushvalue(L, json_export_internal_indentstring_idx);
  1209         lua_pushinteger(L, level);
  1210         lua_pushlstring(L, key->data, key->length);
  1211         lua_rawget(L, json_export_internal_value_idx);
  1212         if (lua_pcall(L, 3, 1, 0)) {
  1213           // free memory of sorted string keys on error:
  1214           if (keybuf) free(keybuf);
  1215           // rethrow error:
  1216           return lua_error(L);
  1217         }
  1218         // add encoded value to output buffer:
  1219         luaL_addvalue(&buf);
  1220       }
  1221       // decrement level variable for all following statements:
  1222       level--;
  1223       // free memory of sorted string keys:
  1224       if (keybuf) free(keybuf);
  1225       // handle indentation for pretty results:
  1226       if (pretty && keycount != 0) {
  1227         luaL_addchar(&buf, '\n');
  1228         for (i=0; i<level; i++) {
  1229           lua_pushvalue(L, json_export_internal_indentstring_idx);
  1230           luaL_addvalue(&buf);
  1231         }
  1232       }
  1233       // add closing bracket to output buffer:
  1234       luaL_addchar(&buf, '}');
  1235       // for pretty results, add final newline character if outermost container is processed:
  1236       if (pretty && level == 0) luaL_addchar(&buf, '\n');
  1237       // convert and return buffer:
  1238       luaL_pushresult(&buf);
  1239       return 1;
  1240     // JSON array:
  1241     case JSON_TABLETYPE_ARRAY:
  1242       // reserve an extra element on the stack (needed because Lua buffer has unknown size on stack):
  1243       lua_settop(L, json_export_internal_tmp_idx);
  1244       // create Lua string buffer:
  1245       luaL_buffinit(L, &buf);
  1246       // add opening bracket to output buffer:
  1247       luaL_addchar(&buf, '[');
  1248       // iterate through integer keys:
  1249       for (arrayidx = 1; ; arrayidx++) {
  1250         // get value in array, and break if nil:
  1251         lua_rawgeti(L, json_export_internal_value_idx, arrayidx);
  1252         if (lua_isnil(L, -1)) {
  1253           lua_pop(L, 1);
  1254           break;
  1255         }
  1256         // store value below Lua string buffer on stack (to allow operation on string buffer):
  1257         lua_replace(L, json_export_internal_tmp_idx);
  1258         //
  1259         // add comma to output buffer unless we process the first element:
  1260         if (anyelement) luaL_addchar(&buf, ',');
  1261         // remember that we processed an element:
  1262         anyelement = 1;
  1263         // handle indentation for pretty results:
  1264         if (pretty) {
  1265           luaL_addchar(&buf, '\n');
  1266           for (i=0; i<level; i++) {
  1267             lua_pushvalue(L, json_export_internal_indentstring_idx);
  1268             luaL_addvalue(&buf);
  1269           }
  1270         }
  1271         // recursive call to encode previously stored value:
  1272         lua_pushcfunction(L, json_export_internal);
  1273         lua_pushvalue(L, json_export_internal_indentstring_idx);
  1274         lua_pushinteger(L, level);
  1275         lua_pushvalue(L, json_export_internal_tmp_idx);
  1276         lua_call(L, 3, 1);
  1277         // add encoded value to output buffer:
  1278         luaL_addvalue(&buf);
  1279       }
  1280       // decrement level variable for all following statements:
  1281       level--;
  1282       // handle indentation for pretty results:
  1283       if (pretty && anyelement) {
  1284         luaL_addchar(&buf, '\n');
  1285         for (i=0; i<level; i++) {
  1286           lua_pushvalue(L, json_export_internal_indentstring_idx);
  1287           luaL_addvalue(&buf);
  1288         }
  1289       }
  1290       // add closing bracket to output buffer:
  1291       luaL_addchar(&buf, ']');
  1292       // for pretty results, add final newline character if outermost container is processed:
  1293       if (pretty && level == 0) luaL_addchar(&buf, '\n');
  1294       // convert and return buffer:
  1295       luaL_pushresult(&buf);
  1296       return 1;
  1297     }
  1298     // throw error if table type is unknown:
  1299     json_export_tabletype_error:
  1300     return luaL_error(L, "JSON export not possible for ambiguous table (cannot decide whether it is an object or array)");
  1301   }
  1302   // all other datatypes are considered an error:
  1303   return luaL_error(L, "JSON export not possible for values of type \"%s\"", lua_typename(L, lua_type(L, json_export_internal_value_idx)));
  1304 }
  1306 // encodes a JSON document (passed as argument):
  1307 static int json_export(lua_State *L) {
  1308   // stack shall contain one function argument:
  1309   lua_settop(L, 1);
  1310   // call json_export_internal function with proper arguments:
  1311   lua_pushcfunction(L, json_export_internal);
  1312   lua_pushnil(L);
  1313   lua_pushinteger(L, 0);
  1314   lua_pushvalue(L, 1);
  1315   lua_call(L, 3, 1);
  1316   // return result:
  1317   return 1;
  1318 }
  1320 // encodes a JSON document (passed as first argument)
  1321 // with indentation (indentation string may be passed as second argument):
  1322 static int json_pretty(lua_State *L) {
  1323   // stack shall contain two function arguments:
  1324   lua_settop(L, 2);
  1325   // call json_export_internal function with proper arguments:
  1326   lua_pushcfunction(L, json_export_internal);
  1327   if (lua_isnil(L, 2)) lua_pushliteral(L, "  ");
  1328   else lua_pushvalue(L, 2);
  1329   lua_pushinteger(L, 0);
  1330   lua_pushvalue(L, 1);
  1331   lua_call(L, 3, 1);
  1332   // return result:
  1333   return 1;
  1334 }
  1336 // functions in library module:
  1337 static const struct luaL_Reg json_module_functions[] = {
  1338   {"object", json_object},
  1339   {"array",  json_array},
  1340   {"import", json_import},
  1341   {"export", json_export},
  1342   {"pretty", json_pretty},
  1343   {"get",    json_get},
  1344   {"type",   json_type},
  1345   {"set",    json_set},
  1346   {NULL, NULL}
  1347 };
  1349 // metamethods for JSON objects, JSON arrays, and unknown JSON collections (object or array):
  1350 static const struct luaL_Reg json_metatable_functions[] = {
  1351   {"__len", json_len},
  1352   {"__index", json_index},
  1353   {"__newindex", json_newindex},
  1354   {"__pairs", json_pairs},
  1355   {"__ipairs", json_ipairs},
  1356   {"__tostring", json_export},
  1357   {NULL, NULL}
  1358 };
  1360 // metamethods for JSON null marker:
  1361 static const struct luaL_Reg json_nullmark_metamethods[] = {
  1362   {"__tostring", json_nullmark_tostring},
  1363   {NULL, NULL}
  1364 };
  1366 // initializes json library:
  1367 int luaopen_json(lua_State *L) {
  1368   // empty stack:
  1369   lua_settop(L, 0);
  1370   // push library module onto stack position 1:
  1371   lua_newtable(L);
  1372   // register library functions:
  1373   luaL_setfuncs(L, json_module_functions, 0);
  1374   // create and store objectmt:
  1375   lua_newtable(L);
  1376   luaL_setfuncs(L, json_metatable_functions, 0);
  1377   json_regstore(L, objectmt);
  1378   // create and store arraymt:
  1379   lua_newtable(L);
  1380   luaL_setfuncs(L, json_metatable_functions, 0);
  1381   json_regstore(L, arraymt);
  1382   // create and store ephemeron table to store shadow tables for each JSON object/array
  1383   // to allow NULL values returned as nil
  1384   lua_newtable(L);
  1385   lua_newtable(L);  // metatable for ephemeron table
  1386   lua_pushliteral(L, "__mode");
  1387   lua_pushliteral(L, "k");
  1388   lua_rawset(L, -3);
  1389   lua_setmetatable(L, -2);
  1390   json_regstore(L, shadowtbl);
  1391   // set metatable of null marker and make it available through library module:
  1392   json_pushnullmark(L);
  1393   lua_newtable(L);
  1394   luaL_setfuncs(L, json_nullmark_metamethods, 0);
  1395   lua_setmetatable(L, -2);
  1396   lua_setfield(L, 1, "null");
  1397   // return library module (that's expected on top of stack):
  1398   return 1;
  1399 }
