Fix calls of pcre2_substitute
If the output buffer given to pcre2_substitute is too small, an error value is written to the last parameter (output length). That value should not be used for calculations. This patch gives a copy as parameter instead. Coincidentally, this commit fixes the crashes of query classifier tests. Also, increase buffer growth rate in utils.c.
This commit is contained in:
@ -290,12 +290,14 @@ char* config_clean_string_list(const char* str)
|
||||
|
||||
const char *replace = "$1,";
|
||||
int rval = 0;
|
||||
size_t destsize_tmp = destsize;
|
||||
while ((rval = pcre2_substitute(re, (PCRE2_SPTR) str, PCRE2_ZERO_TERMINATED, 0,
|
||||
PCRE2_SUBSTITUTE_GLOBAL, data, NULL,
|
||||
(PCRE2_SPTR) replace, PCRE2_ZERO_TERMINATED,
|
||||
(PCRE2_UCHAR*) dest, &destsize)) == PCRE2_ERROR_NOMEMORY)
|
||||
(PCRE2_UCHAR*) dest, &destsize_tmp)) == PCRE2_ERROR_NOMEMORY)
|
||||
{
|
||||
char* tmp = MXS_REALLOC(dest, destsize * 2);
|
||||
destsize_tmp = 2 * destsize;
|
||||
char* tmp = MXS_REALLOC(dest, destsize_tmp);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
MXS_FREE(dest);
|
||||
@ -303,7 +305,7 @@ char* config_clean_string_list(const char* str)
|
||||
break;
|
||||
}
|
||||
dest = tmp;
|
||||
destsize *= 2;
|
||||
destsize = destsize_tmp;
|
||||
}
|
||||
|
||||
/** Remove the trailing comma */
|
||||
|
@ -39,7 +39,7 @@
|
||||
* @param subject Subject string
|
||||
* @param replace Replacement string
|
||||
* @param dest Destination buffer
|
||||
* @param size Size of the desination buffer
|
||||
* @param size Size of the destination buffer
|
||||
* @return MXS_PCRE2_MATCH if replacements were made, MXS_PCRE2_NOMATCH if nothing
|
||||
* was replaced or MXS_PCRE2_ERROR if memory reallocation failed
|
||||
*/
|
||||
@ -52,18 +52,20 @@ mxs_pcre2_result_t mxs_pcre2_substitute(pcre2_code *re, const char *subject, con
|
||||
|
||||
if (mdata)
|
||||
{
|
||||
size_t size_tmp = *size;
|
||||
while ((rc = pcre2_substitute(re, (PCRE2_SPTR) subject, PCRE2_ZERO_TERMINATED, 0,
|
||||
PCRE2_SUBSTITUTE_GLOBAL, mdata, NULL,
|
||||
(PCRE2_SPTR) replace, PCRE2_ZERO_TERMINATED,
|
||||
(PCRE2_UCHAR*) *dest, size)) == PCRE2_ERROR_NOMEMORY)
|
||||
(PCRE2_UCHAR*) *dest, &size_tmp)) == PCRE2_ERROR_NOMEMORY)
|
||||
{
|
||||
char *tmp = MXS_REALLOC(*dest, *size * 2);
|
||||
size_tmp = 2 * (*size);
|
||||
char *tmp = MXS_REALLOC(*dest, size_tmp);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
*dest = tmp;
|
||||
*size *= 2;
|
||||
*size = size_tmp;
|
||||
}
|
||||
|
||||
if (rc > 0)
|
||||
|
@ -548,7 +548,7 @@ strip_escape_chars(char* val)
|
||||
return true;
|
||||
}
|
||||
|
||||
#define BUFFER_GROWTH_RATE 1.2
|
||||
#define BUFFER_GROWTH_RATE 2.0
|
||||
static pcre2_code* remove_comments_re = NULL;
|
||||
static const PCRE2_SPTR remove_comments_pattern = (PCRE2_SPTR)
|
||||
"(?:`[^`]*`\\K)|(\\/[*](?!(M?!)).*?[*]\\/)|(?:#.*|--[[:space:]].*)";
|
||||
@ -576,18 +576,19 @@ char* remove_mysql_comments(const char** src, const size_t* srcsize, char** dest
|
||||
char* output = *dest;
|
||||
size_t orig_len = *srcsize;
|
||||
size_t len = output ? *destsize : orig_len;
|
||||
|
||||
if (orig_len > 0)
|
||||
{
|
||||
if ((output || (output = (char*) malloc(len * sizeof (char)))) &&
|
||||
(mdata = pcre2_match_data_create_from_pattern(remove_comments_re, NULL)))
|
||||
{
|
||||
size_t len_tmp = len;
|
||||
while (pcre2_substitute(remove_comments_re, (PCRE2_SPTR) * src, orig_len, 0,
|
||||
PCRE2_SUBSTITUTE_GLOBAL, mdata, NULL,
|
||||
replace, PCRE2_ZERO_TERMINATED,
|
||||
(PCRE2_UCHAR8*) output, &len) == PCRE2_ERROR_NOMEMORY)
|
||||
(PCRE2_UCHAR8*) output, &len_tmp) == PCRE2_ERROR_NOMEMORY)
|
||||
{
|
||||
char* tmp = (char*) realloc(output, (len = (size_t) (len * BUFFER_GROWTH_RATE + 1)));
|
||||
len_tmp = (size_t) (len * BUFFER_GROWTH_RATE + 1);
|
||||
char* tmp = (char*) realloc(output, len_tmp);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
free(output);
|
||||
@ -595,6 +596,7 @@ char* remove_mysql_comments(const char** src, const size_t* srcsize, char** dest
|
||||
break;
|
||||
}
|
||||
output = tmp;
|
||||
len = len_tmp;
|
||||
}
|
||||
pcre2_match_data_free(mdata);
|
||||
}
|
||||
@ -648,12 +650,14 @@ char* replace_values(const char** src, const size_t* srcsize, char** dest, size_
|
||||
if ((output || (output = (char*) malloc(len * sizeof (char)))) &&
|
||||
(mdata = pcre2_match_data_create_from_pattern(replace_values_re, NULL)))
|
||||
{
|
||||
size_t len_tmp = len;
|
||||
while (pcre2_substitute(replace_values_re, (PCRE2_SPTR) * src, orig_len, 0,
|
||||
PCRE2_SUBSTITUTE_GLOBAL, mdata, NULL,
|
||||
replace, PCRE2_ZERO_TERMINATED,
|
||||
(PCRE2_UCHAR8*) output, &len) == PCRE2_ERROR_NOMEMORY)
|
||||
(PCRE2_UCHAR8*) output, &len_tmp) == PCRE2_ERROR_NOMEMORY)
|
||||
{
|
||||
char* tmp = (char*) realloc(output, (len = (size_t) (len * BUFFER_GROWTH_RATE + 1)));
|
||||
len_tmp = (size_t) (len * BUFFER_GROWTH_RATE + 1);
|
||||
char* tmp = (char*) realloc(output, len_tmp);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
free(output);
|
||||
@ -661,6 +665,7 @@ char* replace_values(const char** src, const size_t* srcsize, char** dest, size_
|
||||
break;
|
||||
}
|
||||
output = tmp;
|
||||
len = len_tmp;
|
||||
}
|
||||
pcre2_match_data_free(mdata);
|
||||
}
|
||||
@ -801,12 +806,14 @@ char* replace_quoted(const char** src, const size_t* srcsize, char** dest, size_
|
||||
if ((output || (output = (char*) malloc(len * sizeof (char)))) &&
|
||||
(mdata = pcre2_match_data_create_from_pattern(replace_quoted_re, NULL)))
|
||||
{
|
||||
size_t len_tmp = len;
|
||||
while (pcre2_substitute(replace_quoted_re, (PCRE2_SPTR) * src, orig_len, 0,
|
||||
PCRE2_SUBSTITUTE_GLOBAL, mdata, NULL,
|
||||
replace, PCRE2_ZERO_TERMINATED,
|
||||
(PCRE2_UCHAR8*) output, &len) == PCRE2_ERROR_NOMEMORY)
|
||||
(PCRE2_UCHAR8*) output, &len_tmp) == PCRE2_ERROR_NOMEMORY)
|
||||
{
|
||||
char* tmp = (char*) realloc(output, (len = (size_t) (len * BUFFER_GROWTH_RATE + 1)));
|
||||
len_tmp = (size_t) (len * BUFFER_GROWTH_RATE + 1);
|
||||
char* tmp = (char*) realloc(output, len_tmp);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
free(output);
|
||||
@ -814,6 +821,7 @@ char* replace_quoted(const char** src, const size_t* srcsize, char** dest, size_
|
||||
break;
|
||||
}
|
||||
output = tmp;
|
||||
len = len_tmp;
|
||||
}
|
||||
pcre2_match_data_free(mdata);
|
||||
}
|
||||
|
@ -427,19 +427,22 @@ regex_replace(const char *sql, pcre2_code *re, pcre2_match_data *match_data, con
|
||||
result_size = strlen(sql) + strlen(replace);
|
||||
result = MXS_MALLOC(result_size);
|
||||
|
||||
size_t result_size_tmp = result_size;
|
||||
while (result &&
|
||||
pcre2_substitute(re, (PCRE2_SPTR) sql, PCRE2_ZERO_TERMINATED, 0,
|
||||
PCRE2_SUBSTITUTE_GLOBAL, match_data, NULL,
|
||||
(PCRE2_SPTR) replace, PCRE2_ZERO_TERMINATED,
|
||||
(PCRE2_UCHAR*) result, (PCRE2_SIZE*) & result_size) == PCRE2_ERROR_NOMEMORY)
|
||||
(PCRE2_UCHAR*) result, (PCRE2_SIZE*) & result_size_tmp) == PCRE2_ERROR_NOMEMORY)
|
||||
{
|
||||
result_size_tmp = 1.5 * result_size;
|
||||
char *tmp;
|
||||
if ((tmp = MXS_REALLOC(result, (result_size *= 1.5))) == NULL)
|
||||
if ((tmp = MXS_REALLOC(result, result_size_tmp)) == NULL)
|
||||
{
|
||||
MXS_FREE(result);
|
||||
result = NULL;
|
||||
}
|
||||
result = tmp;
|
||||
result_size = result_size_tmp;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
Reference in New Issue
Block a user