diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2017-03-14 15:25:02 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2017-03-14 15:25:02 +0400 |
commit | 7c7c0696e7eba3717a592c7c2c28c46af26e3e68 (patch) | |
tree | e4a34aec3eab1c63a4ffbf32c1cee96e49e6cde8 | |
parent | a77c2ea78f76c07446a3014052cb8c3b74c4860c (diff) | |
download | mariadb-git-7c7c0696e7eba3717a592c7c2c28c46af26e3e68.tar.gz |
MDEV-11856 json_search doesn't search for values with double quotes
character (").
The my_wildcmp function doesn't expect the string parameter to
have escapements, only the template. So the string
should be unescaped if necessary.
-rw-r--r-- | include/json_lib.h | 1 | ||||
-rw-r--r-- | mysql-test/r/func_json.result | 6 | ||||
-rw-r--r-- | mysql-test/t/func_json.test | 7 | ||||
-rw-r--r-- | sql/item_jsonfunc.cc | 25 | ||||
-rw-r--r-- | sql/item_jsonfunc.h | 2 | ||||
-rw-r--r-- | strings/json_lib.c | 2 |
6 files changed, 39 insertions, 4 deletions
diff --git a/include/json_lib.h b/include/json_lib.h index cdfcffad38a..567b04dbdc0 100644 --- a/include/json_lib.h +++ b/include/json_lib.h @@ -203,6 +203,7 @@ typedef struct st_json_engine_t enum json_value_types value_type; /* type of the value.*/ const uchar *value; /* Points to the value. */ const uchar *value_begin;/* Points to where the value starts in the JSON. */ + int value_escaped; /* Flag telling if the string value has escaping.*/ uint num_flags; /* the details of the JSON_VALUE_NUMBER, is it negative, or if it has the fractional part. See the enum json_num_flags. */ diff --git a/mysql-test/r/func_json.result b/mysql-test/r/func_json.result index 91640974b22..b1e52efcf8f 100644 --- a/mysql-test/r/func_json.result +++ b/mysql-test/r/func_json.result @@ -589,3 +589,9 @@ json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') "bb": "v2" } } +SELECT JSON_search( '{"x": "\\""}', "one", '"'); +JSON_search( '{"x": "\\""}', "one", '"') +"$.x" +SELECT JSON_search( '{"x": "\\""}', "one", '\\"'); +JSON_search( '{"x": "\\""}', "one", '\\"') +"$.x" diff --git a/mysql-test/t/func_json.test b/mysql-test/t/func_json.test index 09e4f30c325..ed1fe38d57d 100644 --- a/mysql-test/t/func_json.test +++ b/mysql-test/t/func_json.test @@ -238,3 +238,10 @@ select json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}') ; select json_compact('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}'); select json_loose('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}'); select json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}'); + +# +# MDEV-11856 json_search doesn't search for values with double quotes character (") +# + +SELECT JSON_search( '{"x": "\\""}', "one", '"'); +SELECT JSON_search( '{"x": "\\""}', "one", '\\"'); diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 925a7e437f2..7909c605136 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -2800,9 +2800,28 @@ void Item_func_json_search::fix_length_and_dec() int Item_func_json_search::compare_json_value_wild(json_engine_t *je, const String *cmp_str) { - return my_wildcmp(collation.collation, - (const char *) je->value, (const char *) (je->value + je->value_len), - cmp_str->ptr(), cmp_str->end(), escape, wild_one, wild_many) ? 0 : 1; + if (je->value_type != JSON_VALUE_STRING || !je->value_escaped) + return my_wildcmp(collation.collation, + (const char *) je->value, (const char *) (je->value + je->value_len), + cmp_str->ptr(), cmp_str->end(), escape, wild_one, wild_many) ? 0 : 1; + + { + int esc_len; + if (esc_value.alloced_length() < (uint) je->value_len && + esc_value.alloc((je->value_len / 1024 + 1) * 1024)) + return 0; + + esc_len= json_unescape(je->s.cs, je->value, je->value + je->value_len, + je->s.cs, (uchar *) esc_value.ptr(), + (uchar *) (esc_value.ptr() + + esc_value.alloced_length())); + if (esc_len <= 0) + return 0; + + return my_wildcmp(collation.collation, + esc_value.ptr(), esc_value.ptr() + esc_len, + cmp_str->ptr(), cmp_str->end(), escape, wild_one, wild_many) ? 0 : 1; + } } diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h index 535f1bf73a5..ac78ed932d5 100644 --- a/sql/item_jsonfunc.h +++ b/sql/item_jsonfunc.h @@ -392,7 +392,7 @@ public: class Item_func_json_search: public Item_json_str_multipath { protected: - String tmp_js; + String tmp_js, esc_value; bool mode_one; bool ooa_constant, ooa_parsed; int escape; diff --git a/strings/json_lib.c b/strings/json_lib.c index 2a5d71a2133..5eda81d96c5 100644 --- a/strings/json_lib.c +++ b/strings/json_lib.c @@ -366,6 +366,7 @@ static int skip_str_constant(json_engine_t *j) break; if (j->s.c_next == '\\') { + j->value_escaped= 1; if (json_handle_esc(&j->s)) return 1; continue; @@ -394,6 +395,7 @@ static int read_strn(json_engine_t *j) { j->value= j->s.c_str; j->value_type= JSON_VALUE_STRING; + j->value_escaped= 0; if (skip_str_constant(j)) return 1; |