diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2018-05-03 05:55:15 +0200 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-05-03 05:55:15 +0200 |
commit | 43f7a588f96aaf88e7b69441c3b50bc9c7b20df7 (patch) | |
tree | 07d9b26b2f357ee9de04fea0e5e4b8b9a1ff93a4 /security/sandbox/chromium/base/numerics | |
parent | 4613b91ecac2745252c40be64e73de5ff920b02b (diff) | |
download | UXP-43f7a588f96aaf88e7b69441c3b50bc9c7b20df7.tar UXP-43f7a588f96aaf88e7b69441c3b50bc9c7b20df7.tar.gz UXP-43f7a588f96aaf88e7b69441c3b50bc9c7b20df7.tar.lz UXP-43f7a588f96aaf88e7b69441c3b50bc9c7b20df7.tar.xz UXP-43f7a588f96aaf88e7b69441c3b50bc9c7b20df7.zip |
Nuke the sandbox
Diffstat (limited to 'security/sandbox/chromium/base/numerics')
4 files changed, 0 insertions, 1273 deletions
diff --git a/security/sandbox/chromium/base/numerics/safe_conversions.h b/security/sandbox/chromium/base/numerics/safe_conversions.h deleted file mode 100644 index baac188fd..000000000 --- a/security/sandbox/chromium/base/numerics/safe_conversions.h +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_NUMERICS_SAFE_CONVERSIONS_H_ -#define BASE_NUMERICS_SAFE_CONVERSIONS_H_ - -#include <stddef.h> - -#include <limits> -#include <type_traits> - -#include "base/logging.h" -#include "base/numerics/safe_conversions_impl.h" - -namespace base { - -// Convenience function that returns true if the supplied value is in range -// for the destination type. -template <typename Dst, typename Src> -inline bool IsValueInRangeForNumericType(Src value) { - return internal::DstRangeRelationToSrcRange<Dst>(value) == - internal::RANGE_VALID; -} - -// Convenience function for determining if a numeric value is negative without -// throwing compiler warnings on: unsigned(value) < 0. -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type -IsValueNegative(T value) { - static_assert(std::numeric_limits<T>::is_specialized, - "Argument must be numeric."); - return value < 0; -} - -template <typename T> -typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type - IsValueNegative(T) { - static_assert(std::numeric_limits<T>::is_specialized, - "Argument must be numeric."); - return false; -} - -// checked_cast<> is analogous to static_cast<> for numeric types, -// except that it CHECKs that the specified numeric conversion will not -// overflow or underflow. NaN source will always trigger a CHECK. -template <typename Dst, typename Src> -inline Dst checked_cast(Src value) { - CHECK(IsValueInRangeForNumericType<Dst>(value)); - return static_cast<Dst>(value); -} - -// HandleNaN will cause this class to CHECK(false). -struct SaturatedCastNaNBehaviorCheck { - template <typename T> - static T HandleNaN() { - CHECK(false); - return T(); - } -}; - -// HandleNaN will return 0 in this case. -struct SaturatedCastNaNBehaviorReturnZero { - template <typename T> - static T HandleNaN() { - return T(); - } -}; - -// saturated_cast<> is analogous to static_cast<> for numeric types, except -// that the specified numeric conversion will saturate rather than overflow or -// underflow. NaN assignment to an integral will defer the behavior to a -// specified class. By default, it will return 0. -template <typename Dst, - class NaNHandler = SaturatedCastNaNBehaviorReturnZero, - typename Src> -inline Dst saturated_cast(Src value) { - // Optimization for floating point values, which already saturate. - if (std::numeric_limits<Dst>::is_iec559) - return static_cast<Dst>(value); - - switch (internal::DstRangeRelationToSrcRange<Dst>(value)) { - case internal::RANGE_VALID: - return static_cast<Dst>(value); - - case internal::RANGE_UNDERFLOW: - return std::numeric_limits<Dst>::min(); - - case internal::RANGE_OVERFLOW: - return std::numeric_limits<Dst>::max(); - - // Should fail only on attempting to assign NaN to a saturated integer. - case internal::RANGE_INVALID: - return NaNHandler::template HandleNaN<Dst>(); - } - - NOTREACHED(); - return static_cast<Dst>(value); -} - -// strict_cast<> is analogous to static_cast<> for numeric types, except that -// it will cause a compile failure if the destination type is not large enough -// to contain any value in the source type. It performs no runtime checking. -template <typename Dst, typename Src> -inline Dst strict_cast(Src value) { - static_assert(std::numeric_limits<Src>::is_specialized, - "Argument must be numeric."); - static_assert(std::numeric_limits<Dst>::is_specialized, - "Result must be numeric."); - static_assert((internal::StaticDstRangeRelationToSrcRange<Dst, Src>::value == - internal::NUMERIC_RANGE_CONTAINED), - "The numeric conversion is out of range for this type. You " - "should probably use one of the following conversion " - "mechanisms on the value you want to pass:\n" - "- base::checked_cast\n" - "- base::saturated_cast\n" - "- base::CheckedNumeric"); - - return static_cast<Dst>(value); -} - -// StrictNumeric implements compile time range checking between numeric types by -// wrapping assignment operations in a strict_cast. This class is intended to be -// used for function arguments and return types, to ensure the destination type -// can always contain the source type. This is essentially the same as enforcing -// -Wconversion in gcc and C4302 warnings on MSVC, but it can be applied -// incrementally at API boundaries, making it easier to convert code so that it -// compiles cleanly with truncation warnings enabled. -// This template should introduce no runtime overhead, but it also provides no -// runtime checking of any of the associated mathematical operations. Use -// CheckedNumeric for runtime range checks of tha actual value being assigned. -template <typename T> -class StrictNumeric { - public: - typedef T type; - - StrictNumeric() : value_(0) {} - - // Copy constructor. - template <typename Src> - StrictNumeric(const StrictNumeric<Src>& rhs) - : value_(strict_cast<T>(rhs.value_)) {} - - // This is not an explicit constructor because we implicitly upgrade regular - // numerics to StrictNumerics to make them easier to use. - template <typename Src> - StrictNumeric(Src value) - : value_(strict_cast<T>(value)) {} - - // The numeric cast operator basically handles all the magic. - template <typename Dst> - operator Dst() const { - return strict_cast<Dst>(value_); - } - - private: - T value_; -}; - -// Explicitly make a shorter size_t typedef for convenience. -typedef StrictNumeric<size_t> SizeT; - -} // namespace base - -#endif // BASE_NUMERICS_SAFE_CONVERSIONS_H_ diff --git a/security/sandbox/chromium/base/numerics/safe_conversions_impl.h b/security/sandbox/chromium/base/numerics/safe_conversions_impl.h deleted file mode 100644 index 02e68e25d..000000000 --- a/security/sandbox/chromium/base/numerics/safe_conversions_impl.h +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ -#define BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ - -#include <limits.h> -#include <stdint.h> - -#include <limits> - -#include "base/template_util.h" - -namespace base { -namespace internal { - -// The std library doesn't provide a binary max_exponent for integers, however -// we can compute one by adding one to the number of non-sign bits. This allows -// for accurate range comparisons between floating point and integer types. -template <typename NumericType> -struct MaxExponent { - static const int value = std::numeric_limits<NumericType>::is_iec559 - ? std::numeric_limits<NumericType>::max_exponent - : (sizeof(NumericType) * 8 + 1 - - std::numeric_limits<NumericType>::is_signed); -}; - -enum IntegerRepresentation { - INTEGER_REPRESENTATION_UNSIGNED, - INTEGER_REPRESENTATION_SIGNED -}; - -// A range for a given nunmeric Src type is contained for a given numeric Dst -// type if both numeric_limits<Src>::max() <= numeric_limits<Dst>::max() and -// numeric_limits<Src>::min() >= numeric_limits<Dst>::min() are true. -// We implement this as template specializations rather than simple static -// comparisons to ensure type correctness in our comparisons. -enum NumericRangeRepresentation { - NUMERIC_RANGE_NOT_CONTAINED, - NUMERIC_RANGE_CONTAINED -}; - -// Helper templates to statically determine if our destination type can contain -// maximum and minimum values represented by the source type. - -template < - typename Dst, - typename Src, - IntegerRepresentation DstSign = std::numeric_limits<Dst>::is_signed - ? INTEGER_REPRESENTATION_SIGNED - : INTEGER_REPRESENTATION_UNSIGNED, - IntegerRepresentation SrcSign = - std::numeric_limits<Src>::is_signed - ? INTEGER_REPRESENTATION_SIGNED - : INTEGER_REPRESENTATION_UNSIGNED > -struct StaticDstRangeRelationToSrcRange; - -// Same sign: Dst is guaranteed to contain Src only if its range is equal or -// larger. -template <typename Dst, typename Src, IntegerRepresentation Sign> -struct StaticDstRangeRelationToSrcRange<Dst, Src, Sign, Sign> { - static const NumericRangeRepresentation value = - MaxExponent<Dst>::value >= MaxExponent<Src>::value - ? NUMERIC_RANGE_CONTAINED - : NUMERIC_RANGE_NOT_CONTAINED; -}; - -// Unsigned to signed: Dst is guaranteed to contain source only if its range is -// larger. -template <typename Dst, typename Src> -struct StaticDstRangeRelationToSrcRange<Dst, - Src, - INTEGER_REPRESENTATION_SIGNED, - INTEGER_REPRESENTATION_UNSIGNED> { - static const NumericRangeRepresentation value = - MaxExponent<Dst>::value > MaxExponent<Src>::value - ? NUMERIC_RANGE_CONTAINED - : NUMERIC_RANGE_NOT_CONTAINED; -}; - -// Signed to unsigned: Dst cannot be statically determined to contain Src. -template <typename Dst, typename Src> -struct StaticDstRangeRelationToSrcRange<Dst, - Src, - INTEGER_REPRESENTATION_UNSIGNED, - INTEGER_REPRESENTATION_SIGNED> { - static const NumericRangeRepresentation value = NUMERIC_RANGE_NOT_CONTAINED; -}; - -enum RangeConstraint { - RANGE_VALID = 0x0, // Value can be represented by the destination type. - RANGE_UNDERFLOW = 0x1, // Value would overflow. - RANGE_OVERFLOW = 0x2, // Value would underflow. - RANGE_INVALID = RANGE_UNDERFLOW | RANGE_OVERFLOW // Invalid (i.e. NaN). -}; - -// Helper function for coercing an int back to a RangeContraint. -inline RangeConstraint GetRangeConstraint(int integer_range_constraint) { - DCHECK(integer_range_constraint >= RANGE_VALID && - integer_range_constraint <= RANGE_INVALID); - return static_cast<RangeConstraint>(integer_range_constraint); -} - -// This function creates a RangeConstraint from an upper and lower bound -// check by taking advantage of the fact that only NaN can be out of range in -// both directions at once. -inline RangeConstraint GetRangeConstraint(bool is_in_upper_bound, - bool is_in_lower_bound) { - return GetRangeConstraint((is_in_upper_bound ? 0 : RANGE_OVERFLOW) | - (is_in_lower_bound ? 0 : RANGE_UNDERFLOW)); -} - -// The following helper template addresses a corner case in range checks for -// conversion from a floating-point type to an integral type of smaller range -// but larger precision (e.g. float -> unsigned). The problem is as follows: -// 1. Integral maximum is always one less than a power of two, so it must be -// truncated to fit the mantissa of the floating point. The direction of -// rounding is implementation defined, but by default it's always IEEE -// floats, which round to nearest and thus result in a value of larger -// magnitude than the integral value. -// Example: float f = UINT_MAX; // f is 4294967296f but UINT_MAX -// // is 4294967295u. -// 2. If the floating point value is equal to the promoted integral maximum -// value, a range check will erroneously pass. -// Example: (4294967296f <= 4294967295u) // This is true due to a precision -// // loss in rounding up to float. -// 3. When the floating point value is then converted to an integral, the -// resulting value is out of range for the target integral type and -// thus is implementation defined. -// Example: unsigned u = (float)INT_MAX; // u will typically overflow to 0. -// To fix this bug we manually truncate the maximum value when the destination -// type is an integral of larger precision than the source floating-point type, -// such that the resulting maximum is represented exactly as a floating point. -template <typename Dst, typename Src> -struct NarrowingRange { - typedef typename std::numeric_limits<Src> SrcLimits; - typedef typename std::numeric_limits<Dst> DstLimits; - - static Dst max() { - // The following logic avoids warnings where the max function is - // instantiated with invalid values for a bit shift (even though - // such a function can never be called). - static const int shift = - (MaxExponent<Src>::value > MaxExponent<Dst>::value && - SrcLimits::digits < DstLimits::digits && SrcLimits::is_iec559 && - DstLimits::is_integer) - ? (DstLimits::digits - SrcLimits::digits) - : 0; - - // We use UINTMAX_C below to avoid compiler warnings about shifting floating - // points. Since it's a compile time calculation, it shouldn't have any - // performance impact. - return DstLimits::max() - static_cast<Dst>((UINTMAX_C(1) << shift) - 1); - } - - static Dst min() { - return std::numeric_limits<Dst>::is_iec559 ? -DstLimits::max() - : DstLimits::min(); - } -}; - -template < - typename Dst, - typename Src, - IntegerRepresentation DstSign = std::numeric_limits<Dst>::is_signed - ? INTEGER_REPRESENTATION_SIGNED - : INTEGER_REPRESENTATION_UNSIGNED, - IntegerRepresentation SrcSign = std::numeric_limits<Src>::is_signed - ? INTEGER_REPRESENTATION_SIGNED - : INTEGER_REPRESENTATION_UNSIGNED, - NumericRangeRepresentation DstRange = - StaticDstRangeRelationToSrcRange<Dst, Src>::value > -struct DstRangeRelationToSrcRangeImpl; - -// The following templates are for ranges that must be verified at runtime. We -// split it into checks based on signedness to avoid confusing casts and -// compiler warnings on signed an unsigned comparisons. - -// Dst range is statically determined to contain Src: Nothing to check. -template <typename Dst, - typename Src, - IntegerRepresentation DstSign, - IntegerRepresentation SrcSign> -struct DstRangeRelationToSrcRangeImpl<Dst, - Src, - DstSign, - SrcSign, - NUMERIC_RANGE_CONTAINED> { - static RangeConstraint Check(Src value) { return RANGE_VALID; } -}; - -// Signed to signed narrowing: Both the upper and lower boundaries may be -// exceeded. -template <typename Dst, typename Src> -struct DstRangeRelationToSrcRangeImpl<Dst, - Src, - INTEGER_REPRESENTATION_SIGNED, - INTEGER_REPRESENTATION_SIGNED, - NUMERIC_RANGE_NOT_CONTAINED> { - static RangeConstraint Check(Src value) { - return GetRangeConstraint((value <= NarrowingRange<Dst, Src>::max()), - (value >= NarrowingRange<Dst, Src>::min())); - } -}; - -// Unsigned to unsigned narrowing: Only the upper boundary can be exceeded. -template <typename Dst, typename Src> -struct DstRangeRelationToSrcRangeImpl<Dst, - Src, - INTEGER_REPRESENTATION_UNSIGNED, - INTEGER_REPRESENTATION_UNSIGNED, - NUMERIC_RANGE_NOT_CONTAINED> { - static RangeConstraint Check(Src value) { - return GetRangeConstraint(value <= NarrowingRange<Dst, Src>::max(), true); - } -}; - -// Unsigned to signed: The upper boundary may be exceeded. -template <typename Dst, typename Src> -struct DstRangeRelationToSrcRangeImpl<Dst, - Src, - INTEGER_REPRESENTATION_SIGNED, - INTEGER_REPRESENTATION_UNSIGNED, - NUMERIC_RANGE_NOT_CONTAINED> { - static RangeConstraint Check(Src value) { - return sizeof(Dst) > sizeof(Src) - ? RANGE_VALID - : GetRangeConstraint( - value <= static_cast<Src>(NarrowingRange<Dst, Src>::max()), - true); - } -}; - -// Signed to unsigned: The upper boundary may be exceeded for a narrower Dst, -// and any negative value exceeds the lower boundary. -template <typename Dst, typename Src> -struct DstRangeRelationToSrcRangeImpl<Dst, - Src, - INTEGER_REPRESENTATION_UNSIGNED, - INTEGER_REPRESENTATION_SIGNED, - NUMERIC_RANGE_NOT_CONTAINED> { - static RangeConstraint Check(Src value) { - return (MaxExponent<Dst>::value >= MaxExponent<Src>::value) - ? GetRangeConstraint(true, value >= static_cast<Src>(0)) - : GetRangeConstraint( - value <= static_cast<Src>(NarrowingRange<Dst, Src>::max()), - value >= static_cast<Src>(0)); - } -}; - -template <typename Dst, typename Src> -inline RangeConstraint DstRangeRelationToSrcRange(Src value) { - static_assert(std::numeric_limits<Src>::is_specialized, - "Argument must be numeric."); - static_assert(std::numeric_limits<Dst>::is_specialized, - "Result must be numeric."); - return DstRangeRelationToSrcRangeImpl<Dst, Src>::Check(value); -} - -} // namespace internal -} // namespace base - -#endif // BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ diff --git a/security/sandbox/chromium/base/numerics/safe_math.h b/security/sandbox/chromium/base/numerics/safe_math.h deleted file mode 100644 index d169690a8..000000000 --- a/security/sandbox/chromium/base/numerics/safe_math.h +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_NUMERICS_SAFE_MATH_H_ -#define BASE_NUMERICS_SAFE_MATH_H_ - -#include <stddef.h> - -#include "base/numerics/safe_math_impl.h" - -namespace base { - -namespace internal { - -// CheckedNumeric implements all the logic and operators for detecting integer -// boundary conditions such as overflow, underflow, and invalid conversions. -// The CheckedNumeric type implicitly converts from floating point and integer -// data types, and contains overloads for basic arithmetic operations (i.e.: +, -// -, *, /, %). -// -// The following methods convert from CheckedNumeric to standard numeric values: -// IsValid() - Returns true if the underlying numeric value is valid (i.e. has -// has not wrapped and is not the result of an invalid conversion). -// ValueOrDie() - Returns the underlying value. If the state is not valid this -// call will crash on a CHECK. -// ValueOrDefault() - Returns the current value, or the supplied default if the -// state is not valid. -// ValueFloating() - Returns the underlying floating point value (valid only -// only for floating point CheckedNumeric types). -// -// Bitwise operations are explicitly not supported, because correct -// handling of some cases (e.g. sign manipulation) is ambiguous. Comparison -// operations are explicitly not supported because they could result in a crash -// on a CHECK condition. You should use patterns like the following for these -// operations: -// Bitwise operation: -// CheckedNumeric<int> checked_int = untrusted_input_value; -// int x = checked_int.ValueOrDefault(0) | kFlagValues; -// Comparison: -// CheckedNumeric<size_t> checked_size = untrusted_input_value; -// checked_size += HEADER LENGTH; -// if (checked_size.IsValid() && checked_size.ValueOrDie() < buffer_size) -// Do stuff... -template <typename T> -class CheckedNumeric { - public: - typedef T type; - - CheckedNumeric() {} - - // Copy constructor. - template <typename Src> - CheckedNumeric(const CheckedNumeric<Src>& rhs) - : state_(rhs.ValueUnsafe(), rhs.validity()) {} - - template <typename Src> - CheckedNumeric(Src value, RangeConstraint validity) - : state_(value, validity) {} - - // This is not an explicit constructor because we implicitly upgrade regular - // numerics to CheckedNumerics to make them easier to use. - template <typename Src> - CheckedNumeric(Src value) - : state_(value) { - static_assert(std::numeric_limits<Src>::is_specialized, - "Argument must be numeric."); - } - - // This is not an explicit constructor because we want a seamless conversion - // from StrictNumeric types. - template <typename Src> - CheckedNumeric(StrictNumeric<Src> value) - : state_(static_cast<Src>(value)) { - } - - // IsValid() is the public API to test if a CheckedNumeric is currently valid. - bool IsValid() const { return validity() == RANGE_VALID; } - - // ValueOrDie() The primary accessor for the underlying value. If the current - // state is not valid it will CHECK and crash. - T ValueOrDie() const { - CHECK(IsValid()); - return state_.value(); - } - - // ValueOrDefault(T default_value) A convenience method that returns the - // current value if the state is valid, and the supplied default_value for - // any other state. - T ValueOrDefault(T default_value) const { - return IsValid() ? state_.value() : default_value; - } - - // ValueFloating() - Since floating point values include their validity state, - // we provide an easy method for extracting them directly, without a risk of - // crashing on a CHECK. - T ValueFloating() const { - static_assert(std::numeric_limits<T>::is_iec559, "Argument must be float."); - return CheckedNumeric<T>::cast(*this).ValueUnsafe(); - } - - // validity() - DO NOT USE THIS IN EXTERNAL CODE - It is public right now for - // tests and to avoid a big matrix of friend operator overloads. But the - // values it returns are likely to change in the future. - // Returns: current validity state (i.e. valid, overflow, underflow, nan). - // TODO(jschuh): crbug.com/332611 Figure out and implement semantics for - // saturation/wrapping so we can expose this state consistently and implement - // saturated arithmetic. - RangeConstraint validity() const { return state_.validity(); } - - // ValueUnsafe() - DO NOT USE THIS IN EXTERNAL CODE - It is public right now - // for tests and to avoid a big matrix of friend operator overloads. But the - // values it returns are likely to change in the future. - // Returns: the raw numeric value, regardless of the current state. - // TODO(jschuh): crbug.com/332611 Figure out and implement semantics for - // saturation/wrapping so we can expose this state consistently and implement - // saturated arithmetic. - T ValueUnsafe() const { return state_.value(); } - - // Prototypes for the supported arithmetic operator overloads. - template <typename Src> CheckedNumeric& operator+=(Src rhs); - template <typename Src> CheckedNumeric& operator-=(Src rhs); - template <typename Src> CheckedNumeric& operator*=(Src rhs); - template <typename Src> CheckedNumeric& operator/=(Src rhs); - template <typename Src> CheckedNumeric& operator%=(Src rhs); - - CheckedNumeric operator-() const { - RangeConstraint validity; - T value = CheckedNeg(state_.value(), &validity); - // Negation is always valid for floating point. - if (std::numeric_limits<T>::is_iec559) - return CheckedNumeric<T>(value); - - validity = GetRangeConstraint(state_.validity() | validity); - return CheckedNumeric<T>(value, validity); - } - - CheckedNumeric Abs() const { - RangeConstraint validity; - T value = CheckedAbs(state_.value(), &validity); - // Absolute value is always valid for floating point. - if (std::numeric_limits<T>::is_iec559) - return CheckedNumeric<T>(value); - - validity = GetRangeConstraint(state_.validity() | validity); - return CheckedNumeric<T>(value, validity); - } - - // This function is available only for integral types. It returns an unsigned - // integer of the same width as the source type, containing the absolute value - // of the source, and properly handling signed min. - CheckedNumeric<typename UnsignedOrFloatForSize<T>::type> UnsignedAbs() const { - return CheckedNumeric<typename UnsignedOrFloatForSize<T>::type>( - CheckedUnsignedAbs(state_.value()), state_.validity()); - } - - CheckedNumeric& operator++() { - *this += 1; - return *this; - } - - CheckedNumeric operator++(int) { - CheckedNumeric value = *this; - *this += 1; - return value; - } - - CheckedNumeric& operator--() { - *this -= 1; - return *this; - } - - CheckedNumeric operator--(int) { - CheckedNumeric value = *this; - *this -= 1; - return value; - } - - // These static methods behave like a convenience cast operator targeting - // the desired CheckedNumeric type. As an optimization, a reference is - // returned when Src is the same type as T. - template <typename Src> - static CheckedNumeric<T> cast( - Src u, - typename std::enable_if<std::numeric_limits<Src>::is_specialized, - int>::type = 0) { - return u; - } - - template <typename Src> - static CheckedNumeric<T> cast( - const CheckedNumeric<Src>& u, - typename std::enable_if<!is_same<Src, T>::value, int>::type = 0) { - return u; - } - - static const CheckedNumeric<T>& cast(const CheckedNumeric<T>& u) { return u; } - - private: - template <typename NumericType> - struct UnderlyingType { - using type = NumericType; - }; - - template <typename NumericType> - struct UnderlyingType<CheckedNumeric<NumericType>> { - using type = NumericType; - }; - - CheckedNumericState<T> state_; -}; - -// This is the boilerplate for the standard arithmetic operator overloads. A -// macro isn't the prettiest solution, but it beats rewriting these five times. -// Some details worth noting are: -// * We apply the standard arithmetic promotions. -// * We skip range checks for floating points. -// * We skip range checks for destination integers with sufficient range. -// TODO(jschuh): extract these out into templates. -#define BASE_NUMERIC_ARITHMETIC_OPERATORS(NAME, OP, COMPOUND_OP) \ - /* Binary arithmetic operator for CheckedNumerics of the same type. */ \ - template <typename T> \ - CheckedNumeric<typename ArithmeticPromotion<T>::type> operator OP( \ - const CheckedNumeric<T>& lhs, const CheckedNumeric<T>& rhs) { \ - typedef typename ArithmeticPromotion<T>::type Promotion; \ - /* Floating point always takes the fast path */ \ - if (std::numeric_limits<T>::is_iec559) \ - return CheckedNumeric<T>(lhs.ValueUnsafe() OP rhs.ValueUnsafe()); \ - if (IsIntegerArithmeticSafe<Promotion, T, T>::value) \ - return CheckedNumeric<Promotion>( \ - lhs.ValueUnsafe() OP rhs.ValueUnsafe(), \ - GetRangeConstraint(rhs.validity() | lhs.validity())); \ - RangeConstraint validity = RANGE_VALID; \ - T result = static_cast<T>(Checked##NAME( \ - static_cast<Promotion>(lhs.ValueUnsafe()), \ - static_cast<Promotion>(rhs.ValueUnsafe()), \ - &validity)); \ - return CheckedNumeric<Promotion>( \ - result, \ - GetRangeConstraint(validity | lhs.validity() | rhs.validity())); \ - } \ - /* Assignment arithmetic operator implementation from CheckedNumeric. */ \ - template <typename T> \ - template <typename Src> \ - CheckedNumeric<T>& CheckedNumeric<T>::operator COMPOUND_OP(Src rhs) { \ - *this = CheckedNumeric<T>::cast(*this) \ - OP CheckedNumeric<typename UnderlyingType<Src>::type>::cast(rhs); \ - return *this; \ - } \ - /* Binary arithmetic operator for CheckedNumeric of different type. */ \ - template <typename T, typename Src> \ - CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \ - const CheckedNumeric<Src>& lhs, const CheckedNumeric<T>& rhs) { \ - typedef typename ArithmeticPromotion<T, Src>::type Promotion; \ - if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \ - return CheckedNumeric<Promotion>( \ - lhs.ValueUnsafe() OP rhs.ValueUnsafe(), \ - GetRangeConstraint(rhs.validity() | lhs.validity())); \ - return CheckedNumeric<Promotion>::cast(lhs) \ - OP CheckedNumeric<Promotion>::cast(rhs); \ - } \ - /* Binary arithmetic operator for left CheckedNumeric and right numeric. */ \ - template <typename T, typename Src> \ - CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \ - const CheckedNumeric<T>& lhs, Src rhs) { \ - typedef typename ArithmeticPromotion<T, Src>::type Promotion; \ - if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \ - return CheckedNumeric<Promotion>(lhs.ValueUnsafe() OP rhs, \ - lhs.validity()); \ - return CheckedNumeric<Promotion>::cast(lhs) \ - OP CheckedNumeric<Promotion>::cast(rhs); \ - } \ - /* Binary arithmetic operator for right numeric and left CheckedNumeric. */ \ - template <typename T, typename Src> \ - CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \ - Src lhs, const CheckedNumeric<T>& rhs) { \ - typedef typename ArithmeticPromotion<T, Src>::type Promotion; \ - if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \ - return CheckedNumeric<Promotion>(lhs OP rhs.ValueUnsafe(), \ - rhs.validity()); \ - return CheckedNumeric<Promotion>::cast(lhs) \ - OP CheckedNumeric<Promotion>::cast(rhs); \ - } - -BASE_NUMERIC_ARITHMETIC_OPERATORS(Add, +, += ) -BASE_NUMERIC_ARITHMETIC_OPERATORS(Sub, -, -= ) -BASE_NUMERIC_ARITHMETIC_OPERATORS(Mul, *, *= ) -BASE_NUMERIC_ARITHMETIC_OPERATORS(Div, /, /= ) -BASE_NUMERIC_ARITHMETIC_OPERATORS(Mod, %, %= ) - -#undef BASE_NUMERIC_ARITHMETIC_OPERATORS - -} // namespace internal - -using internal::CheckedNumeric; - -} // namespace base - -#endif // BASE_NUMERICS_SAFE_MATH_H_ diff --git a/security/sandbox/chromium/base/numerics/safe_math_impl.h b/security/sandbox/chromium/base/numerics/safe_math_impl.h deleted file mode 100644 index 4fbcc045b..000000000 --- a/security/sandbox/chromium/base/numerics/safe_math_impl.h +++ /dev/null @@ -1,545 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_NUMERICS_SAFE_MATH_IMPL_H_ -#define BASE_NUMERICS_SAFE_MATH_IMPL_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <cmath> -#include <cstdlib> -#include <limits> -#include <type_traits> - -#include "base/numerics/safe_conversions.h" -#include "base/template_util.h" - -namespace base { -namespace internal { - -// Everything from here up to the floating point operations is portable C++, -// but it may not be fast. This code could be split based on -// platform/architecture and replaced with potentially faster implementations. - -// Integer promotion templates used by the portable checked integer arithmetic. -template <size_t Size, bool IsSigned> -struct IntegerForSizeAndSign; -template <> -struct IntegerForSizeAndSign<1, true> { - typedef int8_t type; -}; -template <> -struct IntegerForSizeAndSign<1, false> { - typedef uint8_t type; -}; -template <> -struct IntegerForSizeAndSign<2, true> { - typedef int16_t type; -}; -template <> -struct IntegerForSizeAndSign<2, false> { - typedef uint16_t type; -}; -template <> -struct IntegerForSizeAndSign<4, true> { - typedef int32_t type; -}; -template <> -struct IntegerForSizeAndSign<4, false> { - typedef uint32_t type; -}; -template <> -struct IntegerForSizeAndSign<8, true> { - typedef int64_t type; -}; -template <> -struct IntegerForSizeAndSign<8, false> { - typedef uint64_t type; -}; - -// WARNING: We have no IntegerForSizeAndSign<16, *>. If we ever add one to -// support 128-bit math, then the ArithmeticPromotion template below will need -// to be updated (or more likely replaced with a decltype expression). - -template <typename Integer> -struct UnsignedIntegerForSize { - typedef typename std::enable_if< - std::numeric_limits<Integer>::is_integer, - typename IntegerForSizeAndSign<sizeof(Integer), false>::type>::type type; -}; - -template <typename Integer> -struct SignedIntegerForSize { - typedef typename std::enable_if< - std::numeric_limits<Integer>::is_integer, - typename IntegerForSizeAndSign<sizeof(Integer), true>::type>::type type; -}; - -template <typename Integer> -struct TwiceWiderInteger { - typedef typename std::enable_if< - std::numeric_limits<Integer>::is_integer, - typename IntegerForSizeAndSign< - sizeof(Integer) * 2, - std::numeric_limits<Integer>::is_signed>::type>::type type; -}; - -template <typename Integer> -struct PositionOfSignBit { - static const typename std::enable_if<std::numeric_limits<Integer>::is_integer, - size_t>::type value = - 8 * sizeof(Integer) - 1; -}; - -// This is used for UnsignedAbs, where we need to support floating-point -// template instantiations even though we don't actually support the operations. -// However, there is no corresponding implementation of e.g. CheckedUnsignedAbs, -// so the float versions will not compile. -template <typename Numeric, - bool IsInteger = std::numeric_limits<Numeric>::is_integer, - bool IsFloat = std::numeric_limits<Numeric>::is_iec559> -struct UnsignedOrFloatForSize; - -template <typename Numeric> -struct UnsignedOrFloatForSize<Numeric, true, false> { - typedef typename UnsignedIntegerForSize<Numeric>::type type; -}; - -template <typename Numeric> -struct UnsignedOrFloatForSize<Numeric, false, true> { - typedef Numeric type; -}; - -// Helper templates for integer manipulations. - -template <typename T> -bool HasSignBit(T x) { - // Cast to unsigned since right shift on signed is undefined. - return !!(static_cast<typename UnsignedIntegerForSize<T>::type>(x) >> - PositionOfSignBit<T>::value); -} - -// This wrapper undoes the standard integer promotions. -template <typename T> -T BinaryComplement(T x) { - return ~x; -} - -// Here are the actual portable checked integer math implementations. -// TODO(jschuh): Break this code out from the enable_if pattern and find a clean -// way to coalesce things into the CheckedNumericState specializations below. - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type -CheckedAdd(T x, T y, RangeConstraint* validity) { - // Since the value of x+y is undefined if we have a signed type, we compute - // it using the unsigned type of the same size. - typedef typename UnsignedIntegerForSize<T>::type UnsignedDst; - UnsignedDst ux = static_cast<UnsignedDst>(x); - UnsignedDst uy = static_cast<UnsignedDst>(y); - UnsignedDst uresult = ux + uy; - // Addition is valid if the sign of (x + y) is equal to either that of x or - // that of y. - if (std::numeric_limits<T>::is_signed) { - if (HasSignBit(BinaryComplement((uresult ^ ux) & (uresult ^ uy)))) - *validity = RANGE_VALID; - else // Direction of wrap is inverse of result sign. - *validity = HasSignBit(uresult) ? RANGE_OVERFLOW : RANGE_UNDERFLOW; - - } else { // Unsigned is either valid or overflow. - *validity = BinaryComplement(x) >= y ? RANGE_VALID : RANGE_OVERFLOW; - } - return static_cast<T>(uresult); -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type -CheckedSub(T x, T y, RangeConstraint* validity) { - // Since the value of x+y is undefined if we have a signed type, we compute - // it using the unsigned type of the same size. - typedef typename UnsignedIntegerForSize<T>::type UnsignedDst; - UnsignedDst ux = static_cast<UnsignedDst>(x); - UnsignedDst uy = static_cast<UnsignedDst>(y); - UnsignedDst uresult = ux - uy; - // Subtraction is valid if either x and y have same sign, or (x-y) and x have - // the same sign. - if (std::numeric_limits<T>::is_signed) { - if (HasSignBit(BinaryComplement((uresult ^ ux) & (ux ^ uy)))) - *validity = RANGE_VALID; - else // Direction of wrap is inverse of result sign. - *validity = HasSignBit(uresult) ? RANGE_OVERFLOW : RANGE_UNDERFLOW; - - } else { // Unsigned is either valid or underflow. - *validity = x >= y ? RANGE_VALID : RANGE_UNDERFLOW; - } - return static_cast<T>(uresult); -} - -// Integer multiplication is a bit complicated. In the fast case we just -// we just promote to a twice wider type, and range check the result. In the -// slow case we need to manually check that the result won't be truncated by -// checking with division against the appropriate bound. -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - sizeof(T) * 2 <= sizeof(uintmax_t), - T>::type -CheckedMul(T x, T y, RangeConstraint* validity) { - typedef typename TwiceWiderInteger<T>::type IntermediateType; - IntermediateType tmp = - static_cast<IntermediateType>(x) * static_cast<IntermediateType>(y); - *validity = DstRangeRelationToSrcRange<T>(tmp); - return static_cast<T>(tmp); -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed && - (sizeof(T) * 2 > sizeof(uintmax_t)), - T>::type -CheckedMul(T x, T y, RangeConstraint* validity) { - // If either side is zero then the result will be zero. - if (!x || !y) { - return RANGE_VALID; - - } else if (x > 0) { - if (y > 0) - *validity = - x <= std::numeric_limits<T>::max() / y ? RANGE_VALID : RANGE_OVERFLOW; - else - *validity = y >= std::numeric_limits<T>::min() / x ? RANGE_VALID - : RANGE_UNDERFLOW; - - } else { - if (y > 0) - *validity = x >= std::numeric_limits<T>::min() / y ? RANGE_VALID - : RANGE_UNDERFLOW; - else - *validity = - y >= std::numeric_limits<T>::max() / x ? RANGE_VALID : RANGE_OVERFLOW; - } - - return x * y; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed && - (sizeof(T) * 2 > sizeof(uintmax_t)), - T>::type -CheckedMul(T x, T y, RangeConstraint* validity) { - *validity = (y == 0 || x <= std::numeric_limits<T>::max() / y) - ? RANGE_VALID - : RANGE_OVERFLOW; - return x * y; -} - -// Division just requires a check for an invalid negation on signed min/-1. -template <typename T> -T CheckedDiv(T x, - T y, - RangeConstraint* validity, - typename std::enable_if<std::numeric_limits<T>::is_integer, - int>::type = 0) { - if (std::numeric_limits<T>::is_signed && x == std::numeric_limits<T>::min() && - y == static_cast<T>(-1)) { - *validity = RANGE_OVERFLOW; - return std::numeric_limits<T>::min(); - } - - *validity = RANGE_VALID; - return x / y; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, - T>::type -CheckedMod(T x, T y, RangeConstraint* validity) { - *validity = y > 0 ? RANGE_VALID : RANGE_INVALID; - return x % y; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, - T>::type -CheckedMod(T x, T y, RangeConstraint* validity) { - *validity = RANGE_VALID; - return x % y; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, - T>::type -CheckedNeg(T value, RangeConstraint* validity) { - *validity = - value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW; - // The negation of signed min is min, so catch that one. - return -value; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, - T>::type -CheckedNeg(T value, RangeConstraint* validity) { - // The only legal unsigned negation is zero. - *validity = value ? RANGE_UNDERFLOW : RANGE_VALID; - return static_cast<T>( - -static_cast<typename SignedIntegerForSize<T>::type>(value)); -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, - T>::type -CheckedAbs(T value, RangeConstraint* validity) { - *validity = - value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW; - return static_cast<T>(std::abs(value)); -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, - T>::type -CheckedAbs(T value, RangeConstraint* validity) { - // T is unsigned, so |value| must already be positive. - *validity = RANGE_VALID; - return value; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, - typename UnsignedIntegerForSize<T>::type>::type -CheckedUnsignedAbs(T value) { - typedef typename UnsignedIntegerForSize<T>::type UnsignedT; - return value == std::numeric_limits<T>::min() - ? static_cast<UnsignedT>(std::numeric_limits<T>::max()) + 1 - : static_cast<UnsignedT>(std::abs(value)); -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, - T>::type -CheckedUnsignedAbs(T value) { - // T is unsigned, so |value| must already be positive. - return value; -} - -// These are the floating point stubs that the compiler needs to see. Only the -// negation operation is ever called. -#define BASE_FLOAT_ARITHMETIC_STUBS(NAME) \ - template <typename T> \ - typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type \ - Checked##NAME(T, T, RangeConstraint*) { \ - NOTREACHED(); \ - return 0; \ - } - -BASE_FLOAT_ARITHMETIC_STUBS(Add) -BASE_FLOAT_ARITHMETIC_STUBS(Sub) -BASE_FLOAT_ARITHMETIC_STUBS(Mul) -BASE_FLOAT_ARITHMETIC_STUBS(Div) -BASE_FLOAT_ARITHMETIC_STUBS(Mod) - -#undef BASE_FLOAT_ARITHMETIC_STUBS - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedNeg( - T value, - RangeConstraint*) { - return -value; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedAbs( - T value, - RangeConstraint*) { - return std::abs(value); -} - -// Floats carry around their validity state with them, but integers do not. So, -// we wrap the underlying value in a specialization in order to hide that detail -// and expose an interface via accessors. -enum NumericRepresentation { - NUMERIC_INTEGER, - NUMERIC_FLOATING, - NUMERIC_UNKNOWN -}; - -template <typename NumericType> -struct GetNumericRepresentation { - static const NumericRepresentation value = - std::numeric_limits<NumericType>::is_integer - ? NUMERIC_INTEGER - : (std::numeric_limits<NumericType>::is_iec559 ? NUMERIC_FLOATING - : NUMERIC_UNKNOWN); -}; - -template <typename T, NumericRepresentation type = - GetNumericRepresentation<T>::value> -class CheckedNumericState {}; - -// Integrals require quite a bit of additional housekeeping to manage state. -template <typename T> -class CheckedNumericState<T, NUMERIC_INTEGER> { - private: - T value_; - RangeConstraint validity_; - - public: - template <typename Src, NumericRepresentation type> - friend class CheckedNumericState; - - CheckedNumericState() : value_(0), validity_(RANGE_VALID) {} - - template <typename Src> - CheckedNumericState(Src value, RangeConstraint validity) - : value_(static_cast<T>(value)), - validity_(GetRangeConstraint(validity | - DstRangeRelationToSrcRange<T>(value))) { - static_assert(std::numeric_limits<Src>::is_specialized, - "Argument must be numeric."); - } - - // Copy constructor. - template <typename Src> - CheckedNumericState(const CheckedNumericState<Src>& rhs) - : value_(static_cast<T>(rhs.value())), - validity_(GetRangeConstraint( - rhs.validity() | DstRangeRelationToSrcRange<T>(rhs.value()))) {} - - template <typename Src> - explicit CheckedNumericState( - Src value, - typename std::enable_if<std::numeric_limits<Src>::is_specialized, - int>::type = 0) - : value_(static_cast<T>(value)), - validity_(DstRangeRelationToSrcRange<T>(value)) {} - - RangeConstraint validity() const { return validity_; } - T value() const { return value_; } -}; - -// Floating points maintain their own validity, but need translation wrappers. -template <typename T> -class CheckedNumericState<T, NUMERIC_FLOATING> { - private: - T value_; - - public: - template <typename Src, NumericRepresentation type> - friend class CheckedNumericState; - - CheckedNumericState() : value_(0.0) {} - - template <typename Src> - CheckedNumericState( - Src value, - RangeConstraint validity, - typename std::enable_if<std::numeric_limits<Src>::is_integer, int>::type = - 0) { - switch (DstRangeRelationToSrcRange<T>(value)) { - case RANGE_VALID: - value_ = static_cast<T>(value); - break; - - case RANGE_UNDERFLOW: - value_ = -std::numeric_limits<T>::infinity(); - break; - - case RANGE_OVERFLOW: - value_ = std::numeric_limits<T>::infinity(); - break; - - case RANGE_INVALID: - value_ = std::numeric_limits<T>::quiet_NaN(); - break; - - default: - NOTREACHED(); - } - } - - template <typename Src> - explicit CheckedNumericState( - Src value, - typename std::enable_if<std::numeric_limits<Src>::is_specialized, - int>::type = 0) - : value_(static_cast<T>(value)) {} - - // Copy constructor. - template <typename Src> - CheckedNumericState(const CheckedNumericState<Src>& rhs) - : value_(static_cast<T>(rhs.value())) {} - - RangeConstraint validity() const { - return GetRangeConstraint(value_ <= std::numeric_limits<T>::max(), - value_ >= -std::numeric_limits<T>::max()); - } - T value() const { return value_; } -}; - -// For integers less than 128-bit and floats 32-bit or larger, we can distil -// C/C++ arithmetic promotions down to two simple rules: -// 1. The type with the larger maximum exponent always takes precedence. -// 2. The resulting type must be promoted to at least an int. -// The following template specializations implement that promotion logic. -enum ArithmeticPromotionCategory { - LEFT_PROMOTION, - RIGHT_PROMOTION, - DEFAULT_PROMOTION -}; - -template <typename Lhs, - typename Rhs = Lhs, - ArithmeticPromotionCategory Promotion = - (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value) - ? (MaxExponent<Lhs>::value > MaxExponent<int>::value - ? LEFT_PROMOTION - : DEFAULT_PROMOTION) - : (MaxExponent<Rhs>::value > MaxExponent<int>::value - ? RIGHT_PROMOTION - : DEFAULT_PROMOTION) > -struct ArithmeticPromotion; - -template <typename Lhs, typename Rhs> -struct ArithmeticPromotion<Lhs, Rhs, LEFT_PROMOTION> { - typedef Lhs type; -}; - -template <typename Lhs, typename Rhs> -struct ArithmeticPromotion<Lhs, Rhs, RIGHT_PROMOTION> { - typedef Rhs type; -}; - -template <typename Lhs, typename Rhs> -struct ArithmeticPromotion<Lhs, Rhs, DEFAULT_PROMOTION> { - typedef int type; -}; - -// We can statically check if operations on the provided types can wrap, so we -// can skip the checked operations if they're not needed. So, for an integer we -// care if the destination type preserves the sign and is twice the width of -// the source. -template <typename T, typename Lhs, typename Rhs> -struct IsIntegerArithmeticSafe { - static const bool value = !std::numeric_limits<T>::is_iec559 && - StaticDstRangeRelationToSrcRange<T, Lhs>::value == - NUMERIC_RANGE_CONTAINED && - sizeof(T) >= (2 * sizeof(Lhs)) && - StaticDstRangeRelationToSrcRange<T, Rhs>::value != - NUMERIC_RANGE_CONTAINED && - sizeof(T) >= (2 * sizeof(Rhs)); -}; - -} // namespace internal -} // namespace base - -#endif // BASE_NUMERICS_SAFE_MATH_IMPL_H_ |