FreeBSD Bugzilla – Attachment 150316 Details for
Bug 195436
patch utility, line number overflows checks
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch based on OpenBSD
patch-limits.diff (text/plain), 6.12 KB, created by
Pedro F. Giffuni
on 2014-12-07 19:42:03 UTC
(
hide
)
Description:
Patch based on OpenBSD
Filename:
MIME Type:
Creator:
Pedro F. Giffuni
Created:
2014-12-07 19:42:03 UTC
Size:
6.12 KB
patch
obsolete
>Index: usr.bin/patch/common.h >=================================================================== >--- usr.bin/patch/common.h (revision 275577) >+++ usr.bin/patch/common.h (working copy) >@@ -40,6 +40,7 @@ > #define INITHUNKMAX 125 /* initial dynamic allocation size */ > #define INITLINELEN 4096 > #define BUFFERSIZE 4096 >+#define LINENUM_MAX LONG_MAX > > #define SCCSPREFIX "s." > #define GET "get -e %s" >Index: usr.bin/patch/pch.c >=================================================================== >--- usr.bin/patch/pch.c (revision 275577) >+++ usr.bin/patch/pch.c (working copy) >@@ -78,6 +78,7 @@ > 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 *); >+static LINENUM strtolinenum(char *, char **); > > /* > * Prepare to look for the next patch in the patch file. >@@ -353,7 +354,7 @@ > stars_this_line = strnEQ(s, "********", 8); > if ((!diff_type || diff_type == CONTEXT_DIFF) && stars_last_line && > strnEQ(s, "*** ", 4)) { >- if (atol(s + 4) == 0) >+ if (strtolinenum(s + 4, &s) == 0) > ok_to_create_file = true; > /* > * If this is a new context diff the character just >@@ -591,15 +592,15 @@ > 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 = strtolinenum(s, &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 = strtolinenum(s, &s) - p_first + 1; >+ if (p_ptrn_lines < 0) >+ malformed(); > } else if (p_first) > p_ptrn_lines = 1; > else { >@@ -606,6 +607,9 @@ > 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; >@@ -658,16 +662,16 @@ > ; > if (!*s) > malformed(); >- p_newfirst = (LINENUM) atol(s); >- while (isdigit((unsigned char)*s)) >- s++; >+ p_newfirst = strtolinenum(s, &s); > if (*s == ',') { > for (; *s && !isdigit((unsigned char)*s); s++) > ; > if (!*s) > malformed(); >- p_repl_lines = ((LINENUM) atol(s)) - >+ p_repl_lines = strtolinenum(s, &s) - > p_newfirst + 1; >+ if (p_repl_lines < 0) >+ malformed(); > } else if (p_newfirst) > p_repl_lines = 1; > else { >@@ -674,6 +678,9 @@ > 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", >@@ -866,13 +873,9 @@ > s = buf + 4; > if (!*s) > malformed(); >- p_first = (LINENUM) atol(s); >- while (isdigit((unsigned char)*s)) >- s++; >+ p_first = strtolinenum(s, &s); > if (*s == ',') { >- p_ptrn_lines = (LINENUM) atol(++s); >- while (isdigit((unsigned char)*s)) >- s++; >+ p_ptrn_lines = strtolinenum(s + 1, &s); > } else > p_ptrn_lines = 1; > if (*s == ' ') >@@ -879,13 +882,9 @@ > s++; > if (*s != '+' || !*++s) > malformed(); >- p_newfirst = (LINENUM) atol(s); >- while (isdigit((unsigned char)*s)) >- s++; >+ p_newfirst = strtolinenum(s, &s); > if (*s == ',') { >- p_repl_lines = (LINENUM) atol(++s); >- while (isdigit((unsigned char)*s)) >- s++; >+ p_repl_lines = strtolinenum(s + 1, &s); > } else > p_repl_lines = 1; > if (*s == ' ') >@@ -892,6 +891,10 @@ > 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; >@@ -1031,35 +1034,38 @@ > next_intuit_at(line_beginning, p_input_line); > return false; > } >- p_first = (LINENUM) atol(buf); >- for (s = buf; isdigit((unsigned char)*s); s++) >- ; >+ p_first = strtolinenum(buf, &s); > if (*s == ',') { >- p_ptrn_lines = (LINENUM) atol(++s) - p_first + 1; >- while (isdigit((unsigned char)*s)) >- s++; >+ p_ptrn_lines = strtolinenum(s + 1, &s) - p_first + 1; >+ if (p_ptrn_lines < 0) >+ malformed(); > } else > p_ptrn_lines = (*s != 'a'); >+ 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 = strtolinenum(s + 1, &s); > if (*s == ',') >- max = (LINENUM) atol(++s); >+ max = strtolinenum(s + 1, &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_size, "*** %ld,%ld\n", p_first, > p_first + p_ptrn_lines - 1); > p_line[0] = savestr(buf); >@@ -1579,3 +1585,36 @@ > } > return n; > } >+ >+/* >+ * Convert number at NPTR into LINENUM and save address of first >+ * character that is not a digit in ENDPTR. If conversion is not >+ * possible, call fatal. >+ */ >+static LINENUM >+strtolinenum(char *nptr, char **endptr) >+{ >+ LINENUM rv; >+ char c; >+ char *p; >+ const char *errstr; >+ >+ for (p = nptr; isdigit((unsigned char)*p); p++) >+ ; >+ >+ if (p == nptr) >+ malformed(); >+ >+ c = *p; >+ *p = '\0'; >+ >+ rv = strtonum(nptr, 0, LINENUM_MAX, &errstr); >+ if (errstr != NULL) >+ fatal("invalid line number at line %ld: `%s' is %s\n", >+ p_input_line, nptr, errstr); >+ >+ *p = c; >+ *endptr = p; >+ >+ return rv; >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 195436
:
149926
|
149941
|
149982
|
150316
|
150320