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
This commit is contained in:
Michael Steed 2016-02-21 14:59:03 -07:00 committed by Kurtis Rader
parent 585c03db72
commit 5b0996fd80
3 changed files with 9 additions and 5 deletions

View file

@ -792,8 +792,8 @@ public:
uint32_t options = opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0; uint32_t options = opts.all ? PCRE2_SUBSTITUTE_GLOBAL : 0;
size_t arglen = wcslen(arg); size_t arglen = wcslen(arg);
PCRE2_SIZE outlen = (arglen == 0) ? 16 : 2 * arglen; PCRE2_SIZE bufsize = (arglen == 0) ? 16 : 2 * arglen;
wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * outlen); wchar_t *output = (wchar_t *)malloc(sizeof(wchar_t) * bufsize);
if (output == 0) if (output == 0)
{ {
DIE_MEM(); DIE_MEM();
@ -801,6 +801,7 @@ public:
int pcre2_rc = 0; int pcre2_rc = 0;
for (;;) for (;;)
{ {
PCRE2_SIZE outlen = bufsize;
pcre2_rc = pcre2_substitute( pcre2_rc = pcre2_substitute(
regex.code, regex.code,
PCRE2_SPTR(arg), PCRE2_SPTR(arg),
@ -816,10 +817,10 @@ public:
if (pcre2_rc == PCRE2_ERROR_NOMEMORY) if (pcre2_rc == PCRE2_ERROR_NOMEMORY)
{ {
if (outlen < MAX_REPLACE_SIZE) if (bufsize < MAX_REPLACE_SIZE)
{ {
outlen = std::min(2 * outlen, MAX_REPLACE_SIZE); bufsize = std::min(2 * bufsize, MAX_REPLACE_SIZE);
output = (wchar_t *)realloc(output, sizeof(wchar_t) * outlen); output = (wchar_t *)realloc(output, sizeof(wchar_t) * bufsize);
if (output == 0) if (output == 0)
{ {
DIE_MEM(); DIE_MEM();

View file

@ -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 '\s*newline\s*' '\n' 'put a newline here'
string replace -r -a '(\w)' '$1$1' ab
# test some failure cases # test some failure cases
string match -r '[' 'a[sd' 2>/dev/null; or echo "invalid expression error" string match -r '[' 'a[sd' 2>/dev/null; or echo "invalid expression error"

View file

@ -41,6 +41,7 @@ spaces_to_underscores
right left $ right left $
put a put a
here here
aabb
invalid expression error invalid expression error
invalid argument error invalid argument error
missing argument returns 0 missing argument returns 0