diff options
author | green <green@FreeBSD.org> | 2002-06-01 13:25:47 +0000 |
---|---|---|
committer | green <green@FreeBSD.org> | 2002-06-01 13:25:47 +0000 |
commit | 20552d4d83960955e1b7d3636b29302210bc7686 (patch) | |
tree | 3f50429b3ecc0bb31a42d03f146962b8dbf72448 /usr.bin | |
parent | c7fb877f7f9b3d72c11f42d90a4990fd3750df7b (diff) | |
download | FreeBSD-src-20552d4d83960955e1b7d3636b29302210bc7686.zip FreeBSD-src-20552d4d83960955e1b7d3636b29302210bc7686.tar.gz |
Fix a bug in sed(1)'s "s" command wherein if an escape ("\" character)
was initiated at the last character of the line buffer, the Wrong
Thing was done and sed barfed by interpreting the following NUL byte
as a digit. Instead, pull up the next buffer and record that the "\"
was last seen.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/sed/compile.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/usr.bin/sed/compile.c b/usr.bin/sed/compile.c index 2076297..8265ff8 100644 --- a/usr.bin/sed/compile.c +++ b/usr.bin/sed/compile.c @@ -467,7 +467,7 @@ compile_subst(p, s) int asize, size; u_char ref; char c, *text, *op, *sp; - int more = 1; + int more = 1, sawesc = 0; c = *p++; /* Terminator character */ if (c == '\0') @@ -482,9 +482,29 @@ compile_subst(p, s) do { op = sp = text + size; for (; *p; p++) { - if (*p == '\\') { - p++; - if (strchr("123456789", *p) != NULL) { + if (*p == '\\' || sawesc) { + /* + * If this is a continuation from the last + * buffer, we won't have a character to + * skip over. + */ + if (sawesc) + sawesc = 0; + else + p++; + + if (*p == '\0') { + /* + * This escaped character is continued + * in the next part of the line. Note + * this fact, then cause the loop to + * exit w/ normal EOL case and reenter + * above with the new buffer. + */ + sawesc = 1; + p--; + continue; + } else if (strchr("123456789", *p) != NULL) { *sp++ = '\\'; ref = *p - '0'; if (s->re != NULL && |