From 5ba6cee01255186ea77a69f122d3a15c07f44f6d Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Mon, 18 Jun 2018 23:00:34 +0400 Subject: 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. --- sql/item_jsonfunc.cc | 62 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 26 deletions(-) (limited to 'sql/item_jsonfunc.cc') diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index c8cda66580c..8103aa906ff 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; -- cgit v1.2.1