| Index: mojo/public/cpp/bindings/lib/array_internal.h
|
| diff --git a/mojo/public/cpp/bindings/lib/array_internal.h b/mojo/public/cpp/bindings/lib/array_internal.h
|
| index 865bf1cc8647e82a949ade03dac505887266c184..4ccc22400459d68fac202bfeed3355a666b3e04e 100644
|
| --- a/mojo/public/cpp/bindings/lib/array_internal.h
|
| +++ b/mojo/public/cpp/bindings/lib/array_internal.h
|
| @@ -10,6 +10,7 @@
|
| #include "mojo/public/cpp/bindings/buffer.h"
|
| #include "mojo/public/cpp/bindings/lib/bindings_internal.h"
|
| #include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
|
| +#include "mojo/public/cpp/bindings/lib/bounds_checker.h"
|
| #include "mojo/public/cpp/bindings/passable.h"
|
|
|
| namespace mojo {
|
| @@ -129,6 +130,12 @@ struct ArraySerializationHelper<T, false> {
|
| Message* message) {
|
| return true;
|
| }
|
| +
|
| + static bool ValidateElements(const ArrayHeader* header,
|
| + const ElementType* elements,
|
| + BoundsChecker* bounds_checker) {
|
| + return true;
|
| + }
|
| };
|
|
|
| template <>
|
| @@ -156,6 +163,10 @@ struct ArraySerializationHelper<Handle, true> {
|
| static bool DecodePointersAndHandles(const ArrayHeader* header,
|
| ElementType* elements,
|
| Message* message);
|
| +
|
| + static bool ValidateElements(const ArrayHeader* header,
|
| + const ElementType* elements,
|
| + BoundsChecker* bounds_checker);
|
| };
|
|
|
| template <typename H>
|
| @@ -193,6 +204,13 @@ struct ArraySerializationHelper<H, true> {
|
| return ArraySerializationHelper<Handle, true>::DecodePointersAndHandles(
|
| header, elements, message);
|
| }
|
| +
|
| + static bool ValidateElements(const ArrayHeader* header,
|
| + const ElementType* elements,
|
| + BoundsChecker* bounds_checker) {
|
| + return ArraySerializationHelper<Handle, true>::ValidateElements(
|
| + header, elements, bounds_checker);
|
| + }
|
| };
|
|
|
| template <typename P>
|
| @@ -245,6 +263,18 @@ struct ArraySerializationHelper<P*, false> {
|
| }
|
| return true;
|
| }
|
| +
|
| + static bool ValidateElements(const ArrayHeader* header,
|
| + const ElementType* elements,
|
| + BoundsChecker* bounds_checker) {
|
| + for (uint32_t i = 0; i < header->num_elements; ++i) {
|
| + if (!ValidateEncodedPointer(&elements[i].offset) ||
|
| + !P::Validate(DecodePointerRaw(&elements[i].offset), bounds_checker)) {
|
| + return false;
|
| + }
|
| + }
|
| + return true;
|
| + }
|
| };
|
|
|
| template <typename T>
|
| @@ -269,6 +299,26 @@ class Array_Data {
|
| static_cast<Array_Data*>(address)->CloseHandles();
|
| }
|
|
|
| + static bool Validate(const void* data, BoundsChecker* bounds_checker) {
|
| + if (!data)
|
| + return true;
|
| + if (!IsAligned(data))
|
| + return false;
|
| + if (!bounds_checker->IsWithinUnclaimedRange(data, sizeof(ArrayHeader)))
|
| + return false;
|
| + const ArrayHeader* header = static_cast<const ArrayHeader*>(data);
|
| + if (header->num_bytes < (sizeof(Array_Data<T>) +
|
| + Traits::GetStorageSize(header->num_elements))) {
|
| + return false;
|
| + }
|
| + if (!bounds_checker->ClaimMemory(data, header->num_bytes))
|
| + return false;
|
| +
|
| + const Array_Data<T>* object = static_cast<const Array_Data<T>*>(data);
|
| + return Helper::ValidateElements(&object->header_, object->storage(),
|
| + bounds_checker);
|
| + }
|
| +
|
| size_t size() const { return header_.num_elements; }
|
|
|
| Ref at(size_t offset) {
|
|
|