From 91dd8c77ae849c22a8e4c9275e3f728b474b5be5 Mon Sep 17 00:00:00 2001 From: Bo Xu Date: Tue, 2 Dec 2014 16:34:20 -0800 Subject: Modify big integer library This patch follows https://pdfium.googlesource.com/pdfium/+/44047c3300d07192a67b1714084cc2d43b1e9bd9 Modify the library to resolve compile error, add copyright notice and change pdfium.gyp and BUILD.gn R=tsepez@chromium.org Review URL: https://codereview.chromium.org/754743003 --- BUILD.gn | 16 ++++++++++ pdfium.gyp | 17 +++++++++++ third_party/bigint/BigInteger.cc | 38 ++++++++++++++++++++++++ third_party/bigint/BigInteger.hh | 34 +++++++++++++++++++--- third_party/bigint/BigIntegerLibrary.hh | 8 ++++- third_party/bigint/BigIntegerUtils.cc | 10 +++++++ third_party/bigint/BigIntegerUtils.hh | 6 ++++ third_party/bigint/BigUnsigned.cc | 30 +++++++++++++++++++ third_party/bigint/BigUnsigned.hh | 50 ++++++++++++++++++++++++++++---- third_party/bigint/BigUnsignedInABase.cc | 34 ++++++++++++++++++++++ third_party/bigint/BigUnsignedInABase.hh | 10 +++++-- third_party/bigint/NumberlikeArray.hh | 7 +++++ 12 files changed, 247 insertions(+), 13 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index 5d0210ff34..2e471637d4 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -90,6 +90,7 @@ static_library("pdfium") { deps = [ ":safemath", + ":bigint", ":fdrm", ":formfiller", ":fpdfapi", @@ -128,6 +129,21 @@ component("safemath") { ] } +static_library("bigint") { + sources = [ + "third_party/bigint/BigInteger.hh", + "third_party/bigint/BigIntegerLibrary.hh", + "third_party/bigint/BigIntegerUtils.hh", + "third_party/bigint/BigUnsigned.hh", + "third_party/bigint/NumberlikeArray.hh", + "third_party/bigint/BigUnsignedInABase.hh", + "third_party/bigint/BigInteger.cc", + "third_party/bigint/BigIntegerUtils.cc", + "third_party/bigint/BigUnsigned.cc", + "third_party/bigint/BigUnsignedInABase.cc", + ] +} + static_library("fdrm") { sources = [ "core/include/fdrm/fx_crypt.h", diff --git a/pdfium.gyp b/pdfium.gyp index 606925c5e2..7e7dba9dfc 100644 --- a/pdfium.gyp +++ b/pdfium.gyp @@ -36,6 +36,7 @@ 'type': 'static_library', 'dependencies': [ 'safemath', + 'bigint', 'fdrm', 'fpdfdoc', 'fpdfapi', @@ -136,6 +137,22 @@ 'third_party/numerics/safe_math_impl.h', ], }, + { + 'target_name': 'bigint', + 'type': 'static_library', + 'sources': [ + 'third_party/bigint/BigInteger.hh', + 'third_party/bigint/BigIntegerLibrary.hh', + 'third_party/bigint/BigIntegerUtils.hh', + 'third_party/bigint/BigUnsigned.hh', + 'third_party/bigint/NumberlikeArray.hh', + 'third_party/bigint/BigUnsignedInABase.hh', + 'third_party/bigint/BigInteger.cc', + 'third_party/bigint/BigIntegerUtils.cc', + 'third_party/bigint/BigUnsigned.cc', + 'third_party/bigint/BigUnsignedInABase.cc', + ], + }, { 'target_name': 'fdrm', 'type': 'static_library', diff --git a/third_party/bigint/BigInteger.cc b/third_party/bigint/BigInteger.cc index 3b23aa1e7b..bac578f974 100644 --- a/third_party/bigint/BigInteger.cc +++ b/third_party/bigint/BigInteger.cc @@ -1,3 +1,9 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code by Matt McCutchen, see the LICENSE file. + #include "BigInteger.hh" void BigInteger::operator =(const BigInteger &x) { @@ -14,7 +20,11 @@ BigInteger::BigInteger(const Blk *b, Index blen, Sign s) : mag(b, blen) { switch (s) { case zero: if (!mag.isZero()) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigInteger::BigInteger(const Blk *, Index, Sign): Cannot use a sign of zero with a nonzero magnitude"; +#endif sign = zero; break; case positive: @@ -25,7 +35,11 @@ BigInteger::BigInteger(const Blk *b, Index blen, Sign s) : mag(b, blen) { default: /* g++ seems to be optimizing out this case on the assumption * that the sign is a valid member of the enumeration. Oh well. */ +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigInteger::BigInteger(const Blk *, Index, Sign): Invalid sign"; +#endif } } @@ -33,7 +47,11 @@ BigInteger::BigInteger(const BigUnsigned &x, Sign s) : mag(x) { switch (s) { case zero: if (!mag.isZero()) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Cannot use a sign of zero with a nonzero magnitude"; +#endif sign = zero; break; case positive: @@ -44,7 +62,11 @@ BigInteger::BigInteger(const BigUnsigned &x, Sign s) : mag(x) { default: /* g++ seems to be optimizing out this case on the assumption * that the sign is a valid member of the enumeration. Oh well. */ +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Invalid sign"; +#endif } } @@ -92,8 +114,12 @@ inline X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a) { template X BigInteger::convertToUnsignedPrimitive() const { if (sign == negative) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigInteger::to: " "Cannot convert a negative integer to an unsigned type"; +#endif else return convertBigUnsignedToPrimitiveAccess(mag); } @@ -120,8 +146,12 @@ X BigInteger::convertToSignedPrimitive() const { } // Otherwise fall through. } +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigInteger::to: " "Value is too big to fit in the requested type"; +#endif } unsigned long BigInteger::toUnsignedLong () const { return convertToUnsignedPrimitive (); } @@ -149,7 +179,11 @@ BigInteger::CmpRes BigInteger::compareTo(const BigInteger &x) const { // Compare the magnitudes, but return the opposite result return CmpRes(-mag.compareTo(x.mag)); default: +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigInteger internal error"; +#endif } } @@ -281,7 +315,11 @@ void BigInteger::divideWithRemainder(const BigInteger &b, BigInteger &q) { // Defend against aliased calls; // same idea as in BigUnsigned::divideWithRemainder . if (this == &q) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigInteger::divideWithRemainder: Cannot write quotient and remainder into the same variable"; +#endif if (this == &b || &q == &b) { BigInteger tmpB(b); divideWithRemainder(tmpB, q); diff --git a/third_party/bigint/BigInteger.hh b/third_party/bigint/BigInteger.hh index cf6e91056f..a239d3c954 100644 --- a/third_party/bigint/BigInteger.hh +++ b/third_party/bigint/BigInteger.hh @@ -1,3 +1,9 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code by Matt McCutchen, see the LICENSE file. + #ifndef BIGINTEGER_H #define BIGINTEGER_H @@ -157,14 +163,24 @@ inline BigInteger BigInteger::operator *(const BigInteger &x) const { return ans; } inline BigInteger BigInteger::operator /(const BigInteger &x) const { - if (x.isZero()) throw "BigInteger::operator /: division by zero"; + if (x.isZero()) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else + throw "BigInteger::operator /: division by zero"; +#endif BigInteger q, r; r = *this; r.divideWithRemainder(x, q); return q; } inline BigInteger BigInteger::operator %(const BigInteger &x) const { - if (x.isZero()) throw "BigInteger::operator %: division by zero"; + if (x.isZero()) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else + throw "BigInteger::operator %: division by zero"; +#endif BigInteger q, r; r = *this; r.divideWithRemainder(x, q); @@ -193,7 +209,12 @@ inline void BigInteger::operator *=(const BigInteger &x) { multiply(*this, x); } inline void BigInteger::operator /=(const BigInteger &x) { - if (x.isZero()) throw "BigInteger::operator /=: division by zero"; + if (x.isZero()) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else + throw "BigInteger::operator /=: division by zero"; +#endif /* The following technique is slightly faster than copying *this first * when x is large. */ BigInteger q; @@ -202,7 +223,12 @@ inline void BigInteger::operator /=(const BigInteger &x) { *this = q; } inline void BigInteger::operator %=(const BigInteger &x) { - if (x.isZero()) throw "BigInteger::operator %=: division by zero"; + if (x.isZero()) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else + throw "BigInteger::operator %=: division by zero"; +#endif BigInteger q; // Mods *this by x. Don't care about quotient left in q. divideWithRemainder(x, q); diff --git a/third_party/bigint/BigIntegerLibrary.hh b/third_party/bigint/BigIntegerLibrary.hh index 2a0ebee6a1..2027804dfb 100644 --- a/third_party/bigint/BigIntegerLibrary.hh +++ b/third_party/bigint/BigIntegerLibrary.hh @@ -1,8 +1,14 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code by Matt McCutchen, see the LICENSE file. + // This header file includes all of the library header files. #include "NumberlikeArray.hh" #include "BigUnsigned.hh" #include "BigInteger.hh" -#include "BigIntegerAlgorithms.hh" #include "BigUnsignedInABase.hh" #include "BigIntegerUtils.hh" + diff --git a/third_party/bigint/BigIntegerUtils.cc b/third_party/bigint/BigIntegerUtils.cc index 44073af652..fac8ac34b1 100644 --- a/third_party/bigint/BigIntegerUtils.cc +++ b/third_party/bigint/BigIntegerUtils.cc @@ -1,3 +1,9 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code by Matt McCutchen, see the LICENSE file. + #include "BigIntegerUtils.hh" #include "BigUnsignedInABase.hh" @@ -36,7 +42,11 @@ std::ostream &operator <<(std::ostream &os, const BigUnsigned &x) { if (osFlags & os.showbase) os << '0'; } else +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "std::ostream << BigUnsigned: Could not determine the desired base from output-stream flags"; +#endif std::string s = std::string(BigUnsignedInABase(x, base)); os << s; return os; diff --git a/third_party/bigint/BigIntegerUtils.hh b/third_party/bigint/BigIntegerUtils.hh index c815b5d7c5..d2f81f48ab 100644 --- a/third_party/bigint/BigIntegerUtils.hh +++ b/third_party/bigint/BigIntegerUtils.hh @@ -1,3 +1,9 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code by Matt McCutchen, see the LICENSE file. + #ifndef BIGINTEGERUTILS_H #define BIGINTEGERUTILS_H diff --git a/third_party/bigint/BigUnsigned.cc b/third_party/bigint/BigUnsigned.cc index d7f9889cc6..863fadcb39 100644 --- a/third_party/bigint/BigUnsigned.cc +++ b/third_party/bigint/BigUnsigned.cc @@ -1,3 +1,9 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code by Matt McCutchen, see the LICENSE file. + #include "BigUnsigned.hh" // Memory management definitions have moved to the bottom of NumberlikeArray.hh. @@ -189,8 +195,12 @@ void BigUnsigned::subtract(const BigUnsigned &a, const BigUnsigned &b) { return; } else if (a.len < b.len) // If a is shorter than b, the result is negative. +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsigned::subtract: " "Negative result in unsigned calculation"; +#endif // Some variables... bool borrowIn, borrowOut; Blk temp; @@ -223,7 +233,11 @@ void BigUnsigned::subtract(const BigUnsigned &a, const BigUnsigned &b) { * predictable state. */ if (borrowIn) { len = 0; +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsigned::subtract: Negative result in unsigned calculation"; +#endif } else // Copy over the rest of the blocks for (; i < a.len; i++) @@ -386,7 +400,11 @@ void BigUnsigned::divideWithRemainder(const BigUnsigned &b, BigUnsigned &q) { * It would be silly to try to write quotient and remainder to the * same variable. Rule that out right away. */ if (this == &q) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsigned::divideWithRemainder: Cannot write quotient and remainder into the same variable"; +#endif /* Now *this and q are separate, so the only concern is that b might be * aliased to one of them. If so, use a temporary copy of b. */ if (this == &b || &q == &b) { @@ -596,8 +614,12 @@ void BigUnsigned::bitShiftLeft(const BigUnsigned &a, int b) { DTRT_ALIASED(this == &a, bitShiftLeft(a, b)); if (b < 0) { if (b << 1 == 0) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsigned::bitShiftLeft: " "Pathological shift amount not implemented"; +#endif else { bitShiftRight(a, -b); return; @@ -622,8 +644,12 @@ void BigUnsigned::bitShiftRight(const BigUnsigned &a, int b) { DTRT_ALIASED(this == &a, bitShiftRight(a, b)); if (b < 0) { if (b << 1 == 0) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsigned::bitShiftRight: " "Pathological shift amount not implemented"; +#endif else { bitShiftLeft(a, -b); return; @@ -679,7 +705,11 @@ void BigUnsigned::operator ++(int) { // Prefix decrement void BigUnsigned::operator --() { if (len == 0) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsigned::operator --(): Cannot decrement an unsigned zero"; +#endif Index i; bool borrow = true; for (i = 0; borrow; i++) { diff --git a/third_party/bigint/BigUnsigned.hh b/third_party/bigint/BigUnsigned.hh index adf1c00bc3..ee40522c54 100644 --- a/third_party/bigint/BigUnsigned.hh +++ b/third_party/bigint/BigUnsigned.hh @@ -1,3 +1,9 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code by Matt McCutchen, see the LICENSE file. + #ifndef BIGUNSIGNED_H #define BIGUNSIGNED_H @@ -84,8 +90,8 @@ public: // BIT/BLOCK ACCESSORS // Expose these from NumberlikeArray directly. - NumberlikeArray::getCapacity; - NumberlikeArray::getLength; + using NumberlikeArray::getCapacity; + using NumberlikeArray::getLength; /* Returns the requested block, or 0 if it is beyond the length (as if * the number had 0s infinitely to the left). */ @@ -260,14 +266,24 @@ inline BigUnsigned BigUnsigned::operator *(const BigUnsigned &x) const { return ans; } inline BigUnsigned BigUnsigned::operator /(const BigUnsigned &x) const { - if (x.isZero()) throw "BigUnsigned::operator /: division by zero"; + if (x.isZero()) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else + throw "BigUnsigned::operator /: division by zero"; +#endif BigUnsigned q, r; r = *this; r.divideWithRemainder(x, q); return q; } inline BigUnsigned BigUnsigned::operator %(const BigUnsigned &x) const { - if (x.isZero()) throw "BigUnsigned::operator %: division by zero"; + if (x.isZero()) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else + throw "BigUnsigned::operator %: division by zero"; +#endif BigUnsigned q, r; r = *this; r.divideWithRemainder(x, q); @@ -309,7 +325,12 @@ inline void BigUnsigned::operator *=(const BigUnsigned &x) { multiply(*this, x); } inline void BigUnsigned::operator /=(const BigUnsigned &x) { - if (x.isZero()) throw "BigUnsigned::operator /=: division by zero"; + if (x.isZero()) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else + throw "BigUnsigned::operator /=: division by zero"; +#endif /* The following technique is slightly faster than copying *this first * when x is large. */ BigUnsigned q; @@ -318,7 +339,12 @@ inline void BigUnsigned::operator /=(const BigUnsigned &x) { *this = q; } inline void BigUnsigned::operator %=(const BigUnsigned &x) { - if (x.isZero()) throw "BigUnsigned::operator %=: division by zero"; + if (x.isZero()) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else + throw "BigUnsigned::operator %=: division by zero"; +#endif BigUnsigned q; // Mods *this by x. Don't care about quotient left in q. divideWithRemainder(x, q); @@ -372,8 +398,12 @@ void BigUnsigned::initFromPrimitive(X x) { template void BigUnsigned::initFromSignedPrimitive(X x) { if (x < 0) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsigned constructor: " "Cannot construct a BigUnsigned from a negative number"; +#endif else initFromPrimitive(x); } @@ -397,8 +427,12 @@ X BigUnsigned::convertToPrimitive() const { return x; // Otherwise fall through. } +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsigned::to: " "Value is too big to fit in the requested type"; +#endif } /* Wrap the above in an x >= 0 test to make sure we got a nonnegative result, @@ -411,8 +445,12 @@ X BigUnsigned::convertToSignedPrimitive() const { if (x >= 0) return x; else +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsigned::to(Primitive): " "Value is too big to fit in the requested type"; +#endif } #endif diff --git a/third_party/bigint/BigUnsignedInABase.cc b/third_party/bigint/BigUnsignedInABase.cc index 999faaf2db..a24042d538 100644 --- a/third_party/bigint/BigUnsignedInABase.cc +++ b/third_party/bigint/BigUnsignedInABase.cc @@ -1,15 +1,29 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code by Matt McCutchen, see the LICENSE file. + #include "BigUnsignedInABase.hh" BigUnsignedInABase::BigUnsignedInABase(const Digit *d, Index l, Base base) : NumberlikeArray(d, l), base(base) { // Check the base if (base < 2) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsignedInABase::BigUnsignedInABase(const Digit *, Index, Base): The base must be at least 2"; +#endif // Validate the digits. for (Index i = 0; i < l; i++) if (blk[i] >= base) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsignedInABase::BigUnsignedInABase(const Digit *, Index, Base): A digit is too large for the specified base"; +#endif // Eliminate any leading zeros we may have been passed. zapLeadingZeros(); @@ -32,7 +46,11 @@ namespace { BigUnsignedInABase::BigUnsignedInABase(const BigUnsigned &x, Base base) { // Check the base if (base < 2) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsignedInABase(BigUnsigned, Base): The base must be at least 2"; +#endif this->base = base; // Get an upper bound on how much space we need @@ -73,7 +91,11 @@ BigUnsignedInABase::operator BigUnsigned() const { BigUnsignedInABase::BigUnsignedInABase(const std::string &s, Base base) { // Check the base. if (base > 36) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsignedInABase(std::string, Base): The default string conversion routines use the symbol set 0-9, A-Z and therefore support only up to base 36. You tried a conversion with a base over 36; write your own string conversion routine."; +#endif // Save the base. // This pattern is seldom seen in C++, but the analogous ``this.'' is common in Java. this->base = base; @@ -94,17 +116,29 @@ BigUnsignedInABase::BigUnsignedInABase(const std::string &s, Base base) { else if (theSymbol >= 'a' && theSymbol <= 'z') blk[digitNum] = theSymbol - 'a' + 10; else +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsignedInABase(std::string, Base): Bad symbol in input. Only 0-9, A-Z, a-z are accepted."; +#endif if (blk[digitNum] >= base) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsignedInABase::BigUnsignedInABase(const Digit *, Index, Base): A digit is too large for the specified base"; +#endif } zapLeadingZeros(); } BigUnsignedInABase::operator std::string() const { if (base > 36) +#ifdef FOXIT_CHROME_BUILD + abort(); +#else throw "BigUnsignedInABase ==> std::string: The default string conversion routines use the symbol set 0-9, A-Z and therefore support only up to base 36. You tried a conversion with a base over 36; write your own string conversion routine."; +#endif if (len == 0) return std::string("0"); // Some compilers don't have push_back, so use a char * buffer instead. diff --git a/third_party/bigint/BigUnsignedInABase.hh b/third_party/bigint/BigUnsignedInABase.hh index 8f9bdcecfd..dbd2cf904c 100644 --- a/third_party/bigint/BigUnsignedInABase.hh +++ b/third_party/bigint/BigUnsignedInABase.hh @@ -1,3 +1,9 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code by Matt McCutchen, see the LICENSE file. + #ifndef BIGUNSIGNEDINABASE_H #define BIGUNSIGNEDINABASE_H @@ -100,8 +106,8 @@ public: Base getBase() const { return base; } // Expose these from NumberlikeArray directly. - NumberlikeArray::getCapacity; - NumberlikeArray::getLength; + using NumberlikeArray::getCapacity; + using NumberlikeArray::getLength; /* Returns the requested digit, or 0 if it is beyond the length (as if * the number had 0s infinitely to the left). */ diff --git a/third_party/bigint/NumberlikeArray.hh b/third_party/bigint/NumberlikeArray.hh index 53c8e5be8f..f7917809f4 100644 --- a/third_party/bigint/NumberlikeArray.hh +++ b/third_party/bigint/NumberlikeArray.hh @@ -1,6 +1,13 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code by Matt McCutchen, see the LICENSE file. + #ifndef NUMBERLIKEARRAY_H #define NUMBERLIKEARRAY_H +#include // abort() // Make sure we have NULL. #ifndef NULL #define NULL 0 -- cgit v1.2.3