From f37787df4c03b451c89283be65d88960803d0807 Mon Sep 17 00:00:00 2001 From: hogliux Date: Fri, 9 Sep 2016 14:49:10 +0100 Subject: [PATCH] Fixed incorrect comparison in right shift operator of BigInteger --- modules/juce_core/maths/juce_BigInteger.cpp | 61 +++++++++++++++------ 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/modules/juce_core/maths/juce_BigInteger.cpp b/modules/juce_core/maths/juce_BigInteger.cpp index 351f4f520a..96819cac5d 100644 --- a/modules/juce_core/maths/juce_BigInteger.cpp +++ b/modules/juce_core/maths/juce_BigInteger.cpp @@ -419,6 +419,9 @@ int BigInteger::findNextClearBit (int i) const noexcept //============================================================================== BigInteger& BigInteger::operator+= (const BigInteger& other) { + if (this == &other) + return operator+= (BigInteger (other)); + if (other.isNegative()) return operator-= (-other); @@ -467,21 +470,16 @@ BigInteger& BigInteger::operator+= (const BigInteger& other) BigInteger& BigInteger::operator-= (const BigInteger& other) { + if (this == &other) + { + clear(); + return *this; + } + if (other.isNegative()) return operator+= (-other); - if (! isNegative()) - { - if (compareAbsolute (other) < 0) - { - BigInteger temp (other); - swapWith (temp); - *this -= temp; - negate(); - return *this; - } - } - else + if (isNegative()) { negate(); *this += other; @@ -489,8 +487,17 @@ BigInteger& BigInteger::operator-= (const BigInteger& other) return *this; } - const size_t numInts = sizeNeededToHold (highestBit); - const size_t maxOtherInts = sizeNeededToHold (other.highestBit); + if (compareAbsolute (other) < 0) + { + BigInteger temp (other); + swapWith (temp); + *this -= temp; + negate(); + return *this; + } + + const size_t numInts = sizeNeededToHold (getHighestBit()); + const size_t maxOtherInts = sizeNeededToHold (other.getHighestBit()); jassert (numInts >= maxOtherInts); uint32* const values = getValues(); const uint32* const otherValues = other.getValues(); @@ -514,11 +521,15 @@ BigInteger& BigInteger::operator-= (const BigInteger& other) } } + highestBit = getHighestBit(); return *this; } BigInteger& BigInteger::operator*= (const BigInteger& other) { + if (this == &other) + return operator*= (BigInteger (other)); + int n = getHighestBit(); int t = other.getHighestBit(); @@ -561,6 +572,9 @@ BigInteger& BigInteger::operator*= (const BigInteger& other) void BigInteger::divideBy (const BigInteger& divisor, BigInteger& remainder) { + if (this == &divisor) + return divideBy (BigInteger (divisor), remainder); + jassert (this != &remainder); // (can't handle passing itself in to get the remainder) const int divHB = divisor.getHighestBit(); @@ -612,6 +626,9 @@ BigInteger& BigInteger::operator/= (const BigInteger& other) BigInteger& BigInteger::operator|= (const BigInteger& other) { + if (this == &other) + return *this; + // this operation doesn't take into account negative values.. jassert (isNegative() == other.isNegative()); @@ -636,6 +653,9 @@ BigInteger& BigInteger::operator|= (const BigInteger& other) BigInteger& BigInteger::operator&= (const BigInteger& other) { + if (this == &other) + return *this; + // this operation doesn't take into account negative values.. jassert (isNegative() == other.isNegative()); @@ -659,6 +679,12 @@ BigInteger& BigInteger::operator&= (const BigInteger& other) BigInteger& BigInteger::operator^= (const BigInteger& other) { + if (this == &other) + { + clear(); + return *this; + } + // this operation will only work with the absolute values jassert (isNegative() == other.isNegative()); @@ -752,7 +778,7 @@ void BigInteger::shiftLeft (int bits, const int startBit) { if (startBit > 0) { - for (int i = highestBit + 1; --i >= startBit;) + for (int i = highestBit; i >= startBit; --i) setBit (i + bits, (*this) [i]); while (--bits >= 0) @@ -802,7 +828,7 @@ void BigInteger::shiftRight (int bits, const int startBit) } else { - if (bits >= highestBit) + if (bits > highestBit) { clear(); } @@ -1307,6 +1333,9 @@ public: expect (b4 > b1 && b4 > b2); expect (b4 / b1 == b2); expect (b4 / b2 == b1); + expect (((b4 << 1) >> 1) == b4); + expect (((b4 << 10) >> 10) == b4); + expect (((b4 << 100) >> 100) == b4); // TODO: should add tests for other ops (although they also get pretty well tested in the RSA unit test)