=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/sed/compile.c,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- src/usr.bin/sed/compile.c 2007/03/20 03:50:39 1.24 +++ src/usr.bin/sed/compile.c 2008/10/08 17:26:47 1.25 @@ -1,4 +1,4 @@ -/* $OpenBSD: compile.c,v 1.24 2007/03/20 03:50:39 tedu Exp $ */ +/* $OpenBSD: compile.c,v 1.25 2008/10/08 17:26:47 millert Exp $ */ /*- * Copyright (c) 1992 Diomidis Spinellis. @@ -35,7 +35,7 @@ #ifndef lint /* from: static char sccsid[] = "@(#)compile.c 8.2 (Berkeley) 4/28/95"; */ -static const char rcsid[] = "$OpenBSD: compile.c,v 1.24 2007/03/20 03:50:39 tedu Exp $"; +static const char rcsid[] = "$OpenBSD: compile.c,v 1.25 2008/10/08 17:26:47 millert Exp $"; #endif /* not lint */ #include @@ -147,14 +147,17 @@ 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 len = _POSIX2_LINE_MAX; struct s_command *cmd, *cmd2, *stack; struct s_format *fp; int naddr; /* Number of addresses */ stack = 0; + if (!lbuf) + lbuf = xmalloc(len); for (;;) { - if ((p = cu_fgets(lbuf, sizeof(lbuf))) == NULL) { + if ((p = cu_fgets(&lbuf, &len)) == NULL) { if (stack != 0) err(COMPILE, "unexpected EOF (pending }'s)"); return (link); @@ -428,11 +431,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)); @@ -440,6 +445,7 @@ err(COMPILE, "RE error: %s", strregerror(eval, *repp)); if (maxnsub < (*repp)->re_nsub) maxnsub = (*repp)->re_nsub; + free(re); return (p); } @@ -451,21 +457,31 @@ static char * compile_subst(char *p, struct s_subst *s) { - static char lbuf[_POSIX2_LINE_MAX + 1]; + static char *lbuf; + static size_t len = _POSIX2_LINE_MAX; int asize, ref, size; char c, *text, *op, *sp; int sawesc = 0; + if (!lbuf) + lbuf = xmalloc(len); + c = *p++; /* Terminator character */ if (c == '\0') return (NULL); s->maxbref = 0; s->linenum = linenum; - asize = 2 * _POSIX2_LINE_MAX + 1; + asize = 2 * len + 1; text = xmalloc(asize); size = 0; do { + if (asize - size < len + 1) { + do { + asize *= 2; + } while (asize - size < len + 1); + text = xrealloc(text, asize); + } op = sp = text + size; for (; *p; p++) { if (*p == '\\' || sawesc) { @@ -515,11 +531,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, &len))); err(COMPILE, "unterminated substitute in regular expression"); /* NOTREACHED */ } @@ -532,7 +544,7 @@ { int gn; /* True if we have seen g or n */ long l; - char wfile[_POSIX2_LINE_MAX + 1], *q; + char wfile[PATH_MAX], *q; s->n = 1; /* Default */ s->p = 0; @@ -609,26 +621,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); @@ -637,7 +650,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); } /* @@ -647,13 +666,20 @@ compile_text(void) { int asize, esc_nl, size; - char *text, *p, *op, *s; - char lbuf[_POSIX2_LINE_MAX + 1]; + char *lbuf, *text, *p, *op, *s; + size_t len = _POSIX2_LINE_MAX; - asize = 2 * _POSIX2_LINE_MAX + 1; + lbuf = xmalloc(len); + asize = 2 * len + 1; text = xmalloc(asize); size = 0; - while (cu_fgets(lbuf, sizeof(lbuf))) { + while (cu_fgets(&lbuf, &len)) { + if (asize - size < len + 1) { + do { + asize *= 2; + } while (asize - size < len + 1); + text = xrealloc(text, asize); + } op = s = text + size; p = lbuf; EATSPACE(); @@ -667,11 +693,8 @@ *s = '\0'; break; } - if (asize - size < _POSIX2_LINE_MAX + 1) { - asize *= 2; - text = xmalloc(asize); - } } + free(lbuf); text[size] = '\0'; return (xrealloc(text, size + 1)); }