blob: ec04c77c6c181fbc150581889af02f25801723ac [file] [log] [blame]
[email protected]a7c03d4f32012-01-24 02:36:051// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]946d1b22009-07-22 23:57:212// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ipc/ipc_message_utils.h"
6
avi246998d82015-12-22 02:39:047#include <stddef.h>
8#include <stdint.h>
9
[email protected]57999812013-02-24 05:40:5210#include "base/files/file_path.h"
[email protected]93d49d72009-10-23 20:00:2011#include "base/json/json_writer.h"
jdoerrief1e72e32017-04-26 16:23:5512#include "base/memory/ptr_util.h"
[email protected]0238a162013-06-13 13:47:4613#include "base/strings/nullable_string16.h"
[email protected]4aa794a12013-06-11 06:32:1814#include "base/strings/string_number_conversions.h"
[email protected]906265872013-06-07 22:40:4515#include "base/strings/utf_string_conversions.h"
[email protected]b43e5562013-06-28 15:20:0216#include "base/time/time.h"
tguilbert4a5ac602016-09-19 21:11:2517#include "base/unguessable_token.h"
[email protected]946d1b22009-07-22 23:57:2118#include "base/values.h"
avi246998d82015-12-22 02:39:0419#include "build/build_config.h"
[email protected]bf5aedf02012-06-04 21:18:2520#include "ipc/ipc_channel_handle.h"
morrita1aa788c2015-01-31 05:45:4221#include "ipc/ipc_message_attachment.h"
morrita4b5c28e22015-01-14 21:17:0622#include "ipc/ipc_message_attachment_set.h"
amistry36182522016-06-27 06:34:4223#include "ipc/ipc_mojo_param_traits.h"
[email protected]bf5aedf02012-06-04 21:18:2524
erikchenaf8299d2015-10-09 19:12:0625#if defined(OS_MACOSX) && !defined(OS_IOS)
26#include "ipc/mach_port_mac.h"
27#endif
28
morrita4b5c28e22015-01-14 21:17:0629#if defined(OS_WIN)
[email protected]2e02cfe82012-11-21 00:58:0030#include <tchar.h>
erikchen5ea2ab72015-09-25 22:34:3131#include "ipc/handle_win.h"
erikchend804e1052017-04-29 02:24:3632#include "ipc/ipc_platform_file.h"
Fabrice de Gans-Ribericbce4342018-05-07 20:02:0933#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
34#include "base/file_descriptor_posix.h"
35#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]7a4de7a62010-08-17 18:38:2436#endif
[email protected]946d1b22009-07-22 23:57:2137
Scott Graham3eebff02017-06-30 01:07:1038#if defined(OS_FUCHSIA)
39#include "ipc/handle_fuchsia.h"
40#endif
41
Ken Rockot097248f02018-04-23 16:23:3442#if defined(OS_ANDROID)
43#include "base/android/scoped_hardware_buffer_handle.h"
44#include "ipc/ipc_mojo_handle_attachment.h"
45#include "mojo/public/cpp/system/message_pipe.h"
46#include "mojo/public/cpp/system/scope_to_message_pipe.h"
47#endif
48
[email protected]946d1b22009-07-22 23:57:2149namespace IPC {
50
[email protected]bf5aedf02012-06-04 21:18:2551namespace {
52
joaodasilva383b174a2017-01-10 09:55:3653const int kMaxRecursionDepth = 200;
[email protected]946d1b22009-07-22 23:57:2154
[email protected]bf5aedf02012-06-04 21:18:2555template<typename CharType>
56void LogBytes(const std::vector<CharType>& data, std::string* out) {
57#if defined(OS_WIN)
58 // Windows has a GUI for logging, which can handle arbitrary binary data.
59 for (size_t i = 0; i < data.size(); ++i)
60 out->push_back(data[i]);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:0961#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]bf5aedf02012-06-04 21:18:2562 // On POSIX, we log to stdout, which we assume can display ASCII.
63 static const size_t kMaxBytesToLog = 100;
64 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
65 if (isprint(data[i]))
66 out->push_back(data[i]);
67 else
[email protected]7d3cbc92013-03-18 22:33:0468 out->append(
69 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]bf5aedf02012-06-04 21:18:2570 }
71 if (data.size() > kMaxBytesToLog) {
[email protected]f8660f82013-03-30 17:29:2872 out->append(base::StringPrintf(
73 " and %u more bytes",
74 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
[email protected]bf5aedf02012-06-04 21:18:2575 }
76#endif
77}
[email protected]946d1b22009-07-22 23:57:2178
rockot502c94f2016-02-03 20:20:1679bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:2580 base::PickleIterator* iter,
jdoerrief1e72e32017-04-26 16:23:5581 std::unique_ptr<base::Value>* value,
[email protected]bf5aedf02012-06-04 21:18:2582 int recursion);
[email protected]946d1b22009-07-22 23:57:2183
rockot502c94f2016-02-03 20:20:1684void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
[email protected]dbc761a2012-07-26 01:29:2185 bool result;
[email protected]946d1b22009-07-22 23:57:2186 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:3687 LOG(ERROR) << "Max recursion depth hit in WriteValue.";
[email protected]946d1b22009-07-22 23:57:2188 return;
89 }
90
jdoerrie76cee9c2017-10-06 22:42:4291 m->WriteInt(static_cast<int>(value->type()));
[email protected]946d1b22009-07-22 23:57:2192
jdoerrie76cee9c2017-10-06 22:42:4293 switch (value->type()) {
jdoerriedc72ee942016-12-07 15:43:2894 case base::Value::Type::NONE:
[email protected]946d1b22009-07-22 23:57:2195 break;
jdoerriedc72ee942016-12-07 15:43:2896 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:2197 bool val;
[email protected]dbc761a2012-07-26 01:29:2198 result = value->GetAsBoolean(&val);
99 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21100 WriteParam(m, val);
101 break;
102 }
jdoerriedc72ee942016-12-07 15:43:28103 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21104 int val;
[email protected]dbc761a2012-07-26 01:29:21105 result = value->GetAsInteger(&val);
106 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21107 WriteParam(m, val);
108 break;
109 }
jdoerriedc72ee942016-12-07 15:43:28110 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21111 double val;
[email protected]dbc761a2012-07-26 01:29:21112 result = value->GetAsDouble(&val);
113 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21114 WriteParam(m, val);
115 break;
116 }
jdoerriedc72ee942016-12-07 15:43:28117 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21118 std::string val;
[email protected]dbc761a2012-07-26 01:29:21119 result = value->GetAsString(&val);
120 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21121 WriteParam(m, val);
122 break;
123 }
jdoerriedc72ee942016-12-07 15:43:28124 case base::Value::Type::BINARY: {
jdoerrie9970f20e2018-07-20 21:41:18125 m->WriteData(reinterpret_cast<const char*>(value->GetBlob().data()),
Chris Palmerc5ea9b92017-09-25 22:53:22126 base::checked_cast<int>(value->GetBlob().size()));
[email protected]e4dad9fb2009-10-06 18:15:58127 break;
[email protected]946d1b22009-07-22 23:57:21128 }
jdoerriedc72ee942016-12-07 15:43:28129 case base::Value::Type::DICTIONARY: {
[email protected]ea5ef4c2013-06-13 22:50:27130 const base::DictionaryValue* dict =
131 static_cast<const base::DictionaryValue*>(value);
[email protected]946d1b22009-07-22 23:57:21132
Chris Palmerc5ea9b92017-09-25 22:53:22133 WriteParam(m, base::checked_cast<int>(dict->size()));
[email protected]946d1b22009-07-22 23:57:21134
[email protected]ea5ef4c2013-06-13 22:50:27135 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
136 it.Advance()) {
[email protected]a899c0b02013-01-18 14:43:27137 WriteParam(m, it.key());
138 WriteValue(m, &it.value(), recursion + 1);
[email protected]946d1b22009-07-22 23:57:21139 }
140 break;
141 }
jdoerriedc72ee942016-12-07 15:43:28142 case base::Value::Type::LIST: {
[email protected]ea5ef4c2013-06-13 22:50:27143 const base::ListValue* list = static_cast<const base::ListValue*>(value);
Chris Palmerc5ea9b92017-09-25 22:53:22144 WriteParam(m, base::checked_cast<int>(list->GetSize()));
dchengcb60e702016-05-25 18:30:47145 for (const auto& entry : *list) {
jdoerriea5676c62017-04-11 18:09:14146 WriteValue(m, &entry, recursion + 1);
[email protected]946d1b22009-07-22 23:57:21147 }
148 break;
149 }
150 }
151}
152
153// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
154// object.
rockot502c94f2016-02-03 20:20:16155bool ReadDictionaryValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25156 base::PickleIterator* iter,
157 base::DictionaryValue* value,
158 int recursion) {
[email protected]946d1b22009-07-22 23:57:21159 int size;
160 if (!ReadParam(m, iter, &size))
161 return false;
162
163 for (int i = 0; i < size; ++i) {
[email protected]e7b418b2010-07-30 19:47:47164 std::string key;
jdoerrief1e72e32017-04-26 16:23:55165 std::unique_ptr<base::Value> subval;
[email protected]946d1b22009-07-22 23:57:21166 if (!ReadParam(m, iter, &key) ||
167 !ReadValue(m, iter, &subval, recursion + 1))
168 return false;
jdoerrief1e72e32017-04-26 16:23:55169 value->SetWithoutPathExpansion(key, std::move(subval));
[email protected]946d1b22009-07-22 23:57:21170 }
171
172 return true;
173}
174
175// Helper for ReadValue that reads a ReadListValue into a pre-allocated
176// object.
rockot502c94f2016-02-03 20:20:16177bool ReadListValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25178 base::PickleIterator* iter,
179 base::ListValue* value,
180 int recursion) {
[email protected]946d1b22009-07-22 23:57:21181 int size;
182 if (!ReadParam(m, iter, &size))
183 return false;
184
185 for (int i = 0; i < size; ++i) {
jdoerrief1e72e32017-04-26 16:23:55186 std::unique_ptr<base::Value> subval;
[email protected]946d1b22009-07-22 23:57:21187 if (!ReadValue(m, iter, &subval, recursion + 1))
188 return false;
jdoerrief1e72e32017-04-26 16:23:55189 value->Set(i, std::move(subval));
[email protected]946d1b22009-07-22 23:57:21190 }
191
192 return true;
193}
194
rockot502c94f2016-02-03 20:20:16195bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25196 base::PickleIterator* iter,
jdoerrief1e72e32017-04-26 16:23:55197 std::unique_ptr<base::Value>* value,
[email protected]bf5aedf02012-06-04 21:18:25198 int recursion) {
[email protected]946d1b22009-07-22 23:57:21199 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:36200 LOG(ERROR) << "Max recursion depth hit in ReadValue.";
[email protected]946d1b22009-07-22 23:57:21201 return false;
202 }
203
204 int type;
205 if (!ReadParam(m, iter, &type))
206 return false;
207
jdoerriedc72ee942016-12-07 15:43:28208 switch (static_cast<base::Value::Type>(type)) {
209 case base::Value::Type::NONE:
Jeremy Roman160eb922017-08-29 17:43:43210 *value = std::make_unique<base::Value>();
jdoerriee067999a2017-04-07 06:39:00211 break;
jdoerriedc72ee942016-12-07 15:43:28212 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21213 bool val;
214 if (!ReadParam(m, iter, &val))
215 return false;
Jeremy Roman160eb922017-08-29 17:43:43216 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21217 break;
218 }
jdoerriedc72ee942016-12-07 15:43:28219 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21220 int val;
221 if (!ReadParam(m, iter, &val))
222 return false;
Jeremy Roman160eb922017-08-29 17:43:43223 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21224 break;
225 }
jdoerriedc72ee942016-12-07 15:43:28226 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21227 double val;
228 if (!ReadParam(m, iter, &val))
229 return false;
Jeremy Roman160eb922017-08-29 17:43:43230 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21231 break;
232 }
jdoerriedc72ee942016-12-07 15:43:28233 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21234 std::string val;
235 if (!ReadParam(m, iter, &val))
236 return false;
Jeremy Roman160eb922017-08-29 17:43:43237 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21238 break;
239 }
jdoerriedc72ee942016-12-07 15:43:28240 case base::Value::Type::BINARY: {
[email protected]e4dad9fb2009-10-06 18:15:58241 const char* data;
242 int length;
avi48fc13b2014-12-28 23:31:48243 if (!iter->ReadData(&data, &length))
[email protected]e4dad9fb2009-10-06 18:15:58244 return false;
jdoerrief1e72e32017-04-26 16:23:55245 *value = base::Value::CreateWithCopiedBuffer(data, length);
[email protected]946d1b22009-07-22 23:57:21246 break;
247 }
jdoerriedc72ee942016-12-07 15:43:28248 case base::Value::Type::DICTIONARY: {
jdoerrief1e72e32017-04-26 16:23:55249 base::DictionaryValue val;
250 if (!ReadDictionaryValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21251 return false;
Jeremy Roman160eb922017-08-29 17:43:43252 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21253 break;
254 }
jdoerriedc72ee942016-12-07 15:43:28255 case base::Value::Type::LIST: {
jdoerrief1e72e32017-04-26 16:23:55256 base::ListValue val;
257 if (!ReadListValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21258 return false;
Jeremy Roman160eb922017-08-29 17:43:43259 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21260 break;
261 }
[email protected]e4dad9fb2009-10-06 18:15:58262 default:
[email protected]946d1b22009-07-22 23:57:21263 return false;
264 }
265
266 return true;
267}
268
[email protected]bf5aedf02012-06-04 21:18:25269} // namespace
270
271// -----------------------------------------------------------------------------
272
273LogData::LogData()
274 : routing_id(0),
275 type(0),
276 sent(0),
277 receive(0),
278 dispatch(0) {
279}
280
vmpstrbf0d713a2016-03-24 20:22:54281LogData::LogData(const LogData& other) = default;
282
Chris Watkins2d879af2017-11-30 02:11:59283LogData::~LogData() = default;
[email protected]bf5aedf02012-06-04 21:18:25284
[email protected]bf5aedf02012-06-04 21:18:25285void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
286 l->append(p ? "true" : "false");
287}
288
rockot502c94f2016-02-03 20:20:16289void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno19ecf1842015-10-30 00:46:20290 m->WriteBytes(&p, sizeof(param_type));
291}
292
rockot502c94f2016-02-03 20:20:16293bool ParamTraits<signed char>::Read(const base::Pickle* m,
294 base::PickleIterator* iter,
295 param_type* r) {
ortuno19ecf1842015-10-30 00:46:20296 const char* data;
297 if (!iter->ReadBytes(&data, sizeof(param_type)))
298 return false;
299 memcpy(r, data, sizeof(param_type));
300 return true;
301}
302
303void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38304 l->append(base::NumberToString(p));
ortuno19ecf1842015-10-30 00:46:20305}
306
rockot502c94f2016-02-03 20:20:16307void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28308 m->WriteBytes(&p, sizeof(param_type));
309}
310
rockot502c94f2016-02-03 20:20:16311bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25312 base::PickleIterator* iter,
313 param_type* r) {
[email protected]c1ee48d2013-07-12 23:12:28314 const char* data;
avi48fc13b2014-12-28 23:31:48315 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28316 return false;
317 memcpy(r, data, sizeof(param_type));
318 return true;
319}
320
321void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38322 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28323}
324
rockot502c94f2016-02-03 20:20:16325void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28326 m->WriteBytes(&p, sizeof(param_type));
327}
328
rockot502c94f2016-02-03 20:20:16329bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25330 base::PickleIterator* iter,
[email protected]c1ee48d2013-07-12 23:12:28331 param_type* r) {
332 const char* data;
avi48fc13b2014-12-28 23:31:48333 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28334 return false;
335 memcpy(r, data, sizeof(param_type));
336 return true;
337}
338
339void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09340 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28341}
342
[email protected]252cad62010-08-18 18:33:57343void ParamTraits<int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09344 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57345}
346
347void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09348 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57349}
350
Sergey Ulanova98ff6b52017-07-13 01:54:20351#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_FUCHSIA) || \
jamac78d7d82016-02-11 00:50:28352 (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]252cad62010-08-18 18:33:57353void ParamTraits<long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09354 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57355}
356
357void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09358 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57359}
jam03d8a782016-02-10 20:13:39360#endif
[email protected]252cad62010-08-18 18:33:57361
362void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09363 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57364}
365
366void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09367 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57368}
[email protected]7a4de7a62010-08-17 18:38:24369
[email protected]bf5aedf02012-06-04 21:18:25370void ParamTraits<float>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04371 l->append(base::StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24372}
373
rockot502c94f2016-02-03 20:20:16374void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
[email protected]48328ff2013-10-31 09:27:31375 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52376}
377
rockot502c94f2016-02-03 20:20:16378bool ParamTraits<double>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25379 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25380 param_type* r) {
381 const char *data;
avi48fc13b2014-12-28 23:31:48382 if (!iter->ReadBytes(&data, sizeof(*r))) {
[email protected]bf5aedf02012-06-04 21:18:25383 NOTREACHED();
384 return false;
385 }
386 memcpy(r, data, sizeof(param_type));
387 return true;
[email protected]d84e48b2010-10-21 22:04:52388}
389
[email protected]bf5aedf02012-06-04 21:18:25390void ParamTraits<double>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04391 l->append(base::StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04392}
393
[email protected]bf5aedf02012-06-04 21:18:25394
395void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
396 l->append(p);
[email protected]1d14f582011-09-02 20:42:04397}
398
[email protected]476dafb2013-12-03 00:39:26399void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
[email protected]ad65a3e2013-12-25 18:18:01400 l->append(base::UTF16ToUTF8(p));
[email protected]bf5aedf02012-06-04 21:18:25401}
[email protected]bf5aedf02012-06-04 21:18:25402
rockot502c94f2016-02-03 20:20:16403void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
404 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25405 if (p.empty()) {
406 m->WriteData(NULL, 0);
407 } else {
Chris Palmerc5ea9b92017-09-25 22:53:22408 m->WriteData(&p.front(), base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25409 }
410}
411
rockot502c94f2016-02-03 20:20:16412bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25413 base::PickleIterator* iter,
414 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25415 const char *data;
416 int data_size = 0;
avi48fc13b2014-12-28 23:31:48417 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25418 return false;
419 r->resize(data_size);
420 if (data_size)
421 memcpy(&r->front(), data, data_size);
422 return true;
423}
424
425void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
426 LogBytes(p, l);
427}
428
rockot502c94f2016-02-03 20:20:16429void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
430 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25431 if (p.empty()) {
432 m->WriteData(NULL, 0);
433 } else {
434 m->WriteData(reinterpret_cast<const char*>(&p.front()),
Chris Palmerc5ea9b92017-09-25 22:53:22435 base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25436 }
437}
438
rockot502c94f2016-02-03 20:20:16439bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25440 base::PickleIterator* iter,
441 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25442 const char *data;
443 int data_size = 0;
avi48fc13b2014-12-28 23:31:48444 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25445 return false;
446 r->resize(data_size);
447 if (data_size)
448 memcpy(&r->front(), data, data_size);
449 return true;
450}
451
452void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
453 std::string* l) {
454 LogBytes(p, l);
455}
456
rockot502c94f2016-02-03 20:20:16457void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
458 const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22459 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]d4124852013-03-20 20:25:00460 // Cast to bool below is required because libc++'s
461 // vector<bool>::const_reference is different from bool, and we want to avoid
462 // writing an extra specialization of ParamTraits for it.
[email protected]bf5aedf02012-06-04 21:18:25463 for (size_t i = 0; i < p.size(); i++)
[email protected]d4124852013-03-20 20:25:00464 WriteParam(m, static_cast<bool>(p[i]));
[email protected]bf5aedf02012-06-04 21:18:25465}
466
rockot502c94f2016-02-03 20:20:16467bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25468 base::PickleIterator* iter,
469 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25470 int size;
471 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48472 if (!iter->ReadLength(&size))
[email protected]bf5aedf02012-06-04 21:18:25473 return false;
474 r->resize(size);
475 for (int i = 0; i < size; i++) {
476 bool value;
477 if (!ReadParam(m, iter, &value))
478 return false;
479 (*r)[i] = value;
480 }
481 return true;
482}
483
484void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
485 for (size_t i = 0; i < p.size(); ++i) {
486 if (i != 0)
487 l->push_back(' ');
[email protected]d4124852013-03-20 20:25:00488 LogParam(static_cast<bool>(p[i]), l);
[email protected]bf5aedf02012-06-04 21:18:25489 }
[email protected]d84e48b2010-10-21 22:04:52490}
491
rockot502c94f2016-02-03 20:20:16492void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
[email protected]ea5ef4c2013-06-13 22:50:27493 const param_type& p) {
[email protected]946d1b22009-07-22 23:57:21494 WriteValue(m, &p, 0);
495}
496
rockot502c94f2016-02-03 20:20:16497bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25498 base::PickleIterator* iter,
499 param_type* r) {
[email protected]946d1b22009-07-22 23:57:21500 int type;
jdoerriedc72ee942016-12-07 15:43:28501 if (!ReadParam(m, iter, &type) ||
502 type != static_cast<int>(base::Value::Type::DICTIONARY))
[email protected]946d1b22009-07-22 23:57:21503 return false;
504
505 return ReadDictionaryValue(m, iter, r, 0);
506}
507
[email protected]ea5ef4c2013-06-13 22:50:27508void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
509 std::string* l) {
[email protected]946d1b22009-07-22 23:57:21510 std::string json;
estade8d046462015-05-16 01:02:34511 base::JSONWriter::Write(p, &json);
[email protected]252cad62010-08-18 18:33:57512 l->append(json);
[email protected]946d1b22009-07-22 23:57:21513}
514
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09515#if defined(OS_POSIX) || defined(OS_FUCHSIA)
rockot502c94f2016-02-03 20:20:16516void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
517 const param_type& p) {
erikchen14525202017-05-06 19:16:51518 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06519 // nacl_message_scanner.cc:WriteHandle().
[email protected]7a4de7a62010-08-17 18:38:24520 const bool valid = p.fd >= 0;
521 WriteParam(m, valid);
522
morrita96693852014-09-24 20:11:45523 if (!valid)
524 return;
525
526 if (p.auto_close) {
morrita1aa788c2015-01-31 05:45:42527 if (!m->WriteAttachment(
528 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
morrita96693852014-09-24 20:11:45529 NOTREACHED();
530 } else {
morrita1aa788c2015-01-31 05:45:42531 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
[email protected]7a4de7a62010-08-17 18:38:24532 NOTREACHED();
533 }
534}
535
rockot502c94f2016-02-03 20:20:16536bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25537 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24538 param_type* r) {
morrita96693852014-09-24 20:11:45539 *r = base::FileDescriptor();
540
[email protected]7a4de7a62010-08-17 18:38:24541 bool valid;
542 if (!ReadParam(m, iter, &valid))
543 return false;
544
morrita96693852014-09-24 20:11:45545 if (!valid)
[email protected]7a4de7a62010-08-17 18:38:24546 return true;
[email protected]7a4de7a62010-08-17 18:38:24547
rockot502c94f2016-02-03 20:20:16548 scoped_refptr<base::Pickle::Attachment> attachment;
morrita1aa788c2015-01-31 05:45:42549 if (!m->ReadAttachment(iter, &attachment))
morrita96693852014-09-24 20:11:45550 return false;
551
sammc6ed3efb2016-11-23 03:17:35552 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
553 MessageAttachment::Type::PLATFORM_FILE) {
554 return false;
555 }
556
rockot502c94f2016-02-03 20:20:16557 *r = base::FileDescriptor(
sammc6ed3efb2016-11-23 03:17:35558 static_cast<internal::PlatformFileAttachment*>(attachment.get())
559 ->TakePlatformFile(),
rockot502c94f2016-02-03 20:20:16560 true);
morrita96693852014-09-24 20:11:45561 return true;
[email protected]7a4de7a62010-08-17 18:38:24562}
563
564void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57565 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24566 if (p.auto_close) {
[email protected]7d3cbc92013-03-18 22:33:04567 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24568 } else {
[email protected]7d3cbc92013-03-18 22:33:04569 l->append(base::StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24570 }
571}
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09572#endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]7a4de7a62010-08-17 18:38:24573
Klaus Weidner3824a8882017-11-03 06:24:57574#if defined(OS_ANDROID)
Alexandr Ilin0443a8f2018-07-20 20:14:50575void ParamTraits<base::android::ScopedHardwareBufferHandle>::Write(
576 base::Pickle* m,
577 const param_type& p) {
578 const bool is_valid = p.is_valid();
Ken Rockot097248f02018-04-23 16:23:34579 WriteParam(m, is_valid);
580 if (!is_valid)
581 return;
582
Ken Rockot097248f02018-04-23 16:23:34583 // We must keep a ref to the AHardwareBuffer alive until the receiver has
584 // acquired its own reference. We do this by sending a message pipe handle
585 // along with the buffer. When the receiver deserializes (or even if they
586 // die without ever reading the message) their end of the pipe will be
587 // closed. We will eventually detect this and release the AHB reference.
588 mojo::MessagePipe tracking_pipe;
589 m->WriteAttachment(new internal::MojoHandleAttachment(
590 mojo::ScopedHandle::From(std::move(tracking_pipe.handle0))));
Alexandr Ilin0443a8f2018-07-20 20:14:50591 WriteParam(m, base::FileDescriptor(p.SerializeAsFileDescriptor().release(),
592 true /* auto_close */));
Ken Rockot097248f02018-04-23 16:23:34593
594 // Pass ownership of the input handle to our tracking pipe to keep the AHB
595 // alive long enough to be deserialized by the receiver.
Alexandr Ilin0443a8f2018-07-20 20:14:50596 mojo::ScopeToMessagePipe(std::move(const_cast<param_type&>(p)),
597 std::move(tracking_pipe.handle1));
Klaus Weidner3824a8882017-11-03 06:24:57598}
599
Alexandr Ilin0443a8f2018-07-20 20:14:50600bool ParamTraits<base::android::ScopedHardwareBufferHandle>::Read(
601 const base::Pickle* m,
602 base::PickleIterator* iter,
603 param_type* r) {
604 *r = base::android::ScopedHardwareBufferHandle();
Ken Rockot097248f02018-04-23 16:23:34605
606 bool is_valid;
607 if (!ReadParam(m, iter, &is_valid))
Klaus Weidner3824a8882017-11-03 06:24:57608 return false;
Ken Rockot097248f02018-04-23 16:23:34609 if (!is_valid)
610 return true;
611
612 scoped_refptr<base::Pickle::Attachment> tracking_pipe_attachment;
613 if (!m->ReadAttachment(iter, &tracking_pipe_attachment))
Klaus Weidner3824a8882017-11-03 06:24:57614 return false;
Ken Rockot097248f02018-04-23 16:23:34615
616 // We keep this alive until the AHB is safely deserialized below. When this
617 // goes out of scope, the sender holding the other end of this pipe will treat
618 // this handle closure as a signal that it's safe to release their AHB
619 // keepalive ref.
620 mojo::ScopedHandle tracking_pipe =
621 static_cast<MessageAttachment*>(tracking_pipe_attachment.get())
622 ->TakeMojoHandle();
623
624 base::FileDescriptor descriptor;
625 if (!ReadParam(m, iter, &descriptor))
626 return false;
627
628 // NOTE: It is valid to deserialize an invalid FileDescriptor, so the success
629 // of |ReadParam()| above does not imply that |descriptor| is valid.
630 base::ScopedFD scoped_fd(descriptor.fd);
631 if (!scoped_fd.is_valid())
632 return false;
633
634 *r = base::android::ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(
Alexandr Ilin0443a8f2018-07-20 20:14:50635 std::move(scoped_fd));
Klaus Weidner3824a8882017-11-03 06:24:57636 return true;
637}
638
Alexandr Ilin0443a8f2018-07-20 20:14:50639void ParamTraits<base::android::ScopedHardwareBufferHandle>::Log(
640 const param_type& p,
641 std::string* l) {
642 l->append(base::StringPrintf("base::android::ScopedHardwareBufferHandle(%p)",
643 p.get()));
Klaus Weidner3824a8882017-11-03 06:24:57644}
Ken Rockot097248f02018-04-23 16:23:34645#endif // defined(OS_ANDROID)
Klaus Weidner3824a8882017-11-03 06:24:57646
erikchen22a813b2017-04-28 17:10:50647void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
648 const param_type& p) {
erikchen14525202017-05-06 19:16:51649 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06650 // nacl_message_scanner.cc:WriteHandle().
erikchen22a813b2017-04-28 17:10:50651 const bool valid = p.IsValid();
652 WriteParam(m, valid);
653
654 if (!valid)
655 return;
656
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09657#if defined(OS_WIN)
Wez51eaaad2017-08-09 05:51:38658 HandleWin handle_win(p.GetHandle());
erikchen9d6afd712017-05-18 17:49:06659 WriteParam(m, handle_win);
Wez8c49ebc92017-08-10 17:11:13660#elif defined(OS_FUCHSIA)
661 HandleFuchsia handle_fuchsia(p.GetHandle());
662 WriteParam(m, handle_fuchsia);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09663#elif defined(OS_MACOSX) && !defined(OS_IOS)
664 MachPortMac mach_port_mac(p.GetMemoryObject());
665 WriteParam(m, mach_port_mac);
666#elif defined(OS_POSIX)
Klaus Weidner3824a8882017-11-03 06:24:57667#if defined(OS_ANDROID)
David 'Digit' Turnere2a65762018-01-19 17:51:51668 WriteParam(m, p.IsReadOnly());
669
670 // Ensure the region is read-only before sending it through IPC.
671 if (p.IsReadOnly()) {
672 if (!p.IsRegionReadOnly()) {
673 LOG(ERROR) << "Sending unsealed read-only region through IPC";
674 p.SetRegionReadOnly();
675 }
676 }
Klaus Weidner3824a8882017-11-03 06:24:57677#endif
erikchen22a813b2017-04-28 17:10:50678 if (p.OwnershipPassesToIPC()) {
679 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
680 base::ScopedFD(p.GetHandle()))))
681 NOTREACHED();
682 } else {
683 if (!m->WriteAttachment(
684 new internal::PlatformFileAttachment(p.GetHandle())))
685 NOTREACHED();
686 }
erikchen9d6afd712017-05-18 17:49:06687#endif
688
689#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
690 // If the caller intended to pass ownership to the IPC stack, release a
691 // reference.
692 if (p.OwnershipPassesToIPC())
693 p.Close();
694#endif
695
erikchen14525202017-05-06 19:16:51696 DCHECK(!p.GetGUID().is_empty());
697 WriteParam(m, p.GetGUID());
erikchen9d6afd712017-05-18 17:49:06698 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
erikchen22a813b2017-04-28 17:10:50699}
700
701bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
702 base::PickleIterator* iter,
703 param_type* r) {
704 *r = base::SharedMemoryHandle();
705
706 bool valid;
707 if (!ReadParam(m, iter, &valid))
708 return false;
erikchen22a813b2017-04-28 17:10:50709 if (!valid)
710 return true;
711
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09712#if defined(OS_WIN)
erikchen9d6afd712017-05-18 17:49:06713 HandleWin handle_win;
714 if (!ReadParam(m, iter, &handle_win))
715 return false;
Scott Graham3eebff02017-06-30 01:07:10716#elif defined(OS_FUCHSIA)
717 HandleFuchsia handle_fuchsia;
718 if (!ReadParam(m, iter, &handle_fuchsia))
719 return false;
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09720#elif defined(OS_MACOSX) && !defined(OS_IOS)
721 MachPortMac mach_port_mac;
722 if (!ReadParam(m, iter, &mach_port_mac))
723 return false;
724#elif defined(OS_POSIX)
Klaus Weidner3824a8882017-11-03 06:24:57725#if defined(OS_ANDROID)
David 'Digit' Turnere2a65762018-01-19 17:51:51726 bool is_read_only = false;
Ken Rockot097248f02018-04-23 16:23:34727 if (!ReadParam(m, iter, &is_read_only))
Klaus Weidner3824a8882017-11-03 06:24:57728 return false;
729#endif
erikchen22a813b2017-04-28 17:10:50730 scoped_refptr<base::Pickle::Attachment> attachment;
731 if (!m->ReadAttachment(iter, &attachment))
732 return false;
733
734 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
735 MessageAttachment::Type::PLATFORM_FILE) {
736 return false;
737 }
erikchen9d6afd712017-05-18 17:49:06738#endif
erikchen22a813b2017-04-28 17:10:50739
erikchen14525202017-05-06 19:16:51740 base::UnguessableToken guid;
erikchen9d6afd712017-05-18 17:49:06741 uint64_t size;
Alexandr Ilind497eee2018-04-19 22:50:54742 if (!ReadParam(m, iter, &guid) || !ReadParam(m, iter, &size) ||
743 !base::IsValueInRangeForNumericType<size_t>(size)) {
erikchen14525202017-05-06 19:16:51744 return false;
erikchen9d6afd712017-05-18 17:49:06745 }
erikchen14525202017-05-06 19:16:51746
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09747#if defined(OS_WIN)
erikchen9d6afd712017-05-18 17:49:06748 *r = base::SharedMemoryHandle(handle_win.get_handle(),
749 static_cast<size_t>(size), guid);
Scott Graham3eebff02017-06-30 01:07:10750#elif defined(OS_FUCHSIA)
751 *r = base::SharedMemoryHandle(handle_fuchsia.get_handle(),
752 static_cast<size_t>(size), guid);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09753#elif defined(OS_MACOSX) && !defined(OS_IOS)
754 *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
755 static_cast<size_t>(size), guid);
756#elif defined(OS_POSIX)
erikchen14525202017-05-06 19:16:51757 *r = base::SharedMemoryHandle(
758 base::FileDescriptor(
759 static_cast<internal::PlatformFileAttachment*>(attachment.get())
760 ->TakePlatformFile(),
761 true),
erikchen9d6afd712017-05-18 17:49:06762 static_cast<size_t>(size), guid);
763#endif
764
Ken Rockot097248f02018-04-23 16:23:34765#if defined(OS_ANDROID)
766 if (is_read_only)
767 r->SetReadOnly();
768#endif
769
erikchen22a813b2017-04-28 17:10:50770 return true;
771}
772
773void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
774 std::string* l) {
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09775#if defined(OS_WIN)
erikchen9d6afd712017-05-18 17:49:06776 l->append("HANDLE: ");
777 LogParam(p.GetHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09778#elif defined(OS_MACOSX) && !defined(OS_IOS)
779 l->append("Mach port: ");
780 LogParam(p.GetMemoryObject(), l);
781#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
erikchen9d6afd712017-05-18 17:49:06782 l->append("FD: ");
783 LogParam(p.GetHandle(), l);
784#endif
785
erikchen14525202017-05-06 19:16:51786 l->append("GUID: ");
erikchen9d6afd712017-05-18 17:49:06787 LogParam(p.GetGUID(), l);
788 l->append("size: ");
789 LogParam(static_cast<uint64_t>(p.GetSize()), l);
David 'Digit' Turnere2a65762018-01-19 17:51:51790#if defined(OS_ANDROID)
791 l->append("read-only: ");
792 LogParam(p.IsReadOnly(), l);
793#endif
erikchen22a813b2017-04-28 17:10:50794}
scottmgd19b4f72015-06-19 22:51:00795
Alexandr Ilind497eee2018-04-19 22:50:54796void ParamTraits<base::ReadOnlySharedMemoryRegion>::Write(base::Pickle* m,
797 const param_type& p) {
798 base::subtle::PlatformSharedMemoryRegion handle =
799 base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
800 std::move(const_cast<param_type&>(p)));
801 WriteParam(m, std::move(handle));
802}
803
804bool ParamTraits<base::ReadOnlySharedMemoryRegion>::Read(
805 const base::Pickle* m,
806 base::PickleIterator* iter,
807 param_type* r) {
808 base::subtle::PlatformSharedMemoryRegion handle;
809 if (!ReadParam(m, iter, &handle))
810 return false;
811
812 *r = base::ReadOnlySharedMemoryRegion::Deserialize(std::move(handle));
813 return true;
814}
815
816void ParamTraits<base::ReadOnlySharedMemoryRegion>::Log(const param_type& p,
817 std::string* l) {
818 *l = "<base::ReadOnlySharedMemoryRegion>";
819 // TODO(alexilin): currently there is no way to access underlying handle
820 // without destructing a ReadOnlySharedMemoryRegion instance.
821}
822
823void ParamTraits<base::WritableSharedMemoryRegion>::Write(base::Pickle* m,
824 const param_type& p) {
825 base::subtle::PlatformSharedMemoryRegion handle =
826 base::WritableSharedMemoryRegion::TakeHandleForSerialization(
827 std::move(const_cast<param_type&>(p)));
828 WriteParam(m, std::move(handle));
829}
830
831bool ParamTraits<base::WritableSharedMemoryRegion>::Read(
832 const base::Pickle* m,
833 base::PickleIterator* iter,
834 param_type* r) {
835 base::subtle::PlatformSharedMemoryRegion handle;
836 if (!ReadParam(m, iter, &handle))
837 return false;
838
839 *r = base::WritableSharedMemoryRegion::Deserialize(std::move(handle));
840 return true;
841}
842
843void ParamTraits<base::WritableSharedMemoryRegion>::Log(const param_type& p,
844 std::string* l) {
845 *l = "<base::WritableSharedMemoryRegion>";
846 // TODO(alexilin): currently there is no way to access underlying handle
847 // without destructing a ReadOnlySharedMemoryRegion instance.
848}
849
850void ParamTraits<base::UnsafeSharedMemoryRegion>::Write(base::Pickle* m,
851 const param_type& p) {
852 base::subtle::PlatformSharedMemoryRegion handle =
853 base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
854 std::move(const_cast<param_type&>(p)));
855 WriteParam(m, std::move(handle));
856}
857
858bool ParamTraits<base::UnsafeSharedMemoryRegion>::Read(
859 const base::Pickle* m,
860 base::PickleIterator* iter,
861 param_type* r) {
862 base::subtle::PlatformSharedMemoryRegion handle;
863 if (!ReadParam(m, iter, &handle))
864 return false;
865
866 *r = base::UnsafeSharedMemoryRegion::Deserialize(std::move(handle));
867 return true;
868}
869
870void ParamTraits<base::UnsafeSharedMemoryRegion>::Log(const param_type& p,
871 std::string* l) {
872 *l = "<base::UnsafeSharedMemoryRegion>";
873 // TODO(alexilin): currently there is no way to access underlying handle
874 // without destructing a ReadOnlySharedMemoryRegion instance.
875}
876
877void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Write(
878 base::Pickle* m,
879 const param_type& p) {
Alexandr Ilinebab9da2018-06-01 02:37:47880 // This serialization must be kept in sync with
881 // nacl_message_scanner.cc::WriteHandle().
Alexandr Ilind497eee2018-04-19 22:50:54882 const bool valid = p.IsValid();
883 WriteParam(m, valid);
884
885 if (!valid)
886 return;
887
888 WriteParam(m, p.GetMode());
889 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
890 WriteParam(m, p.GetGUID());
891
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09892#if defined(OS_WIN)
893 base::win::ScopedHandle h = const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54894 HandleWin handle_win(h.Get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09895 WriteParam(m, handle_win);
Alexandr Ilind497eee2018-04-19 22:50:54896#elif defined(OS_FUCHSIA)
Wez157707d62018-07-10 22:48:47897 zx::handle h = const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54898 HandleFuchsia handle_fuchsia(h.get());
Alexandr Ilind497eee2018-04-19 22:50:54899 WriteParam(m, handle_fuchsia);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09900#elif defined(OS_MACOSX) && !defined(OS_IOS)
901 base::mac::ScopedMachSendRight h =
902 const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54903 MachPortMac mach_port_mac(h.get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09904 WriteParam(m, mach_port_mac);
Alexandr Ilind497eee2018-04-19 22:50:54905#elif defined(OS_ANDROID)
906 m->WriteAttachment(new internal::PlatformFileAttachment(
907 base::ScopedFD(const_cast<param_type&>(p).PassPlatformHandle())));
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09908#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:54909 base::subtle::ScopedFDPair h =
910 const_cast<param_type&>(p).PassPlatformHandle();
911 m->WriteAttachment(new internal::PlatformFileAttachment(std::move(h.fd)));
912 if (p.GetMode() ==
913 base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
914 m->WriteAttachment(
915 new internal::PlatformFileAttachment(std::move(h.readonly_fd)));
916 }
917#endif
918}
919
920bool ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Read(
921 const base::Pickle* m,
922 base::PickleIterator* iter,
923 param_type* r) {
924 bool valid;
925 if (!ReadParam(m, iter, &valid))
926 return false;
927 if (!valid) {
928 *r = base::subtle::PlatformSharedMemoryRegion();
929 return true;
930 }
931
932 base::subtle::PlatformSharedMemoryRegion::Mode mode;
933 uint64_t shm_size;
934 base::UnguessableToken guid;
935 if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &shm_size) ||
936 !base::IsValueInRangeForNumericType<size_t>(shm_size) ||
937 !ReadParam(m, iter, &guid)) {
938 return false;
939 }
940 size_t size = static_cast<size_t>(shm_size);
941
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09942#if defined(OS_WIN)
943 HandleWin handle_win;
944 if (!ReadParam(m, iter, &handle_win))
Alexandr Ilind497eee2018-04-19 22:50:54945 return false;
946 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09947 base::win::ScopedHandle(handle_win.get_handle()), mode, size, guid);
Alexandr Ilind497eee2018-04-19 22:50:54948#elif defined(OS_FUCHSIA)
949 HandleFuchsia handle_fuchsia;
950 if (!ReadParam(m, iter, &handle_fuchsia))
951 return false;
952 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Wez157707d62018-07-10 22:48:47953 zx::vmo(handle_fuchsia.get_handle()), mode, size, guid);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09954#elif defined(OS_MACOSX) && !defined(OS_IOS)
955 MachPortMac mach_port_mac;
956 if (!ReadParam(m, iter, &mach_port_mac))
Alexandr Ilind497eee2018-04-19 22:50:54957 return false;
958 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09959 base::mac::ScopedMachSendRight(mach_port_mac.get_mach_port()), mode, size,
960 guid);
961#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:54962 scoped_refptr<base::Pickle::Attachment> attachment;
963 if (!m->ReadAttachment(iter, &attachment))
964 return false;
965 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
966 MessageAttachment::Type::PLATFORM_FILE) {
967 return false;
968 }
969
970#if defined(OS_ANDROID)
971 *r = base::subtle::PlatformSharedMemoryRegion::Take(
972 base::ScopedFD(
973 static_cast<internal::PlatformFileAttachment*>(attachment.get())
974 ->TakePlatformFile()),
975 mode, size, guid);
976#else
977 scoped_refptr<base::Pickle::Attachment> readonly_attachment;
978 if (mode == base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
979 if (!m->ReadAttachment(iter, &readonly_attachment))
980 return false;
981
982 if (static_cast<MessageAttachment*>(readonly_attachment.get())->GetType() !=
983 MessageAttachment::Type::PLATFORM_FILE) {
984 return false;
985 }
986 }
987 *r = base::subtle::PlatformSharedMemoryRegion::Take(
988 base::subtle::ScopedFDPair(
989 base::ScopedFD(
990 static_cast<internal::PlatformFileAttachment*>(attachment.get())
991 ->TakePlatformFile()),
992 readonly_attachment
993 ? base::ScopedFD(static_cast<internal::PlatformFileAttachment*>(
994 readonly_attachment.get())
995 ->TakePlatformFile())
996 : base::ScopedFD()),
997 mode, size, guid);
998#endif // defined(OS_ANDROID)
999
1000#endif
1001
1002 return true;
1003}
1004
1005void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Log(
1006 const param_type& p,
1007 std::string* l) {
Wezb908e432018-09-05 17:35:221008#if defined(OS_FUCHSIA)
1009 l->append("Handle: ");
1010 LogParam(p.GetPlatformHandle()->get(), l);
1011#elif defined(OS_WIN)
Alexandr Ilind497eee2018-04-19 22:50:541012 l->append("Handle: ");
1013 LogParam(p.GetPlatformHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091014#elif defined(OS_MACOSX) && !defined(OS_IOS)
1015 l->append("Mach port: ");
1016 LogParam(p.GetPlatformHandle(), l);
Alexandr Ilind497eee2018-04-19 22:50:541017#elif defined(OS_ANDROID)
1018 l->append("FD: ");
1019 LogParam(p.GetPlatformHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091020#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541021 base::subtle::FDPair h = p.GetPlatformHandle();
1022 l->append("FD: ");
1023 LogParam(h.fd, l);
1024 l->append("Read-only FD: ");
1025 LogParam(h.readonly_fd, l);
1026#endif
1027
1028 l->append("Mode: ");
1029 LogParam(p.GetMode(), l);
1030 l->append("size: ");
1031 LogParam(static_cast<uint64_t>(p.GetSize()), l);
1032 l->append("GUID: ");
1033 LogParam(p.GetGUID(), l);
1034}
1035
1036void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Write(
1037 base::Pickle* m,
1038 const param_type& value) {
1039 DCHECK(static_cast<int>(value) >= 0 &&
1040 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue));
1041 m->WriteInt(static_cast<int>(value));
1042}
1043
1044bool ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Read(
1045 const base::Pickle* m,
1046 base::PickleIterator* iter,
1047 param_type* p) {
1048 int value;
1049 if (!iter->ReadInt(&value))
1050 return false;
1051 if (!(static_cast<int>(value) >= 0 &&
1052 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue))) {
1053 return false;
1054 }
1055 *p = static_cast<param_type>(value);
1056 return true;
1057}
1058
1059void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Log(
1060 const param_type& p,
1061 std::string* l) {
1062 LogParam(static_cast<int>(p), l);
1063}
1064
erikchend804e1052017-04-29 02:24:361065#if defined(OS_WIN)
erikchend804e1052017-04-29 02:24:361066void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
1067 const param_type& p) {
1068 m->WriteBool(p.IsValid());
1069 if (p.IsValid()) {
Wez51eaaad2017-08-09 05:51:381070 HandleWin handle_win(p.GetHandle());
erikchend804e1052017-04-29 02:24:361071 ParamTraits<HandleWin>::Write(m, handle_win);
1072 ::CloseHandle(p.GetHandle());
1073 }
1074}
1075
1076bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
1077 base::PickleIterator* iter,
1078 param_type* r) {
1079 bool is_valid;
1080 if (!iter->ReadBool(&is_valid))
1081 return false;
1082 if (!is_valid) {
1083 *r = PlatformFileForTransit();
1084 return true;
1085 }
1086
1087 HandleWin handle_win;
1088 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
1089 return false;
1090 *r = PlatformFileForTransit(handle_win.get_handle());
1091 return true;
1092}
1093
1094void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
1095 std::string* l) {
1096 LogParam(p.GetHandle(), l);
1097}
1098#endif // defined(OS_WIN)
1099
rockot502c94f2016-02-03 20:20:161100void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:551101 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:251102}
1103
rockot502c94f2016-02-03 20:20:161104bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251105 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:301106 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:551107 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:251108}
1109
[email protected]6d4b67a2013-02-10 04:49:301110void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
1111 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:251112}
1113
rockot502c94f2016-02-03 20:20:161114void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251115 WriteValue(m, &p, 0);
1116}
1117
rockot502c94f2016-02-03 20:20:161118bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251119 base::PickleIterator* iter,
1120 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:251121 int type;
jdoerriedc72ee942016-12-07 15:43:281122 if (!ReadParam(m, iter, &type) ||
1123 type != static_cast<int>(base::Value::Type::LIST))
[email protected]bf5aedf02012-06-04 21:18:251124 return false;
1125
1126 return ReadListValue(m, iter, r, 0);
1127}
1128
[email protected]ea5ef4c2013-06-13 22:50:271129void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251130 std::string json;
estade8d046462015-05-16 01:02:341131 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:251132 l->append(json);
1133}
1134
rockot502c94f2016-02-03 20:20:161135void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
[email protected]0238a162013-06-13 13:47:461136 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251137 WriteParam(m, p.string());
1138 WriteParam(m, p.is_null());
1139}
1140
rockot502c94f2016-02-03 20:20:161141bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251142 base::PickleIterator* iter,
[email protected]0238a162013-06-13 13:47:461143 param_type* r) {
[email protected]476dafb2013-12-03 00:39:261144 base::string16 string;
[email protected]bf5aedf02012-06-04 21:18:251145 if (!ReadParam(m, iter, &string))
1146 return false;
1147 bool is_null;
1148 if (!ReadParam(m, iter, &is_null))
1149 return false;
[email protected]0238a162013-06-13 13:47:461150 *r = base::NullableString16(string, is_null);
[email protected]bf5aedf02012-06-04 21:18:251151 return true;
1152}
1153
[email protected]0238a162013-06-13 13:47:461154void ParamTraits<base::NullableString16>::Log(const param_type& p,
1155 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251156 l->append("(");
1157 LogParam(p.string(), l);
1158 l->append(", ");
1159 LogParam(p.is_null(), l);
1160 l->append(")");
1161}
1162
rockot502c94f2016-02-03 20:20:161163void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:001164 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251165 WriteParam(m, p.size);
1166 WriteParam(m, p.is_directory);
1167 WriteParam(m, p.last_modified.ToDoubleT());
1168 WriteParam(m, p.last_accessed.ToDoubleT());
1169 WriteParam(m, p.creation_time.ToDoubleT());
1170}
1171
rockot502c94f2016-02-03 20:20:161172bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251173 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:001174 param_type* p) {
[email protected]481c3e82014-07-18 01:40:471175 double last_modified, last_accessed, creation_time;
1176 if (!ReadParam(m, iter, &p->size) ||
1177 !ReadParam(m, iter, &p->is_directory) ||
1178 !ReadParam(m, iter, &last_modified) ||
1179 !ReadParam(m, iter, &last_accessed) ||
1180 !ReadParam(m, iter, &creation_time))
1181 return false;
1182 p->last_modified = base::Time::FromDoubleT(last_modified);
1183 p->last_accessed = base::Time::FromDoubleT(last_accessed);
1184 p->creation_time = base::Time::FromDoubleT(creation_time);
1185 return true;
[email protected]bf5aedf02012-06-04 21:18:251186}
1187
[email protected]141bcc52014-01-27 21:36:001188void ParamTraits<base::File::Info>::Log(const param_type& p,
1189 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251190 l->append("(");
1191 LogParam(p.size, l);
1192 l->append(",");
1193 LogParam(p.is_directory, l);
1194 l->append(",");
1195 LogParam(p.last_modified.ToDoubleT(), l);
1196 l->append(",");
1197 LogParam(p.last_accessed.ToDoubleT(), l);
1198 l->append(",");
1199 LogParam(p.creation_time.ToDoubleT(), l);
1200 l->append(")");
1201}
1202
rockot502c94f2016-02-03 20:20:161203void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571204 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251205}
1206
rockot502c94f2016-02-03 20:20:161207bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251208 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251209 param_type* r) {
tfarina10a5c062015-09-04 18:47:571210 int64_t value;
1211 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:251212 return false;
1213 *r = base::Time::FromInternalValue(value);
1214 return true;
1215}
1216
1217void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571218 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251219}
1220
rockot502c94f2016-02-03 20:20:161221void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571222 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251223}
1224
rockot502c94f2016-02-03 20:20:161225bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251226 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251227 param_type* r) {
tfarina10a5c062015-09-04 18:47:571228 int64_t value;
1229 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251230 if (ret)
1231 *r = base::TimeDelta::FromInternalValue(value);
1232
1233 return ret;
1234}
1235
1236void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571237 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251238}
1239
rockot502c94f2016-02-03 20:20:161240void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571241 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251242}
1243
rockot502c94f2016-02-03 20:20:161244bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251245 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251246 param_type* r) {
tfarina10a5c062015-09-04 18:47:571247 int64_t value;
1248 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251249 if (ret)
1250 *r = base::TimeTicks::FromInternalValue(value);
1251
1252 return ret;
1253}
1254
1255void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571256 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251257}
1258
tguilbert4a5ac602016-09-19 21:11:251259// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1260// below should be updated.
1261static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1262 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1263
tguilbert4a5ac602016-09-19 21:11:251264void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1265 const param_type& p) {
1266 DCHECK(!p.is_empty());
1267
1268 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1269 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1270}
1271
1272bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1273 base::PickleIterator* iter,
1274 param_type* r) {
1275 uint64_t high, low;
1276 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1277 !ParamTraits<uint64_t>::Read(m, iter, &low))
1278 return false;
1279
1280 // Receiving a zeroed UnguessableToken is a security issue.
1281 if (high == 0 && low == 0)
1282 return false;
1283
1284 *r = base::UnguessableToken::Deserialize(high, low);
1285 return true;
1286}
1287
1288void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1289 std::string* l) {
1290 l->append(p.ToString());
1291}
1292
rockot502c94f2016-02-03 20:20:161293void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1294 const param_type& p) {
sammc9bf370c2016-11-14 03:29:081295#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241296 WriteParam(m, p.socket);
sammc9bf370c2016-11-14 03:29:081297#else
amistry36182522016-06-27 06:34:421298 WriteParam(m, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:081299#endif
[email protected]7a4de7a62010-08-17 18:38:241300}
1301
rockot502c94f2016-02-03 20:20:161302bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251303 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:241304 param_type* r) {
sammc9bf370c2016-11-14 03:29:081305#if defined(OS_NACL_SFI)
1306 return ReadParam(m, iter, &r->socket);
1307#else
1308 return ReadParam(m, iter, &r->mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241309#endif
[email protected]7a4de7a62010-08-17 18:38:241310}
1311
1312void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571313 std::string* l) {
sammc9bf370c2016-11-14 03:29:081314 l->append("ChannelHandle(");
1315#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241316 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
sammc9bf370c2016-11-14 03:29:081317#else
amistry36182522016-06-27 06:34:421318 LogParam(p.mojo_handle, l);
sammc9bf370c2016-11-14 03:29:081319#endif
[email protected]252cad62010-08-18 18:33:571320 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241321}
1322
rockot502c94f2016-02-03 20:20:161323void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301324 WriteParam(m, p.channel);
1325 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271326 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301327 WriteParam(m, p.flags);
1328 WriteParam(m, p.sent);
1329 WriteParam(m, p.receive);
1330 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451331 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301332 WriteParam(m, p.params);
1333}
1334
rockot502c94f2016-02-03 20:20:161335bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251336 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561337 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271338 return
[email protected]20f0487a2010-09-30 20:06:301339 ReadParam(m, iter, &r->channel) &&
1340 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271341 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301342 ReadParam(m, iter, &r->flags) &&
1343 ReadParam(m, iter, &r->sent) &&
1344 ReadParam(m, iter, &r->receive) &&
1345 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451346 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301347 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301348}
1349
[email protected]bf5aedf02012-06-04 21:18:251350void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1351 // Doesn't make sense to implement this!
1352}
1353
rockot502c94f2016-02-03 20:20:161354void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091355#if defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]34d48612012-06-29 00:05:041356 // We don't serialize the file descriptors in the nested message, so there
1357 // better not be any.
morrita1aa788c2015-01-31 05:45:421358 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041359#endif
1360
1361 // Don't just write out the message. This is used to send messages between
1362 // NaCl (Posix environment) and the browser (could be on Windows). The message
1363 // header formats differ between these systems (so does handle sharing, but
1364 // we already asserted we don't have any handles). So just write out the
1365 // parts of the header we use.
1366 //
1367 // Be careful also to use only explicitly-sized types. The NaCl environment
1368 // could be 64-bit and the host browser could be 32-bits. The nested message
1369 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1370 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:571371 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041372 m->WriteUInt32(p.type());
1373 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:571374 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:251375}
1376
rockot502c94f2016-02-03 20:20:161377bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251378 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251379 Message* r) {
tfarina10a5c062015-09-04 18:47:571380 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481381 if (!iter->ReadUInt32(&routing_id) ||
1382 !iter->ReadUInt32(&type) ||
1383 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251384 return false;
[email protected]34d48612012-06-29 00:05:041385
1386 int payload_size;
1387 const char* payload;
avi48fc13b2014-12-28 23:31:481388 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251389 return false;
[email protected]34d48612012-06-29 00:05:041390
tfarina10a5c062015-09-04 18:47:571391 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
Daniel Cheng0d89f9222017-09-22 05:05:071392 r->WriteBytes(payload, payload_size);
1393 return true;
[email protected]bf5aedf02012-06-04 21:18:251394}
1395
1396void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1397 l->append("<IPC::Message>");
1398}
1399
1400#if defined(OS_WIN)
1401// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031402// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161403void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031404 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251405}
1406
rockot502c94f2016-02-03 20:20:161407bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251408 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251409 param_type* r) {
tfarina10a5c062015-09-04 18:47:571410 int32_t temp;
avi48fc13b2014-12-28 23:31:481411 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251412 return false;
[email protected]4a635b72013-03-04 02:29:031413 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251414 return true;
1415}
1416
1417void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001418 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251419}
1420
rockot502c94f2016-02-03 20:20:161421void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251422 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1423}
1424
rockot502c94f2016-02-03 20:20:161425bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251426 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251427 param_type* r) {
1428 const char *data;
1429 int data_size = 0;
avi48fc13b2014-12-28 23:31:481430 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251431 if (result && data_size == sizeof(MSG)) {
1432 memcpy(r, data, sizeof(MSG));
1433 } else {
1434 result = false;
1435 NOTREACHED();
1436 }
1437
1438 return result;
1439}
1440
1441void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1442 l->append("<MSG>");
1443}
1444
1445#endif // OS_WIN
1446
[email protected]946d1b22009-07-22 23:57:211447} // namespace IPC