diff options
author | Michael Steed <msteed68@gmail.com> | 2016-04-23 18:12:42 -0600 |
---|---|---|
committer | David Adam <zanchey@ucc.gu.uwa.edu.au> | 2016-04-27 12:14:53 +0800 |
commit | c2f9d60eb1f04a3aa0b01d785c1e133cac8ecf1d (patch) | |
tree | 5524c48496b9b12fcf311e900a9d16a77b786e7e /src/builtin_string.cpp | |
parent | c4c7983497e7be798c3bd1c97df38e8d1d1a58b8 (diff) |
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
Diffstat (limited to 'src/builtin_string.cpp')
-rw-r--r-- | src/builtin_string.cpp | 33 |
1 files changed, 11 insertions, 22 deletions
diff --git a/src/builtin_string.cpp b/src/builtin_string.cpp index 9efa6c2f..51c824ca 100644 --- a/src/builtin_string.cpp +++ b/src/builtin_string.cpp @@ -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; } |