diff options
author | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2019-12-02 22:17:33 +0000 |
---|---|---|
committer | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2019-12-02 22:17:33 +0000 |
commit | dd4daa2a0e04057c3f7edff11b24670c8cf5c474 (patch) | |
tree | f4a496ccdbf94ae646eeae5358e809f3fced8eca /usr.bin/patch | |
parent | 81ad68fd2f1fcc87562930a3d7231cdcddc659ec (diff) |
Use getline(3) to handle lines longer than 8192 bytes in patch files
Spotted by jsg@ when working on mesa. Diff tested by sthen@ in
a partial i386 bulk. Input from and ok jsg@ millert@
Diffstat (limited to 'usr.bin/patch')
-rw-r--r-- | usr.bin/patch/common.h | 7 | ||||
-rw-r--r-- | usr.bin/patch/ed.c | 6 | ||||
-rw-r--r-- | usr.bin/patch/patch.c | 10 | ||||
-rw-r--r-- | usr.bin/patch/pch.c | 78 | ||||
-rw-r--r-- | usr.bin/patch/pch.h | 4 | ||||
-rw-r--r-- | usr.bin/patch/util.c | 8 |
6 files changed, 62 insertions, 51 deletions
diff --git a/usr.bin/patch/common.h b/usr.bin/patch/common.h index 78b9b0d047a..8165d5b4bb2 100644 --- a/usr.bin/patch/common.h +++ b/usr.bin/patch/common.h @@ -1,4 +1,4 @@ -/* $OpenBSD: common.h,v 1.29 2015/07/26 14:32:19 millert Exp $ */ +/* $OpenBSD: common.h,v 1.30 2019/12/02 22:17:32 jca Exp $ */ /* * patch - a program to apply diffs to original files @@ -37,7 +37,7 @@ #define MAXHUNKSIZE 100000 /* is this enough lines? */ #define INITHUNKMAX 125 /* initial dynamic allocation size */ -#define MAXLINELEN 8192 +#define INITLINELEN 8192 #define BUFFERSIZE 1024 #define LINENUM_MAX LONG_MAX @@ -59,7 +59,8 @@ typedef long LINENUM; /* must be signed */ extern mode_t filemode; -extern char buf[MAXLINELEN];/* general purpose buffer */ +extern char *buf; /* general purpose buffer */ +extern size_t bufsz; /* general purpose buffer size */ extern bool using_plan_a; /* try to keep everything in memory */ extern bool out_of_mem; /* ran out of memory in plan a */ diff --git a/usr.bin/patch/ed.c b/usr.bin/patch/ed.c index ddaba056c38..3b83cb3f06b 100644 --- a/usr.bin/patch/ed.c +++ b/usr.bin/patch/ed.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ed.c,v 1.3 2016/09/02 21:39:51 tobias Exp $ */ +/* $OpenBSD: ed.c,v 1.4 2019/12/02 22:17:32 jca Exp $ */ /* * Copyright (c) 2015 Tobias Stoeckmann <tobias@openbsd.org> @@ -80,7 +80,7 @@ do_ed_script(void) for (;;) { linepos = ftello(pfp); - if (pgets(buf, sizeof buf, pfp) == NULL) + if (pgetline(&buf, &bufsz, pfp) == -1) break; p_input_line++; @@ -247,7 +247,7 @@ write_lines(char *filename) putc('\n', ofp); } else if (line->src == SRC_PCH) { fseeko(pfp, line->pos.seek, SEEK_SET); - if (pgets(buf, sizeof buf, pfp) == NULL) + if (pgetline(&buf, &bufsz, pfp) == -1) fatal("unexpected end of file"); p = buf; if (line->subst != 0) diff --git a/usr.bin/patch/patch.c b/usr.bin/patch/patch.c index 89e32667fbf..1d9070b0184 100644 --- a/usr.bin/patch/patch.c +++ b/usr.bin/patch/patch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: patch.c,v 1.68 2019/06/28 13:35:02 deraadt Exp $ */ +/* $OpenBSD: patch.c,v 1.69 2019/12/02 22:17:32 jca Exp $ */ /* * patch - a program to apply diffs to original files @@ -47,7 +47,8 @@ mode_t filemode = 0644; -char buf[MAXLINELEN]; /* general purpose buffer */ +char *buf; /* general purpose buffer */ +size_t bufsz; /* general purpose buffer size */ bool using_plan_a = true; /* try to keep everything in memory */ bool out_of_mem = false; /* ran out of memory in plan a */ @@ -153,6 +154,11 @@ main(int argc, char *argv[]) my_exit(2); } + bufsz = INITLINELEN; + if ((buf = malloc(bufsz)) == NULL) + pfatal("allocating input buffer"); + buf[0] = '\0'; + setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(stderr, NULL, _IOLBF, 0); for (i = 0; i < MAXFILEC; i++) diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c index 70f9f934327..d3bd960501f 100644 --- a/usr.bin/patch/pch.c +++ b/usr.bin/patch/pch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pch.c,v 1.60 2018/04/07 14:55:13 anton Exp $ */ +/* $OpenBSD: pch.c,v 1.61 2019/12/02 22:17:32 jca Exp $ */ /* * patch - a program to apply diffs to original files @@ -103,8 +103,8 @@ open_patch_file(const char *filename) pfp = fopen(TMPPATNAME, "w"); if (pfp == NULL) pfatal("can't create %s", TMPPATNAME); - while (fgets(buf, sizeof buf, stdin) != NULL) - fputs(buf, pfp); + while (getline(&buf, &bufsz, stdin) != -1) + fprintf(pfp, "%s", buf); fclose(pfp); filename = TMPPATNAME; } @@ -266,7 +266,7 @@ intuit_diff_type(void) this_line = ftello(pfp); indent = 0; p_input_line++; - if (fgets(buf, sizeof buf, pfp) == NULL) { + if (getline(&buf, &bufsz, pfp) == -1) { if (first_command_line >= 0) { /* nothing but deletes!? */ p_start = first_command_line; @@ -433,7 +433,7 @@ next_intuit_at(off_t file_pos, LINENUM file_line) static void skip_to(off_t file_pos, LINENUM file_line) { - char *ret; + int ret; if (p_base > file_pos) fatal("Internal error: seek %lld>%lld\n", @@ -442,8 +442,8 @@ skip_to(off_t file_pos, LINENUM file_line) fseeko(pfp, p_base, SEEK_SET); say("The text leading up to this was:\n--------------------------\n"); while (ftello(pfp) < file_pos) { - ret = fgets(buf, sizeof buf, pfp); - if (ret == NULL) + ret = getline(&buf, &bufsz, pfp); + if (ret == -1) fatal("Unexpected end of file\n"); say("|%s", buf); } @@ -501,8 +501,9 @@ another_hunk(void) off_t repl_backtrack_position; /* file pos of first repl line */ LINENUM repl_patch_line; /* input line number for same */ LINENUM ptrn_copiable; /* # of copiable lines in ptrn */ - char *s, *ret; + char *s; int context = 0; + int ret; while (p_end >= 0) { if (p_end == p_efake) @@ -526,9 +527,9 @@ another_hunk(void) repl_patch_line = 0; ptrn_copiable = 0; - ret = pgets(buf, sizeof buf, pfp); + ret = pgetline(&buf, &bufsz, pfp); p_input_line++; - if (ret == NULL || strnNE(buf, "********", 8)) { + if (ret == -1 || strnNE(buf, "********", 8)) { next_intuit_at(line_beginning, p_input_line); return false; } @@ -536,12 +537,12 @@ another_hunk(void) p_hunk_beg = p_input_line + 1; while (p_end < p_max) { line_beginning = ftello(pfp); - ret = pgets(buf, sizeof buf, pfp); + ret = pgetline(&buf, &bufsz, pfp); p_input_line++; - if (ret == NULL) { + if (ret == -1) { if (p_max - p_end < 4) { /* assume blank lines got chopped */ - strlcpy(buf, " \n", sizeof buf); + strlcpy(buf, " \n", bufsz); } else { if (repl_beginning && repl_could_be_missing) { repl_missing = true; @@ -695,7 +696,7 @@ another_hunk(void) repl_could_be_missing = false; change_line: if (buf[1] == '\n' && canonicalize) - strlcpy(buf + 1, " \n", sizeof buf - 1); + strlcpy(buf + 1, " \n", bufsz - 1); if (!isspace((unsigned char)buf[1]) && buf[1] != '>' && buf[1] != '<' && repl_beginning && repl_could_be_missing) { @@ -861,9 +862,9 @@ hunk_done: LINENUM filldst; /* index of new lines */ char ch; - ret = pgets(buf, sizeof buf, pfp); + ret = pgetline(&buf, &bufsz, pfp); p_input_line++; - if (ret == NULL || strnNE(buf, "@@ -", 4)) { + if (ret == -1 || strnNE(buf, "@@ -", 4)) { next_intuit_at(line_beginning, p_input_line); return false; } @@ -900,7 +901,7 @@ hunk_done: fillsrc = 1; filldst = fillsrc + p_ptrn_lines; p_end = filldst + p_repl_lines; - snprintf(buf, sizeof buf, "*** %ld,%ld ****\n", p_first, + snprintf(buf, bufsz, "*** %ld,%ld ****\n", p_first, p_first + p_ptrn_lines - 1); p_line[0] = savestr(buf); if (out_of_mem) { @@ -908,7 +909,7 @@ hunk_done: return false; } p_char[0] = '*'; - snprintf(buf, sizeof buf, "--- %ld,%ld ----\n", p_newfirst, + snprintf(buf, bufsz, "--- %ld,%ld ----\n", p_newfirst, p_newfirst + p_repl_lines - 1); p_line[filldst] = savestr(buf); if (out_of_mem) { @@ -921,12 +922,12 @@ hunk_done: p_hunk_beg = p_input_line + 1; while (fillsrc <= p_ptrn_lines || filldst <= p_end) { line_beginning = ftello(pfp); - ret = pgets(buf, sizeof buf, pfp); + ret = pgetline(&buf, &bufsz, pfp); p_input_line++; - if (ret == NULL) { + if (ret == -1) { if (p_max - filldst < 3) { /* assume blank lines got chopped */ - strlcpy(buf, " \n", sizeof buf); + strlcpy(buf, " \n", bufsz); } else { fatal("unexpected end of file in patch\n"); } @@ -1025,9 +1026,9 @@ hunk_done: off_t line_beginning = ftello(pfp); p_context = 0; - ret = pgets(buf, sizeof buf, pfp); + ret = pgetline(&buf, &bufsz, pfp); p_input_line++; - if (ret == NULL || !isdigit((unsigned char)*buf)) { + if (ret == -1 || !isdigit((unsigned char)*buf)) { next_intuit_at(line_beginning, p_input_line); return false; } @@ -1063,7 +1064,7 @@ hunk_done: p_end, p_input_line, buf); while (p_end >= hunkmax) grow_hunkmax(); - snprintf(buf, sizeof buf, "*** %ld,%ld\n", p_first, + snprintf(buf, bufsz, "*** %ld,%ld\n", p_first, p_first + p_ptrn_lines - 1); p_line[0] = savestr(buf); if (out_of_mem) { @@ -1072,9 +1073,9 @@ hunk_done: } p_char[0] = '*'; for (i = 1; i <= p_ptrn_lines; i++) { - ret = pgets(buf, sizeof buf, pfp); + ret = pgetline(&buf, &bufsz, pfp); p_input_line++; - if (ret == NULL) + if (ret == -1) fatal("unexpected end of file in patch at line %ld\n", p_input_line); if (*buf != '<') @@ -1094,16 +1095,16 @@ hunk_done: (p_line[i - 1])[p_len[i - 1]] = 0; } if (hunk_type == 'c') { - ret = pgets(buf, sizeof buf, pfp); + ret = pgetline(&buf, &bufsz, pfp); p_input_line++; - if (ret == NULL) + if (ret == -1) fatal("unexpected end of file in patch at line %ld\n", p_input_line); if (*buf != '-') fatal("--- expected at line %ld of patch\n", p_input_line); } - snprintf(buf, sizeof(buf), "--- %ld,%ld\n", min, max); + snprintf(buf, bufsz, "--- %ld,%ld\n", min, max); p_line[i] = savestr(buf); if (out_of_mem) { p_end = i - 1; @@ -1111,9 +1112,9 @@ hunk_done: } p_char[i] = '='; for (i++; i <= p_end; i++) { - ret = pgets(buf, sizeof buf, pfp); + ret = pgetline(&buf, &bufsz, pfp); p_input_line++; - if (ret == NULL) + if (ret == -1) fatal("unexpected end of file in patch at line %ld\n", p_input_line); if (*buf != '>') @@ -1160,13 +1161,16 @@ hunk_done: /* * Input a line from the patch file, worrying about indentation. */ -char * -pgets(char *bf, int sz, FILE *fp) +int +pgetline(char **bf, size_t *sz, FILE *fp) { - char *s, *ret = fgets(bf, sz, fp); + char *s; int indent = 0; + int ret; + + ret = getline(bf, sz, fp); - if (p_indent && ret != NULL) { + if (p_indent && ret != -1) { for (s = buf; indent < p_indent && (*s == ' ' || *s == '\t' || *s == 'X'); s++) { @@ -1175,8 +1179,8 @@ pgets(char *bf, int sz, FILE *fp) else indent++; } - if (buf != s && strlcpy(buf, s, sizeof(buf)) >= sizeof(buf)) - fatal("buffer too small in pgets()\n"); + if (buf != s && strlcpy(buf, s, bufsz) >= bufsz) + fatal("buffer too small in pgetline()\n"); } return ret; } diff --git a/usr.bin/patch/pch.h b/usr.bin/patch/pch.h index 86dde3db79f..30f4332b770 100644 --- a/usr.bin/patch/pch.h +++ b/usr.bin/patch/pch.h @@ -3,8 +3,8 @@ LINENUM strtolinenum(char *, char **); extern FILE *pfp; extern LINENUM p_input_line; -char *pgets(char *, int, FILE *); -/* $OpenBSD: pch.h,v 1.10 2015/10/16 07:33:47 tobias Exp $ */ +int pgetline(char **, size_t *, FILE *); +/* $OpenBSD: pch.h,v 1.11 2019/12/02 22:17:32 jca Exp $ */ /* * patch - a program to apply diffs to original files diff --git a/usr.bin/patch/util.c b/usr.bin/patch/util.c index 0f274825065..f079b5149c5 100644 --- a/usr.bin/patch/util.c +++ b/usr.bin/patch/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.44 2019/08/17 14:25:06 deraadt Exp $ */ +/* $OpenBSD: util.c,v 1.45 2019/12/02 22:17:32 jca Exp $ */ /* * patch - a program to apply diffs to original files @@ -61,7 +61,7 @@ move_file(const char *from, const char *to) fromfd = open(from, O_RDONLY); if (fromfd == -1) pfatal("internal error, can't reopen %s", from); - while ((i = read(fromfd, buf, sizeof buf)) > 0) + while ((i = read(fromfd, buf, bufsz)) > 0) if (write(STDOUT_FILENO, buf, i) != i) pfatal("write failed"); close(fromfd); @@ -160,7 +160,7 @@ copy_file(const char *from, const char *to) fromfd = open(from, O_RDONLY, 0); if (fromfd == -1) pfatal("internal error, can't reopen %s", from); - while ((i = read(fromfd, buf, sizeof buf)) > 0) + while ((i = read(fromfd, buf, bufsz)) > 0) if (write(tofd, buf, i) != i) pfatal("write to %s failed", to); close(fromfd); @@ -267,7 +267,7 @@ ask(const char *fmt, ...) if (ttyfd < 0) ttyfd = open(_PATH_TTY, O_RDONLY); if (ttyfd >= 0) { - if ((nr = read(ttyfd, buf, sizeof(buf))) > 0 && + if ((nr = read(ttyfd, buf, bufsz)) > 0 && buf[nr - 1] == '\n') buf[nr - 1] = '\0'; } |