Chromium Code Reviews| 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_ |