mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-11562 Assertion `js->state == JST_VALUE' failed in check_contains(json_engine_t*, json_engine_t*).
check_contains() fixed. When an item of an array is a complex structure, it can be half-read after the end of the recursive check_contains() call. So we just manually get to it's ending.
This commit is contained in:
@ -295,13 +295,27 @@ int json_read_value(json_engine_t *j);
|
|||||||
int json_skip_key(json_engine_t *j);
|
int json_skip_key(json_engine_t *j);
|
||||||
|
|
||||||
|
|
||||||
|
typedef const int *json_level_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
json_skip_level() makes parser quickly skip the JSON content
|
json_skip_to_level() makes parser quickly get out of nested
|
||||||
to the end of the current object or array.
|
loops and arrays. It is used when we're not interested in what is
|
||||||
It is used when we're not interested in the rest of an array
|
there in the rest of these structures.
|
||||||
or the rest of the keys of an object.
|
The 'level' should be remembered in advance.
|
||||||
|
json_level_t level= json_get_level(j);
|
||||||
|
.... // getting into the nested JSON structures
|
||||||
|
json_skip_to_level(j, level);
|
||||||
*/
|
*/
|
||||||
int json_skip_level(json_engine_t *j);
|
#define json_get_level(j) (j->stack_p)
|
||||||
|
|
||||||
|
int json_skip_to_level(json_engine_t *j, json_level_t level);
|
||||||
|
|
||||||
|
/*
|
||||||
|
json_skip_level() works as above with just current structre.
|
||||||
|
So it gets to the end of the current JSON array or object.
|
||||||
|
*/
|
||||||
|
#define json_skip_level(json_engine) \
|
||||||
|
json_skip_to_level((json_engine), (json_engine)->stack_p)
|
||||||
|
|
||||||
|
|
||||||
#define json_skip_array_item json_skip_key
|
#define json_skip_array_item json_skip_key
|
||||||
|
@ -143,6 +143,12 @@ json_contains('[1, {"a":1}]', '{}')
|
|||||||
select json_contains('[1, {"a":1}]', '{"a":1}');
|
select json_contains('[1, {"a":1}]', '{"a":1}');
|
||||||
json_contains('[1, {"a":1}]', '{"a":1}')
|
json_contains('[1, {"a":1}]', '{"a":1}')
|
||||||
1
|
1
|
||||||
|
select json_contains('[{"abc":"def", "def":"abc"}]', '["foo","bar"]');
|
||||||
|
json_contains('[{"abc":"def", "def":"abc"}]', '["foo","bar"]')
|
||||||
|
0
|
||||||
|
select json_contains('[{"abc":"def", "def":"abc"}, "bar"]', '["bar", {}]');
|
||||||
|
json_contains('[{"abc":"def", "def":"abc"}, "bar"]', '["bar", {}]')
|
||||||
|
1
|
||||||
select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]");
|
select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]");
|
||||||
json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]")
|
json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]")
|
||||||
1
|
1
|
||||||
|
@ -53,6 +53,8 @@ select json_contains('{"b":[1,2], "a":1}', '{"a":1, "b":2}');
|
|||||||
select json_contains('{"a":1}', '{}');
|
select json_contains('{"a":1}', '{}');
|
||||||
select json_contains('[1, {"a":1}]', '{}');
|
select json_contains('[1, {"a":1}]', '{}');
|
||||||
select json_contains('[1, {"a":1}]', '{"a":1}');
|
select json_contains('[1, {"a":1}]', '{"a":1}');
|
||||||
|
select json_contains('[{"abc":"def", "def":"abc"}]', '["foo","bar"]');
|
||||||
|
select json_contains('[{"abc":"def", "def":"abc"}, "bar"]', '["bar", {}]');
|
||||||
|
|
||||||
select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]");
|
select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]");
|
||||||
select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]");
|
select json_contains_path('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]");
|
||||||
|
@ -796,17 +796,20 @@ static int check_contains(json_engine_t *js, json_engine_t *value)
|
|||||||
{
|
{
|
||||||
while (json_scan_next(js) == 0 && js->state != JST_ARRAY_END)
|
while (json_scan_next(js) == 0 && js->state != JST_ARRAY_END)
|
||||||
{
|
{
|
||||||
|
json_level_t c_level;
|
||||||
DBUG_ASSERT(js->state == JST_VALUE);
|
DBUG_ASSERT(js->state == JST_VALUE);
|
||||||
if (json_read_value(js))
|
if (json_read_value(js))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
c_level= json_value_scalar(js) ? NULL : json_get_level(js);
|
||||||
if (check_contains(js, value))
|
if (check_contains(js, value))
|
||||||
{
|
{
|
||||||
if (json_skip_level(js))
|
if (json_skip_level(js))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if (value->s.error || js->s.error)
|
if (value->s.error || js->s.error ||
|
||||||
|
(c_level && json_skip_to_level(js, c_level)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1158,25 +1158,12 @@ int json_path_setup(json_path_t *p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int json_skip_level(json_engine_t *j)
|
int json_skip_to_level(json_engine_t *j, json_level_t level)
|
||||||
{
|
{
|
||||||
int ct= 0;
|
do {
|
||||||
|
if (j->stack_p < level)
|
||||||
while (json_scan_next(j) == 0)
|
return 0;
|
||||||
{
|
} while (json_scan_next(j) == 0);
|
||||||
switch (j->state) {
|
|
||||||
case JST_OBJ_START:
|
|
||||||
case JST_ARRAY_START:
|
|
||||||
ct++;
|
|
||||||
break;
|
|
||||||
case JST_OBJ_END:
|
|
||||||
case JST_ARRAY_END:
|
|
||||||
if (ct == 0)
|
|
||||||
return 0;
|
|
||||||
ct--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user