| 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 |