]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/engine: fixed serialization of nested tables
authorMarek Vavruša <marek.vavrusa@nic.cz>
Sun, 18 Oct 2015 20:55:01 +0000 (22:55 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Sun, 18 Oct 2015 20:55:23 +0000 (22:55 +0200)
daemon/engine.c

index 048643f0ccd3ba999f774b9837b10b7555a9dab3..de20831fc5684f6d2896f6c5c12515a17df289e5 100644 (file)
@@ -214,39 +214,46 @@ static void l_unpack_json(lua_State *L, JsonNode *table)
        }
 }
 
+/** @internal Recursive Lua/JSON serialization. */
 static JsonNode *l_pack_elem(lua_State *L, int top)
 {
-       if (lua_isstring(L, top)) {
-               return json_mkstring(lua_tostring(L, top));
-       }
-       if (lua_isnumber(L, top)) {
-               return json_mknumber(lua_tonumber(L, top));     
-       }
-       if (lua_isboolean(L, top)) {
-               return json_mkbool(lua_toboolean(L, top));      
+       switch(lua_type(L, top)) {
+       case LUA_TSTRING:  return json_mkstring(lua_tostring(L, top));
+       case LUA_TNUMBER:  return json_mknumber(lua_tonumber(L, top));
+       case LUA_TBOOLEAN: return json_mkbool(lua_toboolean(L, top));
+       case LUA_TTABLE:   break; /* Table, iterate it. */
+       default:           return json_mknull();
+       }
+       /* Use absolute indexes here, as the table may be nested. */
+       JsonNode *node = NULL;
+       lua_pushnil(L);
+       while(lua_next(L, top) != 0) {
+               JsonNode *val = l_pack_elem(L, top + 2);
+               const bool no_key = lua_isnumber(L, top + 1);
+               if (!node) {
+                       node = no_key ? json_mkarray() : json_mkobject();
+                       if (!node) {
+                               return NULL;
+                       }
+               }
+               /* Insert to array/table */
+               if (no_key) {
+                       json_append_element(node, val);
+               } else {
+                       json_append_member(node, lua_tostring(L, top + 1), val);
+               }
+               lua_pop(L, 1);
        }
-       return json_mknull();
+       return node;
 }
 
+/** @internal Serialize to string */
 static char *l_pack_json(lua_State *L, int top)
 {
-       JsonNode *root = json_mkobject();
+       JsonNode *root = l_pack_elem(L, top);
        if (!root) {
                return NULL;
        }
-       /* Iterate table on stack */
-       lua_pushnil(L);
-       while(lua_next(L, top)) {
-               JsonNode *val = l_pack_elem(L, -1);
-               if (lua_isstring(L, -2)) {
-                       json_append_member(root, lua_tostring(L, -2), val);
-               } else {
-                       json_append_element(root, val);
-               }
-               lua_pop(L, 1);
-       }
-       lua_pop(L, 1);
-       /* Serialize to string */
        char *result = json_encode(root);
        json_delete(root);
        return result;