diff options
author | Elliott Hughes <enh@google.com> | 2019-02-12 16:29:09 -0800 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2019-02-12 21:31:20 -0600 |
commit | 7079a558d6e9448d5434965985b650c1e572140e (patch) | |
tree | 5421ca8fe368722a744a7a5c906b05a6a5780c55 /toys | |
parent | 8326fe1f7e141f49a46a57acc6221651298b42c9 (diff) | |
download | toybox-7079a558d6e9448d5434965985b650c1e572140e.tar.gz |
sed: fix substitution of empty capturing groups.
The test for \N where N was larger than the number of capturing groups
in the regular expression was incorrect, and firing for cases such as
matching __(ARM_)?NR_([a-z]*) against __NR_read, where the first group is
empty (because it failed to match) but the second group did match "read".
Use regex_t's re_nsub for the error check, and treat rm_so == -1 as a
signal to just copy nothing into the result.
(Found trying to build minijail in AOSP.)
Diffstat (limited to 'toys')
-rw-r--r-- | toys/posix/sed.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/toys/posix/sed.c b/toys/posix/sed.c index 228055f9..0be2165e 100644 --- a/toys/posix/sed.c +++ b/toys/posix/sed.c @@ -528,15 +528,18 @@ static void sed_line(char **pline, long plen) rswap[mlen-1] = new[off]; continue; - } else if (match[cc].rm_so == -1) error_exit("no s//\\%d/", cc); + } else if (cc > reg->re_nsub) error_exit("no s//\\%d/", cc); } else if (new[off] != '&') { rswap[mlen++] = new[off]; continue; } - ll = match[cc].rm_eo-match[cc].rm_so; - memcpy(rswap+mlen, rline+match[cc].rm_so, ll); + if (match[cc].rm_so == -1) ll = 0; // Empty match. + else { + ll = match[cc].rm_eo-match[cc].rm_so; + memcpy(rswap+mlen, rline+match[cc].rm_so, ll); + } mlen += ll; } |