Skip to content

Commit 7c7c069

Browse files
author
Alexey Botchkov
committed
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.
1 parent a77c2ea commit 7c7c069

File tree

6 files changed

+39
-4
lines changed

6 files changed

+39
-4
lines changed

include/json_lib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ typedef struct st_json_engine_t
203203
enum json_value_types value_type; /* type of the value.*/
204204
const uchar *value; /* Points to the value. */
205205
const uchar *value_begin;/* Points to where the value starts in the JSON. */
206+
int value_escaped; /* Flag telling if the string value has escaping.*/
206207
uint num_flags; /* the details of the JSON_VALUE_NUMBER, is it negative,
207208
or if it has the fractional part.
208209
See the enum json_num_flags. */

mysql-test/r/func_json.result

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,3 +589,9 @@ json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}')
589589
"bb": "v2"
590590
}
591591
}
592+
SELECT JSON_search( '{"x": "\\""}', "one", '"');
593+
JSON_search( '{"x": "\\""}', "one", '"')
594+
"$.x"
595+
SELECT JSON_search( '{"x": "\\""}', "one", '\\"');
596+
JSON_search( '{"x": "\\""}', "one", '\\"')
597+
"$.x"

mysql-test/t/func_json.test

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,3 +238,10 @@ select json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}') ;
238238
select json_compact('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}');
239239
select json_loose('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}');
240240
select json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}');
241+
242+
#
243+
# MDEV-11856 json_search doesn't search for values with double quotes character (")
244+
#
245+
246+
SELECT JSON_search( '{"x": "\\""}', "one", '"');
247+
SELECT JSON_search( '{"x": "\\""}', "one", '\\"');

sql/item_jsonfunc.cc

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2800,9 +2800,28 @@ void Item_func_json_search::fix_length_and_dec()
28002800
int Item_func_json_search::compare_json_value_wild(json_engine_t *je,
28012801
const String *cmp_str)
28022802
{
2803-
return my_wildcmp(collation.collation,
2804-
(const char *) je->value, (const char *) (je->value + je->value_len),
2805-
cmp_str->ptr(), cmp_str->end(), escape, wild_one, wild_many) ? 0 : 1;
2803+
if (je->value_type != JSON_VALUE_STRING || !je->value_escaped)
2804+
return my_wildcmp(collation.collation,
2805+
(const char *) je->value, (const char *) (je->value + je->value_len),
2806+
cmp_str->ptr(), cmp_str->end(), escape, wild_one, wild_many) ? 0 : 1;
2807+
2808+
{
2809+
int esc_len;
2810+
if (esc_value.alloced_length() < (uint) je->value_len &&
2811+
esc_value.alloc((je->value_len / 1024 + 1) * 1024))
2812+
return 0;
2813+
2814+
esc_len= json_unescape(je->s.cs, je->value, je->value + je->value_len,
2815+
je->s.cs, (uchar *) esc_value.ptr(),
2816+
(uchar *) (esc_value.ptr() +
2817+
esc_value.alloced_length()));
2818+
if (esc_len <= 0)
2819+
return 0;
2820+
2821+
return my_wildcmp(collation.collation,
2822+
esc_value.ptr(), esc_value.ptr() + esc_len,
2823+
cmp_str->ptr(), cmp_str->end(), escape, wild_one, wild_many) ? 0 : 1;
2824+
}
28062825
}
28072826

28082827

sql/item_jsonfunc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ class Item_func_json_keys: public Item_str_func
392392
class Item_func_json_search: public Item_json_str_multipath
393393
{
394394
protected:
395-
String tmp_js;
395+
String tmp_js, esc_value;
396396
bool mode_one;
397397
bool ooa_constant, ooa_parsed;
398398
int escape;

strings/json_lib.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ static int skip_str_constant(json_engine_t *j)
366366
break;
367367
if (j->s.c_next == '\\')
368368
{
369+
j->value_escaped= 1;
369370
if (json_handle_esc(&j->s))
370371
return 1;
371372
continue;
@@ -394,6 +395,7 @@ static int read_strn(json_engine_t *j)
394395
{
395396
j->value= j->s.c_str;
396397
j->value_type= JSON_VALUE_STRING;
398+
j->value_escaped= 0;
397399

398400
if (skip_str_constant(j))
399401
return 1;

0 commit comments

Comments
 (0)