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