regsub converter: empty match advances by 1 byte to avoid loops
This commit is contained in:
@ -666,6 +666,13 @@ Otherwise <em>precision</em> is the index (counting from 1) of the match to repl
|
|||||||
Without <em>precision</em> (or 0), all matches are replaced.
|
Without <em>precision</em> (or 0), all matches are replaced.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
When replacing multiple matches, the next match is searched directly after the currently
|
||||||
|
replaced string, so that the <em>subst</em> string itself will never be modified recursively.
|
||||||
|
<span class="new">
|
||||||
|
However if an empty string is matched, searching advances by 1 character in order to
|
||||||
|
avoid matching the same empty string again.</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
In input this converter pre-processes data received from the device before
|
In input this converter pre-processes data received from the device before
|
||||||
following converters read it.
|
following converters read it.
|
||||||
Converters preceding this one will read unmodified input.
|
Converters preceding this one will read unmodified input.
|
||||||
|
@ -197,14 +197,15 @@ static void regsubst(const StreamFormat& fmt, StreamBuffer& buffer, size_t start
|
|||||||
debug("pcre_exec: no match\n");
|
debug("pcre_exec: no match\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!(fmt.flags & sign_flag) && n < fmt.prec) // without + flag
|
|
||||||
{
|
|
||||||
// do not yet replace this match
|
|
||||||
c += ovector[1];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// replace subexpressions
|
|
||||||
l = ovector[1] - ovector[0];
|
l = ovector[1] - ovector[0];
|
||||||
|
|
||||||
|
// no prec: replace all matches
|
||||||
|
// prec with + flag: replace first prec matches
|
||||||
|
// prec without + flag: replace only match number prec
|
||||||
|
|
||||||
|
if ((fmt.flags & sign_flag) || n >= fmt.prec)
|
||||||
|
{
|
||||||
|
// replace subexpressions
|
||||||
debug("before [%d]= \"%s\"\n", ovector[0], buffer.expand(start+c,ovector[0])());
|
debug("before [%d]= \"%s\"\n", ovector[0], buffer.expand(start+c,ovector[0])());
|
||||||
debug("match [%d]= \"%s\"\n", l, buffer.expand(start+c+ovector[0],l)());
|
debug("match [%d]= \"%s\"\n", l, buffer.expand(start+c+ovector[0],l)());
|
||||||
for (r = 1; r < rc; r++)
|
for (r = 1; r < rc; r++)
|
||||||
@ -243,8 +244,16 @@ static void regsubst(const StreamFormat& fmt, StreamBuffer& buffer, size_t start
|
|||||||
debug("subs = \"%s\"\n", s.expand()());
|
debug("subs = \"%s\"\n", s.expand()());
|
||||||
}
|
}
|
||||||
buffer.replace(start+c+ovector[0], l, s);
|
buffer.replace(start+c+ovector[0], l, s);
|
||||||
length += s.length() - l;
|
length -= l;
|
||||||
c += ovector[0] + s.length();
|
length += s.length();
|
||||||
|
c += s.length();
|
||||||
|
}
|
||||||
|
c += ovector[0];
|
||||||
|
if (l == 0)
|
||||||
|
{
|
||||||
|
debug("pcre_exec: empty match\n");
|
||||||
|
c++; // Empty strings may lead to an endless loop. Match them only once.
|
||||||
|
}
|
||||||
if (n == fmt.prec) // max match reached
|
if (n == fmt.prec) // max match reached
|
||||||
{
|
{
|
||||||
debug("pcre_exec: max match %d reached\n", n);
|
debug("pcre_exec: max match %d reached\n", n);
|
||||||
|
Reference in New Issue
Block a user