Module Name:    src
Committed By:   tnn
Date:           Fri Feb 19 16:35:27 UTC 2010

Modified Files:
        src/usr.bin/sed: compile.c defs.h extern.h main.c misc.c

Log Message:
Merge the following revisions from OpenBSD to let sed(1) handle
arbitrarily long lines (closes our PR bin/42261).
openbsd/usr.bin/sed/extern.h 1.5
openbsd/usr.bin/sed/main.c 1.13-1.15
openbsd/usr.bin/sed/misc.c 1.8
openbsd/usr.bin/sed/compile.c 1.25-1.28
openbsd/usr.bin/sed/defs.h 1.4


To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/usr.bin/sed/compile.c
cvs rdiff -u -r1.9 -r1.10 src/usr.bin/sed/defs.h
cvs rdiff -u -r1.10 -r1.11 src/usr.bin/sed/extern.h src/usr.bin/sed/misc.c
cvs rdiff -u -r1.20 -r1.21 src/usr.bin/sed/main.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/sed/compile.c
diff -u src/usr.bin/sed/compile.c:1.36 src/usr.bin/sed/compile.c:1.37
--- src/usr.bin/sed/compile.c:1.36	Mon Apr 13 07:29:55 2009
+++ src/usr.bin/sed/compile.c	Fri Feb 19 16:35:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: compile.c,v 1.36 2009/04/13 07:29:55 lukem Exp $	*/
+/*	$NetBSD: compile.c,v 1.37 2010/02/19 16:35:27 tnn Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -76,7 +76,7 @@
 #if 0
 static char sccsid[] = "@(#)compile.c	8.2 (Berkeley) 4/28/95";
 #else
-__RCSID("$NetBSD: compile.c,v 1.36 2009/04/13 07:29:55 lukem Exp $");
+__RCSID("$NetBSD: compile.c,v 1.37 2010/02/19 16:35:27 tnn Exp $");
 #endif
 #endif /* not lint */
 
@@ -193,14 +193,15 @@
 compile_stream(struct s_command **link)
 {
 	char *p;
-	static char lbuf[_POSIX2_LINE_MAX + 1];	/* To save stack */
+	static char *lbuf;	/* To avoid excessive malloc calls */
+	static size_t bufsize;
 	struct s_command *cmd, *cmd2, *stack;
 	struct s_format *fp;
 	int naddr;				/* Number of addresses */
 
 	stack = 0;
 	for (;;) {
-		if ((p = cu_fgets(lbuf, sizeof(lbuf))) == NULL) {
+		if ((p = cu_fgets(&lbuf, &bufsize)) == NULL) {
 			if (stack != 0)
 				err(COMPILE, "unexpected EOF (pending }'s)");
 			return (link);
@@ -459,11 +460,13 @@
 compile_re(char *p, regex_t **repp)
 {
 	int eval;
-	char re[_POSIX2_LINE_MAX + 1];
+	char *re;
 
+	re = xmalloc(strlen(p) + 1); /* strlen(re) <= strlen(p) */
 	p = compile_delimited(p, re);
 	if (p && strlen(re) == 0) {
 		*repp = NULL;
+		free(re);
 		return (p);
 	}
 	*repp = xmalloc(sizeof(regex_t));
@@ -482,8 +485,9 @@
 static char *
 compile_subst(char *p, struct s_subst *s)
 {
-	static char lbuf[_POSIX2_LINE_MAX + 1];
-	int asize, ref, size;
+	static char *lbuf;
+	static size_t bufsize;
+	int asize, ref, size, len;
 	char c, *text, *op, *sp;
 	int sawesc = 0;
 
@@ -493,10 +497,16 @@
 
 	s->maxbref = 0;
 	s->linenum = linenum;
-	asize = 2 * _POSIX2_LINE_MAX + 1;
-	text = xmalloc(asize);
-	size = 0;
+	text = NULL;
+	asize = size = 0;
 	do {
+		len = ROUNDLEN(strlen(p) + 1);
+		if (asize - size < len) {
+			do {
+				asize += len;
+			} while (asize - size < len);
+			text = xrealloc(text, asize);
+		}
 		op = sp = text + size;
 		for (; *p; p++) {
 			if (*p == '\\' || sawesc) {
@@ -546,11 +556,7 @@
 			*sp++ = *p;
 		}
 		size += sp - op;
-		if (asize - size < _POSIX2_LINE_MAX + 1) {
-			asize *= 2;
-			text = xrealloc(text, asize);
-		}
-	} while (cu_fgets(p = lbuf, sizeof(lbuf)));
+	} while ((p = cu_fgets(&lbuf, &bufsize)));
 	err(COMPILE, "unterminated substitute in regular expression");
 	/* NOTREACHED */
 	return (NULL);
@@ -563,7 +569,7 @@
 compile_flags(char *p, struct s_subst *s)
 {
 	int gn;			/* True if we have seen g or n */
-	char wfile[_POSIX2_LINE_MAX + 1], *q;
+	char wfile[PATH_MAX], *q;
 
 	s->n = 1;				/* Default */
 	s->p = 0;
@@ -638,26 +644,27 @@
 {
 	int i;
 	char *lt, *op, *np;
-	char old[_POSIX2_LINE_MAX + 1];
-	char new[_POSIX2_LINE_MAX + 1];
+	char *old = NULL, *new = NULL;
 
 	if (*p == '\0' || *p == '\\')
 		err(COMPILE,
 "transform pattern can not be delimited by newline or backslash");
+	old = xmalloc(strlen(p) + 1);
 	p = compile_delimited(p, old);
 	if (p == NULL) {
 		err(COMPILE, "unterminated transform source string");
-		return (NULL);
+		goto bad;
 	}
+	new = xmalloc(strlen(p) + 1);
 	p = compile_delimited(--p, new);
 	if (p == NULL) {
 		err(COMPILE, "unterminated transform target string");
-		return (NULL);
+		goto bad;
 	}
 	EATSPACE();
 	if (strlen(new) != strlen(old)) {
 		err(COMPILE, "transform strings are not the same length");
-		return (NULL);
+		goto bad;
 	}
 	/* We assume characters are 8 bits */
 	lt = xmalloc(UCHAR_MAX+1);
@@ -666,7 +673,13 @@
 	for (op = old, np = new; *op; op++, np++)
 		lt[(u_char)*op] = *np;
 	*transtab = lt;
+	free(old);
+	free(new);
 	return (p);
+bad:
+	free(old);
+	free(new);
+	return (NULL);
 }
 
 /*
@@ -675,16 +688,21 @@
 static char *
 compile_text(void)
 {
-	int asize, size;
-	char *text, *p, *op, *s;
-	char lbuf[_POSIX2_LINE_MAX + 1];
-
-	asize = 2 * _POSIX2_LINE_MAX + 1;
-	text = xmalloc(asize);
-	size = 0;
-	while (cu_fgets(lbuf, sizeof(lbuf))) {
+	int asize, size, len;
+	char *lbuf, *text, *p, *op, *s;
+	size_t bufsize;
+
+	lbuf = text = NULL;
+	asize = size = 0;
+	while ((p = cu_fgets(&lbuf, &bufsize))) {
+		len = ROUNDLEN(strlen(p) + 1);
+		if (asize - size < len) {
+			do {
+				asize += len;
+			} while (asize - size < len);
+			text = xrealloc(text, asize);
+		}
 		op = s = text + size;
-		p = lbuf;
 		for (; *p; p++) {
 			if (*p == '\\')
 				p++;
@@ -695,11 +713,8 @@
 			*s = '\0';
 			break;
 		}
-		if (asize - size < _POSIX2_LINE_MAX + 1) {
-			asize *= 2;
-			text = xrealloc(text, asize);
-		}
 	}
+	free(lbuf);
 	return (xrealloc(text, size + 1));
 }
 

Index: src/usr.bin/sed/defs.h
diff -u src/usr.bin/sed/defs.h:1.9 src/usr.bin/sed/defs.h:1.10
--- src/usr.bin/sed/defs.h:1.9	Sat Nov 20 06:40:42 2004
+++ src/usr.bin/sed/defs.h	Fri Feb 19 16:35:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: defs.h,v 1.9 2004/11/20 06:40:42 grant Exp $	*/
+/*	$NetBSD: defs.h,v 1.10 2010/02/19 16:35:27 tnn Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -32,7 +32,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)defs.h	8.1 (Berkeley) 6/6/93
- *	$NetBSD: defs.h,v 1.9 2004/11/20 06:40:42 grant Exp $
+ *	$NetBSD: defs.h,v 1.10 2010/02/19 16:35:27 tnn Exp $
  */
 
 /*-
@@ -70,7 +70,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)defs.h	8.1 (Berkeley) 6/6/93
- *	$NetBSD: defs.h,v 1.9 2004/11/20 06:40:42 grant Exp $
+ *	$NetBSD: defs.h,v 1.10 2010/02/19 16:35:27 tnn Exp $
  */
 
 /*
@@ -179,3 +179,9 @@
 #define	WARNING		2	/* Just print the warning */
 #define	COMPILE		3	/* Print error, count and finish script */
 #define	COMPILE2	3	/* Print error, count and finish script */
+
+/*
+ * Round up to the nearest multiple of _POSIX2_LINE_MAX
+ */
+#define ROUNDLEN(x) \
+    (((x) + _POSIX2_LINE_MAX - 1) & ~(_POSIX2_LINE_MAX - 1))

Index: src/usr.bin/sed/extern.h
diff -u src/usr.bin/sed/extern.h:1.10 src/usr.bin/sed/extern.h:1.11
--- src/usr.bin/sed/extern.h:1.10	Mon Apr 13 07:29:56 2009
+++ src/usr.bin/sed/extern.h	Fri Feb 19 16:35:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: extern.h,v 1.10 2009/04/13 07:29:56 lukem Exp $	*/
+/*	$NetBSD: extern.h,v 1.11 2010/02/19 16:35:27 tnn Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -32,7 +32,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)extern.h	8.1 (Berkeley) 6/6/93
- *	$NetBSD: extern.h,v 1.10 2009/04/13 07:29:56 lukem Exp $
+ *	$NetBSD: extern.h,v 1.11 2010/02/19 16:35:27 tnn Exp $
  */
 
 /*-
@@ -70,7 +70,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)extern.h	8.1 (Berkeley) 6/6/93
- *	$NetBSD: extern.h,v 1.10 2009/04/13 07:29:56 lukem Exp $
+ *	$NetBSD: extern.h,v 1.11 2010/02/19 16:35:27 tnn Exp $
  */
 
 extern struct s_command *prog;
@@ -87,11 +87,11 @@
 void	 cfclose(struct s_command *, struct s_command *);
 void	 compile(void);
 void	 cspace(SPACE *, const char *, size_t, enum e_spflag);
-char	*cu_fgets(char *, int);
+char	*cu_fgets(char **, size_t *);
 void	 err(int, const char *, ...)
      __attribute__((__format__(__printf__, 2, 3)));
 int	 mf_fgets(SPACE *, enum e_spflag);
 void	 process(void);
 char	*strregerror(int, regex_t *);
-void	*xmalloc(u_int);
-void	*xrealloc(void *, u_int);
+void	*xmalloc(size_t);
+void	*xrealloc(void *, size_t);
Index: src/usr.bin/sed/misc.c
diff -u src/usr.bin/sed/misc.c:1.10 src/usr.bin/sed/misc.c:1.11
--- src/usr.bin/sed/misc.c:1.10	Mon Apr 13 07:29:55 2009
+++ src/usr.bin/sed/misc.c	Fri Feb 19 16:35:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: misc.c,v 1.10 2009/04/13 07:29:55 lukem Exp $	*/
+/*	$NetBSD: misc.c,v 1.11 2010/02/19 16:35:27 tnn Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -76,7 +76,7 @@
 #if 0
 static char sccsid[] = "@(#)misc.c	8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: misc.c,v 1.10 2009/04/13 07:29:55 lukem Exp $");
+__RCSID("$NetBSD: misc.c,v 1.11 2010/02/19 16:35:27 tnn Exp $");
 #endif
 #endif /* not lint */
 
@@ -96,7 +96,7 @@
  * malloc with result test
  */
 void *
-xmalloc(u_int size)
+xmalloc(size_t size)
 {
 	void *p;
 
@@ -109,7 +109,7 @@
  * realloc with result test
  */
 void *
-xrealloc(void *p, u_int size)
+xrealloc(void *p, size_t size)
 {
 	if (p == NULL)			/* Compatibility hack. */
 		return (xmalloc(size));

Index: src/usr.bin/sed/main.c
diff -u src/usr.bin/sed/main.c:1.20 src/usr.bin/sed/main.c:1.21
--- src/usr.bin/sed/main.c:1.20	Mon Apr 13 07:29:55 2009
+++ src/usr.bin/sed/main.c	Fri Feb 19 16:35:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.20 2009/04/13 07:29:55 lukem Exp $	*/
+/*	$NetBSD: main.c,v 1.21 2010/02/19 16:35:27 tnn Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -81,7 +81,7 @@
 #if 0
 static char sccsid[] = "@(#)main.c	8.2 (Berkeley) 1/3/94";
 #else
-__RCSID("$NetBSD: main.c,v 1.20 2009/04/13 07:29:55 lukem Exp $");
+__RCSID("$NetBSD: main.c,v 1.21 2010/02/19 16:35:27 tnn Exp $");
 #endif
 #endif /* not lint */
 
@@ -90,6 +90,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <limits.h>
 #include <regex.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -206,14 +207,18 @@
  * together.  Empty strings and files are ignored.
  */
 char *
-cu_fgets(char *buf, int n)
+cu_fgets(char **outbuf, size_t *outsize)
 {
 	static enum {ST_EOF, ST_FILE, ST_STRING} state = ST_EOF;
 	static FILE *f;		/* Current open file */
 	static char *s;		/* Current pointer inside string */
 	static char string_ident[30];
+	size_t len;
 	char *p;
 
+	if (*outbuf == NULL)
+		*outsize = 0;
+
 again:
 	switch (state) {
 	case ST_EOF:
@@ -240,11 +245,18 @@
 			goto again;
 		}
 	case ST_FILE:
-		if ((p = fgets(buf, n, f)) != NULL) {
+		if ((p = fgetln(f, &len)) != NULL) {
 			linenum++;
-			if (linenum == 1 && buf[0] == '#' && buf[1] == 'n')
+			if (len >= *outsize) {
+				free(*outbuf);
+				*outsize = ROUNDLEN(len + 1);
+				*outbuf = xmalloc(*outsize);
+			}
+			memcpy(*outbuf, p, len);
+			(*outbuf)[len] = '\0';
+			if (linenum == 1 && p[0] == '#' && p[1] == 'n')
 				nflag = 1;
-			return (p);
+			return (*outbuf);
 		}
 		script = script->next;
 		(void)fclose(f);
@@ -253,12 +265,15 @@
 	case ST_STRING:
 		if (linenum == 0 && s[0] == '#' && s[1] == 'n')
 			nflag = 1;
-		p = buf;
+		p = *outbuf;
+		len = *outsize;
 		for (;;) {
-			if (n-- <= 1) {
-				*p = '\0';
-				linenum++;
-				return (buf);
+			if (len <= 1) {
+				*outbuf = xrealloc(*outbuf,
+				    *outsize + _POSIX2_LINE_MAX);
+				p = *outbuf + *outsize - len;
+				len += _POSIX2_LINE_MAX;
+				*outsize += _POSIX2_LINE_MAX;
 			}
 			switch (*s) {
 			case '\0':
@@ -270,16 +285,17 @@
 					script = script->next;
 					*p = '\0';
 					linenum++;
-					return (buf);
+					return (*outbuf);
 				}
 			case '\n':
 				*p++ = '\n';
 				*p = '\0';
 				s++;
 				linenum++;
-				return (buf);
+				return (*outbuf);
 			default:
 				*p++ = *s++;
+				len--;
 			}
 		}
 	}

Reply via email to