Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: mojo/public/cpp/bindings/lib/array_internal.h

Issue 469393004: Mojo: Add warning of invalid serialization results (in debug build). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « mojo/mojo_public_tests.gypi ('k') | mojo/public/cpp/bindings/lib/array_serialization.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_
7 7
8 #include <new> 8 #include <new>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 static BitRef ToRef(StorageType* storage, size_t offset) { 107 static BitRef ToRef(StorageType* storage, size_t offset) {
108 return BitRef(&storage[offset / 8], 1 << (offset % 8)); 108 return BitRef(&storage[offset / 8], 1 << (offset % 8));
109 } 109 }
110 static bool ToConstRef(const StorageType* storage, size_t offset) { 110 static bool ToConstRef(const StorageType* storage, size_t offset) {
111 return (storage[offset / 8] & (1 << (offset % 8))) != 0; 111 return (storage[offset / 8] & (1 << (offset % 8))) != 0;
112 } 112 }
113 }; 113 };
114 114
115 // Array type information needed for valdiation. 115 // Array type information needed for valdiation.
116 template <uint32_t in_expected_num_elements, 116 template <uint32_t in_expected_num_elements,
117 bool in_element_nullable, 117 bool in_element_is_nullable,
118 typename InElementValidateParams> 118 typename InElementValidateParams>
119 class ArrayValidateParams { 119 class ArrayValidateParams {
120 public: 120 public:
121 // Validation information for elements. It is either another specialization of 121 // Validation information for elements. It is either another specialization of
122 // ArrayValidateParams (if elements are arrays) or NoValidateParams. 122 // ArrayValidateParams (if elements are arrays) or NoValidateParams.
123 typedef InElementValidateParams ElementValidateParams; 123 typedef InElementValidateParams ElementValidateParams;
124 124
125 // If |expected_num_elements| is not 0, the array is expected to have exactly 125 // If |expected_num_elements| is not 0, the array is expected to have exactly
126 // that number of elements. 126 // that number of elements.
127 static const uint32_t expected_num_elements = in_expected_num_elements; 127 static const uint32_t expected_num_elements = in_expected_num_elements;
128 // Whether the elements are nullable. 128 // Whether the elements are nullable.
129 static const bool element_nullable = in_element_nullable; 129 static const bool element_is_nullable = in_element_is_nullable;
130 }; 130 };
131 131
132 // NoValidateParams is used to indicate the end of an ArrayValidateParams chain. 132 // NoValidateParams is used to indicate the end of an ArrayValidateParams chain.
133 class NoValidateParams { 133 class NoValidateParams {
134 }; 134 };
135 135
136 // What follows is code to support the serialization of Array_Data<T>. There 136 // What follows is code to support the serialization of Array_Data<T>. There
137 // are two interesting cases: arrays of primitives and arrays of objects. 137 // are two interesting cases: arrays of primitives and arrays of objects.
138 // Arrays of objects are represented as arrays of pointers to objects. 138 // Arrays of objects are represented as arrays of pointers to objects.
139 139
140 template <typename T, bool is_handle> struct ArraySerializationHelper; 140 template <typename T, bool is_handle> struct ArraySerializationHelper;
141 141
142 template <typename T> 142 template <typename T>
143 struct ArraySerializationHelper<T, false> { 143 struct ArraySerializationHelper<T, false> {
144 typedef typename ArrayDataTraits<T>::StorageType ElementType; 144 typedef typename ArrayDataTraits<T>::StorageType ElementType;
145 145
146 static void EncodePointersAndHandles(const ArrayHeader* header, 146 static void EncodePointersAndHandles(const ArrayHeader* header,
147 ElementType* elements, 147 ElementType* elements,
148 std::vector<Handle>* handles) { 148 std::vector<Handle>* handles) {
149 } 149 }
150 150
151 static void DecodePointersAndHandles(const ArrayHeader* header, 151 static void DecodePointersAndHandles(const ArrayHeader* header,
152 ElementType* elements, 152 ElementType* elements,
153 std::vector<Handle>* handles) { 153 std::vector<Handle>* handles) {
154 } 154 }
155 155
156 template <bool element_nullable, typename ElementValidateParams> 156 template <bool element_is_nullable, typename ElementValidateParams>
157 static bool ValidateElements(const ArrayHeader* header, 157 static bool ValidateElements(const ArrayHeader* header,
158 const ElementType* elements, 158 const ElementType* elements,
159 BoundsChecker* bounds_checker) { 159 BoundsChecker* bounds_checker) {
160 MOJO_COMPILE_ASSERT(!element_nullable, 160 MOJO_COMPILE_ASSERT(!element_is_nullable,
161 Primitive_type_should_be_non_nullable); 161 Primitive_type_should_be_non_nullable);
162 MOJO_COMPILE_ASSERT( 162 MOJO_COMPILE_ASSERT(
163 (IsSame<ElementValidateParams, NoValidateParams>::value), 163 (IsSame<ElementValidateParams, NoValidateParams>::value),
164 Primitive_type_should_not_have_array_validate_params); 164 Primitive_type_should_not_have_array_validate_params);
165 return true; 165 return true;
166 } 166 }
167 }; 167 };
168 168
169 template <> 169 template <>
170 struct ArraySerializationHelper<Handle, true> { 170 struct ArraySerializationHelper<Handle, true> {
171 typedef ArrayDataTraits<Handle>::StorageType ElementType; 171 typedef ArrayDataTraits<Handle>::StorageType ElementType;
172 172
173 static void EncodePointersAndHandles(const ArrayHeader* header, 173 static void EncodePointersAndHandles(const ArrayHeader* header,
174 ElementType* elements, 174 ElementType* elements,
175 std::vector<Handle>* handles); 175 std::vector<Handle>* handles);
176 176
177 static void DecodePointersAndHandles(const ArrayHeader* header, 177 static void DecodePointersAndHandles(const ArrayHeader* header,
178 ElementType* elements, 178 ElementType* elements,
179 std::vector<Handle>* handles); 179 std::vector<Handle>* handles);
180 180
181 template <bool element_nullable, typename ElementValidateParams> 181 template <bool element_is_nullable, typename ElementValidateParams>
182 static bool ValidateElements(const ArrayHeader* header, 182 static bool ValidateElements(const ArrayHeader* header,
183 const ElementType* elements, 183 const ElementType* elements,
184 BoundsChecker* bounds_checker) { 184 BoundsChecker* bounds_checker) {
185 MOJO_COMPILE_ASSERT( 185 MOJO_COMPILE_ASSERT(
186 (IsSame<ElementValidateParams, NoValidateParams>::value), 186 (IsSame<ElementValidateParams, NoValidateParams>::value),
187 Handle_type_should_not_have_array_validate_params); 187 Handle_type_should_not_have_array_validate_params);
188 188
189 for (uint32_t i = 0; i < header->num_elements; ++i) { 189 for (uint32_t i = 0; i < header->num_elements; ++i) {
190 if (IsNonNullableValidationEnabled() && !element_nullable && 190 if (IsNonNullableValidationEnabled() && !element_is_nullable &&
191 elements[i].value() == kEncodedInvalidHandleValue) { 191 elements[i].value() == kEncodedInvalidHandleValue) {
192 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE); 192 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE);
193 return false; 193 return false;
194 } 194 }
195 if (!bounds_checker->ClaimHandle(elements[i])) { 195 if (!bounds_checker->ClaimHandle(elements[i])) {
196 ReportValidationError(VALIDATION_ERROR_ILLEGAL_HANDLE); 196 ReportValidationError(VALIDATION_ERROR_ILLEGAL_HANDLE);
197 return false; 197 return false;
198 } 198 }
199 } 199 }
200 return true; 200 return true;
(...skipping 11 matching lines...) Expand all
212 header, elements, handles); 212 header, elements, handles);
213 } 213 }
214 214
215 static void DecodePointersAndHandles(const ArrayHeader* header, 215 static void DecodePointersAndHandles(const ArrayHeader* header,
216 ElementType* elements, 216 ElementType* elements,
217 std::vector<Handle>* handles) { 217 std::vector<Handle>* handles) {
218 ArraySerializationHelper<Handle, true>::DecodePointersAndHandles( 218 ArraySerializationHelper<Handle, true>::DecodePointersAndHandles(
219 header, elements, handles); 219 header, elements, handles);
220 } 220 }
221 221
222 template <bool element_nullable, typename ElementValidateParams> 222 template <bool element_is_nullable, typename ElementValidateParams>
223 static bool ValidateElements(const ArrayHeader* header, 223 static bool ValidateElements(const ArrayHeader* header,
224 const ElementType* elements, 224 const ElementType* elements,
225 BoundsChecker* bounds_checker) { 225 BoundsChecker* bounds_checker) {
226 return ArraySerializationHelper<Handle, true>:: 226 return ArraySerializationHelper<Handle, true>::
227 ValidateElements<element_nullable, ElementValidateParams>( 227 ValidateElements<element_is_nullable, ElementValidateParams>(
228 header, elements, bounds_checker); 228 header, elements, bounds_checker);
229 } 229 }
230 }; 230 };
231 231
232 template <typename P> 232 template <typename P>
233 struct ArraySerializationHelper<P*, false> { 233 struct ArraySerializationHelper<P*, false> {
234 typedef typename ArrayDataTraits<P*>::StorageType ElementType; 234 typedef typename ArrayDataTraits<P*>::StorageType ElementType;
235 235
236 static void EncodePointersAndHandles(const ArrayHeader* header, 236 static void EncodePointersAndHandles(const ArrayHeader* header,
237 ElementType* elements, 237 ElementType* elements,
238 std::vector<Handle>* handles) { 238 std::vector<Handle>* handles) {
239 for (uint32_t i = 0; i < header->num_elements; ++i) 239 for (uint32_t i = 0; i < header->num_elements; ++i)
240 Encode(&elements[i], handles); 240 Encode(&elements[i], handles);
241 } 241 }
242 242
243 static void DecodePointersAndHandles(const ArrayHeader* header, 243 static void DecodePointersAndHandles(const ArrayHeader* header,
244 ElementType* elements, 244 ElementType* elements,
245 std::vector<Handle>* handles) { 245 std::vector<Handle>* handles) {
246 for (uint32_t i = 0; i < header->num_elements; ++i) 246 for (uint32_t i = 0; i < header->num_elements; ++i)
247 Decode(&elements[i], handles); 247 Decode(&elements[i], handles);
248 } 248 }
249 249
250 template <bool element_nullable, typename ElementValidateParams> 250 template <bool element_is_nullable, typename ElementValidateParams>
251 static bool ValidateElements(const ArrayHeader* header, 251 static bool ValidateElements(const ArrayHeader* header,
252 const ElementType* elements, 252 const ElementType* elements,
253 BoundsChecker* bounds_checker) { 253 BoundsChecker* bounds_checker) {
254 for (uint32_t i = 0; i < header->num_elements; ++i) { 254 for (uint32_t i = 0; i < header->num_elements; ++i) {
255 if (IsNonNullableValidationEnabled() && !element_nullable && 255 if (IsNonNullableValidationEnabled() && !element_is_nullable &&
256 !elements[i].offset) { 256 !elements[i].offset) {
257 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_NULL_POINTER); 257 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_NULL_POINTER);
258 return false; 258 return false;
259 } 259 }
260 if (!ValidateEncodedPointer(&elements[i].offset)) { 260 if (!ValidateEncodedPointer(&elements[i].offset)) {
261 ReportValidationError(VALIDATION_ERROR_ILLEGAL_POINTER); 261 ReportValidationError(VALIDATION_ERROR_ILLEGAL_POINTER);
262 return false; 262 return false;
263 } 263 }
264 if (!ValidateCaller<P, ElementValidateParams>::Run( 264 if (!ValidateCaller<P, ElementValidateParams>::Run(
265 DecodePointerRaw(&elements[i].offset), bounds_checker)) { 265 DecodePointerRaw(&elements[i].offset), bounds_checker)) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER); 328 ReportValidationError(VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER);
329 return false; 329 return false;
330 } 330 }
331 if (!bounds_checker->ClaimMemory(data, header->num_bytes)) { 331 if (!bounds_checker->ClaimMemory(data, header->num_bytes)) {
332 ReportValidationError(VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE); 332 ReportValidationError(VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
333 return false; 333 return false;
334 } 334 }
335 335
336 const Array_Data<T>* object = static_cast<const Array_Data<T>*>(data); 336 const Array_Data<T>* object = static_cast<const Array_Data<T>*>(data);
337 return Helper::template ValidateElements< 337 return Helper::template ValidateElements<
338 Params::element_nullable, typename Params::ElementValidateParams>( 338 Params::element_is_nullable, typename Params::ElementValidateParams>(
339 &object->header_, object->storage(), bounds_checker); 339 &object->header_, object->storage(), bounds_checker);
340 } 340 }
341 341
342 size_t size() const { return header_.num_elements; } 342 size_t size() const { return header_.num_elements; }
343 343
344 Ref at(size_t offset) { 344 Ref at(size_t offset) {
345 MOJO_DCHECK(offset < static_cast<size_t>(header_.num_elements)); 345 MOJO_DCHECK(offset < static_cast<size_t>(header_.num_elements));
346 return Traits::ToRef(storage(), offset); 346 return Traits::ToRef(storage(), offset);
347 } 347 }
348 348
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 }; 459 };
460 460
461 template <> struct WrapperTraits<String, false> { 461 template <> struct WrapperTraits<String, false> {
462 typedef String_Data* DataType; 462 typedef String_Data* DataType;
463 }; 463 };
464 464
465 } // namespace internal 465 } // namespace internal
466 } // namespace mojo 466 } // namespace mojo
467 467
468 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ 468 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_
OLDNEW
« no previous file with comments | « mojo/mojo_public_tests.gypi ('k') | mojo/public/cpp/bindings/lib/array_serialization.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698