| Index: mojo/public/c/bindings/lib/type_descriptor.c
|
| diff --git a/mojo/public/c/bindings/lib/type_descriptor.c b/mojo/public/c/bindings/lib/type_descriptor.c
|
| index 3e23011dc325f57caf6c1a1664d321d2d6308dfa..2846965b02ee033f267a1463a89ff4fbd5702065 100644
|
| --- a/mojo/public/c/bindings/lib/type_descriptor.c
|
| +++ b/mojo/public/c/bindings/lib/type_descriptor.c
|
| @@ -7,10 +7,11 @@
|
| #include <assert.h>
|
|
|
| #include "mojo/public/c/bindings/array.h"
|
| +#include "mojo/public/c/bindings/interface.h"
|
| #include "mojo/public/c/bindings/lib/util.h"
|
| +#include "mojo/public/c/bindings/map.h"
|
| #include "mojo/public/c/bindings/struct.h"
|
| #include "mojo/public/c/bindings/union.h"
|
| -#include "mojo/public/c/bindings/interface.h"
|
|
|
| const struct MojomTypeDescriptorArray g_mojom_string_type_description = {
|
| MOJOM_TYPE_DESCRIPTOR_TYPE_POD, // elem_type
|
| @@ -25,9 +26,10 @@ const struct MojomTypeDescriptorArray g_mojom_string_type_description = {
|
| static const MojoHandle kEncodedHandleInvalid = (MojoHandle)-1;
|
|
|
| bool MojomType_IsPointer(enum MojomTypeDescriptorType type) {
|
| - return type == MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR ||
|
| - type == MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR ||
|
| - type == MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR;
|
| + return type == MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR ||
|
| + type == MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR ||
|
| + type == MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR ||
|
| + type == MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR;
|
| }
|
|
|
| size_t MojomType_DispatchComputeSerializedSize(
|
| @@ -38,6 +40,7 @@ size_t MojomType_DispatchComputeSerializedSize(
|
| const void* data_ptr = data;
|
| size_t size = 0;
|
| switch (type) {
|
| + case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR:
|
| case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: {
|
| data_ptr = ((const union MojomPointer*)data_ptr)->ptr;
|
| if (!nullable || data_ptr != NULL)
|
| @@ -140,6 +143,7 @@ void MojomType_DispatchEncodePointersAndHandles(
|
|
|
| void* union_buf = inout_buf;
|
| switch (in_elem_type) {
|
| + case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR:
|
| case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: {
|
| struct MojomStructHeader* inout_struct =
|
| ((union MojomPointer*)inout_buf)->ptr;
|
| @@ -205,6 +209,7 @@ void MojomType_DispatchDecodePointersAndHandles(
|
|
|
| void* union_buf = inout_buf;
|
| switch (in_elem_type) {
|
| + case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR:
|
| case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: {
|
| decode_pointer(inout_buf);
|
| struct MojomStructHeader* inout_struct =
|
| @@ -268,3 +273,129 @@ void MojomType_DispatchDecodePointersAndHandles(
|
| break;
|
| }
|
| }
|
| +
|
| +// Validates that the offset (|pointer->offset|) points to a new memory region,
|
| +// i.e. one that hasn't been referenced yet. If so, moves the expected offset
|
| +// (for the next pointer) forward.
|
| +static MojomValidationResult validate_pointer(
|
| + const union MojomPointer* pointer,
|
| + size_t max_offset,
|
| + bool is_nullable,
|
| + struct MojomValidationContext* inout_context) {
|
| + // Offset must be <= UINT32_MAX and within range.
|
| + if (pointer->offset > max_offset || pointer->offset > UINT32_MAX)
|
| + return MOJOM_VALIDATION_ILLEGAL_POINTER;
|
| +
|
| + if (pointer->offset != 0) {
|
| + if ((char*)pointer + pointer->offset < inout_context->next_pointer)
|
| + return MOJOM_VALIDATION_ILLEGAL_MEMORY_RANGE;
|
| +
|
| + inout_context->next_pointer = (char*)pointer + pointer->offset;
|
| + }
|
| +
|
| + // Offset must be 8-byte aligned: this check is sufficient, given that all
|
| + // objects are rounded to 8-bytes.
|
| + if ((pointer->offset & 7) != 0)
|
| + return MOJOM_VALIDATION_MISALIGNED_OBJECT;
|
| +
|
| + if (!is_nullable && pointer->offset == 0)
|
| + return MOJOM_VALIDATION_UNEXPECTED_NULL_POINTER;
|
| +
|
| + return MOJOM_VALIDATION_ERROR_NONE;
|
| +}
|
| +
|
| +static MojomValidationResult validate_handle(
|
| + MojoHandle encoded_handle, uint32_t num_handles, bool is_nullable,
|
| + struct MojomValidationContext* inout_context) {
|
| + if (!is_nullable && encoded_handle == kEncodedHandleInvalid)
|
| + return MOJOM_VALIDATION_UNEXPECTED_INVALID_HANDLE;
|
| +
|
| + if (encoded_handle != kEncodedHandleInvalid) {
|
| + if (encoded_handle >= num_handles ||
|
| + encoded_handle < inout_context->next_handle_index)
|
| + return MOJOM_VALIDATION_ILLEGAL_HANDLE;
|
| +
|
| + inout_context->next_handle_index = encoded_handle + 1;
|
| + }
|
| +
|
| + return MOJOM_VALIDATION_ERROR_NONE;
|
| +}
|
| +
|
| +MojomValidationResult MojomType_DispatchValidate(
|
| + enum MojomTypeDescriptorType in_elem_type, const void* in_type_desc,
|
| + bool in_nullable, const void* in_buf, uint32_t in_buf_size,
|
| + uint32_t in_num_handles, struct MojomValidationContext* inout_context) {
|
| + assert(in_buf);
|
| +
|
| + struct MojomUnionLayout* union_data = (struct MojomUnionLayout*)in_buf;
|
| + switch (in_elem_type) {
|
| + case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR:
|
| + case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: {
|
| + union MojomPointer* pointer = (union MojomPointer*)in_buf;
|
| + MojomValidationResult result =
|
| + validate_pointer(pointer, in_buf_size, in_nullable, inout_context);
|
| + if (result != MOJOM_VALIDATION_ERROR_NONE || pointer->offset == 0)
|
| + return result;
|
| +
|
| + result = MojomStruct_Validate(
|
| + (const struct MojomTypeDescriptorStruct*)in_type_desc,
|
| + (const struct MojomStructHeader*)((char*)in_buf + pointer->offset),
|
| + in_buf_size - pointer->offset, in_num_handles, inout_context);
|
| +
|
| + if (result == MOJOM_VALIDATION_ERROR_NONE &&
|
| + in_elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR) {
|
| + return MojomMap_Validate(
|
| + (const struct MojomTypeDescriptorStruct*)in_type_desc,
|
| + (const struct MojomStructHeader*)((char*)in_buf + pointer->offset),
|
| + in_buf_size - pointer->offset, in_num_handles, inout_context);
|
| + }
|
| +
|
| + return result;
|
| + }
|
| + case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR: {
|
| + union MojomPointer* pointer = (union MojomPointer*)in_buf;
|
| + MojomValidationResult result =
|
| + validate_pointer(pointer, in_buf_size, in_nullable, inout_context);
|
| + if (result != MOJOM_VALIDATION_ERROR_NONE || pointer->offset == 0)
|
| + return result;
|
| +
|
| + return MojomArray_Validate(
|
| + (const struct MojomTypeDescriptorArray*)in_type_desc,
|
| + (const struct MojomArrayHeader*)((char*)in_buf + pointer->offset),
|
| + in_buf_size - pointer->offset, in_num_handles, inout_context);
|
| + }
|
| + case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR: {
|
| + union MojomPointer* pointer = (union MojomPointer*)in_buf;
|
| + MojomValidationResult result =
|
| + validate_pointer(pointer, in_buf_size, in_nullable, inout_context);
|
| + if (result != MOJOM_VALIDATION_ERROR_NONE || pointer->offset == 0)
|
| + return result;
|
| +
|
| + // Since this union is a pointer, we update |next_pointer| to be past the
|
| + // union data.
|
| + inout_context->next_pointer += sizeof(struct MojomUnionLayout);
|
| +
|
| + union_data = (struct MojomUnionLayout*)((char*)in_buf + pointer->offset);
|
| + // Fall through.
|
| + }
|
| + case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION:
|
| + if (union_data->size == 0) {
|
| + return in_nullable ? MOJOM_VALIDATION_ERROR_NONE
|
| + : MOJOM_VALIDATION_UNEXPECTED_NULL_UNION;
|
| + }
|
| +
|
| + return MojomUnion_Validate(
|
| + (const struct MojomTypeDescriptorUnion*)in_type_desc, in_nullable,
|
| + union_data, in_buf_size - ((char*)union_data - (char*)in_buf),
|
| + in_num_handles, inout_context);
|
| + case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE:
|
| + return validate_handle(*(const MojoHandle*)in_buf, in_num_handles,
|
| + in_nullable, inout_context);
|
| + case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE:
|
| + return validate_handle(((const struct MojomInterfaceData*)in_buf)->handle,
|
| + in_num_handles, in_nullable, inout_context);
|
| + case MOJOM_TYPE_DESCRIPTOR_TYPE_POD:
|
| + break;
|
| + }
|
| + return MOJOM_VALIDATION_ERROR_NONE;
|
| +}
|
|
|