OLD | NEW |
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 | 9 |
10 #include "mojo/public/cpp/bindings/buffer.h" | 10 #include "mojo/public/cpp/bindings/buffer.h" |
11 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" | 11 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" |
12 #include "mojo/public/cpp/bindings/lib/bindings_serialization.h" | 12 #include "mojo/public/cpp/bindings/lib/bindings_serialization.h" |
| 13 #include "mojo/public/cpp/bindings/lib/bounds_checker.h" |
13 #include "mojo/public/cpp/bindings/passable.h" | 14 #include "mojo/public/cpp/bindings/passable.h" |
14 | 15 |
15 namespace mojo { | 16 namespace mojo { |
16 template <typename T> class Array; | 17 template <typename T> class Array; |
17 | 18 |
18 namespace internal { | 19 namespace internal { |
19 | 20 |
20 template <typename T> | 21 template <typename T> |
21 struct ArrayDataTraits { | 22 struct ArrayDataTraits { |
22 typedef T StorageType; | 23 typedef T StorageType; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 static void EncodePointersAndHandles(const ArrayHeader* header, | 123 static void EncodePointersAndHandles(const ArrayHeader* header, |
123 ElementType* elements, | 124 ElementType* elements, |
124 std::vector<Handle>* handles) { | 125 std::vector<Handle>* handles) { |
125 } | 126 } |
126 | 127 |
127 static bool DecodePointersAndHandles(const ArrayHeader* header, | 128 static bool DecodePointersAndHandles(const ArrayHeader* header, |
128 ElementType* elements, | 129 ElementType* elements, |
129 Message* message) { | 130 Message* message) { |
130 return true; | 131 return true; |
131 } | 132 } |
| 133 |
| 134 static bool ValidateElements(const ArrayHeader* header, |
| 135 const ElementType* elements, |
| 136 BoundsChecker* bounds_checker) { |
| 137 return true; |
| 138 } |
132 }; | 139 }; |
133 | 140 |
134 template <> | 141 template <> |
135 struct ArraySerializationHelper<Handle, true> { | 142 struct ArraySerializationHelper<Handle, true> { |
136 typedef ArrayDataTraits<Handle>::StorageType ElementType; | 143 typedef ArrayDataTraits<Handle>::StorageType ElementType; |
137 | 144 |
138 static size_t ComputeSizeOfElements(const ArrayHeader* header, | 145 static size_t ComputeSizeOfElements(const ArrayHeader* header, |
139 const ElementType* elements) { | 146 const ElementType* elements) { |
140 return 0; | 147 return 0; |
141 } | 148 } |
142 | 149 |
143 static void CloneElements(const ArrayHeader* header, | 150 static void CloneElements(const ArrayHeader* header, |
144 ElementType* elements, | 151 ElementType* elements, |
145 Buffer* buf) { | 152 Buffer* buf) { |
146 } | 153 } |
147 | 154 |
148 static void ClearHandles(const ArrayHeader* header, ElementType* elements); | 155 static void ClearHandles(const ArrayHeader* header, ElementType* elements); |
149 | 156 |
150 static void CloseHandles(const ArrayHeader* header, ElementType* elements); | 157 static void CloseHandles(const ArrayHeader* header, ElementType* elements); |
151 | 158 |
152 static void EncodePointersAndHandles(const ArrayHeader* header, | 159 static void EncodePointersAndHandles(const ArrayHeader* header, |
153 ElementType* elements, | 160 ElementType* elements, |
154 std::vector<Handle>* handles); | 161 std::vector<Handle>* handles); |
155 | 162 |
156 static bool DecodePointersAndHandles(const ArrayHeader* header, | 163 static bool DecodePointersAndHandles(const ArrayHeader* header, |
157 ElementType* elements, | 164 ElementType* elements, |
158 Message* message); | 165 Message* message); |
| 166 |
| 167 static bool ValidateElements(const ArrayHeader* header, |
| 168 const ElementType* elements, |
| 169 BoundsChecker* bounds_checker); |
159 }; | 170 }; |
160 | 171 |
161 template <typename H> | 172 template <typename H> |
162 struct ArraySerializationHelper<H, true> { | 173 struct ArraySerializationHelper<H, true> { |
163 typedef typename ArrayDataTraits<H>::StorageType ElementType; | 174 typedef typename ArrayDataTraits<H>::StorageType ElementType; |
164 | 175 |
165 static size_t ComputeSizeOfElements(const ArrayHeader* header, | 176 static size_t ComputeSizeOfElements(const ArrayHeader* header, |
166 const ElementType* elements) { | 177 const ElementType* elements) { |
167 return 0; | 178 return 0; |
168 } | 179 } |
(...skipping 17 matching lines...) Expand all Loading... |
186 ArraySerializationHelper<Handle, true>::EncodePointersAndHandles( | 197 ArraySerializationHelper<Handle, true>::EncodePointersAndHandles( |
187 header, elements, handles); | 198 header, elements, handles); |
188 } | 199 } |
189 | 200 |
190 static bool DecodePointersAndHandles(const ArrayHeader* header, | 201 static bool DecodePointersAndHandles(const ArrayHeader* header, |
191 ElementType* elements, | 202 ElementType* elements, |
192 Message* message) { | 203 Message* message) { |
193 return ArraySerializationHelper<Handle, true>::DecodePointersAndHandles( | 204 return ArraySerializationHelper<Handle, true>::DecodePointersAndHandles( |
194 header, elements, message); | 205 header, elements, message); |
195 } | 206 } |
| 207 |
| 208 static bool ValidateElements(const ArrayHeader* header, |
| 209 const ElementType* elements, |
| 210 BoundsChecker* bounds_checker) { |
| 211 return ArraySerializationHelper<Handle, true>::ValidateElements( |
| 212 header, elements, bounds_checker); |
| 213 } |
196 }; | 214 }; |
197 | 215 |
198 template <typename P> | 216 template <typename P> |
199 struct ArraySerializationHelper<P*, false> { | 217 struct ArraySerializationHelper<P*, false> { |
200 typedef typename ArrayDataTraits<P*>::StorageType ElementType; | 218 typedef typename ArrayDataTraits<P*>::StorageType ElementType; |
201 | 219 |
202 static size_t ComputeSizeOfElements(const ArrayHeader* header, | 220 static size_t ComputeSizeOfElements(const ArrayHeader* header, |
203 const ElementType* elements) { | 221 const ElementType* elements) { |
204 size_t result = 0; | 222 size_t result = 0; |
205 for (uint32_t i = 0; i < header->num_elements; ++i) { | 223 for (uint32_t i = 0; i < header->num_elements; ++i) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 | 256 |
239 static bool DecodePointersAndHandles(const ArrayHeader* header, | 257 static bool DecodePointersAndHandles(const ArrayHeader* header, |
240 ElementType* elements, | 258 ElementType* elements, |
241 Message* message) { | 259 Message* message) { |
242 for (uint32_t i = 0; i < header->num_elements; ++i) { | 260 for (uint32_t i = 0; i < header->num_elements; ++i) { |
243 if (!Decode(&elements[i], message)) | 261 if (!Decode(&elements[i], message)) |
244 return false; | 262 return false; |
245 } | 263 } |
246 return true; | 264 return true; |
247 } | 265 } |
| 266 |
| 267 static bool ValidateElements(const ArrayHeader* header, |
| 268 const ElementType* elements, |
| 269 BoundsChecker* bounds_checker) { |
| 270 for (uint32_t i = 0; i < header->num_elements; ++i) { |
| 271 if (!ValidateEncodedPointer(&elements[i].offset) || |
| 272 !P::Validate(DecodePointerRaw(&elements[i].offset), bounds_checker)) { |
| 273 return false; |
| 274 } |
| 275 } |
| 276 return true; |
| 277 } |
248 }; | 278 }; |
249 | 279 |
250 template <typename T> | 280 template <typename T> |
251 class Array_Data { | 281 class Array_Data { |
252 public: | 282 public: |
253 typedef ArrayDataTraits<T> Traits; | 283 typedef ArrayDataTraits<T> Traits; |
254 typedef typename Traits::StorageType StorageType; | 284 typedef typename Traits::StorageType StorageType; |
255 typedef typename Traits::Wrapper Wrapper; | 285 typedef typename Traits::Wrapper Wrapper; |
256 typedef typename Traits::Ref Ref; | 286 typedef typename Traits::Ref Ref; |
257 typedef typename Traits::ConstRef ConstRef; | 287 typedef typename Traits::ConstRef ConstRef; |
258 typedef ArraySerializationHelper<T, TypeTraits<T>::kIsHandle> Helper; | 288 typedef ArraySerializationHelper<T, TypeTraits<T>::kIsHandle> Helper; |
259 | 289 |
260 static Array_Data<T>* New(size_t num_elements, Buffer* buf, | 290 static Array_Data<T>* New(size_t num_elements, Buffer* buf, |
261 Buffer::Destructor dtor = NULL) { | 291 Buffer::Destructor dtor = NULL) { |
262 size_t num_bytes = sizeof(Array_Data<T>) + | 292 size_t num_bytes = sizeof(Array_Data<T>) + |
263 Traits::GetStorageSize(num_elements); | 293 Traits::GetStorageSize(num_elements); |
264 return new (buf->Allocate(num_bytes, dtor)) Array_Data<T>(num_bytes, | 294 return new (buf->Allocate(num_bytes, dtor)) Array_Data<T>(num_bytes, |
265 num_elements); | 295 num_elements); |
266 } | 296 } |
267 | 297 |
268 static void Destructor(void* address) { | 298 static void Destructor(void* address) { |
269 static_cast<Array_Data*>(address)->CloseHandles(); | 299 static_cast<Array_Data*>(address)->CloseHandles(); |
270 } | 300 } |
271 | 301 |
| 302 static bool Validate(const void* data, BoundsChecker* bounds_checker) { |
| 303 if (!data) |
| 304 return true; |
| 305 if (!IsAligned(data)) |
| 306 return false; |
| 307 if (!bounds_checker->IsWithinBounds(data, sizeof(ArrayHeader))) |
| 308 return false; |
| 309 const ArrayHeader* header = static_cast<const ArrayHeader*>(data); |
| 310 if (header->num_bytes < (sizeof(Array_Data<T>) + |
| 311 Traits::GetStorageSize(header->num_elements))) { |
| 312 return false; |
| 313 } |
| 314 if (!bounds_checker->ClaimMemory(data, header->num_bytes)) |
| 315 return false; |
| 316 |
| 317 const Array_Data<T>* object = static_cast<const Array_Data<T>*>(data); |
| 318 return Helper::ValidateElements(&object->header_, object->storage(), |
| 319 bounds_checker); |
| 320 } |
| 321 |
272 size_t size() const { return header_.num_elements; } | 322 size_t size() const { return header_.num_elements; } |
273 | 323 |
274 Ref at(size_t offset) { | 324 Ref at(size_t offset) { |
275 assert(offset < static_cast<size_t>(header_.num_elements)); | 325 assert(offset < static_cast<size_t>(header_.num_elements)); |
276 return Traits::ToRef(storage(), offset); | 326 return Traits::ToRef(storage(), offset); |
277 } | 327 } |
278 | 328 |
279 ConstRef at(size_t offset) const { | 329 ConstRef at(size_t offset) const { |
280 assert(offset < static_cast<size_t>(header_.num_elements)); | 330 assert(offset < static_cast<size_t>(header_.num_elements)); |
281 return Traits::ToConstRef(storage(), offset); | 331 return Traits::ToConstRef(storage(), offset); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 static Ref ToRef(H& data) { return Ref(&data); } | 453 static Ref ToRef(H& data) { return Ref(&data); } |
404 static ConstRef ToConstRef(const H& data) { | 454 static ConstRef ToConstRef(const H& data) { |
405 return ConstRef(const_cast<H*>(&data)); | 455 return ConstRef(const_cast<H*>(&data)); |
406 } | 456 } |
407 }; | 457 }; |
408 | 458 |
409 } // namespace internal | 459 } // namespace internal |
410 } // namespace mojo | 460 } // namespace mojo |
411 | 461 |
412 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ | 462 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
OLD | NEW |