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..83e87d20e422260255e6602cd7fb3528beeaf4df |
--- /dev/null |
+++ b/util/numeric/checked_range.h |
@@ -0,0 +1,116 @@ |
+// 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 { |
+ base::CheckedNumeric<ValueType> checked_base_(base_); |
Robert Sesek
2014/08/14 20:55:52
No underscore at the end of checked_base_, or on l
|
+ if (!base::IsValueInRangeForNumericType<ValueType, SizeType>(size_)) { |
+ return false; |
+ } |
+ base::CheckedNumeric<ValueType> checked_end_(checked_base_ + |
+ static_cast<ValueType>(size_)); |
Robert Sesek
2014/08/14 20:55:52
This read "fishy" for me for me, so I spent 10 min
Mark Mentovai
2014/08/14 23:12:01
rsesek wrote:
|
+ 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(); |
Robert Sesek
2014/08/14 20:55:52
Why base_ but 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(); |
Robert Sesek
2014/08/14 20:55:52
Same.
|
+ } |
+ |
+ private: |
+ ValueType base_; |
+ SizeType size_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CheckedRange); |
+}; |
+ |
+} // namespace crashpad |
+ |
+#endif // CRASHPAD_UTIL_NUMERIC_CHECKED_RANGE_H_ |