From b8ad49048aea66b5b8f2125fb8fadf4ee398cc37 Mon Sep 17 00:00:00 2001 From: pfg Date: Tue, 2 Aug 2016 15:35:53 +0000 Subject: [PATCH] sed(1): Revert r303047 "cleanup" and therefore r303572. While big, the change was meant to have no effect on behavior and instead so far we have found two regressions: one in the etcupdate tests and another one in the games/openttd port[1]. Revert to a known working state. We will likely have to split the patch in functional parts before bringing back the changes. PR: 195929 Reported by: danfe, madpilot [1] --- usr.bin/sed/Makefile | 2 +- usr.bin/sed/compile.c | 236 +++++++++++++++++++++++++------------------------- usr.bin/sed/defs.h | 5 +- usr.bin/sed/extern.h | 6 +- usr.bin/sed/main.c | 78 +++++++++-------- usr.bin/sed/misc.c | 8 +- usr.bin/sed/process.c | 34 ++++---- 7 files changed, 192 insertions(+), 177 deletions(-) diff --git a/usr.bin/sed/Makefile b/usr.bin/sed/Makefile index 51904a6efd9..a741da3233e 100644 --- a/usr.bin/sed/Makefile +++ b/usr.bin/sed/Makefile @@ -6,7 +6,7 @@ PROG= sed SRCS= compile.c main.c misc.c process.c -WARNS?= 5 +WARNS?= 2 .if ${MK_TESTS} != "no" SUBDIR+= tests diff --git a/usr.bin/sed/compile.c b/usr.bin/sed/compile.c index 891fe5b8d78..bafb339a4b5 100644 --- a/usr.bin/sed/compile.c +++ b/usr.bin/sed/compile.c @@ -64,21 +64,21 @@ static struct labhash { int lh_ref; } *labels[LHSZ]; -static const char *compile_addr(const char *, struct s_addr *); -static char *compile_ccl(const char **, char *); -static const char *compile_delimited(const char *, char *, int); -static const char *compile_flags(const char *, struct s_subst *); -static const regex_t *compile_re(const char *, int); -static const char *compile_subst(const char *, struct s_subst *); -static char *compile_text(size_t *); -static const char *compile_tr(const char *, struct s_tr **); +static char *compile_addr(char *, struct s_addr *); +static char *compile_ccl(char **, char *); +static char *compile_delimited(char *, char *, int); +static char *compile_flags(char *, struct s_subst *); +static regex_t *compile_re(char *, int); +static char *compile_subst(char *, struct s_subst *); +static char *compile_text(void); +static char *compile_tr(char *, struct s_tr **); static struct s_command **compile_stream(struct s_command **); -static char *duptoeol(const char *, const char *, size_t *); +static char *duptoeol(char *, const char *); static void enterlabel(struct s_command *); static struct s_command - *findlabel(const char *); -static void fixuplabel(struct s_command *, const struct s_command *); + *findlabel(char *); +static void fixuplabel(struct s_command *, struct s_command *); static void uselabel(void); /* @@ -144,20 +144,17 @@ compile(void) err(1, "malloc"); } -#define EATSPACE() do { \ - while (*p && isspace((unsigned char)*p)) \ - p++; \ - } while (0) - -#define EATSPACEN() do { \ - while (*p && *p != '\n' && isspace((unsigned char)*p)) \ - p++; \ +#define EATSPACE() do { \ + if (p) \ + while (*p && isspace((unsigned char)*p)) \ + p++; \ } while (0) static struct s_command ** compile_stream(struct s_command **link) { - const char *p; + char *p; + static char lbuf[_POSIX2_LINE_MAX + 1]; /* To save stack */ struct s_command *cmd, *cmd2, *stack; struct s_format *fp; char re[_POSIX2_LINE_MAX + 1]; @@ -165,22 +162,22 @@ compile_stream(struct s_command **link) stack = NULL; for (;;) { - if ((p = cu_fgets(NULL)) == NULL) { + if ((p = cu_fgets(lbuf, sizeof(lbuf), NULL)) == NULL) { if (stack != NULL) errx(1, "%lu: %s: unexpected EOF (pending }'s)", linenum, fname); return (link); } -semicolon: EATSPACEN(); - switch (*p) { - case '#': case '\0': case '\n': - continue; /* to next command-unit */ - case ';': - p++; - goto semicolon; +semicolon: EATSPACE(); + if (p) { + if (*p == '#' || *p == '\0') + continue; + else if (*p == ';') { + p++; + goto semicolon; + } } - if ((*link = cmd = malloc(sizeof(struct s_command))) == NULL) err(1, "malloc"); link = &cmd->next; @@ -211,14 +208,14 @@ semicolon: EATSPACEN(); cmd->a1 = cmd->a2 = NULL; nonsel: /* Now parse the command */ - if (*p == '\0' || *p == '\n') + if (!*p) errx(1, "%lu: %s: command expected", linenum, fname); cmd->code = *p; for (fp = cmd_fmts; fp->code; fp++) if (fp->code == *p) break; if (!fp->code) - errx(1, "%lu: %s: invalid command code %c (%s)", linenum, fname, *p, p); + errx(1, "%lu: %s: invalid command code %c", linenum, fname, *p); if (naddr > fp->naddr) errx(1, "%lu: %s: command %c expects up to %d address(es), found %d", @@ -231,11 +228,11 @@ nonsel: /* Now parse the command */ goto nonsel; case GROUP: /* { */ p++; - EATSPACEN(); + EATSPACE(); cmd->next = stack; stack = cmd; link = &cmd->u.c; - if (*p != '\0' && *p != '\n') + if (*p) goto semicolon; break; case ENDGROUP: @@ -252,13 +249,13 @@ nonsel: /* Now parse the command */ /*FALLTHROUGH*/ case EMPTY: /* d D g G h H l n N p P q x = \0 */ p++; - EATSPACEN(); + EATSPACE(); if (*p == ';') { p++; link = &cmd->next; goto semicolon; } - if (*p != '\0' && *p != '\n') + if (*p) errx(1, "%lu: %s: extra characters at the end of %c command", linenum, fname, cmd->code); break; @@ -269,12 +266,12 @@ nonsel: /* Now parse the command */ errx(1, "%lu: %s: command %c expects \\ followed by text", linenum, fname, cmd->code); p++; - EATSPACEN(); - if (*p != '\n') + EATSPACE(); + if (*p) errx(1, - "%lu: %s: extra characters (%c) after \\ at the end of %c command", - linenum, fname, *p, cmd->code); - cmd->t = compile_text(&cmd->tlen); + "%lu: %s: extra characters after \\ at the end of %c command", + linenum, fname, cmd->code); + cmd->t = compile_text(); break; case COMMENT: /* \0 # */ break; @@ -283,10 +280,10 @@ nonsel: /* Now parse the command */ EATSPACE(); if (*p == '\0') errx(1, "%lu: %s: filename expected", linenum, fname); - cmd->t = duptoeol(p, "w command", &cmd->tlen); + cmd->t = duptoeol(p, "w command"); if (aflag) cmd->u.fd = -1; - else if ((cmd->u.fd = open(cmd->t, + else if ((cmd->u.fd = open(p, O_WRONLY|O_APPEND|O_CREAT|O_TRUNC, DEFFILEMODE)) == -1) err(1, "%s", p); @@ -297,27 +294,27 @@ nonsel: /* Now parse the command */ if (*p == '\0') errx(1, "%lu: %s: filename expected", linenum, fname); else - cmd->t = duptoeol(p, "read command", &cmd->tlen); + cmd->t = duptoeol(p, "read command"); break; case BRANCH: /* b t */ p++; - EATSPACEN(); - if (*p == '\0' || *p == '\n') + EATSPACE(); + if (*p == '\0') cmd->t = NULL; else - cmd->t = duptoeol(p, "branch", &cmd->tlen); + cmd->t = duptoeol(p, "branch"); break; case LABEL: /* : */ p++; EATSPACE(); - cmd->t = duptoeol(p, "label", &cmd->tlen); - if (cmd->t[0] == '\0') + cmd->t = duptoeol(p, "label"); + if (strlen(p) == 0) errx(1, "%lu: %s: empty label", linenum, fname); enterlabel(cmd); break; case SUBST: /* s */ p++; - if (*p == '\0' || *p == '\\' || *p == '\n') + if (*p == '\0' || *p == '\\') errx(1, "%lu: %s: substitute pattern can not be delimited by newline or backslash", linenum, fname); @@ -328,15 +325,21 @@ nonsel: /* Now parse the command */ errx(1, "%lu: %s: unterminated substitute pattern", linenum, fname); + /* Compile RE with no case sensitivity temporarily */ + if (*re == '\0') + cmd->u.s->re = NULL; + else + cmd->u.s->re = compile_re(re, 0); --p; p = compile_subst(p, cmd->u.s); p = compile_flags(p, cmd->u.s); - if (*re != '\0') + /* Recompile RE with case sensitivity from "I" flag if any */ + if (*re == '\0') + cmd->u.s->re = NULL; + else cmd->u.s->re = compile_re(re, cmd->u.s->icase); - EATSPACE(); - if (*p == ';') { p++; link = &cmd->next; @@ -369,8 +372,8 @@ nonsel: /* Now parse the command */ * in the case of a non-terminated string. The character array d is filled * with the processed string. */ -static const char * -compile_delimited(const char *p, char *d, int is_tr) +static char * +compile_delimited(char *p, char *d, int is_tr) { char c; @@ -413,10 +416,10 @@ compile_delimited(const char *p, char *d, int is_tr) /* compile_ccl: expand a POSIX character class */ static char * -compile_ccl(const char **sp, char *t) +compile_ccl(char **sp, char *t) { int c, d; - const char *s = *sp; + char *s = *sp; *t++ = *s++; if (*s == '^') @@ -438,8 +441,8 @@ compile_ccl(const char **sp, char *t) * regular expression. * Cflags are passed to regcomp. */ -static const regex_t * -compile_re(const char *re, int case_insensitive) +static regex_t * +compile_re(char *re, int case_insensitive) { regex_t *rep; int eval, flags; @@ -463,13 +466,14 @@ compile_re(const char *re, int case_insensitive) * point to a saved copy of it. Nsub is the number of parenthesized regular * expressions. */ -static const char * -compile_subst(const char *p, struct s_subst *s) +static char * +compile_subst(char *p, struct s_subst *s) { + static char lbuf[_POSIX2_LINE_MAX + 1]; int asize, size; u_char ref; char c, *text, *op, *sp; - int more = 0, sawesc = 0; + int more = 1, sawesc = 0; c = *p++; /* Terminator character */ if (c == '\0') @@ -483,7 +487,7 @@ compile_subst(const char *p, struct s_subst *s) size = 0; do { op = sp = text + size; - for (; *p != '\0' && *p != '\n'; p++) { + for (; *p; p++) { if (*p == '\\' || sawesc) { /* * If this is a continuation from the last @@ -505,10 +509,7 @@ compile_subst(const char *p, struct s_subst *s) */ sawesc = 1; p--; - break; - } else if (*p == '\n') { - *sp++ = '\n'; - break; + continue; } else if (strchr("123456789", *p) != NULL) { *sp++ = '\\'; ref = *p - '0'; @@ -522,11 +523,8 @@ compile_subst(const char *p, struct s_subst *s) *sp++ = '\\'; } else if (*p == c) { if (*++p == '\0' && more) { - const char *nextp; - - nextp = cu_fgets(&more); - if (nextp != NULL) - p = nextp; + if (cu_fgets(lbuf, sizeof(lbuf), &more)) + p = lbuf; } *sp++ = '\0'; size += sp - op; @@ -546,7 +544,7 @@ compile_subst(const char *p, struct s_subst *s) if ((text = realloc(text, asize)) == NULL) err(1, "realloc"); } - } while ((p = cu_fgets(&more)) != NULL); + } while (cu_fgets(p = lbuf, sizeof(lbuf), &more) != NULL); errx(1, "%lu: %s: unterminated substitute in regular expression", linenum, fname); /* NOTREACHED */ @@ -555,12 +553,12 @@ compile_subst(const char *p, struct s_subst *s) /* * Compile the flags of the s command */ -static const char * -compile_flags(const char *p, struct s_subst *s) +static char * +compile_flags(char *p, struct s_subst *s) { int gn; /* True if we have seen g or n */ unsigned long nval; - char *q; + char wfile[_POSIX2_LINE_MAX + 1], *q, *eq; s->n = 1; /* Default */ s->p = 0; @@ -568,7 +566,7 @@ compile_flags(const char *p, struct s_subst *s) s->wfd = -1; s->icase = 0; for (gn = 0;;) { - EATSPACEN(); /* EXTENSION */ + EATSPACE(); /* EXTENSION */ switch (*p) { case 'g': if (gn) @@ -596,13 +594,13 @@ compile_flags(const char *p, struct s_subst *s) "%lu: %s: more than one number or 'g' in substitute flags", linenum, fname); gn = 1; errno = 0; - nval = strtol(p, &q, 10); + nval = strtol(p, &p, 10); if (errno == ERANGE || nval > INT_MAX) errx(1, "%lu: %s: overflow in the 'N' substitute flag", linenum, fname); s->n = nval; - p = q; - continue; + p--; + break; case 'w': p++; #ifdef HISTORIC_PRACTICE @@ -612,15 +610,27 @@ compile_flags(const char *p, struct s_subst *s) } #endif EATSPACE(); - s->wfile = duptoeol(p, "w flag", NULL); - if (!aflag && (s->wfd = open(s->wfile, + q = wfile; + eq = wfile + sizeof(wfile) - 1; + while (*p) { + if (*p == '\n') + break; + if (q >= eq) + err(1, "wfile too long"); + *q++ = *p++; + } + *q = '\0'; + if (q == wfile) + errx(1, "%lu: %s: no wfile specified", linenum, fname); + s->wfile = strdup(wfile); + if (!aflag && (s->wfd = open(wfile, O_WRONLY|O_APPEND|O_CREAT|O_TRUNC, DEFFILEMODE)) == -1) - err(1, "%s", s->wfile); + err(1, "%s", wfile); return (p); default: - errx(1, "%lu: %s: bad flag in substitute command: '%c' (%.10s)", - linenum, fname, *p, p); + errx(1, "%lu: %s: bad flag in substitute command: '%c'", + linenum, fname, *p); break; } p++; @@ -630,8 +640,8 @@ compile_flags(const char *p, struct s_subst *s) /* * Compile a translation set of strings into a lookup table. */ -static const char * -compile_tr(const char *p, struct s_tr **py) +static char * +compile_tr(char *p, struct s_tr **py) { struct s_tr *y; int i; @@ -642,7 +652,7 @@ compile_tr(const char *p, struct s_tr **py) mbstate_t mbs1, mbs2; if ((*py = y = malloc(sizeof(*y))) == NULL) - err(1, "malloc"); + err(1, NULL); y->multis = NULL; y->nmultis = 0; @@ -662,11 +672,11 @@ compile_tr(const char *p, struct s_tr **py) op = old; oldlen = mbsrtowcs(NULL, &op, 0, NULL); if (oldlen == (size_t)-1) - err(1, "mbsrtowcs"); + err(1, NULL); np = new; newlen = mbsrtowcs(NULL, &np, 0, NULL); if (newlen == (size_t)-1) - err(1, "mbsrtowcs"); + err(1, NULL); if (newlen != oldlen) errx(1, "%lu: %s: transform strings are not the same length", linenum, fname); @@ -705,7 +715,7 @@ compile_tr(const char *p, struct s_tr **py) y->multis = realloc(y->multis, (y->nmultis + 1) * sizeof(*y->multis)); if (y->multis == NULL) - err(1, "realloc"); + err(1, NULL); i = y->nmultis++; y->multis[i].fromlen = oclen; memcpy(y->multis[i].from, op, oclen); @@ -723,24 +733,23 @@ compile_tr(const char *p, struct s_tr **py) * Compile the text following an a, c, or i command. */ static char * -compile_text(size_t *ptlen) +compile_text(void) { int asize, esc_nl, size; - char *text, *s; - const char *p, *op; + char *text, *p, *op, *s; + char lbuf[_POSIX2_LINE_MAX + 1]; asize = 2 * _POSIX2_LINE_MAX + 1; if ((text = malloc(asize)) == NULL) err(1, "malloc"); size = 0; - while ((p = cu_fgets(NULL)) != NULL) { + while (cu_fgets(lbuf, sizeof(lbuf), NULL) != NULL) { op = s = text + size; + p = lbuf; for (esc_nl = 0; *p != '\0'; p++) { if (*p == '\\' && p[1] != '\0' && *++p == '\n') esc_nl = 1; *s++ = *p; - if (*p == '\n') - break; } size += s - op; if (!esc_nl) { @@ -754,18 +763,17 @@ compile_text(size_t *ptlen) } } text[size] = '\0'; - if ((text = realloc(text, size + 1)) == NULL) + if ((p = realloc(text, size + 1)) == NULL) err(1, "realloc"); - *ptlen = size; - return (text); + return (p); } /* * Get an address and return a pointer to the first character after * it. Fill the structure pointed to according to the address. */ -static const char * -compile_addr(const char *p, struct s_addr *a) +static char * +compile_addr(char *p, struct s_addr *a) { char *end, re[_POSIX2_LINE_MAX + 1]; int icase; @@ -819,26 +827,22 @@ compile_addr(const char *p, struct s_addr *a) * Return a copy of all the characters up to \n or \0. */ static char * -duptoeol(const char *s, const char *ctype, size_t *ptlen) +duptoeol(char *s, const char *ctype) { size_t len; int ws; - char *p; - const char *start; + char *p, *start; ws = 0; for (start = s; *s != '\0' && *s != '\n'; ++s) ws = isspace((unsigned char)*s); + *s = '\0'; if (ws) warnx("%lu: %s: whitespace after %s", linenum, fname, ctype); - len = s - start; - if ((p = malloc(len + 1)) == NULL) + len = s - start + 1; + if ((p = malloc(len)) == NULL) err(1, "malloc"); - memmove(p, start, len); - p[len] = '\0'; - if (ptlen != NULL) - *ptlen = len; - return p; + return (memmove(p, start, len)); } /* @@ -849,7 +853,7 @@ duptoeol(const char *s, const char *ctype, size_t *ptlen) * TODO: Remove } nodes */ static void -fixuplabel(struct s_command *cp, const struct s_command *end) +fixuplabel(struct s_command *cp, struct s_command *end) { for (; cp != end; cp = cp->next) @@ -866,7 +870,7 @@ fixuplabel(struct s_command *cp, const struct s_command *end) break; } if ((cp->u.c = findlabel(cp->t)) == NULL) - errx(1, "%lu: %s: %c: undefined label '%s'", linenum, fname, cp->code, cp->t); + errx(1, "%lu: %s: undefined label '%s'", linenum, fname, cp->t); free(cp->t); break; case '{': @@ -906,13 +910,13 @@ enterlabel(struct s_command *cp) * list cp. L is excluded from the search. Return NULL if not found. */ static struct s_command * -findlabel(const char *name) +findlabel(char *name) { struct labhash *lh; - const u_char *p; + u_char *p; u_int h, c; - for (h = 0, p = (const u_char *)name; (c = *p) != 0; p++) + for (h = 0, p = (u_char *)name; (c = *p) != 0; p++) h = (h << 5) + h + c; for (lh = labels[h & LHMASK]; lh != NULL; lh = lh->lh_next) { if (lh->lh_hash == h && strcmp(name, lh->lh_cmd->t) == 0) { diff --git a/usr.bin/sed/defs.h b/usr.bin/sed/defs.h index 7d48d75e0c9..fb336765d63 100644 --- a/usr.bin/sed/defs.h +++ b/usr.bin/sed/defs.h @@ -51,7 +51,7 @@ struct s_addr { enum e_atype type; /* Address type */ union { u_long l; /* Line number */ - const regex_t *r; /* Regular expression */ + regex_t *r; /* Regular expression */ } u; }; @@ -64,7 +64,7 @@ struct s_subst { int icase; /* True if I flag */ char *wfile; /* NULL if no wfile */ int wfd; /* Cached file descriptor */ - const regex_t *re; /* Regular expression */ + regex_t *re; /* Regular expression */ unsigned int maxbref; /* Largest backreference. */ u_long linenum; /* Line number. */ char *new; /* Replacement text */ @@ -94,7 +94,6 @@ struct s_command { struct s_addr *a1, *a2; /* Start and end address */ u_long startline; /* Start line number or zero */ char *t; /* Text for : a c i r w */ - size_t tlen; union { struct s_command *c; /* Command(s) for b t { */ struct s_subst *s; /* Substitute command */ diff --git a/usr.bin/sed/extern.h b/usr.bin/sed/extern.h index 85f10b62b1a..f2bd71bacfa 100644 --- a/usr.bin/sed/extern.h +++ b/usr.bin/sed/extern.h @@ -45,12 +45,12 @@ extern const char *fname, *outfname; extern FILE *infile, *outfile; extern int rflags; /* regex flags to use */ -void cfclose(struct s_command *, const struct s_command *); +void cfclose(struct s_command *, struct s_command *); void compile(void); void cspace(SPACE *, const char *, size_t, enum e_spflag); -const char *cu_fgets(int *); +char *cu_fgets(char *, int, int *); int mf_fgets(SPACE *, enum e_spflag); int lastline(void); void process(void); void resetstate(void); -char *strregerror(int, const regex_t *); +char *strregerror(int, regex_t *); diff --git a/usr.bin/sed/main.c b/usr.bin/sed/main.c index 39d720cbb48..742881b649b 100644 --- a/usr.bin/sed/main.c +++ b/usr.bin/sed/main.c @@ -72,7 +72,7 @@ static const char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/3/94"; struct s_compunit { struct s_compunit *next; enum e_cut {CU_FILE, CU_STRING} type; - const char *s; /* Pointer to string or fname */ + char *s; /* Pointer to string or fname */ }; /* @@ -85,7 +85,7 @@ static struct s_compunit *script, **cu_nextp = &script; * Linked list of files to be processed */ struct s_flist { - const char *fname; + char *fname; struct s_flist *next; }; @@ -116,15 +116,15 @@ static char tmpfname[PATH_MAX]; /* Temporary file name (for in-place editing) */ static const char *inplace; /* Inplace edit file extension. */ u_long linenum; -static void add_compunit(enum e_cut, const char *); -static void add_file(const char *); +static void add_compunit(enum e_cut, char *); +static void add_file(char *); static void usage(void); int main(int argc, char *argv[]) { - char *temp_arg; int c, fflag; + char *temp_arg; (void) setlocale(LC_ALL, ""); @@ -146,9 +146,10 @@ main(int argc, char *argv[]) break; case 'e': eflag = 1; - asprintf(&temp_arg, "%s\n", optarg); - if (temp_arg == NULL) - errx(1, "Couldn't allocate temporary buffer"); + if ((temp_arg = malloc(strlen(optarg) + 2)) == NULL) + err(1, "malloc"); + strcpy(temp_arg, optarg); + strcat(temp_arg, "\n"); add_compunit(CU_STRING, temp_arg); break; case 'f': @@ -212,16 +213,14 @@ usage(void) * Like fgets, but go through the chain of compilation units chaining them * together. Empty strings and files are ignored. */ -const char * -cu_fgets(int *more) +char * +cu_fgets(char *buf, int n, int *more) { static enum {ST_EOF, ST_FILE, ST_STRING} state = ST_EOF; static FILE *f; /* Current open file */ - static const char *s; /* Current pointer inside string */ - static char string_ident[30], *lastresult; - static size_t lastsize; + static char *s; /* Current pointer inside string */ + static char string_ident[30]; char *p; - const char *start; again: switch (state) { @@ -251,16 +250,14 @@ again: goto again; } case ST_FILE: - p = lastresult; - if (getline(&p, &lastsize, f) != -1) { + if ((p = fgets(buf, n, f)) != NULL) { linenum++; - if (linenum == 1 && p[0] == '#' && p[1] == 'n') + if (linenum == 1 && buf[0] == '#' && buf[1] == 'n') nflag = 1; if (more != NULL) *more = !feof(f); - return (lastresult = p); - } else if (ferror(f)) - err(1, "%s", script->s); + return (p); + } script = script->next; (void)fclose(f); state = ST_EOF; @@ -268,26 +265,39 @@ again: case ST_STRING: if (linenum == 0 && s[0] == '#' && s[1] == 'n') nflag = 1; - else if (s[0] == '\0') { - state = ST_EOF; - script = script->next; - goto again; - } - start = s; + p = buf; for (;;) { + if (n-- <= 1) { + *p = '\0'; + linenum++; + if (more != NULL) + *more = 1; + return (buf); + } switch (*s) { case '\0': state = ST_EOF; - script = script->next; - /* FALLTHROUGH */ + if (s == script->s) { + script = script->next; + goto again; + } else { + script = script->next; + *p = '\0'; + linenum++; + if (more != NULL) + *more = 0; + return (buf); + } case '\n': + *p++ = '\n'; + *p = '\0'; s++; linenum++; if (more != NULL) *more = 0; - return (start); + return (buf); default: - s++; + *p++ = *s++; } } } @@ -390,7 +400,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag) sizeof(oldfname)); len = strlcat(oldfname, inplace, sizeof(oldfname)); - if ((size_t)len > sizeof(oldfname)) + if (len > (ssize_t)sizeof(oldfname)) errx(1, "%s: name too long", fname); } if ((dirbuf = strdup(fname)) == NULL || @@ -401,7 +411,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag) basename(basebuf)); free(dirbuf); free(basebuf); - if ((size_t)len >= sizeof(tmpfname)) + if (len >= (ssize_t)sizeof(tmpfname)) errx(1, "%s: name too long", fname); unlink(tmpfname); if (outfile != NULL && outfile != stdout) @@ -455,7 +465,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag) * Add a compilation unit to the linked list */ static void -add_compunit(enum e_cut type, const char *s) +add_compunit(enum e_cut type, char *s) { struct s_compunit *cu; @@ -472,7 +482,7 @@ add_compunit(enum e_cut type, const char *s) * Add a file to the linked list */ static void -add_file(const char *s) +add_file(char *s) { struct s_flist *fp; diff --git a/usr.bin/sed/misc.c b/usr.bin/sed/misc.c index 650c728c9f5..f3b513784a6 100644 --- a/usr.bin/sed/misc.c +++ b/usr.bin/sed/misc.c @@ -56,14 +56,16 @@ static const char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/6/93"; * the buffer). */ char * -strregerror(int errcode, const regex_t *preg) +strregerror(int errcode, regex_t *preg) { static char *oe; size_t s; + if (oe != NULL) + free(oe); s = regerror(errcode, preg, NULL, 0); - if ((oe = realloc(oe, s)) == NULL) - err(1, "realloc"); + if ((oe = malloc(s)) == NULL) + err(1, "malloc"); (void)regerror(errcode, preg, oe, s); return (oe); } diff --git a/usr.bin/sed/process.c b/usr.bin/sed/process.c index ba2a12f4dd7..d4779febd8f 100644 --- a/usr.bin/sed/process.c +++ b/usr.bin/sed/process.c @@ -67,14 +67,14 @@ static SPACE HS, PS, SS, YS; #define hs HS.space #define hsl HS.len -static inline int applies(struct s_command *); -static void do_tr(const struct s_tr *); -static void flush_appends(void); -static void lputs(const char *, size_t); -static int regexec_e(const regex_t *, const char *, int, int, - size_t, size_t); -static void regsub(SPACE *, const char *, const char *); -static int substitute(const struct s_command *); +static inline int applies(struct s_command *); +static void do_tr(struct s_tr *); +static void flush_appends(void); +static void lputs(char *, size_t); +static int regexec_e(regex_t *, const char *, int, int, size_t, + size_t); +static void regsub(SPACE *, char *, char *); +static int substitute(struct s_command *); struct s_appends *appends; /* Array of pointers to strings to append. */ static int appendx; /* Index into appends array. */ @@ -83,7 +83,7 @@ int appendnum; /* Size of appends array. */ static int lastaddr; /* Set by applies if last address of a range. */ static int sdone; /* If any substitutes since last line input. */ /* Iov structure for 'w' commands. */ -static const regex_t *defpreg; +static regex_t *defpreg; size_t maxnsub; regmatch_t *match; @@ -377,13 +377,13 @@ resetstate(void) * and then swap them. */ static int -substitute(const struct s_command *cp) +substitute(struct s_command *cp) { SPACE tspace; - const regex_t *re; + regex_t *re; regoff_t slen; int lastempty, n; - regoff_t le = 0; + size_t le = 0; char *s; s = ps; @@ -489,7 +489,7 @@ substitute(const struct s_command *cp) * Perform translation ('y' command) in the pattern space. */ static void -do_tr(const struct s_tr *y) +do_tr(struct s_tr *y) { SPACE tmp; char c, *p; @@ -579,7 +579,7 @@ flush_appends(void) } static void -lputs(const char *s, size_t len) +lputs(char *s, size_t len) { static const char escapes[] = "\\\a\b\f\r\t\v"; int c, col, width; @@ -659,7 +659,7 @@ lputs(const char *s, size_t len) } static int -regexec_e(const regex_t *preg, const char *string, int eflags, int nomatch, +regexec_e(regex_t *preg, const char *string, int eflags, int nomatch, size_t start, size_t stop) { int eval; @@ -691,7 +691,7 @@ regexec_e(const regex_t *preg, const char *string, int eflags, int nomatch, * Based on a routine by Henry Spencer */ static void -regsub(SPACE *sp, const char *string, const char *src) +regsub(SPACE *sp, char *string, char *src) { int len, no; char c, *dst; @@ -763,7 +763,7 @@ cspace(SPACE *sp, const char *p, size_t len, enum e_spflag spflag) * Close all cached opened files and report any errors */ void -cfclose(struct s_command *cp, const struct s_command *end) +cfclose(struct s_command *cp, struct s_command *end) { for (; cp != end; cp = cp->next) -- 2.11.4.GIT