Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/patch Avoid coredumps when the linenumbers in the hu...
details: https://anonhg.NetBSD.org/src/rev/6cbfd30dc557
branches: trunk
changeset: 804146:6cbfd30dc557
user: christos <christos%NetBSD.org@localhost>
date: Wed Nov 26 00:31:32 2014 +0000
description:
Avoid coredumps when the linenumbers in the hunks turn negative.
From: http://marc.info/?l=openbsd-tech&m=141693055412785
XXX: pullup 7
diffstat:
usr.bin/patch/common.h | 3 +-
usr.bin/patch/pch.c | 102 ++++++++++++++++++++++++++++++++----------------
2 files changed, 69 insertions(+), 36 deletions(-)
diffs (227 lines):
diff -r 03d14ff1120f -r 6cbfd30dc557 usr.bin/patch/common.h
--- a/usr.bin/patch/common.h Tue Nov 25 19:54:08 2014 +0000
+++ b/usr.bin/patch/common.h Wed Nov 26 00:31:32 2014 +0000
@@ -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.19 2008/09/19 18:33:34 joerg Exp $
+ * $NetBSD: common.h,v 1.20 2014/11/26 00:31:32 christos Exp $
*/
/*
@@ -43,6 +43,7 @@
#define INITHUNKMAX 125 /* initial dynamic allocation size */
#define MAXLINELEN 8192
#define BUFFERSIZE 1024
+#define LINENUM_MAX LONG_MAX
#define SCCSPREFIX "s."
#define GET "get -e %s"
diff -r 03d14ff1120f -r 6cbfd30dc557 usr.bin/patch/pch.c
--- a/usr.bin/patch/pch.c Tue Nov 25 19:54:08 2014 +0000
+++ b/usr.bin/patch/pch.c Wed Nov 26 00:31:32 2014 +0000
@@ -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.25 2013/01/29 09:30:11 wiz Exp $
+ * $NetBSD: pch.c,v 1.26 2014/11/26 00:31:32 christos Exp $
*/
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: pch.c,v 1.25 2013/01/29 09:30:11 wiz Exp $");
+__RCSID("$NetBSD: pch.c,v 1.26 2014/11/26 00:31:32 christos Exp $");
#include <sys/types.h>
#include <sys/stat.h>
@@ -455,6 +455,28 @@
/* about as informative as "Syntax error" in C */
}
+static LINENUM
+getlinenum(const char *s)
+{
+ LINENUM l = (LINENUM)atol(s);
+ if (l < 0) {
+ l = 0;
+ malformed();
+ }
+ return l;
+}
+
+static LINENUM
+getskiplinenum(char **p)
+{
+ char *s = *p;
+ LINENUM l = getlinenum(s);
+ while (isdigit((unsigned char)*s))
+ s++;
+ *p = s;
+ return l;
+}
+
/*
* True if the line has been discarded (i.e., it is a line saying
* "\ No newline at end of file".)
@@ -582,21 +604,24 @@
malformed();
if (strnEQ(s, "0,0", 3))
memmove(s, s + 2, strlen(s + 2) + 1);
- p_first = (LINENUM) atol(s);
- while (isdigit((unsigned char)*s))
- s++;
+ p_first = getskiplinenum(&s);
if (*s == ',') {
for (; *s && !isdigit((unsigned char)*s); s++)
;
if (!*s)
malformed();
- p_ptrn_lines = ((LINENUM) atol(s)) - p_first + 1;
+ p_ptrn_lines = (getlinenum(s)) - p_first + 1;
+ if (p_ptrn_lines < 0)
+ malformed();
} else if (p_first)
p_ptrn_lines = 1;
else {
p_ptrn_lines = 0;
p_first = 1;
}
+ if (p_first <= LINENUM_MAX - p_ptrn_lines ||
+ p_ptrn_lines <= LINENUM_MAX - 6)
+ malformed();
/* we need this much at least */
p_max = p_ptrn_lines + 6;
@@ -649,22 +674,25 @@
;
if (!*s)
malformed();
- p_newfirst = (LINENUM) atol(s);
- while (isdigit((unsigned char)*s))
- s++;
+ p_newfirst = getskiplinenum(&s);
if (*s == ',') {
for (; *s && !isdigit((unsigned char)*s); s++)
;
if (!*s)
malformed();
- p_repl_lines = ((LINENUM) atol(s)) -
+ p_repl_lines = (getlinenum(s)) -
p_newfirst + 1;
+ if (p_repl_lines < 0)
+ malformed();
} else if (p_newfirst)
p_repl_lines = 1;
else {
p_repl_lines = 0;
p_newfirst = 1;
}
+ if (p_newfirst >= LINENUM_MAX - p_repl_lines ||
+ p_repl_lines >= LINENUM_MAX - p_end)
+ malformed();
p_max = p_repl_lines + p_end;
if (p_max > MAXHUNKSIZE)
fatal("hunk too large (%ld lines) at line %ld: %s",
@@ -857,32 +885,32 @@
s = buf + 4;
if (!*s)
malformed();
- p_first = (LINENUM) atol(s);
- while (isdigit((unsigned char)*s))
- s++;
+ p_first = getskiplinenum(&s);
if (*s == ',') {
- p_ptrn_lines = (LINENUM) atol(++s);
- while (isdigit((unsigned char)*s))
- s++;
+ s++;
+ p_ptrn_lines = getskiplinenum(&s);
} else
p_ptrn_lines = 1;
+ if (p_first >= LINENUM_MAX - p_ptrn_lines)
+ malformed();
if (*s == ' ')
s++;
if (*s != '+' || !*++s)
malformed();
- p_newfirst = (LINENUM) atol(s);
- while (isdigit((unsigned char)*s))
- s++;
+ p_newfirst = getskiplinenum(&s);
if (*s == ',') {
- p_repl_lines = (LINENUM) atol(++s);
- while (isdigit((unsigned char)*s))
- s++;
+ s++;
+ p_repl_lines = getskiplinenum(&s);
} else
p_repl_lines = 1;
if (*s == ' ')
s++;
if (*s != '@')
malformed();
+ if (p_first >= LINENUM_MAX - p_ptrn_lines ||
+ p_newfirst > LINENUM_MAX - p_repl_lines ||
+ p_ptrn_lines >= LINENUM_MAX - p_repl_lines - 1)
+ malformed();
if (!p_ptrn_lines)
p_first++; /* do append rather than insert */
p_max = p_ptrn_lines + p_repl_lines + 1;
@@ -1022,35 +1050,39 @@
next_intuit_at(line_beginning, p_input_line);
return false;
}
- p_first = (LINENUM) atol(buf);
- for (s = buf; isdigit((unsigned char)*s); s++)
- ;
+ s = buf;
+ p_first = getskiplinenum(&s);
if (*s == ',') {
- p_ptrn_lines = (LINENUM) atol(++s) - p_first + 1;
- while (isdigit((unsigned char)*s))
- s++;
+ s++;
+ p_ptrn_lines = getskiplinenum(&s) - p_first + 1;
} else
p_ptrn_lines = (*s != 'a');
- hunk_type = *s;
+ if (p_first >= LINENUM_MAX - p_ptrn_lines)
+ malformed();
+ hunk_type = *s++;
if (hunk_type == 'a')
p_first++; /* do append rather than insert */
- min = (LINENUM) atol(++s);
- for (; isdigit((unsigned char)*s); s++)
- ;
+ min = getskiplinenum(&s);
if (*s == ',')
- max = (LINENUM) atol(++s);
+ max = getlinenum(++s);
else
max = min;
+ if (min < 0 || min > max || max - min == LINENUM_MAX)
+ malformed();
if (hunk_type == 'd')
min++;
p_end = p_ptrn_lines + 1 + max - min + 1;
+ p_newfirst = min;
+ p_repl_lines = max - min + 1;
+ if (p_newfirst > LINENUM_MAX - p_repl_lines ||
+ p_ptrn_lines >= LINENUM_MAX - p_repl_lines - 1)
+ malformed();
+ p_end = p_ptrn_lines + p_repl_lines + 1;
if (p_end > MAXHUNKSIZE)
fatal("hunk too large (%ld lines) at line %ld: %s",
p_end, p_input_line, buf);
while (p_end >= hunkmax)
grow_hunkmax();
- p_newfirst = min;
- p_repl_lines = max - min + 1;
snprintf(buf, buf_len, "*** %ld,%ld\n", p_first,
p_first + p_ptrn_lines - 1);
p_line[0] = savestr(buf);
Home |
Main Index |
Thread Index |
Old Index