diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2021-08-22 13:54:04 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2021-08-22 14:02:22 -0700 |
commit | 57e5c514dfe12ccaf6c12d2b07047bd15ee306fb (patch) | |
tree | 8d6a230d065498df8def47dcbf4cac73d880029f | |
parent | dadc7f231f524b08a2d6497d55e702ef418c0b60 (diff) | |
download | diffutils-57e5c514dfe12ccaf6c12d2b07047bd15ee306fb.tar.gz |
maint: refactor integer overflow checking
Rely on more-modern Gnulib capabilities instead of doing
integer overflow checking by hand, in some cases.
* lib/cmpbuf.c (buffer_lcm):
* src/io.c (slurp, find_identical_ends):
Use INT_ADD_WRAPV and INT_MULTIPLY_WRAPV rather than checking
overflow by hand.
* src/diff3.c (process_diff):
* src/dir.c (dir_read):
* src/io.c (find_identical_ends, read_files):
Use xnmalloc rather than checking overflow by hand.
(read_files): Rely on xcalloc to do overflow checking.
-rw-r--r-- | lib/cmpbuf.c | 3 | ||||
-rw-r--r-- | src/diff3.c | 15 | ||||
-rw-r--r-- | src/dir.c | 4 | ||||
-rw-r--r-- | src/io.c | 21 |
4 files changed, 14 insertions, 29 deletions
diff --git a/lib/cmpbuf.c b/lib/cmpbuf.c index 7cee45a..f7c34e2 100644 --- a/lib/cmpbuf.c +++ b/lib/cmpbuf.c @@ -104,6 +104,5 @@ buffer_lcm (size_t a, size_t b, size_t lcm_max) /* Yield a if there is an overflow. */ q = a / n; - lcm = q * b; - return lcm <= lcm_max && lcm / b == q ? lcm : a; + return !INT_MULTIPLY_WRAPV (q, b, &lcm) && lcm <= lcm_max ? lcm : a; } diff --git a/src/diff3.c b/src/diff3.c index c67eb40..9e4ad54 100644 --- a/src/diff3.c +++ b/src/diff3.c @@ -1008,9 +1008,6 @@ process_diff (char const *filea, lin i; struct diff_block *block_list; struct diff_block **block_list_end = &block_list; - size_t too_many_lines = (PTRDIFF_MAX - / MIN (sizeof *block_list->lines[1], - sizeof *block_list->lengths[1])); diff_limit = read_diff (filea, fileb, &diff_contents); *buf_to_free = diff_contents; @@ -1056,10 +1053,8 @@ process_diff (char const *filea, if (dt != ADD) { lin numlines = D_NUMLINES (bptr, 0); - if (too_many_lines <= numlines) - xalloc_die (); - bptr->lines[0] = xmalloc (numlines * sizeof *bptr->lines[0]); - bptr->lengths[0] = xmalloc (numlines * sizeof *bptr->lengths[0]); + bptr->lines[0] = xnmalloc (numlines, sizeof *bptr->lines[0]); + bptr->lengths[0] = xnmalloc (numlines, sizeof *bptr->lengths[0]); for (i = 0; i < numlines; i++) scan_diff = scan_diff_line (scan_diff, &(bptr->lines[0][i]), @@ -1081,10 +1076,8 @@ process_diff (char const *filea, if (dt != DELETE) { lin numlines = D_NUMLINES (bptr, 1); - if (too_many_lines <= numlines) - xalloc_die (); - bptr->lines[1] = xmalloc (numlines * sizeof *bptr->lines[1]); - bptr->lengths[1] = xmalloc (numlines * sizeof *bptr->lengths[1]); + bptr->lines[1] = xnmalloc (numlines, sizeof *bptr->lines[1]); + bptr->lengths[1] = xnmalloc (numlines, sizeof *bptr->lengths[1]); for (i = 0; i < numlines; i++) scan_diff = scan_diff_line (scan_diff, &(bptr->lines[1][i]), @@ -126,9 +126,7 @@ dir_read (struct file_data const *dir, struct dirdata *dirdata) } /* Create the 'names' table from the 'data' table. */ - if (PTRDIFF_MAX / sizeof *names - 1 <= nnames) - xalloc_die (); - dirdata->names = names = xmalloc ((nnames + 1) * sizeof *names); + dirdata->names = names = xnmalloc (nnames + 1, sizeof *names); dirdata->nnames = nnames; for (i = 0; i < nnames; i++) { @@ -165,10 +165,9 @@ slurp (struct file_data *current) /* Get the size out of the stat block. Allocate just enough room for appended newline plus word sentinel, plus word-alignment since we want the buffer word-aligned. */ - size_t file_size = current->stat.st_size; - cc = file_size + 2 * sizeof (word) - file_size % sizeof (word); - if (file_size != current->stat.st_size || cc < file_size - || PTRDIFF_MAX <= cc) + off_t file_size = current->stat.st_size; + if (INT_ADD_WRAPV (2 * sizeof (word) - file_size % sizeof (word), + file_size, &cc)) xalloc_die (); if (current->bufsize < cc) @@ -716,11 +715,11 @@ find_identical_ends (struct file_data filevec[]) middle_guess = guess_lines (lines, p0 - buffer0, p1 - filevec[1].prefix_end); suffix_guess = guess_lines (lines, p0 - buffer0, buffer1 + n1 - p1); - alloc_lines1 = buffered_prefix + middle_guess + MIN (context, suffix_guess); - if (alloc_lines1 < buffered_prefix - || PTRDIFF_MAX / sizeof *linbuf1 <= alloc_lines1) + if (INT_ADD_WRAPV (buffered_prefix, + middle_guess + MIN (context, suffix_guess), + &alloc_lines1)) xalloc_die (); - linbuf1 = xmalloc (alloc_lines1 * sizeof *linbuf1); + linbuf1 = xnmalloc (alloc_lines1, sizeof *linbuf1); if (buffered_prefix != lines) { @@ -791,9 +790,7 @@ read_files (struct file_data filevec[], bool pretend_binary) find_identical_ends (filevec); equivs_alloc = filevec[0].alloc_lines + filevec[1].alloc_lines + 1; - if (PTRDIFF_MAX / sizeof *equivs <= equivs_alloc) - xalloc_die (); - equivs = xmalloc (equivs_alloc * sizeof *equivs); + equivs = xnmalloc (equivs_alloc, sizeof *equivs); /* Equivalence class 0 is permanently safe for lines that were not hashed. Real equivalence classes start at 1. */ equivs_index = 1; @@ -804,8 +801,6 @@ read_files (struct file_data filevec[], bool pretend_binary) for (i = 9; (size_t) 1 << i < equivs_alloc / 3; i++) continue; nbuckets = ((size_t) 1 << i) - prime_offset[i]; - if (PTRDIFF_MAX / sizeof *buckets <= nbuckets) - xalloc_die (); buckets = xcalloc (nbuckets + 1, sizeof *buckets); buckets++; |