bounds_checker.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "mojo/public/cpp/bindings/lib/bounds_checker.h" 6 7#include <assert.h> 8 9#include "mojo/public/cpp/bindings/lib/bindings_serialization.h" 10#include "mojo/public/cpp/system/core.h" 11 12namespace mojo { 13namespace internal { 14 15BoundsChecker::BoundsChecker(const void* data, uint32_t data_num_bytes, 16 size_t num_handles) 17 : data_begin_(reinterpret_cast<uintptr_t>(data)), 18 data_end_(data_begin_ + data_num_bytes), 19 handle_begin_(0), 20 handle_end_(static_cast<uint32_t>(num_handles)) { 21 if (data_end_ < data_begin_) { 22 // The calculation of |data_end_| overflowed. 23 // It shouldn't happen but if it does, set the range to empty so 24 // IsValidRange() and ClaimMemory() always fail. 25 assert(false); // Not reached. 26 data_end_ = data_begin_; 27 } 28 if (handle_end_ < num_handles) { 29 // Assigning |num_handles| to |handle_end_| overflowed. 30 // It shouldn't happen but if it does, set the handle index range to empty. 31 assert(false); // Not reached. 32 handle_end_ = 0; 33 } 34} 35 36BoundsChecker::~BoundsChecker() { 37} 38 39bool BoundsChecker::ClaimMemory(const void* position, uint32_t num_bytes) { 40 uintptr_t begin = reinterpret_cast<uintptr_t>(position); 41 uintptr_t end = begin + num_bytes; 42 43 if (!InternalIsValidRange(begin, end)) 44 return false; 45 46 data_begin_ = end; 47 return true; 48} 49 50bool BoundsChecker::ClaimHandle(const Handle& encoded_handle) { 51 uint32_t index = encoded_handle.value(); 52 if (index == kEncodedInvalidHandleValue) 53 return true; 54 55 if (index < handle_begin_ || index >= handle_end_) 56 return false; 57 58 // |index| + 1 shouldn't overflow, because |index| is not the max value of 59 // uint32_t (it is less than |handle_end_|). 60 handle_begin_ = index + 1; 61 return true; 62} 63 64bool BoundsChecker::IsValidRange(const void* position, 65 uint32_t num_bytes) const { 66 uintptr_t begin = reinterpret_cast<uintptr_t>(position); 67 uintptr_t end = begin + num_bytes; 68 69 return InternalIsValidRange(begin, end); 70} 71 72bool BoundsChecker::InternalIsValidRange(uintptr_t begin, uintptr_t end) const { 73 return end > begin && begin >= data_begin_ && end <= data_end_; 74} 75 76} // namespace internal 77} // namespace mojo 78