Commit 4730a698 authored by Rucha Deodhar's avatar Rucha Deodhar

MDEV-28350: Test failing on buildbot with UBSAN

 Analysis: There were two kinds of failing tests on buildbot with UBSAN.
1) runtime error: signed integer overflow and
2) runtime error: load of value is not valid value for type
Signed integer overflow was occuring because addition of two integers
(size of json array + item number in array) was causing overflow in
json_path_parts_compare. This overflow happens because a->n_item_end
wasn't set.
The second error was occuring because c_path->p.types_used is not
initialized but the value is used later on to check for negative path index.
Fix: For signed integer overflow, use a->n_item_end only in case of range
so that it is set.
parent 3716eaff
...@@ -844,18 +844,21 @@ String *Item_func_json_extract::read_json(String *str, ...@@ -844,18 +844,21 @@ String *Item_func_json_extract::read_json(String *str,
for (n_arg=1; n_arg < arg_count; n_arg++) for (n_arg=1; n_arg < arg_count; n_arg++)
{ {
json_path_with_flags *c_path= paths + n_arg - 1; json_path_with_flags *c_path= paths + n_arg - 1;
c_path->p.types_used= JSON_PATH_KEY_NULL;
if (!c_path->parsed) if (!c_path->parsed)
{ {
String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-1)); String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-1));
if (s_p && if (s_p)
json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
{ {
report_path_error(s_p, &c_path->p, n_arg); if (json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
goto return_null; (const uchar *) s_p->ptr() + s_p->length()))
{
report_path_error(s_p, &c_path->p, n_arg);
goto return_null;
}
c_path->parsed= c_path->constant;
has_negative_path|= c_path->p.types_used & JSON_PATH_NEGATIVE_INDEX;
} }
c_path->parsed= c_path->constant;
has_negative_path|= c_path->p.types_used & JSON_PATH_NEGATIVE_INDEX;
} }
if (args[n_arg]->null_value) if (args[n_arg]->null_value)
...@@ -1391,15 +1394,18 @@ longlong Item_func_json_contains_path::val_int() ...@@ -1391,15 +1394,18 @@ longlong Item_func_json_contains_path::val_int()
json_path_with_flags *c_path= paths + n_arg - 2; json_path_with_flags *c_path= paths + n_arg - 2;
if (!c_path->parsed) if (!c_path->parsed)
{ {
String *s_p= args[n_arg]->val_str(tmp_paths+(n_arg-2)); String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-2));
if (s_p && if (s_p)
json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
{ {
report_path_error(s_p, &c_path->p, n_arg-2); if (json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
goto return_null; (const uchar *) s_p->ptr() + s_p->length()))
{
report_path_error(s_p, &c_path->p, n_arg);
goto null_return;
}
c_path->parsed= c_path->constant;
has_negative_path|= c_path->p.types_used & JSON_PATH_NEGATIVE_INDEX;
} }
c_path->parsed= c_path->constant;
} }
if (args[n_arg]->null_value) if (args[n_arg]->null_value)
...@@ -1460,18 +1466,21 @@ longlong Item_func_json_contains_path::val_int() ...@@ -1460,18 +1466,21 @@ longlong Item_func_json_contains_path::val_int()
for (n_arg=2; n_arg < arg_count; n_arg++) for (n_arg=2; n_arg < arg_count; n_arg++)
{ {
json_path_with_flags *c_path= paths + n_arg - 2; json_path_with_flags *c_path= paths + n_arg - 2;
c_path->p.types_used= JSON_PATH_KEY_NULL;
if (!c_path->parsed) if (!c_path->parsed)
{ {
String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-2)); String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-2));
if (s_p && if (s_p)
json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
{ {
report_path_error(s_p, &c_path->p, n_arg); if (json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
goto null_return; (const uchar *) s_p->ptr() + s_p->length()))
{
report_path_error(s_p, &c_path->p, n_arg);
goto null_return;
}
c_path->parsed= c_path->constant;
has_negative_path|= c_path->p.types_used & JSON_PATH_NEGATIVE_INDEX;
} }
c_path->parsed= c_path->constant;
has_negative_path|= c_path->p.types_used & JSON_PATH_NEGATIVE_INDEX;
} }
if (args[n_arg]->null_value) if (args[n_arg]->null_value)
goto null_return; goto null_return;
...@@ -3633,18 +3642,21 @@ String *Item_func_json_search::val_str(String *str) ...@@ -3633,18 +3642,21 @@ String *Item_func_json_search::val_str(String *str)
for (n_arg=4; n_arg < arg_count; n_arg++) for (n_arg=4; n_arg < arg_count; n_arg++)
{ {
json_path_with_flags *c_path= paths + n_arg - 4; json_path_with_flags *c_path= paths + n_arg - 4;
c_path->p.types_used= JSON_PATH_KEY_NULL;
if (!c_path->parsed) if (!c_path->parsed)
{ {
String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-4)); String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-4));
if (s_p && if (s_p)
json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
{ {
report_path_error(s_p, &c_path->p, n_arg); if (json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
goto null_return; (const uchar *) s_p->ptr() + s_p->length()))
{
report_path_error(s_p, &c_path->p, n_arg);
goto null_return;
}
c_path->parsed= c_path->constant;
has_negative_path|= c_path->p.types_used & JSON_PATH_NEGATIVE_INDEX;
} }
c_path->parsed= c_path->constant;
has_negative_path|= c_path->p.types_used & JSON_PATH_NEGATIVE_INDEX;
} }
if (args[n_arg]->null_value) if (args[n_arg]->null_value)
goto null_return; goto null_return;
......
...@@ -1373,6 +1373,8 @@ static int handle_match(json_engine_t *je, json_path_t *p, ...@@ -1373,6 +1373,8 @@ static int handle_match(json_engine_t *je, json_path_t *p,
(int) (next_step->type & JSON_PATH_KEY_OR_ARRAY)) (int) (next_step->type & JSON_PATH_KEY_OR_ARRAY))
return json_skip_level(je); return json_skip_level(je);
array_counters[next_step - p->steps]= 0;
if (next_step->type & JSON_PATH_ARRAY) if (next_step->type & JSON_PATH_ARRAY)
{ {
int array_size; int array_size;
...@@ -1891,21 +1893,22 @@ int json_path_parts_compare( ...@@ -1891,21 +1893,22 @@ int json_path_parts_compare(
{ {
if (b->type & JSON_PATH_ARRAY) if (b->type & JSON_PATH_ARRAY)
{ {
int res= 0, corrected_n_item_a= 0, corrected_n_item_end_a= 0; int res= 0, corrected_n_item_a= 0;
if (array_sizes) if (array_sizes)
{ corrected_n_item_a= a->n_item < 0 ?
corrected_n_item_a= a->n_item < 0 ? array_sizes[b-temp_b] + array_sizes[b-temp_b] + a->n_item : a->n_item;
a->n_item :
a->n_item;
corrected_n_item_end_a= a->n_item_end < 0 ? array_sizes[b-temp_b] +
a->n_item_end :
a->n_item_end;
}
if (a->type & JSON_PATH_ARRAY_RANGE) if (a->type & JSON_PATH_ARRAY_RANGE)
{
int corrected_n_item_end_a= 0;
if (array_sizes)
corrected_n_item_end_a= a->n_item_end < 0 ?
array_sizes[b-temp_b] + a->n_item_end :
a->n_item_end;
res= b->n_item >= corrected_n_item_a && res= b->n_item >= corrected_n_item_a &&
b->n_item <= corrected_n_item_end_a; b->n_item <= corrected_n_item_end_a;
}
else else
res= corrected_n_item_a == b->n_item; res= corrected_n_item_a == b->n_item;
if ((a->type & JSON_PATH_WILD) || res) if ((a->type & JSON_PATH_WILD) || res)
goto step_fits; goto step_fits;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment