Skip to content

Commit df7678c

Browse files
committed
Bug#21383284: ASSERTION IN SELECT_LEX::SETUP_CONDS
JSON_SEARCH evaluates the escape expression at resolve time in Item_func_json_search::fix_fields(), but it doesn't check if the evaluation is successful, and it could end up returning false (indicating success) even though an error has been raised. SELECT_LEX::setup_conds() has an assert which checks that no error has been raised if fix_fields() returns false. This assert gets hit if a JSON_SEARCH call is in a WHERE clause and the evaluation of the escape expression fails. Errors could be raised either when fix_fields() calls val_str() on the item representing the escape expression, or when it calls fix_fields() on its synthetic Item_func_like object. Item_func_json_search::fix_fields() also allocates some objects without checking if the allocation was successful. This patch makes fix_fields() check for all of the above error conditions and return true to indicate that an error has happened.
1 parent a980025 commit df7678c

File tree

3 files changed

+73
-48
lines changed

3 files changed

+73
-48
lines changed

mysql-test/r/json.result

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7738,6 +7738,8 @@ select json_search( '{ "a": "foo" }', 'one', 'foo', null, '$a' );
77387738
ERROR 42000: Invalid JSON path expression. The error is around character position 1 in '$a'.
77397739
select json_search( '{ "a": "foo" }', 'all', 'foo', null, '$.a', '$b' );
77407740
ERROR 42000: Invalid JSON path expression. The error is around character position 1 in '$b'.
7741+
select json_search(a, b, c);
7742+
ERROR 42S22: Unknown column 'a' in 'field list'
77417743
select json_search( '{ "a": "foobar" }', 'one', 'foo%' );
77427744
json_search( '{ "a": "foobar" }', 'one', 'foo%' )
77437745
"$.a"
@@ -12814,3 +12816,10 @@ SELECT JSON_EXTRACT('1E+36181012216111515851075235238', '$');
1281412816
ERROR 22032: Invalid JSON text in argument 1 to function json_extract: "Number too big to be stored in double." at position 6 in '1E+36181012216111515851075235238'.
1281512817
SELECT JSON_EXTRACT('-1E+36181012216111515851075235238', '$');
1281612818
ERROR 22032: Invalid JSON text in argument 1 to function json_extract: "Number too big to be stored in double." at position 7 in '-1E+36181012216111515851075235238'.
12819+
#
12820+
# Bug#21383284: ASSERTION IN SELECT_LEX::SETUP_CONDS
12821+
#
12822+
SELECT 1 FROM dual WHERE JSON_SEARCH('{}', 'one', 'foo', 'too-long-escape');
12823+
ERROR HY000: Incorrect arguments to ESCAPE
12824+
SELECT 1 FROM dual WHERE JSON_SEARCH('{}', 'one', 'foo', JSON_EXTRACT('', '$'));
12825+
ERROR 22032: Invalid JSON text in argument 1 to function json_extract: "The document is empty." at position 0 in ''.

mysql-test/t/json.test

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2588,6 +2588,9 @@ select json_search( '{ "a": "foo" }', 'one', 'foo', null, '$a' );
25882588
--error ER_INVALID_JSON_PATH
25892589
select json_search( '{ "a": "foo" }', 'all', 'foo', null, '$.a', '$b' );
25902590

2591+
--error ER_BAD_FIELD_ERROR
2592+
select json_search(a, b, c);
2593+
25912594
# simple tests for search without path arguments
25922595
select json_search( '{ "a": "foobar" }', 'one', 'foo%' );
25932596
select json_search( '{ "a": "foobar", "b": "focus", "c": [ "arm", "foot", "shoulder" ] }', 'one', 'foo%' );
@@ -5754,6 +5757,14 @@ SELECT JSON_EXTRACT('1E+36181012216111515851075235238', '$');
57545757
--error ER_INVALID_JSON_TEXT_IN_PARAM
57555758
SELECT JSON_EXTRACT('-1E+36181012216111515851075235238', '$');
57565759

5760+
--echo #
5761+
--echo # Bug#21383284: ASSERTION IN SELECT_LEX::SETUP_CONDS
5762+
--echo #
5763+
--error ER_WRONG_ARGUMENTS
5764+
SELECT 1 FROM dual WHERE JSON_SEARCH('{}', 'one', 'foo', 'too-long-escape');
5765+
--error ER_INVALID_JSON_TEXT_IN_PARAM
5766+
SELECT 1 FROM dual WHERE JSON_SEARCH('{}', 'one', 'foo', JSON_EXTRACT('', '$'));
5767+
57575768

57585769
# Local Variables:
57595770
# mode: sql

sql/item_json_func.cc

Lines changed: 53 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2590,67 +2590,72 @@ bool Item_func_json_row_object::val_json(Json_wrapper *wr)
25902590

25912591
bool Item_func_json_search::fix_fields(THD *thd, Item **items)
25922592
{
2593-
bool retval= Item_json_func::fix_fields(thd, items);
2593+
if (Item_json_func::fix_fields(thd, items))
2594+
return true;
25942595

2595-
if (!retval)
2596-
{
2597-
// Fabricate a LIKE node
2596+
// Fabricate a LIKE node
25982597

2599-
m_source_string_item= new Item_string(&my_charset_utf8mb4_bin);
2600-
Item *like_string_item= args[2];
2598+
m_source_string_item= new Item_string(&my_charset_utf8mb4_bin);
2599+
Item_string *default_escape= new Item_string(&my_charset_utf8mb4_bin);
2600+
if (m_source_string_item == NULL || default_escape == NULL)
2601+
return true; /* purecov: inspected */
26012602

2602-
Item_string *default_escape= new Item_string(&my_charset_utf8mb4_bin);
2603-
bool escape_initialized= false;
2603+
Item *like_string_item= args[2];
2604+
bool escape_initialized= false;
26042605

2605-
// Get the escape character, if any
2606-
if (arg_count > 3)
2607-
{
2608-
Item *orig_escape= args[3];
2609-
2610-
/*
2611-
Evaluate the escape clause. For a standalone LIKE expression,
2612-
the escape clause only has to be constant during execution.
2613-
However, we require a stronger condition: it must be constant.
2614-
That means that we can evaluate the escape clause at resolution time
2615-
and copy the results from the JSON_SEARCH() args into the arguments
2616-
for the LIKE node which we're fabricating.
2617-
*/
2618-
if (!orig_escape->const_item())
2619-
{
2620-
my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
2621-
return true;
2622-
}
2606+
// Get the escape character, if any
2607+
if (arg_count > 3)
2608+
{
2609+
Item *orig_escape= args[3];
26232610

2624-
String *escape_str= orig_escape->val_str(&m_escape);
2625-
if (!orig_escape->null_value)
2626-
{
2627-
uint escape_length= static_cast<uint>(escape_str->length());
2628-
default_escape->set_str_with_copy(escape_str->ptr(), escape_length);
2629-
escape_initialized= true;
2630-
}
2611+
/*
2612+
Evaluate the escape clause. For a standalone LIKE expression,
2613+
the escape clause only has to be constant during execution.
2614+
However, we require a stronger condition: it must be constant.
2615+
That means that we can evaluate the escape clause at resolution time
2616+
and copy the results from the JSON_SEARCH() args into the arguments
2617+
for the LIKE node which we're fabricating.
2618+
*/
2619+
if (!orig_escape->const_item())
2620+
{
2621+
my_error(ER_WRONG_ARGUMENTS, MYF(0), "ESCAPE");
2622+
return true;
26312623
}
2632-
if (!escape_initialized)
2624+
2625+
String *escape_str= orig_escape->val_str(&m_escape);
2626+
if (thd->is_error())
2627+
return true;
2628+
if (escape_str)
26332629
{
2634-
default_escape->set_str_with_copy("\\", 1);
2630+
uint escape_length= static_cast<uint>(escape_str->length());
2631+
default_escape->set_str_with_copy(escape_str->ptr(), escape_length);
2632+
escape_initialized= true;
26352633
}
2634+
}
26362635

2637-
m_like_node= new Item_func_like(m_source_string_item,
2638-
like_string_item,
2639-
default_escape, true);
2636+
if (!escape_initialized)
2637+
{
2638+
default_escape->set_str_with_copy("\\", 1);
2639+
}
26402640

2641-
Item *like_args[3];
2642-
like_args[0]= m_source_string_item;
2643-
like_args[1]= like_string_item;
2644-
like_args[2]= default_escape;
2641+
m_like_node= new Item_func_like(m_source_string_item, like_string_item,
2642+
default_escape, true);
2643+
if (m_like_node == NULL)
2644+
return true; /* purecov: inspected */
26452645

2646-
m_like_node->fix_fields(thd, like_args);
2646+
Item *like_args[3];
2647+
like_args[0]= m_source_string_item;
2648+
like_args[1]= like_string_item;
2649+
like_args[2]= default_escape;
26472650

2648-
// resolving the LIKE node may overwrite its arguments
2649-
Item **resolved_like_args= m_like_node->arguments();
2650-
m_source_string_item= down_cast<Item_string *>(resolved_like_args[0]);
2651-
}
2651+
if (m_like_node->fix_fields(thd, like_args))
2652+
return true;
2653+
2654+
// resolving the LIKE node may overwrite its arguments
2655+
Item **resolved_like_args= m_like_node->arguments();
2656+
m_source_string_item= down_cast<Item_string *>(resolved_like_args[0]);
26522657

2653-
return retval;
2658+
return false;
26542659
}
26552660

26562661

0 commit comments

Comments
 (0)