Subject: Re: bin/25899: sed fails when 2048'th character is a backslash
To: Min Sik Kim <minskim@NetBSD.org>
From: James Chacon <jmc@NetBSD.org>
List: tech-userlevel
Date: 06/11/2004 23:04:03
On Fri, Jun 11, 2004 at 10:26:25PM -0500, Min Sik Kim wrote:
> * Min Sik Kim, Thu, 10 Jun 2004 20:04:39 -0500 (CDT):
> > >Number:         25899
> > >Category:       bin
> > >Synopsis:       sed fails when 2048'th character is a backslash
> > >Description:
> > When reading a command from a file using '-f' option, sed fails as
> > follows if the 2048'th character in a subst command is a backslash.
> > 
> >   % sed -f sedcmd
> >   sed: 1: sedcmd: \ not defined in the RE
> 
> FreeBSD already fixed this as follows.  Is it okay to commit?

Looks good

James

> 
> 
> Index: compile.c
> ===================================================================
> RCS file: /cvsroot/src/usr.bin/sed/compile.c,v
> retrieving revision 1.25
> diff -u -r1.25 compile.c
> --- compile.c	7 Aug 2003 11:15:49 -0000	1.25
> +++ compile.c	12 Jun 2004 03:23:23 -0000
> @@ -481,6 +481,7 @@
>  	static char lbuf[_POSIX2_LINE_MAX + 1];
>  	int asize, ref, size;
>  	char c, *text, *op, *sp;
> +	int sawesc = 0;
>  
>  	c = *p++;			/* Terminator character */
>  	if (c == '\0')
> @@ -494,9 +495,29 @@
>  	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 &&