summaryrefslogtreecommitdiffstats
path: root/usr.bin/sed/process.c
diff options
context:
space:
mode:
authorfanf <fanf@FreeBSD.org>2003-06-04 15:31:55 +0000
committerfanf <fanf@FreeBSD.org>2003-06-04 15:31:55 +0000
commit2001590435998db840a897211df3c21c349552aa (patch)
tree566ae47cff2a19cb44a7c1aaef732a20d4472a21 /usr.bin/sed/process.c
parent8e268e6fc3d8a44c4d957d3dd880c64e848a354e (diff)
downloadFreeBSD-src-2001590435998db840a897211df3c21c349552aa.zip
FreeBSD-src-2001590435998db840a897211df3c21c349552aa.tar.gz
Fix substitution when the regex matches the zero-length string.
There are two bugs: in the s///g case, the substitution didn't occur at the end of the line; in the s///N case, the code didn't count forwards along the line properly. See the sg, s3, s4, and s5 tests in src/tools/regression/usr.bin/sed/. Reviewed by: tjr
Diffstat (limited to 'usr.bin/sed/process.c')
-rw-r--r--usr.bin/sed/process.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/usr.bin/sed/process.c b/usr.bin/sed/process.c
index da9c7c5..f7d730d 100644
--- a/usr.bin/sed/process.c
+++ b/usr.bin/sed/process.c
@@ -323,7 +323,7 @@ substitute(cp)
{
SPACE tspace;
regex_t *re;
- size_t re_off, slen;
+ regoff_t re_off, slen;
int lastempty, n;
char *s;
@@ -361,9 +361,6 @@ substitute(cp)
s += match[0].rm_eo;
slen -= match[0].rm_eo;
lastempty = 0;
- } else if (match[0].rm_so == slen) {
- s += match[0].rm_so;
- slen = 0;
} else {
if (match[0].rm_so == 0)
cspace(&SS, s, match[0].rm_so + 1,
@@ -375,15 +372,19 @@ substitute(cp)
slen -= match[0].rm_so + 1;
lastempty = 1;
}
- } while (slen > 0 && regexec_e(re, s, REG_NOTBOL, 0, slen));
+ } while (slen >= 0 && regexec_e(re, s, REG_NOTBOL, 0, slen));
/* Copy trailing retained string. */
if (slen > 0)
cspace(&SS, s, slen, APPEND);
break;
default: /* Nth occurrence */
while (--n) {
+ if (match[0].rm_eo == match[0].rm_so)
+ match[0].rm_eo = match[0].rm_so + 1;
s += match[0].rm_eo;
slen -= match[0].rm_eo;
+ if (slen < 0)
+ return (0);
if (!regexec_e(re, s, REG_NOTBOL, 0, slen))
return (0);
}
OpenPOWER on IntegriCloud