From 7fca133028709a3fbe24af4156edac2d35a0670b Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Sat, 3 Dec 2016 12:36:10 +0400 Subject: [PATCH] MDEV-11463 Server crashes in mark_array upon JSON_VALID. The depth of nested arrays should be controlled, as it's limited. --- mysql-test/r/func_json.result | 3 +++ mysql-test/t/func_json.test | 1 + strings/json_lib.c | 38 ++++++++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/func_json.result b/mysql-test/r/func_json.result index 53a1dfbfcf9..5fe88547580 100644 --- a/mysql-test/r/func_json.result +++ b/mysql-test/r/func_json.result @@ -10,6 +10,9 @@ json_valid('{"key1":1, "key2":[2,3]}') select json_valid('[false, true, null]'); json_valid('[false, true, null]') 1 +select json_valid(repeat('[', 1000)); +json_valid(repeat('[', 1000)) +0 select json_value('{"key1":123}', '$.key2'); json_value('{"key1":123}', '$.key2') NULL diff --git a/mysql-test/t/func_json.test b/mysql-test/t/func_json.test index e84d5324438..3d3fdb7fcd8 100644 --- a/mysql-test/t/func_json.test +++ b/mysql-test/t/func_json.test @@ -2,6 +2,7 @@ select json_valid('[1, 2]'); select json_valid('"string"}'); select json_valid('{"key1":1, "key2":[2,3]}'); select json_valid('[false, true, null]'); +select json_valid(repeat('[', 1000)); select json_value('{"key1":123}', '$.key2'); select json_value('{"key1":123}', '$.key1'); diff --git a/strings/json_lib.c b/strings/json_lib.c index 662207c3899..3c6cc717aac 100644 --- a/strings/json_lib.c +++ b/strings/json_lib.c @@ -126,8 +126,13 @@ static int syntax_error(json_engine_t *j) static int mark_object(json_engine_t *j) { j->state= JST_OBJ_START; - *(++j->stack_p)= JST_OBJ_CONT; - return 0; + if ((++j->stack_p) - j->stack < JSON_DEPTH_LIMIT) + { + *j->stack_p= JST_OBJ_CONT; + return 0; + } + j->s.error= JE_DEPTH; + return 1; } @@ -137,8 +142,13 @@ static int read_obj(json_engine_t *j) j->state= JST_OBJ_START; j->value_type= JSON_VALUE_OBJECT; j->value= j->value_begin; - *(++j->stack_p)= JST_OBJ_CONT; - return 0; + if ((++j->stack_p) - j->stack < JSON_DEPTH_LIMIT) + { + *j->stack_p= JST_OBJ_CONT; + return 0; + } + j->s.error= JE_DEPTH; + return 1; } @@ -146,9 +156,14 @@ static int read_obj(json_engine_t *j) static int mark_array(json_engine_t *j) { j->state= JST_ARRAY_START; - *(++j->stack_p)= JST_ARRAY_CONT; - j->value= j->value_begin; - return 0; + if ((++j->stack_p) - j->stack < JSON_DEPTH_LIMIT) + { + *j->stack_p= JST_ARRAY_CONT; + j->value= j->value_begin; + return 0; + } + j->s.error= JE_DEPTH; + return 1; } /* Read value of object. */ @@ -157,8 +172,13 @@ static int read_array(json_engine_t *j) j->state= JST_ARRAY_START; j->value_type= JSON_VALUE_ARRAY; j->value= j->value_begin; - *(++j->stack_p)= JST_ARRAY_CONT; - return 0; + if ((++j->stack_p) - j->stack < JSON_DEPTH_LIMIT) + { + *j->stack_p= JST_ARRAY_CONT; + return 0; + } + j->s.error= JE_DEPTH; + return 1; }