Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/json_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ typedef struct st_json_path_t
} json_path_t;


__attribute__((nonnull, warn_unused_result))
int json_path_setup(json_path_t *p,
CHARSET_INFO *i_cs, const uchar *str, const uchar *end);

Expand Down
63 changes: 63 additions & 0 deletions mysql-test/main/func_json.result
Original file line number Diff line number Diff line change
Expand Up @@ -2938,4 +2938,67 @@ JSON_EXTRACT('0E+0','$')
SELECT JSON_ARRAY_INSERT (0,NULL,1) as j;
j
NULL
#
# MDEV-32331 JSON path functions with no charset on path crash server
#
SELECT 1 FROM
(SELECT CASE WHEN x * x THEN x END as a
FROM ( SELECT json_array_append ( 'x' , ( 'x' % 'x' ) , 1 , 'x' , 1 ) as x ) dt2
) dt
WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_array_append ( 'x' , ( 'x' % 'x' ) , 1 , 'x' , 1 ) as x ) dt2 ) dt WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_array_insert ( '[1]' , ( 'x' % 'x' ) , 1 , '$[0]' , 9 ) as x ) dt2 ) dt WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_insert ( '1' , ( 'x' % 'x' ) , 1 , '$.a' , 2 ) as x ) dt2 ) dt WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_remove ( '[1,2]' , ( 'x' % 'x' ) , '$[0]' ) as x ) dt2 ) dt WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_replace ( '1' , ( 'x' % 'x' ) , 1 , '$.a' , 2 ) as x ) dt2 ) dt WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_set ( '1' , ( 'x' % 'x' ) , 1 , '$.a' , 2 ) as x ) dt2 ) dt WHERE a;
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'x'
SELECT x FROM (SELECT 1 AS x UNION SELECT 2) AS t WHERE x IN ( SELECT JSON_REPLACE('1', UPPER(CAST(NULL AS CHAR)), 100));
x
SELECT ( WITH RECURSIVE x ( x ) AS (WITH RECURSIVE x ( x ) AS ( SELECT 1 UNION SELECT x + 1 FROM x ) SELECT json_array_append ( '[[], [], []]' , NOT ( NULL LIKE 'ABC%' ) , 315 )) SELECT x FROM x WHERE x > 10 AND x < 1) AS x;
x
NULL
SELECT 1 FROM (SELECT JSON_REMOVE(46, DATE(NULL)) AS x EXCEPT SELECT 1) AS d WHERE NOT(NOT(x > 10)) AND (x < 1 OR x > 1);
1
# End of 10.11 Test
20 changes: 20 additions & 0 deletions mysql-test/main/func_json.test
Original file line number Diff line number Diff line change
Expand Up @@ -2114,4 +2114,24 @@ SELECT JSON_EXTRACT('0E+0','$');

SELECT JSON_ARRAY_INSERT (0,NULL,1) as j;

--echo #
--echo # MDEV-32331 JSON path functions with no charset on path crash server
--echo #

SELECT 1 FROM
(SELECT CASE WHEN x * x THEN x END as a
FROM ( SELECT json_array_append ( 'x' , ( 'x' % 'x' ) , 1 , 'x' , 1 ) as x ) dt2
) dt
WHERE a;
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_array_append ( 'x' , ( 'x' % 'x' ) , 1 , 'x' , 1 ) as x ) dt2 ) dt WHERE a;
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_array_insert ( '[1]' , ( 'x' % 'x' ) , 1 , '$[0]' , 9 ) as x ) dt2 ) dt WHERE a;
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_insert ( '1' , ( 'x' % 'x' ) , 1 , '$.a' , 2 ) as x ) dt2 ) dt WHERE a;
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_remove ( '[1,2]' , ( 'x' % 'x' ) , '$[0]' ) as x ) dt2 ) dt WHERE a;
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_replace ( '1' , ( 'x' % 'x' ) , 1 , '$.a' , 2 ) as x ) dt2 ) dt WHERE a;
SELECT 1 FROM (SELECT CASE WHEN x * x THEN x END as a FROM ( SELECT json_set ( '1' , ( 'x' % 'x' ) , 1 , '$.a' , 2 ) as x ) dt2 ) dt WHERE a;

SELECT x FROM (SELECT 1 AS x UNION SELECT 2) AS t WHERE x IN ( SELECT JSON_REPLACE('1', UPPER(CAST(NULL AS CHAR)), 100));
SELECT ( WITH RECURSIVE x ( x ) AS (WITH RECURSIVE x ( x ) AS ( SELECT 1 UNION SELECT x + 1 FROM x ) SELECT json_array_append ( '[[], [], []]' , NOT ( NULL LIKE 'ABC%' ) , 315 )) SELECT x FROM x WHERE x > 10 AND x < 1) AS x;
SELECT 1 FROM (SELECT JSON_REMOVE(46, DATE(NULL)) AS x EXCEPT SELECT 1) AS d WHERE NOT(NOT(x > 10)) AND (x < 1 OR x > 1);

--echo # End of 10.11 Test
74 changes: 53 additions & 21 deletions sql/item_jsonfunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ void report_path_error_ex(const char *ps, json_path_t *p,
Checks if the path has '.*' '[*]' or '**' constructions
and sets the NO_WILDCARD_ALLOWED error if the case.
*/
__attribute__((nonnull, warn_unused_result))
static int path_setup_nwc(json_path_t *p, CHARSET_INFO *i_cs,
const uchar *str, const uchar *end)
{
Expand All @@ -586,6 +587,13 @@ static int path_setup_nwc(json_path_t *p, CHARSET_INFO *i_cs,
return 1;
}

static inline
CHARSET_INFO *def_path_charset(CHARSET_INFO *cs, CHARSET_INFO *alt)
{
if (cs) return cs;
if (alt) return alt;
return &my_charset_utf8mb4_bin;
}

bool Item_func_json_valid::val_bool()
{
Expand Down Expand Up @@ -768,18 +776,20 @@ bool Json_path_extractor::extract(String *str, Item *item_js, Item *item_jp,
{
String *s_p= item_jp->val_str(&tmp_path);

if (!s_p)
return true;
if (allow_wildcard)
{
if (s_p &&
if (!s_p->charset() ||
json_path_setup(&p, s_p->charset(), (const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
error= true;
}
else
{
if (s_p &&
path_setup_nwc(&p, s_p->charset(), (const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
if (path_setup_nwc(&p, def_path_charset(s_p->charset(), cs),
(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
error= true;
}

Expand Down Expand Up @@ -1599,8 +1609,11 @@ bool Item_func_json_contains::val_bool()
if (!path.parsed)
{
String *s_p= args[2]->val_str(&tmp_path);
if (s_p &&
path_setup_nwc(&path.p,s_p->charset(),(const uchar *) s_p->ptr(),
if (!s_p)
goto return_null;
if (path_setup_nwc(&path.p,
def_path_charset(s_p->charset(), js->charset()),
(const uchar *) s_p->ptr(),
(const uchar *) s_p->end()))
{
report_path_error(s_p, &path.p, 2);
Expand Down Expand Up @@ -2160,8 +2173,11 @@ String *Item_func_json_array_append::val_str(String *str)
if (!c_path->parsed)
{
String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
if (s_p &&
path_setup_nwc(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
if (!s_p)
goto return_null;
if (path_setup_nwc(&c_path->p,
def_path_charset(s_p->charset(), js->charset()),
(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
{
report_path_error(s_p, &c_path->p, n_arg);
Expand Down Expand Up @@ -2297,15 +2313,19 @@ String *Item_func_json_array_insert::val_str(String *str)
String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
if (!s_p)
goto return_null;
if (!s_p->charset())
goto path_err;

if (path_setup_nwc(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()) ||
if (path_setup_nwc(&c_path->p,
def_path_charset(s_p->charset(), js->charset()),
(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()) ||
c_path->p.last_step - 1 < c_path->p.steps ||
c_path->p.last_step->type != JSON_PATH_ARRAY)
{
if (c_path->p.s.error == 0)
c_path->p.s.error= SHOULD_END_WITH_ARRAY;
path_err:
report_path_error(s_p, &c_path->p, n_arg);

goto return_null;
Expand Down Expand Up @@ -3161,8 +3181,11 @@ longlong Item_func_json_length::val_int()
if (!path.parsed)
{
String *s_p= args[1]->val_str(&tmp_path);
if (s_p &&
path_setup_nwc(&path.p, s_p->charset(), (const uchar *) s_p->ptr(),
if (!s_p)
goto null_return;
if (path_setup_nwc(&path.p,
def_path_charset(s_p->charset(), js->charset()),
(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
{
report_path_error(s_p, &path.p, 1);
Expand Down Expand Up @@ -3406,7 +3429,8 @@ String *Item_func_json_insert::val_str(String *str)
String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
if (s_p)
{
if (path_setup_nwc(&c_path->p,s_p->charset(),
if (path_setup_nwc(&c_path->p,
def_path_charset(s_p->charset(), js->charset()),
(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
{
Expand All @@ -3417,6 +3441,8 @@ String *Item_func_json_insert::val_str(String *str)
/* We search to the last step. */
c_path->p.last_step--;
}
else
goto return_null;
c_path->parsed= c_path->constant;
}
if (args[n_arg]->null_value)
Expand Down Expand Up @@ -3671,7 +3697,8 @@ String *Item_func_json_remove::val_str(String *str)
String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
if (s_p)
{
if (path_setup_nwc(&c_path->p,s_p->charset(),
if (path_setup_nwc(&c_path->p,
def_path_charset(s_p->charset(), js->charset()),
(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
{
Expand All @@ -3688,6 +3715,8 @@ String *Item_func_json_remove::val_str(String *str)
goto null_return;
}
}
else
goto null_return;
c_path->parsed= c_path->constant;
}
if (args[n_arg]->null_value)
Expand Down Expand Up @@ -3901,13 +3930,16 @@ String *Item_func_json_keys::val_str(String *str)
if (!path.parsed)
{
String *s_p= args[1]->val_str(&tmp_path);
if (s_p &&
path_setup_nwc(&path.p, s_p->charset(), (const uchar *) s_p->ptr(),
if (!s_p)
goto null_return;
if (path_setup_nwc(&path.p,
def_path_charset(s_p->charset(), js->charset()),
(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
{
report_path_error(s_p, &path.p, 1);
goto null_return;
}
{
report_path_error(s_p, &path.p, 1);
goto null_return;
}
path.parsed= path.constant;
}

Expand Down