summaryrefslogtreecommitdiff
path: root/usr.bin/patch
diff options
context:
space:
mode:
authorJeremie Courreges-Anglas <jca@cvs.openbsd.org>2019-12-02 22:17:33 +0000
committerJeremie Courreges-Anglas <jca@cvs.openbsd.org>2019-12-02 22:17:33 +0000
commitdd4daa2a0e04057c3f7edff11b24670c8cf5c474 (patch)
treef4a496ccdbf94ae646eeae5358e809f3fced8eca /usr.bin/patch
parent81ad68fd2f1fcc87562930a3d7231cdcddc659ec (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.h7
-rw-r--r--usr.bin/patch/ed.c6
-rw-r--r--usr.bin/patch/patch.c10
-rw-r--r--usr.bin/patch/pch.c78
-rw-r--r--usr.bin/patch/pch.h4
-rw-r--r--usr.bin/patch/util.c8
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';
}