item_json*: handle memory allocations
JSON functions append in multiple ways, however there isn't always error handling, and many time it doesn't make it to the end user. Made the appending string functions withing item_jsonfunc warn if their true/false result (did an error occur) isn't handled. Add error handling to many json functions. realloc_with_extra_if_needed was also previously lacking OOM handing.
This commit is contained in:
parent
ca144971e1
commit
7d9660ed93
@ -74,7 +74,8 @@ static bool eq_ascii_string(const CHARSET_INFO *cs,
|
||||
}
|
||||
|
||||
|
||||
static bool append_simple(String *s, const char *a, size_t a_len)
|
||||
static bool __attribute__((warn_unused_result))
|
||||
append_simple(String *s, const char *a, size_t a_len)
|
||||
{
|
||||
if (!s->realloc_with_extra_if_needed(s->length() + a_len))
|
||||
{
|
||||
@ -86,7 +87,8 @@ static bool append_simple(String *s, const char *a, size_t a_len)
|
||||
}
|
||||
|
||||
|
||||
static inline bool append_simple(String *s, const uchar *a, size_t a_len)
|
||||
static inline bool __attribute__((warn_unused_result))
|
||||
append_simple(String *s, const uchar *a, size_t a_len)
|
||||
{
|
||||
return append_simple(s, (const char *) a, a_len);
|
||||
}
|
||||
@ -300,7 +302,9 @@ static int json_nice(json_engine_t *je, String *nice_js,
|
||||
|
||||
nice_js->length(0);
|
||||
nice_js->set_charset(je->s.cs);
|
||||
nice_js->alloc(je->s.str_end - je->s.c_str + 32);
|
||||
|
||||
if (nice_js->alloc(je->s.str_end - je->s.c_str + 32))
|
||||
goto error;
|
||||
|
||||
DBUG_ASSERT(mode != Item_func_json_format::DETAILED ||
|
||||
(tab_size >= 0 && tab_size <= TAB_SIZE_LIMIT));
|
||||
@ -347,7 +351,8 @@ static int json_nice(json_engine_t *je, String *nice_js,
|
||||
goto error;
|
||||
|
||||
nice_js->append('"');
|
||||
append_simple(nice_js, key_start, key_end - key_start);
|
||||
if (append_simple(nice_js, key_start, key_end - key_start))
|
||||
goto error;
|
||||
nice_js->append(colon, colon_len);
|
||||
}
|
||||
/* now we have key value to handle, so no 'break'. */
|
||||
@ -2248,25 +2253,68 @@ String *Item_func_json_array_insert::val_str(String *str)
|
||||
str->set_charset(js->charset());
|
||||
if (item_pos)
|
||||
{
|
||||
if (append_simple(str, js->ptr(), item_pos - js->ptr()) ||
|
||||
(n_item > 0 && str->append(" ", 1)) ||
|
||||
append_json_value(str, args[n_arg+1], &tmp_val) ||
|
||||
str->append(",", 1) ||
|
||||
(n_item == 0 && str->append(" ", 1)) ||
|
||||
append_simple(str, item_pos, js->end() - item_pos))
|
||||
my_ptrdiff_t size= item_pos - js->ptr();
|
||||
if (append_simple(str, js->ptr(), size))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), (int) size);
|
||||
goto return_null; /* Out of memory. */
|
||||
}
|
||||
if (n_item > 0 && str->append(" ", 1))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), 1);
|
||||
goto return_null; /* Out of memory. */
|
||||
}
|
||||
if (append_json_value(str, args[n_arg+1], &tmp_val))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), tmp_val.length());
|
||||
goto return_null; /* Out of memory. */
|
||||
}
|
||||
if (str->append(",", 1))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), 1);
|
||||
goto return_null; /* Out of memory. */
|
||||
}
|
||||
if (n_item == 0 && str->append(" ", 1))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), 1);
|
||||
goto return_null; /* Out of memory. */
|
||||
}
|
||||
size= js->end() - item_pos;
|
||||
if (append_simple(str, item_pos, size))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), (int) size);
|
||||
goto return_null; /* Out of memory. */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my_ptrdiff_t size;
|
||||
/* Insert position wasn't found - append to the array. */
|
||||
DBUG_ASSERT(je.state == JST_ARRAY_END);
|
||||
item_pos= (const char *) (je.s.c_str - je.sav_c_len);
|
||||
if (append_simple(str, js->ptr(), item_pos - js->ptr()) ||
|
||||
(n_item > 0 && str->append(", ", 2)) ||
|
||||
append_json_value(str, args[n_arg+1], &tmp_val) ||
|
||||
append_simple(str, item_pos, js->end() - item_pos))
|
||||
size= item_pos - js->ptr();
|
||||
if (append_simple(str, js->ptr(), size))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), (int) size);
|
||||
goto return_null; /* Out of memory. */
|
||||
}
|
||||
if (n_item > 0 && str->append(", ", 2))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), 2);
|
||||
goto return_null; /* Out of memory. */
|
||||
}
|
||||
if (append_json_value(str, args[n_arg+1], &tmp_val))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), tmp_val.length());
|
||||
goto return_null; /* Out of memory. */
|
||||
}
|
||||
size= js->end() - item_pos;
|
||||
if (append_simple(str, item_pos, size))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), (int) size);
|
||||
goto return_null; /* Out of memory. */
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/* Swap str and js. */
|
||||
@ -4117,8 +4165,12 @@ int Arg_comparator::compare_json_str_basic(Item *j, Item *s)
|
||||
goto error;
|
||||
if (je.value_type == JSON_VALUE_STRING)
|
||||
{
|
||||
if (value2.realloc_with_extra_if_needed(je.value_len) ||
|
||||
(c_len= json_unescape(js->charset(), je.value,
|
||||
if (value2.realloc_with_extra_if_needed(je.value_len))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), je.value_len);
|
||||
goto error;
|
||||
}
|
||||
if ((c_len= json_unescape(js->charset(), je.value,
|
||||
je.value + je.value_len,
|
||||
&my_charset_utf8mb4_bin,
|
||||
(uchar *) value2.ptr(),
|
||||
@ -4172,8 +4224,12 @@ int Arg_comparator::compare_e_json_str_basic(Item *j, Item *s)
|
||||
|
||||
if (type == JSON_VALUE_STRING)
|
||||
{
|
||||
if (value1.realloc_with_extra_if_needed(value_len) ||
|
||||
(c_len= json_unescape(value1.charset(), (uchar *) value,
|
||||
if (value1.realloc_with_extra_if_needed(value_len))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), value_len);
|
||||
return 1;
|
||||
}
|
||||
if ((c_len= json_unescape(value1.charset(), (uchar *) value,
|
||||
(uchar *) value+value_len,
|
||||
&my_charset_utf8mb4_bin,
|
||||
(uchar *) value1.ptr(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user