lua: json: add optional argument in the json parse() method to limit the number of recursions
This allows partially parsing a json object, allowing some parts to be passed on as strings to another component that does its own parsing (ex. a pipewire module)
This commit is contained in:
@@ -95,7 +95,7 @@ spa_json_is_object (lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
push_luajson (lua_State *L, WpSpaJson *json)
|
push_luajson (lua_State *L, WpSpaJson *json, gint n_recursions)
|
||||||
{
|
{
|
||||||
/* Null */
|
/* Null */
|
||||||
if (wp_spa_json_is_null (json)) {
|
if (wp_spa_json_is_null (json)) {
|
||||||
@@ -124,20 +124,20 @@ push_luajson (lua_State *L, WpSpaJson *json)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Array */
|
/* Array */
|
||||||
else if (wp_spa_json_is_array (json)) {
|
else if (wp_spa_json_is_array (json) && n_recursions > 0) {
|
||||||
g_auto (GValue) item = G_VALUE_INIT;
|
g_auto (GValue) item = G_VALUE_INIT;
|
||||||
g_autoptr (WpIterator) it = wp_spa_json_new_iterator (json);
|
g_autoptr (WpIterator) it = wp_spa_json_new_iterator (json);
|
||||||
guint i = 1;
|
guint i = 1;
|
||||||
lua_newtable (L);
|
lua_newtable (L);
|
||||||
for (; wp_iterator_next (it, &item); g_value_unset (&item)) {
|
for (; wp_iterator_next (it, &item); g_value_unset (&item)) {
|
||||||
WpSpaJson *j = g_value_get_boxed (&item);
|
WpSpaJson *j = g_value_get_boxed (&item);
|
||||||
push_luajson (L, j);
|
push_luajson (L, j, n_recursions - 1);
|
||||||
lua_rawseti (L, -2, i++);
|
lua_rawseti (L, -2, i++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Object */
|
/* Object */
|
||||||
else if (wp_spa_json_is_object (json)) {
|
else if (wp_spa_json_is_object (json) && n_recursions > 0) {
|
||||||
g_auto (GValue) item = G_VALUE_INIT;
|
g_auto (GValue) item = G_VALUE_INIT;
|
||||||
g_autoptr (WpIterator) it = wp_spa_json_new_iterator (json);
|
g_autoptr (WpIterator) it = wp_spa_json_new_iterator (json);
|
||||||
lua_newtable (L);
|
lua_newtable (L);
|
||||||
@@ -151,7 +151,7 @@ push_luajson (lua_State *L, WpSpaJson *json)
|
|||||||
if (!wp_iterator_next (it, &item))
|
if (!wp_iterator_next (it, &item))
|
||||||
break;
|
break;
|
||||||
value = g_value_get_boxed (&item);
|
value = g_value_get_boxed (&item);
|
||||||
push_luajson (L, value);
|
push_luajson (L, value, n_recursions - 1);
|
||||||
lua_setfield (L, -2, key_str);
|
lua_setfield (L, -2, key_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,8 @@ static int
|
|||||||
spa_json_parse (lua_State *L)
|
spa_json_parse (lua_State *L)
|
||||||
{
|
{
|
||||||
WpSpaJson *json = wplua_checkboxed (L, 1, WP_TYPE_SPA_JSON);
|
WpSpaJson *json = wplua_checkboxed (L, 1, WP_TYPE_SPA_JSON);
|
||||||
push_luajson (L, json);
|
gint n_recursions = luaL_opt (L, luaL_checkinteger, 2, INT_MAX);
|
||||||
|
push_luajson (L, json, n_recursions);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -186,3 +186,40 @@ assert (val.name == "wireplumber")
|
|||||||
assert (val.version[1] == 0)
|
assert (val.version[1] == 0)
|
||||||
assert (val.version[2] == 4)
|
assert (val.version[2] == 4)
|
||||||
assert (val.version[3] == 7)
|
assert (val.version[3] == 7)
|
||||||
|
|
||||||
|
-- recursion limit
|
||||||
|
json = Json.Raw ("{ name = wireplumber, version = [0, 4, 15], args = { test = [0, 1] } }")
|
||||||
|
|
||||||
|
val = json:parse (0)
|
||||||
|
assert (type (val) == "string")
|
||||||
|
assert (val == "{ name = wireplumber, version = [0, 4, 15], args = { test = [0, 1] } }")
|
||||||
|
|
||||||
|
val = json:parse (1)
|
||||||
|
assert (type (val) == "table")
|
||||||
|
assert (val.name == "wireplumber")
|
||||||
|
assert (type (val.version) == "string")
|
||||||
|
assert (val.version == "[0, 4, 15]")
|
||||||
|
assert (type (val.args) == "string")
|
||||||
|
assert (val.args == "{ test = [0, 1] }")
|
||||||
|
|
||||||
|
val = json:parse(2)
|
||||||
|
assert (type (val) == "table")
|
||||||
|
assert (val.name == "wireplumber")
|
||||||
|
assert (type (val.version) == "table")
|
||||||
|
assert (val.version[1] == 0)
|
||||||
|
assert (val.version[2] == 4)
|
||||||
|
assert (val.version[3] == 15)
|
||||||
|
assert (type (val.args) == "table")
|
||||||
|
assert (val.args.test == "[0, 1]")
|
||||||
|
|
||||||
|
val = json:parse(3)
|
||||||
|
assert (type (val) == "table")
|
||||||
|
assert (val.name == "wireplumber")
|
||||||
|
assert (type (val.version) == "table")
|
||||||
|
assert (val.version[1] == 0)
|
||||||
|
assert (val.version[2] == 4)
|
||||||
|
assert (val.version[3] == 15)
|
||||||
|
assert (type (val.args) == "table")
|
||||||
|
assert (type (val.args.test) == "table")
|
||||||
|
assert (val.args.test[1] == 0)
|
||||||
|
assert (val.args.test[2] == 1)
|
||||||
|
Reference in New Issue
Block a user