| Index: mojo/public/c/bindings/lib/struct.c
|
| diff --git a/mojo/public/c/bindings/lib/struct.c b/mojo/public/c/bindings/lib/struct.c
|
| index d5d54683e0f27a1f16789b222dad2dc86a0298f4..93a552c5c7f75de34f677275f37cc544b31e105b 100644
|
| --- a/mojo/public/c/bindings/lib/struct.c
|
| +++ b/mojo/public/c/bindings/lib/struct.c
|
| @@ -7,7 +7,6 @@
|
| #include <assert.h>
|
|
|
| #include "mojo/public/c/bindings/lib/type_descriptor.h"
|
| -#include "mojo/public/c/bindings/lib/util.h"
|
| #include "mojo/public/c/bindings/union.h"
|
|
|
| size_t MojomStruct_ComputeSerializedSize(
|
| @@ -96,3 +95,71 @@ void MojomStruct_DecodePointersAndHandles(
|
| in_num_handles);
|
| }
|
| }
|
| +
|
| +static bool is_valid_size_for_version(
|
| + const struct MojomStructHeader* in_struct,
|
| + const struct MojomTypeDescriptorStructVersion versions[],
|
| + uint32_t num_versions) {
|
| + // Scan for a version size in reverse order (assuming structs are often newer
|
| + // versions than old). Seek to the most recent version that |in_struct| is
|
| + // compatible with.
|
| + uint32_t i = num_versions - 1;
|
| + for (; i > 0 && versions[i].version > in_struct->version; i--);
|
| +
|
| + if (in_struct->version == versions[i].version) {
|
| + return in_struct->num_bytes == versions[i].num_bytes;
|
| + } else {
|
| + return in_struct->num_bytes >= versions[i].num_bytes;
|
| + }
|
| +}
|
| +
|
| +MojomValidationResult MojomStruct_Validate(
|
| + const struct MojomTypeDescriptorStruct* in_type_desc,
|
| + const struct MojomStructHeader* in_struct,
|
| + uint32_t in_struct_size,
|
| + uint32_t in_num_handles,
|
| + struct MojomValidationContext* inout_context) {
|
| + assert(in_type_desc);
|
| + assert(in_struct);
|
| +
|
| + // Struct header validation.
|
| + if (in_struct_size < sizeof(struct MojomStructHeader))
|
| + return MOJOM_VALIDATION_ILLEGAL_MEMORY_RANGE;
|
| +
|
| + if (in_struct->num_bytes > in_struct_size)
|
| + return MOJOM_VALIDATION_ILLEGAL_MEMORY_RANGE;
|
| +
|
| + if (!is_valid_size_for_version(in_struct, in_type_desc->versions,
|
| + in_type_desc->num_versions)) {
|
| + return MOJOM_VALIDATION_UNEXPECTED_STRUCT_HEADER;
|
| + }
|
| +
|
| + if ((in_struct->num_bytes & 7) != 0)
|
| + return MOJOM_VALIDATION_MISALIGNED_OBJECT;
|
| +
|
| + // From here on out, all pointers need to point past the end of this struct.
|
| + inout_context->next_pointer = (char*)in_struct + in_struct->num_bytes;
|
| +
|
| + for (size_t i = 0; i < in_type_desc->num_entries; i++) {
|
| + const struct MojomTypeDescriptorStructEntry* entry =
|
| + &(in_type_desc->entries[i]);
|
| +
|
| + if (in_struct->version < entry->min_version)
|
| + continue;
|
| +
|
| + void* elem_data = ((char*)in_struct + sizeof(struct MojomStructHeader) +
|
| + entry->offset);
|
| + MojomValidationResult result = MojomType_DispatchValidate(
|
| + entry->elem_type,
|
| + entry->elem_descriptor,
|
| + entry->nullable,
|
| + elem_data,
|
| + in_struct_size - ((char*)elem_data - (char*)in_struct),
|
| + in_num_handles,
|
| + inout_context);
|
| + if (result != MOJOM_VALIDATION_ERROR_NONE)
|
| + return result;
|
| + }
|
| +
|
| + return MOJOM_VALIDATION_ERROR_NONE;
|
| +}
|
|
|