summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2021-03-24 16:06:12 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2021-03-24 16:08:22 -0700
commit4c92a42eb832cecaa1fa27946ca28e896e0fa1d6 (patch)
treed2884b99d10e86f261f4c7c4d8710436fb966ec1 /src
parent6feddb95b496856240f70295addb431cf5ec722d (diff)
downloaddiffutils-4c92a42eb832cecaa1fa27946ca28e896e0fa1d6.tar.gz
diff3: avoid signed int overflow
* src/diff3.c (main): Avoid signed integer overflow in the very unlikely case of more than INT_MAX incompatible options. Instead, use one bit to record the presence of each type of incompatible option, and report an error if more than one bit is set.
Diffstat (limited to 'src')
-rw-r--r--src/diff3.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/src/diff3.c b/src/diff3.c
index 18a7341..6be7e3c 100644
--- a/src/diff3.c
+++ b/src/diff3.c
@@ -257,6 +257,7 @@ main (int argc, char **argv)
int mapping[3];
int rev_mapping[3];
int incompat = 0;
+ enum { OPTION_3, OPTION_A, OPTION_E, OPTION_X, OPTION_e, OPTION_x };
bool conflicts_found;
struct diff_block *thread0, *thread1, *last_block;
struct diff3_block *diff3;
@@ -285,15 +286,15 @@ main (int argc, char **argv)
case 'A':
show_2nd = true;
flagging = true;
- incompat++;
+ incompat |= 1 << OPTION_A;
break;
case 'x':
overlap_only = true;
- incompat++;
+ incompat |= 1 << OPTION_x;
break;
case '3':
simple_only = true;
- incompat++;
+ incompat |= 1 << OPTION_3;
break;
case 'i':
finalwrite = true;
@@ -303,12 +304,14 @@ main (int argc, char **argv)
break;
case 'X':
overlap_only = true;
- FALLTHROUGH;
+ incompat |= 1 << OPTION_X;
+ break;
case 'E':
flagging = true;
- FALLTHROUGH;
+ incompat |= 1 << OPTION_E;
+ break;
case 'e':
- incompat++;
+ incompat |= 1 << OPTION_e;
break;
case 'T':
initial_tab = true;
@@ -342,12 +345,12 @@ main (int argc, char **argv)
}
/* -AeExX3 without -m implies ed script. */
- edscript = incompat & ~(int) merge;
+ edscript = !!incompat & !merge;
- show_2nd |= ~incompat & merge; /* -m without -AeExX3 implies -A. */
- flagging |= ~incompat & merge;
+ show_2nd |= !incompat & merge; /* -m without -AeExX3 implies -A. */
+ flagging |= !incompat & merge;
- if (incompat > 1 /* Ensure at most one of -AeExX3. */
+ if (incompat & (incompat - 1) /* Ensure at most one of -AeExX3. */
|| finalwrite & merge /* -i -m would rewrite input file. */
|| (tag_count && ! flagging)) /* -L requires one of -AEX. */
try_help ("incompatible options", 0);