Update usage of pcre2_substitute() for pcre2-10.21

- Set PCRE2_SUBSTITUTE_OVERFLOW_LENGTH to get the required buffer length
  from pcre2 instead of guessing
- Set PCRE2_SUBSTITUTE_EXTENDED to enable extra goodies in the
  replacement string
This commit is contained in:
Michael Steed 2016-04-23 18:12:42 -06:00 committed by David Adam
parent c4c7983497
commit c2f9d60eb1

View File

@ -33,7 +33,6 @@
class parser_t;
#define MAX_REPLACE_SIZE size_t(1048576) // pcre2_substitute maximum output size in wchar_t
#define STRING_ERR_MISSING _(L"%ls: Expected argument\n")
/* externs from builtin.cpp */
@ -813,7 +812,6 @@ public:
bool replace_matches(const wchar_t *arg)
{
// A return value of true means all is well (even if no replacements
// were performed), false indicates an unrecoverable error.
if (regex.code == 0)
@ -822,17 +820,18 @@ public:
return false;
}
uint32_t options = opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0;
uint32_t options = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH | PCRE2_SUBSTITUTE_EXTENDED |
(opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0);
size_t arglen = wcslen(arg);
PCRE2_SIZE bufsize = (arglen == 0) ? 16 : 2 * arglen;
wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * bufsize);
if (output == NULL)
{
DIE_MEM();
}
int pcre2_rc = 0;
for (;;)
{
if (output == NULL)
{
DIE_MEM();
}
PCRE2_SIZE outlen = bufsize;
pcre2_rc = pcre2_substitute(
regex.code,
@ -847,22 +846,12 @@ public:
(PCRE2_UCHAR *)output,
&outlen);
if (pcre2_rc == PCRE2_ERROR_NOMEMORY)
if (pcre2_rc == PCRE2_ERROR_NOMEMORY && bufsize < outlen)
{
if (bufsize < MAX_REPLACE_SIZE)
{
bufsize = std::min(2 * bufsize, MAX_REPLACE_SIZE);
// cppcheck-suppress memleakOnRealloc
output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize);
if (output == NULL)
{
DIE_MEM();
}
continue;
}
string_error(streams, _(L"%ls: Replacement string too large\n"), argv0);
free(output);
return false;
bufsize = outlen;
// cppcheck-suppress memleakOnRealloc
output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize);
continue;
}
break;
}