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--; } } }