| 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 5e7dea878ef399863ca019e202be1714fd29df3e..c1cf3e47c1089cbb828d0a6ceba657d060ca2bc7 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/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/lib/buffer.h"
|
|
|
| namespace mojo {
|
| @@ -110,6 +111,12 @@ struct ArraySerializationHelper<T, false> {
|
| Message* message) {
|
| return true;
|
| }
|
| +
|
| + static bool ValidateElements(const ArrayHeader* header,
|
| + const ElementType* elements,
|
| + BoundsChecker* bounds_checker) {
|
| + return true;
|
| + }
|
| };
|
|
|
| template <>
|
| @@ -123,6 +130,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>
|
| @@ -142,6 +153,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>
|
| @@ -164,6 +182,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>
|
| @@ -182,6 +212,26 @@ class Array_Data {
|
| num_elements);
|
| }
|
|
|
| + static bool Validate(const void* data, BoundsChecker* bounds_checker) {
|
| + if (!data)
|
| + return true;
|
| + if (!IsAligned(data))
|
| + return false;
|
| + if (!bounds_checker->IsValidRange(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) {
|
|
|