aboutsummaryrefslogtreecommitdiff
path: root/toys/posix/sed.c
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2019-02-12 16:29:09 -0800
committerRob Landley <rob@landley.net>2019-02-12 21:31:20 -0600
commit7079a558d6e9448d5434965985b650c1e572140e (patch)
tree5421ca8fe368722a744a7a5c906b05a6a5780c55 /toys/posix/sed.c
parent8326fe1f7e141f49a46a57acc6221651298b42c9 (diff)
downloadtoybox-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/posix/sed.c')
-rw-r--r--toys/posix/sed.c9
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;
}