[Commits] 5ba6cee: MDEV-16209 JSON_EXTRACT in query crashes server.
revision-id: 5ba6cee01255186ea77a69f122d3a15c07f44f6d (mariadb-10.2.15-63-g5ba6cee) parent(s): eb77f8cf8de44ecaa7155afa7f55ece73b2b0497 committer: Alexey Botchkov timestamp: 2018-06-18 23:00:34 +0400 message: MDEV-16209 JSON_EXTRACT in query crashes server. The optimizer can create various item's over the original one, so we can't count on the exact item's type inside the comparison. --- mysql-test/r/func_json.result | 5 ++++ mysql-test/t/func_json.test | 8 ++++++ sql/item_jsonfunc.cc | 62 +++++++++++++++++++++++++------------------ 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/mysql-test/r/func_json.result b/mysql-test/r/func_json.result index 77a4241..564442a 100644 --- a/mysql-test/r/func_json.result +++ b/mysql-test/r/func_json.result @@ -742,3 +742,8 @@ json_extract('{"test":8.437e-5}','$.test') select json_value('{"b":true}','$.b')=1; json_value('{"b":true}','$.b')=1 1 +CREATE TABLE t1 (c VARCHAR(8)); +INSERT INTO t1 VALUES ('foo'),('bar'); +SELECT * FROM t1 WHERE c IN (JSON_EXTRACT('{"a":"b"}', '$.*')); +c +DROP TABLE t1; diff --git a/mysql-test/t/func_json.test b/mysql-test/t/func_json.test index b74915c..1b91061 100644 --- a/mysql-test/t/func_json.test +++ b/mysql-test/t/func_json.test @@ -404,4 +404,12 @@ select json_extract('{"test":8.437e-5}','$.test'); # select json_value('{"b":true}','$.b')=1; +# +# MDEV-16209 JSON_EXTRACT in query crashes server. +# + +CREATE TABLE t1 (c VARCHAR(8)); +INSERT INTO t1 VALUES ('foo'),('bar'); +SELECT * FROM t1 WHERE c IN (JSON_EXTRACT('{"a":"b"}', '$.*')); +DROP TABLE t1; diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index c8cda66..8103aa9 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -3229,34 +3229,44 @@ String *Item_func_json_format::val_json(String *str) int Arg_comparator::compare_json_str_basic(Item *j, Item *s) { - String *res1,*res2; - json_value_types type; - char *value; - int value_len, c_len; - Item_func_json_extract *e= (Item_func_json_extract *) j; - - if ((res1= e->read_json(&value1, &type, &value, &value_len))) - { - if ((res2= s->val_str(&value2))) - { - if (type == JSON_VALUE_STRING) - { - if (value1.realloc_with_extra_if_needed(value_len) || - (c_len= json_unescape(value1.charset(), (uchar *) value, - (uchar *) value+value_len, - &my_charset_utf8_general_ci, - (uchar *) value1.ptr(), - (uchar *) (value1.ptr() + value_len))) < 0) - goto error; - value1.length(c_len); - res1= &value1; - } + String *js,*str; + int c_len; + json_engine_t je; - if (set_null) - owner->null_value= 0; - return sortcmp(res1, res2, compare_collation()); - } + if ((js= j->val_str(&value1))) + { + json_scan_start(&je, js->charset(), (const uchar *) js->ptr(), + (const uchar *) js->ptr()+js->length()); + if (json_read_value(&je)) + goto error; + if (je.value_type == JSON_VALUE_STRING) + { + if (value2.realloc_with_extra_if_needed(je.value_len) || + (c_len= json_unescape(js->charset(), je.value, + je.value + je.value_len, + &my_charset_utf8_general_ci, + (uchar *) value2.ptr(), + (uchar *) (value2.ptr() + je.value_len))) < 0) + goto error; + + value2.length(c_len); + js= &value2; + str= &value1; + } + else + { + str= &value2; + } + + + if ((str= s->val_str(str))) + { + if (set_null) + owner->null_value= 0; + return sortcmp(js, str, compare_collation()); + } } + error: if (set_null) owner->null_value= 1;
participants (1)
-
holyfoot@askmonty.org