aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Michael Steed <msteed68@gmail.com>2016-02-21 14:59:03 -0700
committerGravatar Kurtis Rader <krader@skepticism.us>2016-02-21 19:32:08 -0800
commit5b0996fd80c6f2e5844dc42be2a0368ea3ff9e12 (patch)
treee23a32691eb0d788ac2329cc75805d5ba838da2c
parent585c03db72fad2fe790937890dc0a82b4354baf6 (diff)
make fish compatible with pcre2 10.21
pcre2_substitute() now sets the output buffer length to PCRE2_UNSET (~0) if the output buffer is determined to be too small. This change keeps track of the buffer size separately where pcre2 can't touch it. A better fix would be to let pcre2 tell fish what size buffer it needs. This can be done with PCRE2_SUBSTITUTE_OVERFLOW_LENGTH, but this requires pcre2 10.21 or later (released January 12), which may be too new to introduce as a dependency at this point. Fixes #2743
-rw-r--r--src/builtin_string.cpp11
-rw-r--r--tests/string.in2
-rw-r--r--tests/string.out1
3 files changed, 9 insertions, 5 deletions
diff --git a/src/builtin_string.cpp b/src/builtin_string.cpp
index a35903cb..ab864e88 100644
--- a/src/builtin_string.cpp
+++ b/src/builtin_string.cpp
@@ -792,8 +792,8 @@ public:
uint32_t options = opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0;
size_t arglen = wcslen(arg);
- PCRE2_SIZE outlen = (arglen == 0) ? 16 : 2 * arglen;
- wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * outlen);
+ PCRE2_SIZE bufsize = (arglen == 0) ? 16 : 2 * arglen;
+ wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * bufsize);
if (output == 0)
{
DIE_MEM();
@@ -801,6 +801,7 @@ public:
int pcre2_rc = 0;
for (;;)
{
+ PCRE2_SIZE outlen = bufsize;
pcre2_rc = pcre2_substitute(
regex.code,
PCRE2_SPTR(arg),
@@ -816,10 +817,10 @@ public:
if (pcre2_rc == PCRE2_ERROR_NOMEMORY)
{
- if (outlen < MAX_REPLACE_SIZE)
+ if (bufsize < MAX_REPLACE_SIZE)
{
- outlen = std::min(2 * outlen, MAX_REPLACE_SIZE);
- output = (wchar_t *)realloc(output, sizeof(wchar_t) * outlen);
+ bufsize = std::min(2 * bufsize, MAX_REPLACE_SIZE);
+ output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize);
if (output == 0)
{
DIE_MEM();
diff --git a/tests/string.in b/tests/string.in
index 1c78e2b3..8afc97ff 100644
--- a/tests/string.in
+++ b/tests/string.in
@@ -55,6 +55,8 @@ string replace -r '(\w+)\s+(\w+)' '$2 $1 $$' 'left right'
string replace -r '\s*newline\s*' '\n' 'put a newline here'
+string replace -r -a '(\w)' '$1$1' ab
+
# test some failure cases
string match -r '[' 'a[sd' 2>/dev/null; or echo "invalid expression error"
diff --git a/tests/string.out b/tests/string.out
index 64b956e3..45ccb369 100644
--- a/tests/string.out
+++ b/tests/string.out
@@ -41,6 +41,7 @@ spaces_to_underscores
right left $
put a
here
+aabb
invalid expression error
invalid argument error
missing argument returns 0