summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2017-03-14 15:25:02 +0400
committerAlexey Botchkov <holyfoot@askmonty.org>2017-03-14 15:25:02 +0400
commit7c7c0696e7eba3717a592c7c2c28c46af26e3e68 (patch)
treee4a34aec3eab1c63a4ffbf32c1cee96e49e6cde8
parenta77c2ea78f76c07446a3014052cb8c3b74c4860c (diff)
downloadmariadb-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.h1
-rw-r--r--mysql-test/r/func_json.result6
-rw-r--r--mysql-test/t/func_json.test7
-rw-r--r--sql/item_jsonfunc.cc25
-rw-r--r--sql/item_jsonfunc.h2
-rw-r--r--strings/json_lib.c2
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;