diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2021-03-24 16:06:12 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2021-03-24 16:08:22 -0700 |
commit | 4c92a42eb832cecaa1fa27946ca28e896e0fa1d6 (patch) | |
tree | d2884b99d10e86f261f4c7c4d8710436fb966ec1 /src | |
parent | 6feddb95b496856240f70295addb431cf5ec722d (diff) | |
download | diffutils-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.c | 23 |
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); |