aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRicardo M. Correia <[email protected]>2012-05-14 21:17:24 +0200
committerRicardo M. Correia <[email protected]>2012-05-14 21:26:02 +0200
commit5849bd472a3a7296f91b887884946218897ca11f (patch)
tree981fd61f70c870ca74bbe73037620d38f388b018 /src
parentAdd test case for CBigNum::setint64(). (diff)
downloaddiscoin-5849bd472a3a7296f91b887884946218897ca11f.tar.xz
discoin-5849bd472a3a7296f91b887884946218897ca11f.zip
Fix signed subtraction overflow in CBigNum::setint64().
As noticed by sipa (Pieter Wuille), this can happen when CBigNum::setint64() is called with an integer value of INT64_MIN (-2^63). When compiled with -ftrapv, the program would crash. Otherwise, it would execute an undefined operation (although in practice, usually the correct one).
Diffstat (limited to 'src')
-rw-r--r--src/bignum.h10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/bignum.h b/src/bignum.h
index 3716c4965..5190c2f39 100644
--- a/src/bignum.h
+++ b/src/bignum.h
@@ -131,7 +131,15 @@ public:
if (sn < (int64)0)
{
- n = -sn;
+ // We negate in 2 steps to avoid signed subtraction overflow,
+ // i.e. -(-2^63), which is an undefined operation and causes SIGILL
+ // when compiled with -ftrapv.
+ //
+ // Note that uint64_t n = sn, when sn is an int64_t, is a
+ // well-defined operation and n will be equal to sn + 2^64 when sn
+ // is negative.
+ n = sn;
+ n = -n;
fNegative = true;
} else {
n = sn;