| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/public/c/bindings/array.h" | 5 #include "mojo/public/c/bindings/array.h" |
| 6 | 6 |
| 7 #include <assert.h> | 7 #include <assert.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 return arr; | 38 return arr; |
| 39 } | 39 } |
| 40 | 40 |
| 41 // Gets the |index|th element (whose type is described by |type|) of |array|. | 41 // Gets the |index|th element (whose type is described by |type|) of |array|. |
| 42 // Only supports non-POD types. | 42 // Only supports non-POD types. |
| 43 static void* array_index_by_type(const struct MojomArrayHeader* array, | 43 static void* array_index_by_type(const struct MojomArrayHeader* array, |
| 44 enum MojomTypeDescriptorType type, | 44 enum MojomTypeDescriptorType type, |
| 45 size_t index) { | 45 size_t index) { |
| 46 switch (type) { | 46 switch (type) { |
| 47 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: | 47 case MOJOM_TYPE_DESCRIPTOR_TYPE_STRUCT_PTR: |
| 48 case MOJOM_TYPE_DESCRIPTOR_TYPE_MAP_PTR: |
| 48 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR: | 49 case MOJOM_TYPE_DESCRIPTOR_TYPE_ARRAY_PTR: |
| 49 return MOJOM_ARRAY_INDEX(array, union MojomPointer, index); | 50 return MOJOM_ARRAY_INDEX(array, union MojomPointer, index); |
| 50 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION: | 51 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION: |
| 51 return MOJOM_ARRAY_INDEX(array, struct MojomUnionLayout, index); | 52 return MOJOM_ARRAY_INDEX(array, struct MojomUnionLayout, index); |
| 52 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE: | 53 case MOJOM_TYPE_DESCRIPTOR_TYPE_HANDLE: |
| 53 return MOJOM_ARRAY_INDEX(array, MojoHandle, index); | 54 return MOJOM_ARRAY_INDEX(array, MojoHandle, index); |
| 54 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE: | 55 case MOJOM_TYPE_DESCRIPTOR_TYPE_INTERFACE: |
| 55 return MOJOM_ARRAY_INDEX(array, struct MojomInterfaceData, index); | 56 return MOJOM_ARRAY_INDEX(array, struct MojomInterfaceData, index); |
| 56 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR: | 57 case MOJOM_TYPE_DESCRIPTOR_TYPE_UNION_PTR: |
| 57 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD: | 58 case MOJOM_TYPE_DESCRIPTOR_TYPE_POD: |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 MojomType_DispatchDecodePointersAndHandles( | 136 MojomType_DispatchDecodePointersAndHandles( |
| 136 in_type_desc->elem_type, | 137 in_type_desc->elem_type, |
| 137 in_type_desc->elem_descriptor, | 138 in_type_desc->elem_descriptor, |
| 138 in_type_desc->nullable, | 139 in_type_desc->nullable, |
| 139 elem_data, | 140 elem_data, |
| 140 in_array_size - (uint32_t)(elem_data - (char*)inout_array), | 141 in_array_size - (uint32_t)(elem_data - (char*)inout_array), |
| 141 inout_handles, | 142 inout_handles, |
| 142 in_num_handles); | 143 in_num_handles); |
| 143 } | 144 } |
| 144 } | 145 } |
| 146 |
| 147 // Rounds up to nearest byte. |
| 148 static uint64_t bits_to_bytes(uint64_t bits) { |
| 149 return (bits + 7) / 8; |
| 150 } |
| 151 |
| 152 static MojomValidationResult validate_array_header( |
| 153 const struct MojomTypeDescriptorArray* in_type_desc, |
| 154 const struct MojomArrayHeader* in_array, |
| 155 uint32_t in_buf_size) { |
| 156 if (in_buf_size < sizeof(struct MojomArrayHeader)) |
| 157 return MOJOM_VALIDATION_ILLEGAL_MEMORY_RANGE; |
| 158 |
| 159 if (in_array->num_bytes < sizeof(struct MojomArrayHeader)) |
| 160 return MOJOM_VALIDATION_UNEXPECTED_ARRAY_HEADER; |
| 161 |
| 162 if (in_array->num_bytes > in_buf_size) |
| 163 return MOJOM_VALIDATION_ILLEGAL_MEMORY_RANGE; |
| 164 |
| 165 if (in_type_desc->num_elements != 0 && |
| 166 in_array->num_elements != in_type_desc->num_elements) |
| 167 return MOJOM_VALIDATION_UNEXPECTED_ARRAY_HEADER; |
| 168 |
| 169 // Array size is less than what we need to fit the elements. |
| 170 if (in_array->num_bytes < |
| 171 sizeof(struct MojomArrayHeader) + |
| 172 bits_to_bytes((uint64_t)in_type_desc->elem_num_bits * |
| 173 (uint64_t)in_array->num_elements)) { |
| 174 return MOJOM_VALIDATION_UNEXPECTED_ARRAY_HEADER; |
| 175 } |
| 176 |
| 177 return MOJOM_VALIDATION_ERROR_NONE; |
| 178 } |
| 179 |
| 180 MojomValidationResult MojomArray_Validate( |
| 181 const struct MojomTypeDescriptorArray* in_type_desc, |
| 182 const struct MojomArrayHeader* in_array, |
| 183 uint32_t in_array_size, |
| 184 uint32_t in_num_handles, |
| 185 struct MojomValidationContext* inout_context) { |
| 186 assert(in_type_desc); |
| 187 assert(in_array); |
| 188 |
| 189 MojomValidationResult result = |
| 190 validate_array_header(in_type_desc, in_array, in_array_size); |
| 191 if (result != MOJOM_VALIDATION_ERROR_NONE) |
| 192 return result; |
| 193 |
| 194 // From here on out, all pointers need to point past the end of this struct. |
| 195 inout_context->next_pointer = (char*)in_array + in_array->num_bytes; |
| 196 |
| 197 // Nothing to validate for POD types. |
| 198 if (in_type_desc->elem_type == MOJOM_TYPE_DESCRIPTOR_TYPE_POD) |
| 199 return MOJOM_VALIDATION_ERROR_NONE; |
| 200 |
| 201 for (size_t i = 0; i < in_array->num_elements; i++) { |
| 202 char* elem_data = |
| 203 array_index_by_type(in_array, in_type_desc->elem_type, i); |
| 204 |
| 205 MojomValidationResult result = MojomType_DispatchValidate( |
| 206 in_type_desc->elem_type, |
| 207 in_type_desc->elem_descriptor, |
| 208 in_type_desc->nullable, |
| 209 elem_data, |
| 210 in_array_size - (uint32_t)(elem_data - (char*)in_array), |
| 211 in_num_handles, |
| 212 inout_context); |
| 213 if (result != MOJOM_VALIDATION_ERROR_NONE) |
| 214 return result; |
| 215 } |
| 216 |
| 217 return MOJOM_VALIDATION_ERROR_NONE; |
| 218 } |
| OLD | NEW |