diff options
author | fanf <fanf@FreeBSD.org> | 2003-06-04 15:31:55 +0000 |
---|---|---|
committer | fanf <fanf@FreeBSD.org> | 2003-06-04 15:31:55 +0000 |
commit | 2001590435998db840a897211df3c21c349552aa (patch) | |
tree | 566ae47cff2a19cb44a7c1aaef732a20d4472a21 /usr.bin/sed | |
parent | 8e268e6fc3d8a44c4d957d3dd880c64e848a354e (diff) | |
download | FreeBSD-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')
-rw-r--r-- | usr.bin/sed/process.c | 11 |
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); } |