Chromium Code Reviews| 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..47c79a622174d2867aa2056ff577ffbc19a0d830 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 < 2^32 and within range. |
| + if (pointer->offset >= UINT32_MAX || pointer->offset > max_offset) |
|
viettrungluu
2016/07/28 23:03:01
Not that it really makes a difference, but why is
vardhan
2016/07/29 21:29:21
the comment says <2^32, not <=. so checking that i
viettrungluu
2016/08/01 21:17:19
UINT32_MAX is the maximum value of a uint32_t, whi
vardhan
2016/08/01 22:18:16
oh right! both the condition and the comment are t
|
| + 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; |
| +} |