Module Name: src
Committed By: cjep
Date: Tue May 25 11:25:59 UTC 2021
Modified Files:
src/usr.bin/patch: common.h inp.c patch.c pch.c util.c
Log Message:
As per OpenBSD, use malloc for the line buffer. Fixes the known issue
with long lines and makes our ATF test suite pass fully.
Closes PR bin/54620 from coypu who suggested the approach.
Reviewed by christos.
To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/usr.bin/patch/common.h
cvs rdiff -u -r1.26 -r1.27 src/usr.bin/patch/inp.c
cvs rdiff -u -r1.31 -r1.32 src/usr.bin/patch/patch.c src/usr.bin/patch/pch.c
cvs rdiff -u -r1.29 -r1.30 src/usr.bin/patch/util.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/patch/common.h
diff -u src/usr.bin/patch/common.h:1.21 src/usr.bin/patch/common.h:1.22
--- src/usr.bin/patch/common.h:1.21 Fri Jul 24 18:56:44 2015
+++ src/usr.bin/patch/common.h Tue May 25 11:25:59 2021
@@ -1,7 +1,7 @@
/*
* $OpenBSD: common.h,v 1.26 2006/03/11 19:41:30 otto Exp $
* $DragonFly: src/usr.bin/patch/common.h,v 1.5 2008/08/10 23:50:12 joerg Exp $
- * $NetBSD: common.h,v 1.21 2015/07/24 18:56:44 christos Exp $
+ * $NetBSD: common.h,v 1.22 2021/05/25 11:25:59 cjep Exp $
*/
/*
@@ -41,7 +41,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
@@ -71,8 +71,8 @@ typedef long LINENUM; /* must be sign
extern mode_t filemode;
-extern char buf[MAXLINELEN];/* general purpose buffer */
-extern size_t buf_len;
+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 */
Index: src/usr.bin/patch/inp.c
diff -u src/usr.bin/patch/inp.c:1.26 src/usr.bin/patch/inp.c:1.27
--- src/usr.bin/patch/inp.c:1.26 Mon Jun 18 18:33:31 2018
+++ src/usr.bin/patch/inp.c Tue May 25 11:25:59 2021
@@ -1,7 +1,7 @@
/*
* $OpenBSD: inp.c,v 1.34 2006/03/11 19:41:30 otto Exp $
* $DragonFly: src/usr.bin/patch/inp.c,v 1.6 2007/09/29 23:11:10 swildner Exp $
- * $NetBSD: inp.c,v 1.26 2018/06/18 18:33:31 christos Exp $
+ * $NetBSD: inp.c,v 1.27 2021/05/25 11:25:59 cjep Exp $
*/
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: inp.c,v 1.26 2018/06/18 18:33:31 christos Exp $");
+__RCSID("$NetBSD: inp.c,v 1.27 2021/05/25 11:25:59 cjep Exp $");
#include <sys/types.h>
#include <sys/file.h>
@@ -142,11 +142,11 @@ static bool
plan_a(const char *filename)
{
int ifd, statfailed, devnull, pstat;
- char *p, *s, lbuf[MAXLINELEN];
+ char *p, *s, *lbuf;
struct stat filestat;
off_t i;
ptrdiff_t sz;
- size_t iline, lines_allocated;
+ size_t iline, lines_allocated, lbufsz;
pid_t pid;
char *argp[4] = {NULL};
@@ -193,9 +193,14 @@ plan_a(const char *filename)
filebase = basename(tmp_filename1);
filedir = dirname(tmp_filename2);
+
+ lbufsz = INITLINELEN;
+ if ((lbuf = malloc(bufsz)) == NULL)
+ pfatal("allocating line buffer");
+ lbuf[0] = '\0';
#define try(f, a1, a2, a3) \
- (snprintf(lbuf, sizeof lbuf, f, a1, a2, a3), stat(lbuf, &cstat) == 0)
+ (snprintf(lbuf, lbufsz, f, a1, a2, a3), stat(lbuf, &cstat) == 0)
/*
* else we can't write to it but it's not under a version
@@ -391,7 +396,7 @@ plan_b(const char *filename)
unlink(TMPINNAME);
if ((tifd = open(TMPINNAME, O_EXCL | O_CREAT | O_WRONLY, 0666)) < 0)
pfatal("can't open file %s", TMPINNAME);
- while (fgets(buf, buf_len, ifp) != NULL) {
+ while (getline(&buf, &bufsz, ifp) != -1) {
if (revision != NULL && !found_revision && rev_in_string(buf))
found_revision = true;
if ((i = strlen(buf)) > maxlen)
Index: src/usr.bin/patch/patch.c
diff -u src/usr.bin/patch/patch.c:1.31 src/usr.bin/patch/patch.c:1.32
--- src/usr.bin/patch/patch.c:1.31 Sat Feb 20 09:17:13 2021
+++ src/usr.bin/patch/patch.c Tue May 25 11:25:59 2021
@@ -1,7 +1,7 @@
/*
* $OpenBSD: patch.c,v 1.45 2007/04/18 21:52:24 sobrado Exp $
* $DragonFly: src/usr.bin/patch/patch.c,v 1.10 2008/08/10 23:39:56 joerg Exp $
- * $NetBSD: patch.c,v 1.31 2021/02/20 09:17:13 nia Exp $
+ * $NetBSD: patch.c,v 1.32 2021/05/25 11:25:59 cjep Exp $
*/
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: patch.c,v 1.31 2021/02/20 09:17:13 nia Exp $");
+__RCSID("$NetBSD: patch.c,v 1.32 2021/05/25 11:25:59 cjep Exp $");
#include <sys/types.h>
#include <sys/stat.h>
@@ -53,8 +53,8 @@ __RCSID("$NetBSD: patch.c,v 1.31 2021/02
mode_t filemode = 0644;
-char buf[MAXLINELEN]; /* general purpose buffer */
-size_t buf_len = sizeof(buf);
+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 */
@@ -157,6 +157,11 @@ main(int argc, char *argv[])
const char *tmpdir;
char *v;
+ bufsz = INITLINELEN;
+ if ((buf = malloc(bufsz)) == NULL)
+ pfatal("allocating input buffer");
+ buf[0] = '\0';
+
setbuf(stderr, serrbuf);
for (i = 0; i < MAXFILEC; i++)
filearg[i] = NULL;
Index: src/usr.bin/patch/pch.c
diff -u src/usr.bin/patch/pch.c:1.31 src/usr.bin/patch/pch.c:1.32
--- src/usr.bin/patch/pch.c:1.31 Tue Nov 17 20:49:12 2020
+++ src/usr.bin/patch/pch.c Tue May 25 11:25:59 2021
@@ -1,7 +1,7 @@
/*
* $OpenBSD: pch.c,v 1.37 2007/09/02 15:19:33 deraadt Exp $
* $DragonFly: src/usr.bin/patch/pch.c,v 1.6 2008/08/10 23:35:40 joerg Exp $
- * $NetBSD: pch.c,v 1.31 2020/11/17 20:49:12 rhialto Exp $
+ * $NetBSD: pch.c,v 1.32 2021/05/25 11:25:59 cjep Exp $
*/
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: pch.c,v 1.31 2020/11/17 20:49:12 rhialto Exp $");
+__RCSID("$NetBSD: pch.c,v 1.32 2021/05/25 11:25:59 cjep Exp $");
#include <sys/types.h>
#include <sys/stat.h>
@@ -79,7 +79,7 @@ static void grow_hunkmax(void);
static int intuit_diff_type(void);
static void next_intuit_at(LINENUM, LINENUM);
static void skip_to(LINENUM, LINENUM);
-static char *pgets(char *, int, FILE *);
+static int pgetline(char **, size_t *, FILE *);
static char *best_name(const struct file_name *, bool);
static char *posix_name(const struct file_name *, bool);
static size_t num_components(const char *);
@@ -111,8 +111,8 @@ open_patch_file(const char *filename)
pfp = fopen(TMPPATNAME, "w");
if (pfp == NULL)
pfatal("can't create %s", TMPPATNAME);
- while (fgets(buf, buf_len, stdin) != NULL)
- fputs(buf, pfp);
+ while (getline(&buf, &bufsz, stdin) != -1)
+ fprintf(pfp, "%s", buf);
if (ferror(pfp) || fclose(pfp))
pfatal("can't write %s", TMPPATNAME);
filename = TMPPATNAME;
@@ -271,7 +271,7 @@ intuit_diff_type(void)
this_line = ftell(pfp);
indent = 0;
p_input_line++;
- if (fgets(buf, buf_len, pfp) == NULL) {
+ if (getline(&buf, &bufsz, pfp) == -1) {
if (first_command_line >= 0L) {
/* nothing but deletes!? */
p_start = first_command_line;
@@ -428,7 +428,7 @@ next_intuit_at(LINENUM file_pos, LINENUM
static void
skip_to(LINENUM file_pos, LINENUM file_line)
{
- char *ret;
+ int ret;
if (p_base > file_pos)
fatal("Internal error: seek %ld>%ld\n", p_base, file_pos);
@@ -436,8 +436,8 @@ skip_to(LINENUM file_pos, LINENUM file_l
fseek(pfp, p_base, SEEK_SET);
say("The text leading up to this was:\n--------------------------\n");
while (ftell(pfp) < file_pos) {
- ret = fgets(buf, buf_len, pfp);
- if (ret == NULL)
+ ret = getline(&buf, &bufsz, pfp);
+ if (ret == -1)
fatal("Unexpected end of file\n");
say("|%s", buf);
}
@@ -517,8 +517,9 @@ another_hunk(void)
long 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)
@@ -543,9 +544,9 @@ another_hunk(void)
repl_patch_line = 0;
ptrn_copiable = 0;
- ret = pgets(buf, buf_len, 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;
}
@@ -553,9 +554,9 @@ another_hunk(void)
p_hunk_beg = p_input_line + 1;
while (p_end < p_max) {
line_beginning = ftell(pfp);
- ret = pgets(buf, buf_len, pfp);
+ ret = pgetline(&buf, &bufsz, pfp);
p_input_line++;
- if (ret == NULL) {
+ if (ret == -1) {
if (repl_beginning && repl_could_be_missing) {
repl_missing = true;
goto hunk_done;
@@ -705,7 +706,7 @@ another_hunk(void)
repl_could_be_missing = false;
change_line:
if (buf[1] == '\n' && canonicalize)
- strlcpy(buf + 1, " \n", buf_len - 1);
+ strlcpy(buf + 1, " \n", bufsz - 1);
if (!isspace((unsigned char)buf[1]) && buf[1] != '>' &&
buf[1] != '<' &&
repl_beginning && repl_could_be_missing) {
@@ -871,9 +872,9 @@ hunk_done:
char ch;
line_beginning = ftell(pfp); /* file pos of the current line */
- ret = pgets(buf, buf_len, 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;
}
@@ -914,7 +915,7 @@ hunk_done:
fillold = 1;
fillnew = fillold + p_ptrn_lines;
p_end = fillnew + p_repl_lines;
- snprintf(buf, buf_len, "*** %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) {
@@ -922,7 +923,7 @@ hunk_done:
return false;
}
p_char[0] = '*';
- snprintf(buf, buf_len, "--- %ld,%ld ----\n", p_newfirst,
+ snprintf(buf, bufsz, "--- %ld,%ld ----\n", p_newfirst,
p_newfirst + p_repl_lines - 1);
p_line[fillnew] = savestr(buf);
if (out_of_mem) {
@@ -935,12 +936,12 @@ hunk_done:
p_hunk_beg = p_input_line + 1;
while (fillold <= p_ptrn_lines || fillnew <= p_end) {
line_beginning = ftell(pfp);
- ret = pgets(buf, buf_len, pfp);
+ ret = pgetline(&buf, &bufsz, pfp);
p_input_line++;
- if (ret == NULL) {
+ if (ret == -1) {
if (p_max - fillnew < 3) {
/* assume blank lines got chopped */
- strlcpy(buf, " \n", buf_len);
+ strlcpy(buf, " \n", bufsz);
} else {
fatal("unexpected end of file in patch\n");
}
@@ -1039,9 +1040,9 @@ hunk_done:
line_beginning = ftell(pfp);
p_context = 0;
- ret = pgets(buf, buf_len, 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;
}
@@ -1078,7 +1079,7 @@ hunk_done:
p_end, p_input_line, buf);
while (p_end >= hunkmax)
grow_hunkmax();
- snprintf(buf, buf_len, "*** %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) {
@@ -1087,9 +1088,9 @@ hunk_done:
}
p_char[0] = '*';
for (i = 1; i <= p_ptrn_lines; i++) {
- ret = pgets(buf, buf_len, 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 != '<')
@@ -1109,16 +1110,16 @@ hunk_done:
(p_line[i - 1])[p_len[i - 1]] = 0;
}
if (hunk_type == 'c') {
- ret = pgets(buf, buf_len, 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, buf_len, "--- %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;
@@ -1126,9 +1127,9 @@ hunk_done:
}
p_char[i] = '=';
for (i++; i <= p_end; i++) {
- ret = pgets(buf, buf_len, 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 != '>')
@@ -1175,13 +1176,16 @@ hunk_done:
/*
* Input a line from the patch file, worrying about indentation.
*/
-static 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++) {
@@ -1190,8 +1194,8 @@ pgets(char *bf, int sz, FILE *fp)
else
indent++;
}
- if (buf != s && strlcpy(buf, s, buf_len) >= buf_len)
- fatal("buffer too small in pgets()\n");
+ if (buf != s && strlcpy(buf, s, bufsz) >= bufsz)
+ fatal("buffer too small in pgetline()\n");
}
return ret;
}
@@ -1409,13 +1413,13 @@ do_ed_script(void)
unlink(TMPOUTNAME);
fatal("can't create temp file %s", TMPOUTNAME);
}
- snprintf(buf, buf_len, "%s -S%s %s", _PATH_ED,
+ snprintf(buf, bufsz, "%s -S%s %s", _PATH_ED,
verbose ? "" : "s", TMPOUTNAME);
pipefp = popen(buf, "w");
}
for (;;) {
beginning_of_this_line = ftell(pfp);
- if (pgets(buf, buf_len, pfp) == NULL) {
+ if (pgetline(&buf, &bufsz, pfp) == -1) {
next_intuit_at(beginning_of_this_line, p_input_line);
break;
}
@@ -1426,7 +1430,7 @@ do_ed_script(void)
if (isdigit((unsigned char)*buf) && (*t == 'a' || *t == 'c' ||
*t == 'd' || *t == 'i' || *t == 's')) {
if (pipefp != NULL)
- fputs(buf, pipefp);
+ fprintf(pipefp, "%s", buf);
if (*t == 's') {
for (;;) {
continuation = 0;
@@ -1434,16 +1438,16 @@ do_ed_script(void)
while (--t >= buf && *t == '\\')
continuation = !continuation;
if (!continuation ||
- pgets(buf, sizeof buf, pfp) == NULL)
+ pgetline(&buf, &bufsz, pfp) == -1)
break;
if (pipefp != NULL)
- fputs(buf, pipefp);
+ fprintf(pipefp, "%s", buf);
}
} else if (*t != 'd') {
- while (pgets(buf, buf_len, pfp) != NULL) {
+ while (pgetline(&buf, &bufsz, pfp) != -1) {
p_input_line++;
if (pipefp != NULL)
- fputs(buf, pipefp);
+ fprintf(pipefp, "%s", buf);
if (strEQ(buf, ".\n"))
break;
}
Index: src/usr.bin/patch/util.c
diff -u src/usr.bin/patch/util.c:1.29 src/usr.bin/patch/util.c:1.30
--- src/usr.bin/patch/util.c:1.29 Tue Nov 17 20:49:12 2020
+++ src/usr.bin/patch/util.c Tue May 25 11:25:59 2021
@@ -1,7 +1,7 @@
/*
* $OpenBSD: util.c,v 1.32 2006/03/11 19:41:30 otto Exp $
* $DragonFly: src/usr.bin/patch/util.c,v 1.9 2007/09/29 23:11:10 swildner Exp $
- * $NetBSD: util.c,v 1.29 2020/11/17 20:49:12 rhialto Exp $
+ * $NetBSD: util.c,v 1.30 2021/05/25 11:25:59 cjep Exp $
*/
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: util.c,v 1.29 2020/11/17 20:49:12 rhialto Exp $");
+__RCSID("$NetBSD: util.c,v 1.30 2021/05/25 11:25:59 cjep Exp $");
#include <sys/param.h>
#include <sys/stat.h>
@@ -70,7 +70,7 @@ move_file(const char *from, const char *
fromfd = open(from, O_RDONLY);
if (fromfd < 0)
pfatal("internal error, can't reopen %s", from);
- while ((i = read(fromfd, buf, buf_len)) > 0)
+ while ((i = read(fromfd, buf, bufsz)) > 0)
if (write(STDOUT_FILENO, buf, i) != i)
pfatal("write failed");
close(fromfd);
@@ -178,7 +178,7 @@ copy_file(const char *from, const char *
fromfd = open(from, O_RDONLY, 0);
if (fromfd < 0)
pfatal("internal error, can't reopen %s", from);
- while ((i = read(fromfd, buf, buf_len)) > 0)
+ while ((i = read(fromfd, buf, bufsz)) > 0)
if (write(tofd, buf, i) != i)
pfatal("write to %s failed", to);
close(fromfd);
@@ -269,7 +269,7 @@ ask(const char *fmt, ...)
if (ttyfd < 0)
ttyfd = open(_PATH_TTY, O_RDONLY);
if (ttyfd >= 0) {
- if ((nr = read(ttyfd, buf, buf_len)) > 0 &&
+ if ((nr = read(ttyfd, buf, bufsz)) > 0 &&
buf[nr - 1] == '\n')
buf[nr - 1] = '\0';
}