Index: util/numeric/checked_range.h |
diff --git a/util/numeric/checked_range.h b/util/numeric/checked_range.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..fabffcb5e1206ad30cb3360b597076827bfc4077 |
--- /dev/null |
+++ b/util/numeric/checked_range.h |
@@ -0,0 +1,115 @@ |
+// Copyright 2014 The Crashpad Authors. All rights reserved. |
+// |
+// Licensed under the Apache License, Version 2.0 (the "License"); |
+// you may not use this file except in compliance with the License. |
+// You may obtain a copy of the License at |
+// |
+// http://www.apache.org/licenses/LICENSE-2.0 |
+// |
+// Unless required by applicable law or agreed to in writing, software |
+// distributed under the License is distributed on an "AS IS" BASIS, |
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+// See the License for the specific language governing permissions and |
+// limitations under the License. |
+ |
+#ifndef CRASHPAD_UTIL_NUMERIC_CHECKED_RANGE_H_ |
+#define CRASHPAD_UTIL_NUMERIC_CHECKED_RANGE_H_ |
+ |
+#include <limits> |
+ |
+#include "base/basictypes.h" |
+#include "base/logging.h" |
+#include "base/numerics/safe_conversions.h" |
+#include "base/numerics/safe_math.h" |
+ |
+namespace crashpad { |
+ |
+//! \brief Ensures that a range, composed of a base and size, does not overflow |
+//! its data type. |
+template <typename ValueType, typename SizeType = ValueType> |
+class CheckedRange { |
+ public: |
+ CheckedRange(ValueType base, SizeType size) { |
+ COMPILE_ASSERT(!std::numeric_limits<SizeType>::is_signed, |
+ SizeType_must_be_unsigned); |
+ SetRange(base, size); |
+ } |
+ |
+ //! \brief Sets the range’s base and size to \a base and \a size, |
+ //! respectively. |
+ void SetRange(ValueType base, SizeType size) { |
+ base_ = base; |
+ size_ = size; |
+ } |
+ |
+ //! \brief The range’s base. |
+ ValueType base() const { return base_; } |
+ |
+ //! \brief The range’s size. |
+ SizeType size() const { return size_; } |
+ |
+ //! \brief The range’s end, its base plus its size. |
+ ValueType end() const { return base_ + size_; } |
+ |
+ //! \brief Returns the validity of the range. |
+ //! |
+ //! \return `true` if the range is valid, `false` otherwise. |
+ //! |
+ //! A range is valid if its size can be converted to the range’s data type |
+ //! without data loss, and if its end (base plus size) can be computed without |
+ //! overflowing its data type. |
+ bool IsValid() const { |
+ if (!base::IsValueInRangeForNumericType<ValueType, SizeType>(size_)) { |
+ return false; |
+ } |
+ base::CheckedNumeric<ValueType> checked_end(base_); |
+ checked_end += static_cast<ValueType>(size_); |
+ return checked_end.IsValid(); |
+ } |
+ |
+ //! \brief Returns whether the range contains another value. |
+ //! |
+ //! \param[in] value The (possibly) contained value. |
+ //! |
+ //! \return `true` if the range contains \a value, `false` otherwise. |
+ //! |
+ //! A range contains a value if the value is greater than or equal to its |
+ //! base, and less than its end (base plus size). |
+ //! |
+ //! This method must only be called if IsValid() would return `true`. |
+ bool ContainsValue(ValueType value) const { |
+ DCHECK(IsValid()); |
+ |
+ return value >= base() && value < end(); |
+ } |
+ |
+ //! \brief Returns whether the range contains another range. |
+ //! |
+ //! \param[in] that The (possibly) contained range. |
+ //! |
+ //! \return `true` if `this` range, the containing range, contains \a that, |
+ //! the contained range. `false` otherwise. |
+ //! |
+ //! A range contains another range when the contained range’s base is greater |
+ //! than or equal to the containing range’s base, and the contained range’s |
+ //! end is less than or equal to the containing range’s end. |
+ //! |
+ //! This method must only be called if IsValid() would return `true` for both |
+ //! CheckedRange objects involved. |
+ bool ContainsRange(const CheckedRange<ValueType, SizeType>& that) const { |
+ DCHECK(IsValid()); |
+ DCHECK(that.IsValid()); |
+ |
+ return that.base() >= base() && that.end() <= end(); |
+ } |
+ |
+ private: |
+ ValueType base_; |
+ SizeType size_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CheckedRange); |
+}; |
+ |
+} // namespace crashpad |
+ |
+#endif // CRASHPAD_UTIL_NUMERIC_CHECKED_RANGE_H_ |