blob: dd7783dc77adeacda5208132e0e818510b1a301e [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:
jdoerriee1b1f3a2019-03-16 04:08:0195 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 }
jdoerriee1b1f3a2019-03-16 04:08:01150
151 // TODO(crbug.com/859477): Remove after root cause is found.
152 default:
153 CHECK(false);
154 break;
[email protected]946d1b22009-07-22 23:57:21155 }
156}
157
158// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
159// object.
rockot502c94f2016-02-03 20:20:16160bool ReadDictionaryValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25161 base::PickleIterator* iter,
162 base::DictionaryValue* value,
163 int recursion) {
[email protected]946d1b22009-07-22 23:57:21164 int size;
165 if (!ReadParam(m, iter, &size))
166 return false;
167
168 for (int i = 0; i < size; ++i) {
[email protected]e7b418b2010-07-30 19:47:47169 std::string key;
jdoerrief1e72e32017-04-26 16:23:55170 std::unique_ptr<base::Value> subval;
[email protected]946d1b22009-07-22 23:57:21171 if (!ReadParam(m, iter, &key) ||
172 !ReadValue(m, iter, &subval, recursion + 1))
173 return false;
jdoerrief1e72e32017-04-26 16:23:55174 value->SetWithoutPathExpansion(key, std::move(subval));
[email protected]946d1b22009-07-22 23:57:21175 }
176
177 return true;
178}
179
180// Helper for ReadValue that reads a ReadListValue into a pre-allocated
181// object.
rockot502c94f2016-02-03 20:20:16182bool ReadListValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25183 base::PickleIterator* iter,
184 base::ListValue* value,
185 int recursion) {
[email protected]946d1b22009-07-22 23:57:21186 int size;
187 if (!ReadParam(m, iter, &size))
188 return false;
189
190 for (int i = 0; i < size; ++i) {
jdoerrief1e72e32017-04-26 16:23:55191 std::unique_ptr<base::Value> subval;
[email protected]946d1b22009-07-22 23:57:21192 if (!ReadValue(m, iter, &subval, recursion + 1))
193 return false;
jdoerrief1e72e32017-04-26 16:23:55194 value->Set(i, std::move(subval));
[email protected]946d1b22009-07-22 23:57:21195 }
196
197 return true;
198}
199
rockot502c94f2016-02-03 20:20:16200bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25201 base::PickleIterator* iter,
jdoerrief1e72e32017-04-26 16:23:55202 std::unique_ptr<base::Value>* value,
[email protected]bf5aedf02012-06-04 21:18:25203 int recursion) {
[email protected]946d1b22009-07-22 23:57:21204 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:36205 LOG(ERROR) << "Max recursion depth hit in ReadValue.";
[email protected]946d1b22009-07-22 23:57:21206 return false;
207 }
208
209 int type;
210 if (!ReadParam(m, iter, &type))
211 return false;
212
jdoerriedc72ee942016-12-07 15:43:28213 switch (static_cast<base::Value::Type>(type)) {
214 case base::Value::Type::NONE:
Jeremy Roman160eb922017-08-29 17:43:43215 *value = std::make_unique<base::Value>();
jdoerriee067999a2017-04-07 06:39:00216 break;
jdoerriedc72ee942016-12-07 15:43:28217 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21218 bool val;
219 if (!ReadParam(m, iter, &val))
220 return false;
Jeremy Roman160eb922017-08-29 17:43:43221 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21222 break;
223 }
jdoerriedc72ee942016-12-07 15:43:28224 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21225 int val;
226 if (!ReadParam(m, iter, &val))
227 return false;
Jeremy Roman160eb922017-08-29 17:43:43228 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21229 break;
230 }
jdoerriedc72ee942016-12-07 15:43:28231 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21232 double val;
233 if (!ReadParam(m, iter, &val))
234 return false;
Jeremy Roman160eb922017-08-29 17:43:43235 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21236 break;
237 }
jdoerriedc72ee942016-12-07 15:43:28238 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21239 std::string val;
240 if (!ReadParam(m, iter, &val))
241 return false;
Jeremy Roman160eb922017-08-29 17:43:43242 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21243 break;
244 }
jdoerriedc72ee942016-12-07 15:43:28245 case base::Value::Type::BINARY: {
[email protected]e4dad9fb2009-10-06 18:15:58246 const char* data;
247 int length;
avi48fc13b2014-12-28 23:31:48248 if (!iter->ReadData(&data, &length))
[email protected]e4dad9fb2009-10-06 18:15:58249 return false;
jdoerrief1e72e32017-04-26 16:23:55250 *value = base::Value::CreateWithCopiedBuffer(data, length);
[email protected]946d1b22009-07-22 23:57:21251 break;
252 }
jdoerriedc72ee942016-12-07 15:43:28253 case base::Value::Type::DICTIONARY: {
jdoerrief1e72e32017-04-26 16:23:55254 base::DictionaryValue val;
255 if (!ReadDictionaryValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21256 return false;
Jeremy Roman160eb922017-08-29 17:43:43257 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21258 break;
259 }
jdoerriedc72ee942016-12-07 15:43:28260 case base::Value::Type::LIST: {
jdoerrief1e72e32017-04-26 16:23:55261 base::ListValue val;
262 if (!ReadListValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21263 return false;
Jeremy Roman160eb922017-08-29 17:43:43264 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21265 break;
266 }
[email protected]e4dad9fb2009-10-06 18:15:58267 default:
jdoerriee1b1f3a2019-03-16 04:08:01268 // TODO(crbug.com/859477): Remove after root cause is found.
269 CHECK(false);
270 return false;
[email protected]946d1b22009-07-22 23:57:21271 }
272
273 return true;
274}
275
[email protected]bf5aedf02012-06-04 21:18:25276} // namespace
277
278// -----------------------------------------------------------------------------
279
280LogData::LogData()
281 : routing_id(0),
282 type(0),
283 sent(0),
284 receive(0),
285 dispatch(0) {
286}
287
vmpstrbf0d713a2016-03-24 20:22:54288LogData::LogData(const LogData& other) = default;
289
Chris Watkins2d879af2017-11-30 02:11:59290LogData::~LogData() = default;
[email protected]bf5aedf02012-06-04 21:18:25291
[email protected]bf5aedf02012-06-04 21:18:25292void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
293 l->append(p ? "true" : "false");
294}
295
rockot502c94f2016-02-03 20:20:16296void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno19ecf1842015-10-30 00:46:20297 m->WriteBytes(&p, sizeof(param_type));
298}
299
rockot502c94f2016-02-03 20:20:16300bool ParamTraits<signed char>::Read(const base::Pickle* m,
301 base::PickleIterator* iter,
302 param_type* r) {
ortuno19ecf1842015-10-30 00:46:20303 const char* data;
304 if (!iter->ReadBytes(&data, sizeof(param_type)))
305 return false;
306 memcpy(r, data, sizeof(param_type));
307 return true;
308}
309
310void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38311 l->append(base::NumberToString(p));
ortuno19ecf1842015-10-30 00:46:20312}
313
rockot502c94f2016-02-03 20:20:16314void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28315 m->WriteBytes(&p, sizeof(param_type));
316}
317
rockot502c94f2016-02-03 20:20:16318bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25319 base::PickleIterator* iter,
320 param_type* r) {
[email protected]c1ee48d2013-07-12 23:12:28321 const char* data;
avi48fc13b2014-12-28 23:31:48322 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28323 return false;
324 memcpy(r, data, sizeof(param_type));
325 return true;
326}
327
328void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38329 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28330}
331
rockot502c94f2016-02-03 20:20:16332void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28333 m->WriteBytes(&p, sizeof(param_type));
334}
335
rockot502c94f2016-02-03 20:20:16336bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25337 base::PickleIterator* iter,
[email protected]c1ee48d2013-07-12 23:12:28338 param_type* r) {
339 const char* data;
avi48fc13b2014-12-28 23:31:48340 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28341 return false;
342 memcpy(r, data, sizeof(param_type));
343 return true;
344}
345
346void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09347 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28348}
349
[email protected]252cad62010-08-18 18:33:57350void ParamTraits<int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09351 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57352}
353
354void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09355 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57356}
357
Sergey Ulanova98ff6b52017-07-13 01:54:20358#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_FUCHSIA) || \
jamac78d7d82016-02-11 00:50:28359 (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]252cad62010-08-18 18:33:57360void ParamTraits<long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09361 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57362}
363
364void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09365 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57366}
jam03d8a782016-02-10 20:13:39367#endif
[email protected]252cad62010-08-18 18:33:57368
369void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09370 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57371}
372
373void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09374 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57375}
[email protected]7a4de7a62010-08-17 18:38:24376
[email protected]bf5aedf02012-06-04 21:18:25377void ParamTraits<float>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04378 l->append(base::StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24379}
380
rockot502c94f2016-02-03 20:20:16381void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
[email protected]48328ff2013-10-31 09:27:31382 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52383}
384
rockot502c94f2016-02-03 20:20:16385bool ParamTraits<double>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25386 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25387 param_type* r) {
388 const char *data;
avi48fc13b2014-12-28 23:31:48389 if (!iter->ReadBytes(&data, sizeof(*r))) {
[email protected]bf5aedf02012-06-04 21:18:25390 NOTREACHED();
391 return false;
392 }
393 memcpy(r, data, sizeof(param_type));
394 return true;
[email protected]d84e48b2010-10-21 22:04:52395}
396
[email protected]bf5aedf02012-06-04 21:18:25397void ParamTraits<double>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04398 l->append(base::StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04399}
400
[email protected]bf5aedf02012-06-04 21:18:25401
402void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
403 l->append(p);
[email protected]1d14f582011-09-02 20:42:04404}
405
[email protected]476dafb2013-12-03 00:39:26406void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
[email protected]ad65a3e2013-12-25 18:18:01407 l->append(base::UTF16ToUTF8(p));
[email protected]bf5aedf02012-06-04 21:18:25408}
[email protected]bf5aedf02012-06-04 21:18:25409
rockot502c94f2016-02-03 20:20:16410void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
411 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25412 if (p.empty()) {
413 m->WriteData(NULL, 0);
414 } else {
Chris Palmerc5ea9b92017-09-25 22:53:22415 m->WriteData(&p.front(), base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25416 }
417}
418
rockot502c94f2016-02-03 20:20:16419bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25420 base::PickleIterator* iter,
421 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25422 const char *data;
423 int data_size = 0;
avi48fc13b2014-12-28 23:31:48424 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25425 return false;
426 r->resize(data_size);
427 if (data_size)
428 memcpy(&r->front(), data, data_size);
429 return true;
430}
431
432void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
433 LogBytes(p, l);
434}
435
rockot502c94f2016-02-03 20:20:16436void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
437 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25438 if (p.empty()) {
439 m->WriteData(NULL, 0);
440 } else {
441 m->WriteData(reinterpret_cast<const char*>(&p.front()),
Chris Palmerc5ea9b92017-09-25 22:53:22442 base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25443 }
444}
445
rockot502c94f2016-02-03 20:20:16446bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25447 base::PickleIterator* iter,
448 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25449 const char *data;
450 int data_size = 0;
avi48fc13b2014-12-28 23:31:48451 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25452 return false;
453 r->resize(data_size);
454 if (data_size)
455 memcpy(&r->front(), data, data_size);
456 return true;
457}
458
459void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
460 std::string* l) {
461 LogBytes(p, l);
462}
463
rockot502c94f2016-02-03 20:20:16464void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
465 const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22466 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]d4124852013-03-20 20:25:00467 // Cast to bool below is required because libc++'s
468 // vector<bool>::const_reference is different from bool, and we want to avoid
469 // writing an extra specialization of ParamTraits for it.
[email protected]bf5aedf02012-06-04 21:18:25470 for (size_t i = 0; i < p.size(); i++)
[email protected]d4124852013-03-20 20:25:00471 WriteParam(m, static_cast<bool>(p[i]));
[email protected]bf5aedf02012-06-04 21:18:25472}
473
rockot502c94f2016-02-03 20:20:16474bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25475 base::PickleIterator* iter,
476 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25477 int size;
478 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48479 if (!iter->ReadLength(&size))
[email protected]bf5aedf02012-06-04 21:18:25480 return false;
481 r->resize(size);
482 for (int i = 0; i < size; i++) {
483 bool value;
484 if (!ReadParam(m, iter, &value))
485 return false;
486 (*r)[i] = value;
487 }
488 return true;
489}
490
491void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
492 for (size_t i = 0; i < p.size(); ++i) {
493 if (i != 0)
494 l->push_back(' ');
[email protected]d4124852013-03-20 20:25:00495 LogParam(static_cast<bool>(p[i]), l);
[email protected]bf5aedf02012-06-04 21:18:25496 }
[email protected]d84e48b2010-10-21 22:04:52497}
498
rockot502c94f2016-02-03 20:20:16499void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
[email protected]ea5ef4c2013-06-13 22:50:27500 const param_type& p) {
[email protected]946d1b22009-07-22 23:57:21501 WriteValue(m, &p, 0);
502}
503
rockot502c94f2016-02-03 20:20:16504bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25505 base::PickleIterator* iter,
506 param_type* r) {
[email protected]946d1b22009-07-22 23:57:21507 int type;
jdoerriedc72ee942016-12-07 15:43:28508 if (!ReadParam(m, iter, &type) ||
509 type != static_cast<int>(base::Value::Type::DICTIONARY))
[email protected]946d1b22009-07-22 23:57:21510 return false;
511
512 return ReadDictionaryValue(m, iter, r, 0);
513}
514
[email protected]ea5ef4c2013-06-13 22:50:27515void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
516 std::string* l) {
[email protected]946d1b22009-07-22 23:57:21517 std::string json;
estade8d046462015-05-16 01:02:34518 base::JSONWriter::Write(p, &json);
[email protected]252cad62010-08-18 18:33:57519 l->append(json);
[email protected]946d1b22009-07-22 23:57:21520}
521
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09522#if defined(OS_POSIX) || defined(OS_FUCHSIA)
rockot502c94f2016-02-03 20:20:16523void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
524 const param_type& p) {
erikchen14525202017-05-06 19:16:51525 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06526 // nacl_message_scanner.cc:WriteHandle().
[email protected]7a4de7a62010-08-17 18:38:24527 const bool valid = p.fd >= 0;
528 WriteParam(m, valid);
529
morrita96693852014-09-24 20:11:45530 if (!valid)
531 return;
532
533 if (p.auto_close) {
morrita1aa788c2015-01-31 05:45:42534 if (!m->WriteAttachment(
535 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
morrita96693852014-09-24 20:11:45536 NOTREACHED();
537 } else {
morrita1aa788c2015-01-31 05:45:42538 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
[email protected]7a4de7a62010-08-17 18:38:24539 NOTREACHED();
540 }
541}
542
rockot502c94f2016-02-03 20:20:16543bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25544 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24545 param_type* r) {
morrita96693852014-09-24 20:11:45546 *r = base::FileDescriptor();
547
[email protected]7a4de7a62010-08-17 18:38:24548 bool valid;
549 if (!ReadParam(m, iter, &valid))
550 return false;
551
morrita96693852014-09-24 20:11:45552 if (!valid)
[email protected]7a4de7a62010-08-17 18:38:24553 return true;
[email protected]7a4de7a62010-08-17 18:38:24554
rockot502c94f2016-02-03 20:20:16555 scoped_refptr<base::Pickle::Attachment> attachment;
morrita1aa788c2015-01-31 05:45:42556 if (!m->ReadAttachment(iter, &attachment))
morrita96693852014-09-24 20:11:45557 return false;
558
sammc6ed3efb2016-11-23 03:17:35559 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
560 MessageAttachment::Type::PLATFORM_FILE) {
561 return false;
562 }
563
rockot502c94f2016-02-03 20:20:16564 *r = base::FileDescriptor(
sammc6ed3efb2016-11-23 03:17:35565 static_cast<internal::PlatformFileAttachment*>(attachment.get())
566 ->TakePlatformFile(),
rockot502c94f2016-02-03 20:20:16567 true);
morrita96693852014-09-24 20:11:45568 return true;
[email protected]7a4de7a62010-08-17 18:38:24569}
570
571void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57572 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24573 if (p.auto_close) {
[email protected]7d3cbc92013-03-18 22:33:04574 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24575 } else {
[email protected]7d3cbc92013-03-18 22:33:04576 l->append(base::StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24577 }
578}
Sergey Ulanovac89bb92019-03-22 18:46:49579
580void ParamTraits<base::ScopedFD>::Write(base::Pickle* m, const param_type& p) {
581 // This serialization must be kept in sync with
582 // nacl_message_scanner.cc:WriteHandle().
583 const bool valid = p.is_valid();
584 WriteParam(m, valid);
585
586 if (!valid)
587 return;
588
589 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
590 std::move(const_cast<param_type&>(p))))) {
591 NOTREACHED();
592 }
593}
594
595bool ParamTraits<base::ScopedFD>::Read(const base::Pickle* m,
596 base::PickleIterator* iter,
597 param_type* r) {
598 r->reset();
599
600 bool valid;
601 if (!ReadParam(m, iter, &valid))
602 return false;
603
604 if (!valid)
605 return true;
606
607 scoped_refptr<base::Pickle::Attachment> attachment;
608 if (!m->ReadAttachment(iter, &attachment))
609 return false;
610
611 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
612 MessageAttachment::Type::PLATFORM_FILE) {
613 return false;
614 }
615
616 *r = base::ScopedFD(
617 static_cast<internal::PlatformFileAttachment*>(attachment.get())
618 ->TakePlatformFile());
619 return true;
620}
621
622void ParamTraits<base::ScopedFD>::Log(const param_type& p, std::string* l) {
623 l->append(base::StringPrintf("ScopedFD(%d)", p.get()));
624}
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09625#endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]7a4de7a62010-08-17 18:38:24626
Klaus Weidner3824a8882017-11-03 06:24:57627#if defined(OS_ANDROID)
Alexandr Ilin0443a8f2018-07-20 20:14:50628void ParamTraits<base::android::ScopedHardwareBufferHandle>::Write(
629 base::Pickle* m,
630 const param_type& p) {
631 const bool is_valid = p.is_valid();
Ken Rockot097248f02018-04-23 16:23:34632 WriteParam(m, is_valid);
633 if (!is_valid)
634 return;
635
Ken Rockot097248f02018-04-23 16:23:34636 // We must keep a ref to the AHardwareBuffer alive until the receiver has
637 // acquired its own reference. We do this by sending a message pipe handle
638 // along with the buffer. When the receiver deserializes (or even if they
639 // die without ever reading the message) their end of the pipe will be
640 // closed. We will eventually detect this and release the AHB reference.
641 mojo::MessagePipe tracking_pipe;
642 m->WriteAttachment(new internal::MojoHandleAttachment(
643 mojo::ScopedHandle::From(std::move(tracking_pipe.handle0))));
Alexandr Ilin0443a8f2018-07-20 20:14:50644 WriteParam(m, base::FileDescriptor(p.SerializeAsFileDescriptor().release(),
645 true /* auto_close */));
Ken Rockot097248f02018-04-23 16:23:34646
647 // Pass ownership of the input handle to our tracking pipe to keep the AHB
648 // alive long enough to be deserialized by the receiver.
Alexandr Ilin0443a8f2018-07-20 20:14:50649 mojo::ScopeToMessagePipe(std::move(const_cast<param_type&>(p)),
650 std::move(tracking_pipe.handle1));
Klaus Weidner3824a8882017-11-03 06:24:57651}
652
Alexandr Ilin0443a8f2018-07-20 20:14:50653bool ParamTraits<base::android::ScopedHardwareBufferHandle>::Read(
654 const base::Pickle* m,
655 base::PickleIterator* iter,
656 param_type* r) {
657 *r = base::android::ScopedHardwareBufferHandle();
Ken Rockot097248f02018-04-23 16:23:34658
659 bool is_valid;
660 if (!ReadParam(m, iter, &is_valid))
Klaus Weidner3824a8882017-11-03 06:24:57661 return false;
Ken Rockot097248f02018-04-23 16:23:34662 if (!is_valid)
663 return true;
664
665 scoped_refptr<base::Pickle::Attachment> tracking_pipe_attachment;
666 if (!m->ReadAttachment(iter, &tracking_pipe_attachment))
Klaus Weidner3824a8882017-11-03 06:24:57667 return false;
Ken Rockot097248f02018-04-23 16:23:34668
669 // We keep this alive until the AHB is safely deserialized below. When this
670 // goes out of scope, the sender holding the other end of this pipe will treat
671 // this handle closure as a signal that it's safe to release their AHB
672 // keepalive ref.
673 mojo::ScopedHandle tracking_pipe =
674 static_cast<MessageAttachment*>(tracking_pipe_attachment.get())
675 ->TakeMojoHandle();
676
677 base::FileDescriptor descriptor;
678 if (!ReadParam(m, iter, &descriptor))
679 return false;
680
681 // NOTE: It is valid to deserialize an invalid FileDescriptor, so the success
682 // of |ReadParam()| above does not imply that |descriptor| is valid.
683 base::ScopedFD scoped_fd(descriptor.fd);
684 if (!scoped_fd.is_valid())
685 return false;
686
687 *r = base::android::ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(
Alexandr Ilin0443a8f2018-07-20 20:14:50688 std::move(scoped_fd));
Klaus Weidner3824a8882017-11-03 06:24:57689 return true;
690}
691
Alexandr Ilin0443a8f2018-07-20 20:14:50692void ParamTraits<base::android::ScopedHardwareBufferHandle>::Log(
693 const param_type& p,
694 std::string* l) {
695 l->append(base::StringPrintf("base::android::ScopedHardwareBufferHandle(%p)",
696 p.get()));
Klaus Weidner3824a8882017-11-03 06:24:57697}
Ken Rockot097248f02018-04-23 16:23:34698#endif // defined(OS_ANDROID)
Klaus Weidner3824a8882017-11-03 06:24:57699
erikchen22a813b2017-04-28 17:10:50700void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
701 const param_type& p) {
erikchen14525202017-05-06 19:16:51702 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06703 // nacl_message_scanner.cc:WriteHandle().
erikchen22a813b2017-04-28 17:10:50704 const bool valid = p.IsValid();
705 WriteParam(m, valid);
706
707 if (!valid)
708 return;
709
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09710#if defined(OS_WIN)
Wez51eaaad2017-08-09 05:51:38711 HandleWin handle_win(p.GetHandle());
erikchen9d6afd712017-05-18 17:49:06712 WriteParam(m, handle_win);
Wez8c49ebc92017-08-10 17:11:13713#elif defined(OS_FUCHSIA)
714 HandleFuchsia handle_fuchsia(p.GetHandle());
715 WriteParam(m, handle_fuchsia);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09716#elif defined(OS_MACOSX) && !defined(OS_IOS)
717 MachPortMac mach_port_mac(p.GetMemoryObject());
718 WriteParam(m, mach_port_mac);
719#elif defined(OS_POSIX)
Klaus Weidner3824a8882017-11-03 06:24:57720#if defined(OS_ANDROID)
David 'Digit' Turnere2a65762018-01-19 17:51:51721 WriteParam(m, p.IsReadOnly());
722
723 // Ensure the region is read-only before sending it through IPC.
724 if (p.IsReadOnly()) {
725 if (!p.IsRegionReadOnly()) {
726 LOG(ERROR) << "Sending unsealed read-only region through IPC";
727 p.SetRegionReadOnly();
728 }
729 }
Klaus Weidner3824a8882017-11-03 06:24:57730#endif
erikchen22a813b2017-04-28 17:10:50731 if (p.OwnershipPassesToIPC()) {
732 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
733 base::ScopedFD(p.GetHandle()))))
734 NOTREACHED();
735 } else {
736 if (!m->WriteAttachment(
737 new internal::PlatformFileAttachment(p.GetHandle())))
738 NOTREACHED();
739 }
erikchen9d6afd712017-05-18 17:49:06740#endif
741
742#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
743 // If the caller intended to pass ownership to the IPC stack, release a
744 // reference.
745 if (p.OwnershipPassesToIPC())
746 p.Close();
747#endif
748
erikchen14525202017-05-06 19:16:51749 DCHECK(!p.GetGUID().is_empty());
750 WriteParam(m, p.GetGUID());
erikchen9d6afd712017-05-18 17:49:06751 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
erikchen22a813b2017-04-28 17:10:50752}
753
754bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
755 base::PickleIterator* iter,
756 param_type* r) {
757 *r = base::SharedMemoryHandle();
758
759 bool valid;
760 if (!ReadParam(m, iter, &valid))
761 return false;
erikchen22a813b2017-04-28 17:10:50762 if (!valid)
763 return true;
764
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09765#if defined(OS_WIN)
erikchen9d6afd712017-05-18 17:49:06766 HandleWin handle_win;
767 if (!ReadParam(m, iter, &handle_win))
768 return false;
Scott Graham3eebff02017-06-30 01:07:10769#elif defined(OS_FUCHSIA)
770 HandleFuchsia handle_fuchsia;
771 if (!ReadParam(m, iter, &handle_fuchsia))
772 return false;
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09773#elif defined(OS_MACOSX) && !defined(OS_IOS)
774 MachPortMac mach_port_mac;
775 if (!ReadParam(m, iter, &mach_port_mac))
776 return false;
777#elif defined(OS_POSIX)
Klaus Weidner3824a8882017-11-03 06:24:57778#if defined(OS_ANDROID)
David 'Digit' Turnere2a65762018-01-19 17:51:51779 bool is_read_only = false;
Ken Rockot097248f02018-04-23 16:23:34780 if (!ReadParam(m, iter, &is_read_only))
Klaus Weidner3824a8882017-11-03 06:24:57781 return false;
782#endif
erikchen22a813b2017-04-28 17:10:50783 scoped_refptr<base::Pickle::Attachment> attachment;
784 if (!m->ReadAttachment(iter, &attachment))
785 return false;
786
787 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
788 MessageAttachment::Type::PLATFORM_FILE) {
789 return false;
790 }
erikchen9d6afd712017-05-18 17:49:06791#endif
erikchen22a813b2017-04-28 17:10:50792
erikchen14525202017-05-06 19:16:51793 base::UnguessableToken guid;
erikchen9d6afd712017-05-18 17:49:06794 uint64_t size;
Alexandr Ilind497eee2018-04-19 22:50:54795 if (!ReadParam(m, iter, &guid) || !ReadParam(m, iter, &size) ||
796 !base::IsValueInRangeForNumericType<size_t>(size)) {
erikchen14525202017-05-06 19:16:51797 return false;
erikchen9d6afd712017-05-18 17:49:06798 }
erikchen14525202017-05-06 19:16:51799
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09800#if defined(OS_WIN)
erikchen9d6afd712017-05-18 17:49:06801 *r = base::SharedMemoryHandle(handle_win.get_handle(),
802 static_cast<size_t>(size), guid);
Scott Graham3eebff02017-06-30 01:07:10803#elif defined(OS_FUCHSIA)
804 *r = base::SharedMemoryHandle(handle_fuchsia.get_handle(),
805 static_cast<size_t>(size), guid);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09806#elif defined(OS_MACOSX) && !defined(OS_IOS)
807 *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
808 static_cast<size_t>(size), guid);
809#elif defined(OS_POSIX)
erikchen14525202017-05-06 19:16:51810 *r = base::SharedMemoryHandle(
811 base::FileDescriptor(
812 static_cast<internal::PlatformFileAttachment*>(attachment.get())
813 ->TakePlatformFile(),
814 true),
erikchen9d6afd712017-05-18 17:49:06815 static_cast<size_t>(size), guid);
816#endif
817
Ken Rockot097248f02018-04-23 16:23:34818#if defined(OS_ANDROID)
819 if (is_read_only)
820 r->SetReadOnly();
821#endif
822
erikchen22a813b2017-04-28 17:10:50823 return true;
824}
825
826void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
827 std::string* l) {
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09828#if defined(OS_WIN)
erikchen9d6afd712017-05-18 17:49:06829 l->append("HANDLE: ");
830 LogParam(p.GetHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09831#elif defined(OS_MACOSX) && !defined(OS_IOS)
832 l->append("Mach port: ");
833 LogParam(p.GetMemoryObject(), l);
834#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
erikchen9d6afd712017-05-18 17:49:06835 l->append("FD: ");
836 LogParam(p.GetHandle(), l);
837#endif
838
erikchen14525202017-05-06 19:16:51839 l->append("GUID: ");
erikchen9d6afd712017-05-18 17:49:06840 LogParam(p.GetGUID(), l);
841 l->append("size: ");
842 LogParam(static_cast<uint64_t>(p.GetSize()), l);
David 'Digit' Turnere2a65762018-01-19 17:51:51843#if defined(OS_ANDROID)
844 l->append("read-only: ");
845 LogParam(p.IsReadOnly(), l);
846#endif
erikchen22a813b2017-04-28 17:10:50847}
scottmgd19b4f72015-06-19 22:51:00848
Alexandr Ilind497eee2018-04-19 22:50:54849void ParamTraits<base::ReadOnlySharedMemoryRegion>::Write(base::Pickle* m,
850 const param_type& p) {
851 base::subtle::PlatformSharedMemoryRegion handle =
852 base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
853 std::move(const_cast<param_type&>(p)));
854 WriteParam(m, std::move(handle));
855}
856
857bool ParamTraits<base::ReadOnlySharedMemoryRegion>::Read(
858 const base::Pickle* m,
859 base::PickleIterator* iter,
860 param_type* r) {
861 base::subtle::PlatformSharedMemoryRegion handle;
862 if (!ReadParam(m, iter, &handle))
863 return false;
864
865 *r = base::ReadOnlySharedMemoryRegion::Deserialize(std::move(handle));
866 return true;
867}
868
869void ParamTraits<base::ReadOnlySharedMemoryRegion>::Log(const param_type& p,
870 std::string* l) {
871 *l = "<base::ReadOnlySharedMemoryRegion>";
872 // TODO(alexilin): currently there is no way to access underlying handle
873 // without destructing a ReadOnlySharedMemoryRegion instance.
874}
875
876void ParamTraits<base::WritableSharedMemoryRegion>::Write(base::Pickle* m,
877 const param_type& p) {
878 base::subtle::PlatformSharedMemoryRegion handle =
879 base::WritableSharedMemoryRegion::TakeHandleForSerialization(
880 std::move(const_cast<param_type&>(p)));
881 WriteParam(m, std::move(handle));
882}
883
884bool ParamTraits<base::WritableSharedMemoryRegion>::Read(
885 const base::Pickle* m,
886 base::PickleIterator* iter,
887 param_type* r) {
888 base::subtle::PlatformSharedMemoryRegion handle;
889 if (!ReadParam(m, iter, &handle))
890 return false;
891
892 *r = base::WritableSharedMemoryRegion::Deserialize(std::move(handle));
893 return true;
894}
895
896void ParamTraits<base::WritableSharedMemoryRegion>::Log(const param_type& p,
897 std::string* l) {
898 *l = "<base::WritableSharedMemoryRegion>";
899 // TODO(alexilin): currently there is no way to access underlying handle
900 // without destructing a ReadOnlySharedMemoryRegion instance.
901}
902
903void ParamTraits<base::UnsafeSharedMemoryRegion>::Write(base::Pickle* m,
904 const param_type& p) {
905 base::subtle::PlatformSharedMemoryRegion handle =
906 base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
907 std::move(const_cast<param_type&>(p)));
908 WriteParam(m, std::move(handle));
909}
910
911bool ParamTraits<base::UnsafeSharedMemoryRegion>::Read(
912 const base::Pickle* m,
913 base::PickleIterator* iter,
914 param_type* r) {
915 base::subtle::PlatformSharedMemoryRegion handle;
916 if (!ReadParam(m, iter, &handle))
917 return false;
918
919 *r = base::UnsafeSharedMemoryRegion::Deserialize(std::move(handle));
920 return true;
921}
922
923void ParamTraits<base::UnsafeSharedMemoryRegion>::Log(const param_type& p,
924 std::string* l) {
925 *l = "<base::UnsafeSharedMemoryRegion>";
926 // TODO(alexilin): currently there is no way to access underlying handle
927 // without destructing a ReadOnlySharedMemoryRegion instance.
928}
929
930void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Write(
931 base::Pickle* m,
932 const param_type& p) {
Alexandr Ilinebab9da2018-06-01 02:37:47933 // This serialization must be kept in sync with
934 // nacl_message_scanner.cc::WriteHandle().
Alexandr Ilind497eee2018-04-19 22:50:54935 const bool valid = p.IsValid();
936 WriteParam(m, valid);
937
938 if (!valid)
939 return;
940
941 WriteParam(m, p.GetMode());
942 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
943 WriteParam(m, p.GetGUID());
944
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09945#if defined(OS_WIN)
946 base::win::ScopedHandle h = const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54947 HandleWin handle_win(h.Get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09948 WriteParam(m, handle_win);
Alexandr Ilind497eee2018-04-19 22:50:54949#elif defined(OS_FUCHSIA)
Wez157707d62018-07-10 22:48:47950 zx::handle h = const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54951 HandleFuchsia handle_fuchsia(h.get());
Alexandr Ilind497eee2018-04-19 22:50:54952 WriteParam(m, handle_fuchsia);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09953#elif defined(OS_MACOSX) && !defined(OS_IOS)
954 base::mac::ScopedMachSendRight h =
955 const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54956 MachPortMac mach_port_mac(h.get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09957 WriteParam(m, mach_port_mac);
Alexandr Ilind497eee2018-04-19 22:50:54958#elif defined(OS_ANDROID)
959 m->WriteAttachment(new internal::PlatformFileAttachment(
960 base::ScopedFD(const_cast<param_type&>(p).PassPlatformHandle())));
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09961#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:54962 base::subtle::ScopedFDPair h =
963 const_cast<param_type&>(p).PassPlatformHandle();
964 m->WriteAttachment(new internal::PlatformFileAttachment(std::move(h.fd)));
965 if (p.GetMode() ==
966 base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
967 m->WriteAttachment(
968 new internal::PlatformFileAttachment(std::move(h.readonly_fd)));
969 }
970#endif
971}
972
973bool ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Read(
974 const base::Pickle* m,
975 base::PickleIterator* iter,
976 param_type* r) {
977 bool valid;
978 if (!ReadParam(m, iter, &valid))
979 return false;
980 if (!valid) {
981 *r = base::subtle::PlatformSharedMemoryRegion();
982 return true;
983 }
984
985 base::subtle::PlatformSharedMemoryRegion::Mode mode;
986 uint64_t shm_size;
987 base::UnguessableToken guid;
988 if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &shm_size) ||
989 !base::IsValueInRangeForNumericType<size_t>(shm_size) ||
990 !ReadParam(m, iter, &guid)) {
991 return false;
992 }
993 size_t size = static_cast<size_t>(shm_size);
994
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09995#if defined(OS_WIN)
996 HandleWin handle_win;
997 if (!ReadParam(m, iter, &handle_win))
Alexandr Ilind497eee2018-04-19 22:50:54998 return false;
999 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091000 base::win::ScopedHandle(handle_win.get_handle()), mode, size, guid);
Alexandr Ilind497eee2018-04-19 22:50:541001#elif defined(OS_FUCHSIA)
1002 HandleFuchsia handle_fuchsia;
1003 if (!ReadParam(m, iter, &handle_fuchsia))
1004 return false;
1005 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Wez157707d62018-07-10 22:48:471006 zx::vmo(handle_fuchsia.get_handle()), mode, size, guid);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091007#elif defined(OS_MACOSX) && !defined(OS_IOS)
1008 MachPortMac mach_port_mac;
1009 if (!ReadParam(m, iter, &mach_port_mac))
Alexandr Ilind497eee2018-04-19 22:50:541010 return false;
1011 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091012 base::mac::ScopedMachSendRight(mach_port_mac.get_mach_port()), mode, size,
1013 guid);
1014#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541015 scoped_refptr<base::Pickle::Attachment> attachment;
1016 if (!m->ReadAttachment(iter, &attachment))
1017 return false;
1018 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
1019 MessageAttachment::Type::PLATFORM_FILE) {
1020 return false;
1021 }
1022
1023#if defined(OS_ANDROID)
1024 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1025 base::ScopedFD(
1026 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1027 ->TakePlatformFile()),
1028 mode, size, guid);
1029#else
1030 scoped_refptr<base::Pickle::Attachment> readonly_attachment;
1031 if (mode == base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
1032 if (!m->ReadAttachment(iter, &readonly_attachment))
1033 return false;
1034
1035 if (static_cast<MessageAttachment*>(readonly_attachment.get())->GetType() !=
1036 MessageAttachment::Type::PLATFORM_FILE) {
1037 return false;
1038 }
1039 }
1040 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1041 base::subtle::ScopedFDPair(
1042 base::ScopedFD(
1043 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1044 ->TakePlatformFile()),
1045 readonly_attachment
1046 ? base::ScopedFD(static_cast<internal::PlatformFileAttachment*>(
1047 readonly_attachment.get())
1048 ->TakePlatformFile())
1049 : base::ScopedFD()),
1050 mode, size, guid);
1051#endif // defined(OS_ANDROID)
1052
1053#endif
1054
1055 return true;
1056}
1057
1058void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Log(
1059 const param_type& p,
1060 std::string* l) {
Wezb908e432018-09-05 17:35:221061#if defined(OS_FUCHSIA)
1062 l->append("Handle: ");
1063 LogParam(p.GetPlatformHandle()->get(), l);
1064#elif defined(OS_WIN)
Alexandr Ilind497eee2018-04-19 22:50:541065 l->append("Handle: ");
1066 LogParam(p.GetPlatformHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091067#elif defined(OS_MACOSX) && !defined(OS_IOS)
1068 l->append("Mach port: ");
1069 LogParam(p.GetPlatformHandle(), l);
Alexandr Ilind497eee2018-04-19 22:50:541070#elif defined(OS_ANDROID)
1071 l->append("FD: ");
1072 LogParam(p.GetPlatformHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091073#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541074 base::subtle::FDPair h = p.GetPlatformHandle();
1075 l->append("FD: ");
1076 LogParam(h.fd, l);
1077 l->append("Read-only FD: ");
1078 LogParam(h.readonly_fd, l);
1079#endif
1080
1081 l->append("Mode: ");
1082 LogParam(p.GetMode(), l);
1083 l->append("size: ");
1084 LogParam(static_cast<uint64_t>(p.GetSize()), l);
1085 l->append("GUID: ");
1086 LogParam(p.GetGUID(), l);
1087}
1088
1089void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Write(
1090 base::Pickle* m,
1091 const param_type& value) {
1092 DCHECK(static_cast<int>(value) >= 0 &&
1093 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue));
1094 m->WriteInt(static_cast<int>(value));
1095}
1096
1097bool ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Read(
1098 const base::Pickle* m,
1099 base::PickleIterator* iter,
1100 param_type* p) {
1101 int value;
1102 if (!iter->ReadInt(&value))
1103 return false;
1104 if (!(static_cast<int>(value) >= 0 &&
1105 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue))) {
1106 return false;
1107 }
1108 *p = static_cast<param_type>(value);
1109 return true;
1110}
1111
1112void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Log(
1113 const param_type& p,
1114 std::string* l) {
1115 LogParam(static_cast<int>(p), l);
1116}
1117
erikchend804e1052017-04-29 02:24:361118#if defined(OS_WIN)
erikchend804e1052017-04-29 02:24:361119void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
1120 const param_type& p) {
1121 m->WriteBool(p.IsValid());
1122 if (p.IsValid()) {
Wez51eaaad2017-08-09 05:51:381123 HandleWin handle_win(p.GetHandle());
erikchend804e1052017-04-29 02:24:361124 ParamTraits<HandleWin>::Write(m, handle_win);
1125 ::CloseHandle(p.GetHandle());
1126 }
1127}
1128
1129bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
1130 base::PickleIterator* iter,
1131 param_type* r) {
1132 bool is_valid;
1133 if (!iter->ReadBool(&is_valid))
1134 return false;
1135 if (!is_valid) {
1136 *r = PlatformFileForTransit();
1137 return true;
1138 }
1139
1140 HandleWin handle_win;
1141 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
1142 return false;
1143 *r = PlatformFileForTransit(handle_win.get_handle());
1144 return true;
1145}
1146
1147void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
1148 std::string* l) {
1149 LogParam(p.GetHandle(), l);
1150}
1151#endif // defined(OS_WIN)
1152
rockot502c94f2016-02-03 20:20:161153void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:551154 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:251155}
1156
rockot502c94f2016-02-03 20:20:161157bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251158 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:301159 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:551160 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:251161}
1162
[email protected]6d4b67a2013-02-10 04:49:301163void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
1164 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:251165}
1166
rockot502c94f2016-02-03 20:20:161167void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251168 WriteValue(m, &p, 0);
1169}
1170
rockot502c94f2016-02-03 20:20:161171bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251172 base::PickleIterator* iter,
1173 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:251174 int type;
jdoerriedc72ee942016-12-07 15:43:281175 if (!ReadParam(m, iter, &type) ||
1176 type != static_cast<int>(base::Value::Type::LIST))
[email protected]bf5aedf02012-06-04 21:18:251177 return false;
1178
1179 return ReadListValue(m, iter, r, 0);
1180}
1181
[email protected]ea5ef4c2013-06-13 22:50:271182void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251183 std::string json;
estade8d046462015-05-16 01:02:341184 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:251185 l->append(json);
1186}
1187
rockot502c94f2016-02-03 20:20:161188void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
[email protected]0238a162013-06-13 13:47:461189 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251190 WriteParam(m, p.string());
1191 WriteParam(m, p.is_null());
1192}
1193
rockot502c94f2016-02-03 20:20:161194bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251195 base::PickleIterator* iter,
[email protected]0238a162013-06-13 13:47:461196 param_type* r) {
[email protected]476dafb2013-12-03 00:39:261197 base::string16 string;
[email protected]bf5aedf02012-06-04 21:18:251198 if (!ReadParam(m, iter, &string))
1199 return false;
1200 bool is_null;
1201 if (!ReadParam(m, iter, &is_null))
1202 return false;
[email protected]0238a162013-06-13 13:47:461203 *r = base::NullableString16(string, is_null);
[email protected]bf5aedf02012-06-04 21:18:251204 return true;
1205}
1206
[email protected]0238a162013-06-13 13:47:461207void ParamTraits<base::NullableString16>::Log(const param_type& p,
1208 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251209 l->append("(");
1210 LogParam(p.string(), l);
1211 l->append(", ");
1212 LogParam(p.is_null(), l);
1213 l->append(")");
1214}
1215
rockot502c94f2016-02-03 20:20:161216void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:001217 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251218 WriteParam(m, p.size);
1219 WriteParam(m, p.is_directory);
1220 WriteParam(m, p.last_modified.ToDoubleT());
1221 WriteParam(m, p.last_accessed.ToDoubleT());
1222 WriteParam(m, p.creation_time.ToDoubleT());
1223}
1224
rockot502c94f2016-02-03 20:20:161225bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251226 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:001227 param_type* p) {
[email protected]481c3e82014-07-18 01:40:471228 double last_modified, last_accessed, creation_time;
1229 if (!ReadParam(m, iter, &p->size) ||
1230 !ReadParam(m, iter, &p->is_directory) ||
1231 !ReadParam(m, iter, &last_modified) ||
1232 !ReadParam(m, iter, &last_accessed) ||
1233 !ReadParam(m, iter, &creation_time))
1234 return false;
1235 p->last_modified = base::Time::FromDoubleT(last_modified);
1236 p->last_accessed = base::Time::FromDoubleT(last_accessed);
1237 p->creation_time = base::Time::FromDoubleT(creation_time);
1238 return true;
[email protected]bf5aedf02012-06-04 21:18:251239}
1240
[email protected]141bcc52014-01-27 21:36:001241void ParamTraits<base::File::Info>::Log(const param_type& p,
1242 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251243 l->append("(");
1244 LogParam(p.size, l);
1245 l->append(",");
1246 LogParam(p.is_directory, l);
1247 l->append(",");
1248 LogParam(p.last_modified.ToDoubleT(), l);
1249 l->append(",");
1250 LogParam(p.last_accessed.ToDoubleT(), l);
1251 l->append(",");
1252 LogParam(p.creation_time.ToDoubleT(), l);
1253 l->append(")");
1254}
1255
rockot502c94f2016-02-03 20:20:161256void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571257 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251258}
1259
rockot502c94f2016-02-03 20:20:161260bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251261 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251262 param_type* r) {
tfarina10a5c062015-09-04 18:47:571263 int64_t value;
1264 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:251265 return false;
1266 *r = base::Time::FromInternalValue(value);
1267 return true;
1268}
1269
1270void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571271 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251272}
1273
rockot502c94f2016-02-03 20:20:161274void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571275 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251276}
1277
rockot502c94f2016-02-03 20:20:161278bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251279 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251280 param_type* r) {
tfarina10a5c062015-09-04 18:47:571281 int64_t value;
1282 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251283 if (ret)
1284 *r = base::TimeDelta::FromInternalValue(value);
1285
1286 return ret;
1287}
1288
1289void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571290 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251291}
1292
rockot502c94f2016-02-03 20:20:161293void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571294 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251295}
1296
rockot502c94f2016-02-03 20:20:161297bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251298 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251299 param_type* r) {
tfarina10a5c062015-09-04 18:47:571300 int64_t value;
1301 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251302 if (ret)
1303 *r = base::TimeTicks::FromInternalValue(value);
1304
1305 return ret;
1306}
1307
1308void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571309 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251310}
1311
tguilbert4a5ac602016-09-19 21:11:251312// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1313// below should be updated.
1314static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1315 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1316
tguilbert4a5ac602016-09-19 21:11:251317void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1318 const param_type& p) {
1319 DCHECK(!p.is_empty());
1320
1321 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1322 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1323}
1324
1325bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1326 base::PickleIterator* iter,
1327 param_type* r) {
1328 uint64_t high, low;
1329 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1330 !ParamTraits<uint64_t>::Read(m, iter, &low))
1331 return false;
1332
1333 // Receiving a zeroed UnguessableToken is a security issue.
1334 if (high == 0 && low == 0)
1335 return false;
1336
1337 *r = base::UnguessableToken::Deserialize(high, low);
1338 return true;
1339}
1340
1341void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1342 std::string* l) {
1343 l->append(p.ToString());
1344}
1345
rockot502c94f2016-02-03 20:20:161346void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1347 const param_type& p) {
sammc9bf370c2016-11-14 03:29:081348#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241349 WriteParam(m, p.socket);
sammc9bf370c2016-11-14 03:29:081350#else
amistry36182522016-06-27 06:34:421351 WriteParam(m, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:081352#endif
[email protected]7a4de7a62010-08-17 18:38:241353}
1354
rockot502c94f2016-02-03 20:20:161355bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251356 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:241357 param_type* r) {
sammc9bf370c2016-11-14 03:29:081358#if defined(OS_NACL_SFI)
1359 return ReadParam(m, iter, &r->socket);
1360#else
1361 return ReadParam(m, iter, &r->mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241362#endif
[email protected]7a4de7a62010-08-17 18:38:241363}
1364
1365void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571366 std::string* l) {
sammc9bf370c2016-11-14 03:29:081367 l->append("ChannelHandle(");
1368#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241369 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
sammc9bf370c2016-11-14 03:29:081370#else
amistry36182522016-06-27 06:34:421371 LogParam(p.mojo_handle, l);
sammc9bf370c2016-11-14 03:29:081372#endif
[email protected]252cad62010-08-18 18:33:571373 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241374}
1375
rockot502c94f2016-02-03 20:20:161376void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301377 WriteParam(m, p.channel);
1378 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271379 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301380 WriteParam(m, p.flags);
1381 WriteParam(m, p.sent);
1382 WriteParam(m, p.receive);
1383 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451384 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301385 WriteParam(m, p.params);
1386}
1387
rockot502c94f2016-02-03 20:20:161388bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251389 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561390 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271391 return
[email protected]20f0487a2010-09-30 20:06:301392 ReadParam(m, iter, &r->channel) &&
1393 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271394 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301395 ReadParam(m, iter, &r->flags) &&
1396 ReadParam(m, iter, &r->sent) &&
1397 ReadParam(m, iter, &r->receive) &&
1398 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451399 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301400 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301401}
1402
[email protected]bf5aedf02012-06-04 21:18:251403void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1404 // Doesn't make sense to implement this!
1405}
1406
rockot502c94f2016-02-03 20:20:161407void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091408#if defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]34d48612012-06-29 00:05:041409 // We don't serialize the file descriptors in the nested message, so there
1410 // better not be any.
morrita1aa788c2015-01-31 05:45:421411 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041412#endif
1413
1414 // Don't just write out the message. This is used to send messages between
1415 // NaCl (Posix environment) and the browser (could be on Windows). The message
1416 // header formats differ between these systems (so does handle sharing, but
1417 // we already asserted we don't have any handles). So just write out the
1418 // parts of the header we use.
1419 //
1420 // Be careful also to use only explicitly-sized types. The NaCl environment
1421 // could be 64-bit and the host browser could be 32-bits. The nested message
1422 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1423 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:571424 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041425 m->WriteUInt32(p.type());
1426 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:571427 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:251428}
1429
rockot502c94f2016-02-03 20:20:161430bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251431 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251432 Message* r) {
tfarina10a5c062015-09-04 18:47:571433 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481434 if (!iter->ReadUInt32(&routing_id) ||
1435 !iter->ReadUInt32(&type) ||
1436 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251437 return false;
[email protected]34d48612012-06-29 00:05:041438
1439 int payload_size;
1440 const char* payload;
avi48fc13b2014-12-28 23:31:481441 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251442 return false;
[email protected]34d48612012-06-29 00:05:041443
tfarina10a5c062015-09-04 18:47:571444 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
Daniel Cheng0d89f9222017-09-22 05:05:071445 r->WriteBytes(payload, payload_size);
1446 return true;
[email protected]bf5aedf02012-06-04 21:18:251447}
1448
1449void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1450 l->append("<IPC::Message>");
1451}
1452
1453#if defined(OS_WIN)
1454// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031455// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161456void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031457 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251458}
1459
rockot502c94f2016-02-03 20:20:161460bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251461 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251462 param_type* r) {
tfarina10a5c062015-09-04 18:47:571463 int32_t temp;
avi48fc13b2014-12-28 23:31:481464 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251465 return false;
[email protected]4a635b72013-03-04 02:29:031466 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251467 return true;
1468}
1469
1470void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001471 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251472}
1473
rockot502c94f2016-02-03 20:20:161474void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251475 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1476}
1477
rockot502c94f2016-02-03 20:20:161478bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251479 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251480 param_type* r) {
1481 const char *data;
1482 int data_size = 0;
avi48fc13b2014-12-28 23:31:481483 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251484 if (result && data_size == sizeof(MSG)) {
1485 memcpy(r, data, sizeof(MSG));
1486 } else {
1487 result = false;
1488 NOTREACHED();
1489 }
1490
1491 return result;
1492}
1493
1494void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1495 l->append("<MSG>");
1496}
1497
1498#endif // OS_WIN
1499
[email protected]946d1b22009-07-22 23:57:211500} // namespace IPC