aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/builtin_string.cpp
diff options
context:
space:
mode:
authorGravatar Michael Steed <msteed68@gmail.com>2016-04-23 18:12:42 -0600
committerGravatar David Adam <zanchey@ucc.gu.uwa.edu.au>2016-04-27 12:14:53 +0800
commitc2f9d60eb1f04a3aa0b01d785c1e133cac8ecf1d (patch)
tree5524c48496b9b12fcf311e900a9d16a77b786e7e /src/builtin_string.cpp
parentc4c7983497e7be798c3bd1c97df38e8d1d1a58b8 (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.cpp33
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;
}