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_BINDINGS_SERIALIZATION_H_ | 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ |
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ | 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ |
7 | 7 |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "mojo/public/cpp/bindings/buffer.h" | 10 #include "mojo/public/cpp/bindings/buffer.h" |
11 #include "mojo/public/cpp/bindings/message.h" | 11 #include "mojo/public/cpp/bindings/message.h" |
12 | 12 |
13 namespace mojo { | 13 namespace mojo { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
| 16 class BoundsChecker; |
| 17 |
| 18 // Please note that this is a different value than |mojo::kInvalidHandleValue|, |
| 19 // which is the "decoded" invalid handle. |
| 20 const MojoHandle kEncodedInvalidHandleValue = static_cast<MojoHandle>(-1); |
| 21 |
16 size_t Align(size_t size); | 22 size_t Align(size_t size); |
17 char* AlignPointer(char* ptr); | 23 char* AlignPointer(char* ptr); |
18 | 24 |
| 25 bool IsAligned(const void* ptr); |
| 26 |
19 // Pointers are encoded as relative offsets. The offsets are relative to the | 27 // Pointers are encoded as relative offsets. The offsets are relative to the |
20 // address of where the offset value is stored, such that the pointer may be | 28 // address of where the offset value is stored, such that the pointer may be |
21 // recovered with the expression: | 29 // recovered with the expression: |
22 // | 30 // |
23 // ptr = reinterpret_cast<char*>(offset) + *offset | 31 // ptr = reinterpret_cast<char*>(offset) + *offset |
24 // | 32 // |
25 // A null pointer is encoded as an offset value of 0. | 33 // A null pointer is encoded as an offset value of 0. |
26 // | 34 // |
27 void EncodePointer(const void* ptr, uint64_t* offset); | 35 void EncodePointer(const void* ptr, uint64_t* offset); |
28 const void* DecodePointerRaw(const uint64_t* offset); | 36 const void* DecodePointerRaw(const uint64_t* offset); |
29 | 37 |
30 template <typename T> | 38 template <typename T> |
31 inline void DecodePointer(const uint64_t* offset, T** ptr) { | 39 inline void DecodePointer(const uint64_t* offset, T** ptr) { |
32 *ptr = reinterpret_cast<T*>(const_cast<void*>(DecodePointerRaw(offset))); | 40 *ptr = reinterpret_cast<T*>(const_cast<void*>(DecodePointerRaw(offset))); |
33 } | 41 } |
34 | 42 |
| 43 // Checks whether decoding the pointer will overflow and produce a pointer |
| 44 // smaller than |offset|. |
| 45 bool ValidateEncodedPointer(const uint64_t* offset); |
| 46 |
35 // Check that the given pointer references memory contained within the message. | 47 // Check that the given pointer references memory contained within the message. |
36 bool ValidatePointer(const void* ptr, const Message& message); | 48 bool ValidatePointer(const void* ptr, const Message& message); |
37 | 49 |
38 // Handles are encoded as indices into a vector of handles. These functions | 50 // Handles are encoded as indices into a vector of handles. These functions |
39 // manipulate the value of |handle|, mapping it to and from an index. | 51 // manipulate the value of |handle|, mapping it to and from an index. |
40 void EncodeHandle(Handle* handle, std::vector<Handle>* handles); | 52 void EncodeHandle(Handle* handle, std::vector<Handle>* handles); |
41 bool DecodeHandle(Handle* handle, std::vector<Handle>* handles); | 53 bool DecodeHandle(Handle* handle, std::vector<Handle>* handles); |
42 | 54 |
43 // The following 2 functions are used to encode/decode all objects (structs and | 55 // The following 2 functions are used to encode/decode all objects (structs and |
44 // arrays) in a consistent manner. | 56 // arrays) in a consistent manner. |
45 | 57 |
46 template <typename T> | 58 template <typename T> |
47 inline void Encode(T* obj, std::vector<Handle>* handles) { | 59 inline void Encode(T* obj, std::vector<Handle>* handles) { |
48 if (obj->ptr) | 60 if (obj->ptr) |
49 obj->ptr->EncodePointersAndHandles(handles); | 61 obj->ptr->EncodePointersAndHandles(handles); |
50 EncodePointer(obj->ptr, &obj->offset); | 62 EncodePointer(obj->ptr, &obj->offset); |
51 } | 63 } |
52 | 64 |
| 65 // TODO(yzshen): Remove all redundant validation during decoding. And make |
| 66 // Decode*() functions/methods return void. |
53 template <typename T> | 67 template <typename T> |
54 inline bool Decode(T* obj, Message* message) { | 68 inline bool Decode(T* obj, Message* message) { |
55 DecodePointer(&obj->offset, &obj->ptr); | 69 DecodePointer(&obj->offset, &obj->ptr); |
56 if (obj->ptr) { | 70 if (obj->ptr) { |
57 if (!ValidatePointer(obj->ptr, *message)) | 71 if (!ValidatePointer(obj->ptr, *message)) |
58 return false; | 72 return false; |
59 if (!obj->ptr->DecodePointersAndHandles(message)) | 73 if (!obj->ptr->DecodePointersAndHandles(message)) |
60 return false; | 74 return false; |
61 } | 75 } |
62 return true; | 76 return true; |
63 } | 77 } |
64 | 78 |
| 79 // If returns true, this function also claims the memory range of the size |
| 80 // specified in the struct header, starting from |data|. |
| 81 bool ValidateStructHeader(const void* data, |
| 82 uint32_t min_num_bytes, |
| 83 uint32_t min_num_fields, |
| 84 BoundsChecker* bounds_checker); |
| 85 |
65 } // namespace internal | 86 } // namespace internal |
66 } // namespace mojo | 87 } // namespace mojo |
67 | 88 |
68 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ | 89 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ |
OLD | NEW |