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 #include <vector> | 9 #include <vector> |
10 | 10 |
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/lib/buffer.h" | 14 #include "mojo/public/cpp/bindings/lib/buffer.h" |
14 | 15 |
15 namespace mojo { | 16 namespace mojo { |
16 template <typename T> class Array; | 17 template <typename T> class Array; |
17 class String; | 18 class String; |
18 | 19 |
19 namespace internal { | 20 namespace internal { |
20 | 21 |
21 template <typename T> | 22 template <typename T> |
22 struct ArrayDataTraits { | 23 struct ArrayDataTraits { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 static void EncodePointersAndHandles(const ArrayHeader* header, | 104 static void EncodePointersAndHandles(const ArrayHeader* header, |
104 ElementType* elements, | 105 ElementType* elements, |
105 std::vector<Handle>* handles) { | 106 std::vector<Handle>* handles) { |
106 } | 107 } |
107 | 108 |
108 static bool DecodePointersAndHandles(const ArrayHeader* header, | 109 static bool DecodePointersAndHandles(const ArrayHeader* header, |
109 ElementType* elements, | 110 ElementType* elements, |
110 Message* message) { | 111 Message* message) { |
111 return true; | 112 return true; |
112 } | 113 } |
| 114 |
| 115 static bool ValidateElements(const ArrayHeader* header, |
| 116 const ElementType* elements, |
| 117 BoundsChecker* bounds_checker) { |
| 118 return true; |
| 119 } |
113 }; | 120 }; |
114 | 121 |
115 template <> | 122 template <> |
116 struct ArraySerializationHelper<Handle, true> { | 123 struct ArraySerializationHelper<Handle, true> { |
117 typedef ArrayDataTraits<Handle>::StorageType ElementType; | 124 typedef ArrayDataTraits<Handle>::StorageType ElementType; |
118 | 125 |
119 static void EncodePointersAndHandles(const ArrayHeader* header, | 126 static void EncodePointersAndHandles(const ArrayHeader* header, |
120 ElementType* elements, | 127 ElementType* elements, |
121 std::vector<Handle>* handles); | 128 std::vector<Handle>* handles); |
122 | 129 |
123 static bool DecodePointersAndHandles(const ArrayHeader* header, | 130 static bool DecodePointersAndHandles(const ArrayHeader* header, |
124 ElementType* elements, | 131 ElementType* elements, |
125 Message* message); | 132 Message* message); |
| 133 |
| 134 static bool ValidateElements(const ArrayHeader* header, |
| 135 const ElementType* elements, |
| 136 BoundsChecker* bounds_checker); |
126 }; | 137 }; |
127 | 138 |
128 template <typename H> | 139 template <typename H> |
129 struct ArraySerializationHelper<H, true> { | 140 struct ArraySerializationHelper<H, true> { |
130 typedef typename ArrayDataTraits<H>::StorageType ElementType; | 141 typedef typename ArrayDataTraits<H>::StorageType ElementType; |
131 | 142 |
132 static void EncodePointersAndHandles(const ArrayHeader* header, | 143 static void EncodePointersAndHandles(const ArrayHeader* header, |
133 ElementType* elements, | 144 ElementType* elements, |
134 std::vector<Handle>* handles) { | 145 std::vector<Handle>* handles) { |
135 ArraySerializationHelper<Handle, true>::EncodePointersAndHandles( | 146 ArraySerializationHelper<Handle, true>::EncodePointersAndHandles( |
136 header, elements, handles); | 147 header, elements, handles); |
137 } | 148 } |
138 | 149 |
139 static bool DecodePointersAndHandles(const ArrayHeader* header, | 150 static bool DecodePointersAndHandles(const ArrayHeader* header, |
140 ElementType* elements, | 151 ElementType* elements, |
141 Message* message) { | 152 Message* message) { |
142 return ArraySerializationHelper<Handle, true>::DecodePointersAndHandles( | 153 return ArraySerializationHelper<Handle, true>::DecodePointersAndHandles( |
143 header, elements, message); | 154 header, elements, message); |
144 } | 155 } |
| 156 |
| 157 static bool ValidateElements(const ArrayHeader* header, |
| 158 const ElementType* elements, |
| 159 BoundsChecker* bounds_checker) { |
| 160 return ArraySerializationHelper<Handle, true>::ValidateElements( |
| 161 header, elements, bounds_checker); |
| 162 } |
145 }; | 163 }; |
146 | 164 |
147 template <typename P> | 165 template <typename P> |
148 struct ArraySerializationHelper<P*, false> { | 166 struct ArraySerializationHelper<P*, false> { |
149 typedef typename ArrayDataTraits<P*>::StorageType ElementType; | 167 typedef typename ArrayDataTraits<P*>::StorageType ElementType; |
150 | 168 |
151 static void EncodePointersAndHandles(const ArrayHeader* header, | 169 static void EncodePointersAndHandles(const ArrayHeader* header, |
152 ElementType* elements, | 170 ElementType* elements, |
153 std::vector<Handle>* handles) { | 171 std::vector<Handle>* handles) { |
154 for (uint32_t i = 0; i < header->num_elements; ++i) | 172 for (uint32_t i = 0; i < header->num_elements; ++i) |
155 Encode(&elements[i], handles); | 173 Encode(&elements[i], handles); |
156 } | 174 } |
157 | 175 |
158 static bool DecodePointersAndHandles(const ArrayHeader* header, | 176 static bool DecodePointersAndHandles(const ArrayHeader* header, |
159 ElementType* elements, | 177 ElementType* elements, |
160 Message* message) { | 178 Message* message) { |
161 for (uint32_t i = 0; i < header->num_elements; ++i) { | 179 for (uint32_t i = 0; i < header->num_elements; ++i) { |
162 if (!Decode(&elements[i], message)) | 180 if (!Decode(&elements[i], message)) |
163 return false; | 181 return false; |
164 } | 182 } |
165 return true; | 183 return true; |
166 } | 184 } |
| 185 |
| 186 static bool ValidateElements(const ArrayHeader* header, |
| 187 const ElementType* elements, |
| 188 BoundsChecker* bounds_checker) { |
| 189 for (uint32_t i = 0; i < header->num_elements; ++i) { |
| 190 if (!ValidateEncodedPointer(&elements[i].offset) || |
| 191 !P::Validate(DecodePointerRaw(&elements[i].offset), bounds_checker)) { |
| 192 return false; |
| 193 } |
| 194 } |
| 195 return true; |
| 196 } |
167 }; | 197 }; |
168 | 198 |
169 template <typename T> | 199 template <typename T> |
170 class Array_Data { | 200 class Array_Data { |
171 public: | 201 public: |
172 typedef ArrayDataTraits<T> Traits; | 202 typedef ArrayDataTraits<T> Traits; |
173 typedef typename Traits::StorageType StorageType; | 203 typedef typename Traits::StorageType StorageType; |
174 typedef typename Traits::Ref Ref; | 204 typedef typename Traits::Ref Ref; |
175 typedef typename Traits::ConstRef ConstRef; | 205 typedef typename Traits::ConstRef ConstRef; |
176 typedef ArraySerializationHelper<T, IsHandle<T>::value> Helper; | 206 typedef ArraySerializationHelper<T, IsHandle<T>::value> Helper; |
177 | 207 |
178 static Array_Data<T>* New(size_t num_elements, Buffer* buf) { | 208 static Array_Data<T>* New(size_t num_elements, Buffer* buf) { |
179 size_t num_bytes = sizeof(Array_Data<T>) + | 209 size_t num_bytes = sizeof(Array_Data<T>) + |
180 Traits::GetStorageSize(num_elements); | 210 Traits::GetStorageSize(num_elements); |
181 return new (buf->Allocate(num_bytes)) Array_Data<T>(num_bytes, | 211 return new (buf->Allocate(num_bytes)) Array_Data<T>(num_bytes, |
182 num_elements); | 212 num_elements); |
183 } | 213 } |
184 | 214 |
| 215 static bool Validate(const void* data, BoundsChecker* bounds_checker) { |
| 216 if (!data) |
| 217 return true; |
| 218 if (!IsAligned(data)) |
| 219 return false; |
| 220 if (!bounds_checker->IsValidRange(data, sizeof(ArrayHeader))) |
| 221 return false; |
| 222 const ArrayHeader* header = static_cast<const ArrayHeader*>(data); |
| 223 if (header->num_bytes < (sizeof(Array_Data<T>) + |
| 224 Traits::GetStorageSize(header->num_elements))) { |
| 225 return false; |
| 226 } |
| 227 if (!bounds_checker->ClaimMemory(data, header->num_bytes)) |
| 228 return false; |
| 229 |
| 230 const Array_Data<T>* object = static_cast<const Array_Data<T>*>(data); |
| 231 return Helper::ValidateElements(&object->header_, object->storage(), |
| 232 bounds_checker); |
| 233 } |
| 234 |
185 size_t size() const { return header_.num_elements; } | 235 size_t size() const { return header_.num_elements; } |
186 | 236 |
187 Ref at(size_t offset) { | 237 Ref at(size_t offset) { |
188 assert(offset < static_cast<size_t>(header_.num_elements)); | 238 assert(offset < static_cast<size_t>(header_.num_elements)); |
189 return Traits::ToRef(storage(), offset); | 239 return Traits::ToRef(storage(), offset); |
190 } | 240 } |
191 | 241 |
192 ConstRef at(size_t offset) const { | 242 ConstRef at(size_t offset) const { |
193 assert(offset < static_cast<size_t>(header_.num_elements)); | 243 assert(offset < static_cast<size_t>(header_.num_elements)); |
194 return Traits::ToConstRef(storage(), offset); | 244 return Traits::ToConstRef(storage(), offset); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 }; | 320 }; |
271 | 321 |
272 template <> struct WrapperTraits<String, false> { | 322 template <> struct WrapperTraits<String, false> { |
273 typedef String_Data* DataType; | 323 typedef String_Data* DataType; |
274 }; | 324 }; |
275 | 325 |
276 } // namespace internal | 326 } // namespace internal |
277 } // namespace mojo | 327 } // namespace mojo |
278 | 328 |
279 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ | 329 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
OLD | NEW |