blob: d945f04d9e09f2da7d715e2d832921b3f30b23ee [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)
Sergey Ulanova97f3282019-04-17 01:27:3439#include "ipc/handle_attachment_fuchsia.h"
Scott Graham3eebff02017-06-30 01:07:1040#include "ipc/handle_fuchsia.h"
41#endif
42
Ken Rockot097248f02018-04-23 16:23:3443#if defined(OS_ANDROID)
44#include "base/android/scoped_hardware_buffer_handle.h"
45#include "ipc/ipc_mojo_handle_attachment.h"
46#include "mojo/public/cpp/system/message_pipe.h"
47#include "mojo/public/cpp/system/scope_to_message_pipe.h"
48#endif
49
[email protected]946d1b22009-07-22 23:57:2150namespace IPC {
51
[email protected]bf5aedf02012-06-04 21:18:2552namespace {
53
joaodasilva383b174a2017-01-10 09:55:3654const int kMaxRecursionDepth = 200;
[email protected]946d1b22009-07-22 23:57:2155
[email protected]bf5aedf02012-06-04 21:18:2556template<typename CharType>
57void LogBytes(const std::vector<CharType>& data, std::string* out) {
58#if defined(OS_WIN)
59 // Windows has a GUI for logging, which can handle arbitrary binary data.
60 for (size_t i = 0; i < data.size(); ++i)
61 out->push_back(data[i]);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:0962#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]bf5aedf02012-06-04 21:18:2563 // On POSIX, we log to stdout, which we assume can display ASCII.
64 static const size_t kMaxBytesToLog = 100;
65 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
66 if (isprint(data[i]))
67 out->push_back(data[i]);
68 else
[email protected]7d3cbc92013-03-18 22:33:0469 out->append(
70 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]bf5aedf02012-06-04 21:18:2571 }
72 if (data.size() > kMaxBytesToLog) {
[email protected]f8660f82013-03-30 17:29:2873 out->append(base::StringPrintf(
74 " and %u more bytes",
75 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
[email protected]bf5aedf02012-06-04 21:18:2576 }
77#endif
78}
[email protected]946d1b22009-07-22 23:57:2179
rockot502c94f2016-02-03 20:20:1680bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:2581 base::PickleIterator* iter,
jdoerrief1e72e32017-04-26 16:23:5582 std::unique_ptr<base::Value>* value,
[email protected]bf5aedf02012-06-04 21:18:2583 int recursion);
[email protected]946d1b22009-07-22 23:57:2184
rockot502c94f2016-02-03 20:20:1685void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
[email protected]dbc761a2012-07-26 01:29:2186 bool result;
[email protected]946d1b22009-07-22 23:57:2187 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:3688 LOG(ERROR) << "Max recursion depth hit in WriteValue.";
[email protected]946d1b22009-07-22 23:57:2189 return;
90 }
91
jdoerrie76cee9c2017-10-06 22:42:4292 m->WriteInt(static_cast<int>(value->type()));
[email protected]946d1b22009-07-22 23:57:2193
jdoerrie76cee9c2017-10-06 22:42:4294 switch (value->type()) {
jdoerriedc72ee942016-12-07 15:43:2895 case base::Value::Type::NONE:
jdoerriee1b1f3a2019-03-16 04:08:0196 break;
jdoerriedc72ee942016-12-07 15:43:2897 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:2198 bool val;
[email protected]dbc761a2012-07-26 01:29:2199 result = value->GetAsBoolean(&val);
100 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21101 WriteParam(m, val);
102 break;
103 }
jdoerriedc72ee942016-12-07 15:43:28104 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21105 int val;
[email protected]dbc761a2012-07-26 01:29:21106 result = value->GetAsInteger(&val);
107 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21108 WriteParam(m, val);
109 break;
110 }
jdoerriedc72ee942016-12-07 15:43:28111 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21112 double val;
[email protected]dbc761a2012-07-26 01:29:21113 result = value->GetAsDouble(&val);
114 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21115 WriteParam(m, val);
116 break;
117 }
jdoerriedc72ee942016-12-07 15:43:28118 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21119 std::string val;
[email protected]dbc761a2012-07-26 01:29:21120 result = value->GetAsString(&val);
121 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21122 WriteParam(m, val);
123 break;
124 }
jdoerriedc72ee942016-12-07 15:43:28125 case base::Value::Type::BINARY: {
jdoerrie9970f20e2018-07-20 21:41:18126 m->WriteData(reinterpret_cast<const char*>(value->GetBlob().data()),
Chris Palmerc5ea9b92017-09-25 22:53:22127 base::checked_cast<int>(value->GetBlob().size()));
[email protected]e4dad9fb2009-10-06 18:15:58128 break;
[email protected]946d1b22009-07-22 23:57:21129 }
jdoerriedc72ee942016-12-07 15:43:28130 case base::Value::Type::DICTIONARY: {
[email protected]ea5ef4c2013-06-13 22:50:27131 const base::DictionaryValue* dict =
132 static_cast<const base::DictionaryValue*>(value);
[email protected]946d1b22009-07-22 23:57:21133
Chris Palmerc5ea9b92017-09-25 22:53:22134 WriteParam(m, base::checked_cast<int>(dict->size()));
[email protected]946d1b22009-07-22 23:57:21135
[email protected]ea5ef4c2013-06-13 22:50:27136 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
137 it.Advance()) {
[email protected]a899c0b02013-01-18 14:43:27138 WriteParam(m, it.key());
139 WriteValue(m, &it.value(), recursion + 1);
[email protected]946d1b22009-07-22 23:57:21140 }
141 break;
142 }
jdoerriedc72ee942016-12-07 15:43:28143 case base::Value::Type::LIST: {
[email protected]ea5ef4c2013-06-13 22:50:27144 const base::ListValue* list = static_cast<const base::ListValue*>(value);
Chris Palmerc5ea9b92017-09-25 22:53:22145 WriteParam(m, base::checked_cast<int>(list->GetSize()));
dchengcb60e702016-05-25 18:30:47146 for (const auto& entry : *list) {
jdoerriea5676c62017-04-11 18:09:14147 WriteValue(m, &entry, recursion + 1);
[email protected]946d1b22009-07-22 23:57:21148 }
149 break;
150 }
jdoerriee1b1f3a2019-03-16 04:08:01151
152 // TODO(crbug.com/859477): Remove after root cause is found.
153 default:
154 CHECK(false);
155 break;
[email protected]946d1b22009-07-22 23:57:21156 }
157}
158
159// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
160// object.
rockot502c94f2016-02-03 20:20:16161bool ReadDictionaryValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25162 base::PickleIterator* iter,
163 base::DictionaryValue* value,
164 int recursion) {
[email protected]946d1b22009-07-22 23:57:21165 int size;
166 if (!ReadParam(m, iter, &size))
167 return false;
168
169 for (int i = 0; i < size; ++i) {
[email protected]e7b418b2010-07-30 19:47:47170 std::string key;
jdoerrief1e72e32017-04-26 16:23:55171 std::unique_ptr<base::Value> subval;
[email protected]946d1b22009-07-22 23:57:21172 if (!ReadParam(m, iter, &key) ||
173 !ReadValue(m, iter, &subval, recursion + 1))
174 return false;
jdoerrief1e72e32017-04-26 16:23:55175 value->SetWithoutPathExpansion(key, std::move(subval));
[email protected]946d1b22009-07-22 23:57:21176 }
177
178 return true;
179}
180
181// Helper for ReadValue that reads a ReadListValue into a pre-allocated
182// object.
rockot502c94f2016-02-03 20:20:16183bool ReadListValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25184 base::PickleIterator* iter,
185 base::ListValue* value,
186 int recursion) {
[email protected]946d1b22009-07-22 23:57:21187 int size;
188 if (!ReadParam(m, iter, &size))
189 return false;
190
191 for (int i = 0; i < size; ++i) {
jdoerrief1e72e32017-04-26 16:23:55192 std::unique_ptr<base::Value> subval;
[email protected]946d1b22009-07-22 23:57:21193 if (!ReadValue(m, iter, &subval, recursion + 1))
194 return false;
jdoerrief1e72e32017-04-26 16:23:55195 value->Set(i, std::move(subval));
[email protected]946d1b22009-07-22 23:57:21196 }
197
198 return true;
199}
200
rockot502c94f2016-02-03 20:20:16201bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25202 base::PickleIterator* iter,
jdoerrief1e72e32017-04-26 16:23:55203 std::unique_ptr<base::Value>* value,
[email protected]bf5aedf02012-06-04 21:18:25204 int recursion) {
[email protected]946d1b22009-07-22 23:57:21205 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:36206 LOG(ERROR) << "Max recursion depth hit in ReadValue.";
[email protected]946d1b22009-07-22 23:57:21207 return false;
208 }
209
210 int type;
211 if (!ReadParam(m, iter, &type))
212 return false;
213
jdoerriedc72ee942016-12-07 15:43:28214 switch (static_cast<base::Value::Type>(type)) {
215 case base::Value::Type::NONE:
Jeremy Roman160eb922017-08-29 17:43:43216 *value = std::make_unique<base::Value>();
jdoerriee067999a2017-04-07 06:39:00217 break;
jdoerriedc72ee942016-12-07 15:43:28218 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21219 bool val;
220 if (!ReadParam(m, iter, &val))
221 return false;
Jeremy Roman160eb922017-08-29 17:43:43222 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21223 break;
224 }
jdoerriedc72ee942016-12-07 15:43:28225 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21226 int val;
227 if (!ReadParam(m, iter, &val))
228 return false;
Jeremy Roman160eb922017-08-29 17:43:43229 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21230 break;
231 }
jdoerriedc72ee942016-12-07 15:43:28232 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21233 double val;
234 if (!ReadParam(m, iter, &val))
235 return false;
Jeremy Roman160eb922017-08-29 17:43:43236 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21237 break;
238 }
jdoerriedc72ee942016-12-07 15:43:28239 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21240 std::string val;
241 if (!ReadParam(m, iter, &val))
242 return false;
Jeremy Roman160eb922017-08-29 17:43:43243 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21244 break;
245 }
jdoerriedc72ee942016-12-07 15:43:28246 case base::Value::Type::BINARY: {
[email protected]e4dad9fb2009-10-06 18:15:58247 const char* data;
248 int length;
avi48fc13b2014-12-28 23:31:48249 if (!iter->ReadData(&data, &length))
[email protected]e4dad9fb2009-10-06 18:15:58250 return false;
jdoerrief1e72e32017-04-26 16:23:55251 *value = base::Value::CreateWithCopiedBuffer(data, length);
[email protected]946d1b22009-07-22 23:57:21252 break;
253 }
jdoerriedc72ee942016-12-07 15:43:28254 case base::Value::Type::DICTIONARY: {
jdoerrief1e72e32017-04-26 16:23:55255 base::DictionaryValue val;
256 if (!ReadDictionaryValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21257 return false;
Jeremy Roman160eb922017-08-29 17:43:43258 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21259 break;
260 }
jdoerriedc72ee942016-12-07 15:43:28261 case base::Value::Type::LIST: {
jdoerrief1e72e32017-04-26 16:23:55262 base::ListValue val;
263 if (!ReadListValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21264 return false;
Jeremy Roman160eb922017-08-29 17:43:43265 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21266 break;
267 }
[email protected]e4dad9fb2009-10-06 18:15:58268 default:
Jan Wilken Dörrie271086b42019-06-13 20:03:41269 NOTREACHED();
jdoerriee1b1f3a2019-03-16 04:08:01270 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
Sergey Ulanova97f3282019-04-17 01:27:34627#if defined(OS_FUCHSIA)
628void ParamTraits<zx::vmo>::Write(base::Pickle* m, const param_type& p) {
629 // This serialization must be kept in sync with
630 // nacl_message_scanner.cc:WriteHandle().
631 const bool valid = p.is_valid();
632 WriteParam(m, valid);
633
634 if (!valid)
635 return;
636
637 if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
638 const_cast<param_type&>(p).release()))) {
639 NOTREACHED();
640 }
641}
642
643bool ParamTraits<zx::vmo>::Read(const base::Pickle* m,
644 base::PickleIterator* iter,
645 param_type* r) {
646 r->reset();
647
648 bool valid;
649 if (!ReadParam(m, iter, &valid))
650 return false;
651
652 if (!valid)
653 return true;
654
655 scoped_refptr<base::Pickle::Attachment> attachment;
656 if (!m->ReadAttachment(iter, &attachment))
657 return false;
658
659 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
660 MessageAttachment::Type::FUCHSIA_HANDLE) {
661 return false;
662 }
663
664 *r = zx::vmo(static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
665 ->Take());
666 return true;
667}
668
669void ParamTraits<zx::vmo>::Log(const param_type& p, std::string* l) {
670 l->append("ZirconVMO");
671}
672#endif // defined(OS_FUCHSIA)
673
Klaus Weidner3824a8882017-11-03 06:24:57674#if defined(OS_ANDROID)
Alexandr Ilin0443a8f2018-07-20 20:14:50675void ParamTraits<base::android::ScopedHardwareBufferHandle>::Write(
676 base::Pickle* m,
677 const param_type& p) {
678 const bool is_valid = p.is_valid();
Ken Rockot097248f02018-04-23 16:23:34679 WriteParam(m, is_valid);
680 if (!is_valid)
681 return;
682
Ken Rockot097248f02018-04-23 16:23:34683 // We must keep a ref to the AHardwareBuffer alive until the receiver has
684 // acquired its own reference. We do this by sending a message pipe handle
685 // along with the buffer. When the receiver deserializes (or even if they
686 // die without ever reading the message) their end of the pipe will be
687 // closed. We will eventually detect this and release the AHB reference.
688 mojo::MessagePipe tracking_pipe;
689 m->WriteAttachment(new internal::MojoHandleAttachment(
690 mojo::ScopedHandle::From(std::move(tracking_pipe.handle0))));
Alexandr Ilin0443a8f2018-07-20 20:14:50691 WriteParam(m, base::FileDescriptor(p.SerializeAsFileDescriptor().release(),
692 true /* auto_close */));
Ken Rockot097248f02018-04-23 16:23:34693
694 // Pass ownership of the input handle to our tracking pipe to keep the AHB
695 // alive long enough to be deserialized by the receiver.
Alexandr Ilin0443a8f2018-07-20 20:14:50696 mojo::ScopeToMessagePipe(std::move(const_cast<param_type&>(p)),
697 std::move(tracking_pipe.handle1));
Klaus Weidner3824a8882017-11-03 06:24:57698}
699
Alexandr Ilin0443a8f2018-07-20 20:14:50700bool ParamTraits<base::android::ScopedHardwareBufferHandle>::Read(
701 const base::Pickle* m,
702 base::PickleIterator* iter,
703 param_type* r) {
704 *r = base::android::ScopedHardwareBufferHandle();
Ken Rockot097248f02018-04-23 16:23:34705
706 bool is_valid;
707 if (!ReadParam(m, iter, &is_valid))
Klaus Weidner3824a8882017-11-03 06:24:57708 return false;
Ken Rockot097248f02018-04-23 16:23:34709 if (!is_valid)
710 return true;
711
712 scoped_refptr<base::Pickle::Attachment> tracking_pipe_attachment;
713 if (!m->ReadAttachment(iter, &tracking_pipe_attachment))
Klaus Weidner3824a8882017-11-03 06:24:57714 return false;
Ken Rockot097248f02018-04-23 16:23:34715
716 // We keep this alive until the AHB is safely deserialized below. When this
717 // goes out of scope, the sender holding the other end of this pipe will treat
718 // this handle closure as a signal that it's safe to release their AHB
719 // keepalive ref.
720 mojo::ScopedHandle tracking_pipe =
721 static_cast<MessageAttachment*>(tracking_pipe_attachment.get())
722 ->TakeMojoHandle();
723
724 base::FileDescriptor descriptor;
725 if (!ReadParam(m, iter, &descriptor))
726 return false;
727
728 // NOTE: It is valid to deserialize an invalid FileDescriptor, so the success
729 // of |ReadParam()| above does not imply that |descriptor| is valid.
730 base::ScopedFD scoped_fd(descriptor.fd);
731 if (!scoped_fd.is_valid())
732 return false;
733
734 *r = base::android::ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(
Alexandr Ilin0443a8f2018-07-20 20:14:50735 std::move(scoped_fd));
Klaus Weidner3824a8882017-11-03 06:24:57736 return true;
737}
738
Alexandr Ilin0443a8f2018-07-20 20:14:50739void ParamTraits<base::android::ScopedHardwareBufferHandle>::Log(
740 const param_type& p,
741 std::string* l) {
742 l->append(base::StringPrintf("base::android::ScopedHardwareBufferHandle(%p)",
743 p.get()));
Klaus Weidner3824a8882017-11-03 06:24:57744}
Ken Rockot097248f02018-04-23 16:23:34745#endif // defined(OS_ANDROID)
Klaus Weidner3824a8882017-11-03 06:24:57746
erikchen22a813b2017-04-28 17:10:50747void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
748 const param_type& p) {
erikchen14525202017-05-06 19:16:51749 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06750 // nacl_message_scanner.cc:WriteHandle().
erikchen22a813b2017-04-28 17:10:50751 const bool valid = p.IsValid();
752 WriteParam(m, valid);
753
754 if (!valid)
755 return;
756
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09757#if defined(OS_WIN)
Wez51eaaad2017-08-09 05:51:38758 HandleWin handle_win(p.GetHandle());
erikchen9d6afd712017-05-18 17:49:06759 WriteParam(m, handle_win);
Wez8c49ebc92017-08-10 17:11:13760#elif defined(OS_FUCHSIA)
761 HandleFuchsia handle_fuchsia(p.GetHandle());
762 WriteParam(m, handle_fuchsia);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09763#elif defined(OS_MACOSX) && !defined(OS_IOS)
764 MachPortMac mach_port_mac(p.GetMemoryObject());
765 WriteParam(m, mach_port_mac);
766#elif defined(OS_POSIX)
Klaus Weidner3824a8882017-11-03 06:24:57767#if defined(OS_ANDROID)
David 'Digit' Turnere2a65762018-01-19 17:51:51768 WriteParam(m, p.IsReadOnly());
769
770 // Ensure the region is read-only before sending it through IPC.
771 if (p.IsReadOnly()) {
772 if (!p.IsRegionReadOnly()) {
773 LOG(ERROR) << "Sending unsealed read-only region through IPC";
774 p.SetRegionReadOnly();
775 }
776 }
Klaus Weidner3824a8882017-11-03 06:24:57777#endif
erikchen22a813b2017-04-28 17:10:50778 if (p.OwnershipPassesToIPC()) {
779 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
780 base::ScopedFD(p.GetHandle()))))
781 NOTREACHED();
782 } else {
783 if (!m->WriteAttachment(
784 new internal::PlatformFileAttachment(p.GetHandle())))
785 NOTREACHED();
786 }
erikchen9d6afd712017-05-18 17:49:06787#endif
788
789#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
790 // If the caller intended to pass ownership to the IPC stack, release a
791 // reference.
792 if (p.OwnershipPassesToIPC())
793 p.Close();
794#endif
795
erikchen14525202017-05-06 19:16:51796 DCHECK(!p.GetGUID().is_empty());
797 WriteParam(m, p.GetGUID());
erikchen9d6afd712017-05-18 17:49:06798 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
erikchen22a813b2017-04-28 17:10:50799}
800
801bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
802 base::PickleIterator* iter,
803 param_type* r) {
804 *r = base::SharedMemoryHandle();
805
806 bool valid;
807 if (!ReadParam(m, iter, &valid))
808 return false;
erikchen22a813b2017-04-28 17:10:50809 if (!valid)
810 return true;
811
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09812#if defined(OS_WIN)
erikchen9d6afd712017-05-18 17:49:06813 HandleWin handle_win;
814 if (!ReadParam(m, iter, &handle_win))
815 return false;
Scott Graham3eebff02017-06-30 01:07:10816#elif defined(OS_FUCHSIA)
817 HandleFuchsia handle_fuchsia;
818 if (!ReadParam(m, iter, &handle_fuchsia))
819 return false;
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09820#elif defined(OS_MACOSX) && !defined(OS_IOS)
821 MachPortMac mach_port_mac;
822 if (!ReadParam(m, iter, &mach_port_mac))
823 return false;
824#elif defined(OS_POSIX)
Klaus Weidner3824a8882017-11-03 06:24:57825#if defined(OS_ANDROID)
David 'Digit' Turnere2a65762018-01-19 17:51:51826 bool is_read_only = false;
Ken Rockot097248f02018-04-23 16:23:34827 if (!ReadParam(m, iter, &is_read_only))
Klaus Weidner3824a8882017-11-03 06:24:57828 return false;
829#endif
erikchen22a813b2017-04-28 17:10:50830 scoped_refptr<base::Pickle::Attachment> attachment;
831 if (!m->ReadAttachment(iter, &attachment))
832 return false;
833
834 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
835 MessageAttachment::Type::PLATFORM_FILE) {
836 return false;
837 }
erikchen9d6afd712017-05-18 17:49:06838#endif
erikchen22a813b2017-04-28 17:10:50839
erikchen14525202017-05-06 19:16:51840 base::UnguessableToken guid;
erikchen9d6afd712017-05-18 17:49:06841 uint64_t size;
Alexandr Ilind497eee2018-04-19 22:50:54842 if (!ReadParam(m, iter, &guid) || !ReadParam(m, iter, &size) ||
843 !base::IsValueInRangeForNumericType<size_t>(size)) {
erikchen14525202017-05-06 19:16:51844 return false;
erikchen9d6afd712017-05-18 17:49:06845 }
erikchen14525202017-05-06 19:16:51846
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09847#if defined(OS_WIN)
erikchen9d6afd712017-05-18 17:49:06848 *r = base::SharedMemoryHandle(handle_win.get_handle(),
849 static_cast<size_t>(size), guid);
Scott Graham3eebff02017-06-30 01:07:10850#elif defined(OS_FUCHSIA)
851 *r = base::SharedMemoryHandle(handle_fuchsia.get_handle(),
852 static_cast<size_t>(size), guid);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09853#elif defined(OS_MACOSX) && !defined(OS_IOS)
854 *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
855 static_cast<size_t>(size), guid);
856#elif defined(OS_POSIX)
erikchen14525202017-05-06 19:16:51857 *r = base::SharedMemoryHandle(
858 base::FileDescriptor(
859 static_cast<internal::PlatformFileAttachment*>(attachment.get())
860 ->TakePlatformFile(),
861 true),
erikchen9d6afd712017-05-18 17:49:06862 static_cast<size_t>(size), guid);
863#endif
864
Ken Rockot097248f02018-04-23 16:23:34865#if defined(OS_ANDROID)
866 if (is_read_only)
867 r->SetReadOnly();
868#endif
869
erikchen22a813b2017-04-28 17:10:50870 return true;
871}
872
873void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
874 std::string* l) {
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09875#if defined(OS_WIN)
erikchen9d6afd712017-05-18 17:49:06876 l->append("HANDLE: ");
877 LogParam(p.GetHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09878#elif defined(OS_MACOSX) && !defined(OS_IOS)
879 l->append("Mach port: ");
880 LogParam(p.GetMemoryObject(), l);
881#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
erikchen9d6afd712017-05-18 17:49:06882 l->append("FD: ");
883 LogParam(p.GetHandle(), l);
884#endif
885
erikchen14525202017-05-06 19:16:51886 l->append("GUID: ");
erikchen9d6afd712017-05-18 17:49:06887 LogParam(p.GetGUID(), l);
888 l->append("size: ");
889 LogParam(static_cast<uint64_t>(p.GetSize()), l);
David 'Digit' Turnere2a65762018-01-19 17:51:51890#if defined(OS_ANDROID)
891 l->append("read-only: ");
892 LogParam(p.IsReadOnly(), l);
893#endif
erikchen22a813b2017-04-28 17:10:50894}
scottmgd19b4f72015-06-19 22:51:00895
Alexandr Ilind497eee2018-04-19 22:50:54896void ParamTraits<base::ReadOnlySharedMemoryRegion>::Write(base::Pickle* m,
897 const param_type& p) {
898 base::subtle::PlatformSharedMemoryRegion handle =
899 base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
900 std::move(const_cast<param_type&>(p)));
901 WriteParam(m, std::move(handle));
902}
903
904bool ParamTraits<base::ReadOnlySharedMemoryRegion>::Read(
905 const base::Pickle* m,
906 base::PickleIterator* iter,
907 param_type* r) {
908 base::subtle::PlatformSharedMemoryRegion handle;
909 if (!ReadParam(m, iter, &handle))
910 return false;
911
912 *r = base::ReadOnlySharedMemoryRegion::Deserialize(std::move(handle));
913 return true;
914}
915
916void ParamTraits<base::ReadOnlySharedMemoryRegion>::Log(const param_type& p,
917 std::string* l) {
918 *l = "<base::ReadOnlySharedMemoryRegion>";
919 // TODO(alexilin): currently there is no way to access underlying handle
920 // without destructing a ReadOnlySharedMemoryRegion instance.
921}
922
923void ParamTraits<base::WritableSharedMemoryRegion>::Write(base::Pickle* m,
924 const param_type& p) {
925 base::subtle::PlatformSharedMemoryRegion handle =
926 base::WritableSharedMemoryRegion::TakeHandleForSerialization(
927 std::move(const_cast<param_type&>(p)));
928 WriteParam(m, std::move(handle));
929}
930
931bool ParamTraits<base::WritableSharedMemoryRegion>::Read(
932 const base::Pickle* m,
933 base::PickleIterator* iter,
934 param_type* r) {
935 base::subtle::PlatformSharedMemoryRegion handle;
936 if (!ReadParam(m, iter, &handle))
937 return false;
938
939 *r = base::WritableSharedMemoryRegion::Deserialize(std::move(handle));
940 return true;
941}
942
943void ParamTraits<base::WritableSharedMemoryRegion>::Log(const param_type& p,
944 std::string* l) {
945 *l = "<base::WritableSharedMemoryRegion>";
946 // TODO(alexilin): currently there is no way to access underlying handle
947 // without destructing a ReadOnlySharedMemoryRegion instance.
948}
949
950void ParamTraits<base::UnsafeSharedMemoryRegion>::Write(base::Pickle* m,
951 const param_type& p) {
952 base::subtle::PlatformSharedMemoryRegion handle =
953 base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
954 std::move(const_cast<param_type&>(p)));
955 WriteParam(m, std::move(handle));
956}
957
958bool ParamTraits<base::UnsafeSharedMemoryRegion>::Read(
959 const base::Pickle* m,
960 base::PickleIterator* iter,
961 param_type* r) {
962 base::subtle::PlatformSharedMemoryRegion handle;
963 if (!ReadParam(m, iter, &handle))
964 return false;
965
966 *r = base::UnsafeSharedMemoryRegion::Deserialize(std::move(handle));
967 return true;
968}
969
970void ParamTraits<base::UnsafeSharedMemoryRegion>::Log(const param_type& p,
971 std::string* l) {
972 *l = "<base::UnsafeSharedMemoryRegion>";
973 // TODO(alexilin): currently there is no way to access underlying handle
974 // without destructing a ReadOnlySharedMemoryRegion instance.
975}
976
977void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Write(
978 base::Pickle* m,
979 const param_type& p) {
Alexandr Ilinebab9da2018-06-01 02:37:47980 // This serialization must be kept in sync with
981 // nacl_message_scanner.cc::WriteHandle().
Alexandr Ilind497eee2018-04-19 22:50:54982 const bool valid = p.IsValid();
983 WriteParam(m, valid);
984
985 if (!valid)
986 return;
987
988 WriteParam(m, p.GetMode());
989 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
990 WriteParam(m, p.GetGUID());
991
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09992#if defined(OS_WIN)
993 base::win::ScopedHandle h = const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54994 HandleWin handle_win(h.Get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09995 WriteParam(m, handle_win);
Alexandr Ilind497eee2018-04-19 22:50:54996#elif defined(OS_FUCHSIA)
Wez157707d62018-07-10 22:48:47997 zx::handle h = const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54998 HandleFuchsia handle_fuchsia(h.get());
Alexandr Ilind497eee2018-04-19 22:50:54999 WriteParam(m, handle_fuchsia);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091000#elif defined(OS_MACOSX) && !defined(OS_IOS)
1001 base::mac::ScopedMachSendRight h =
1002 const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:541003 MachPortMac mach_port_mac(h.get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091004 WriteParam(m, mach_port_mac);
Alexandr Ilind497eee2018-04-19 22:50:541005#elif defined(OS_ANDROID)
1006 m->WriteAttachment(new internal::PlatformFileAttachment(
1007 base::ScopedFD(const_cast<param_type&>(p).PassPlatformHandle())));
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091008#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541009 base::subtle::ScopedFDPair h =
1010 const_cast<param_type&>(p).PassPlatformHandle();
1011 m->WriteAttachment(new internal::PlatformFileAttachment(std::move(h.fd)));
1012 if (p.GetMode() ==
1013 base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
1014 m->WriteAttachment(
1015 new internal::PlatformFileAttachment(std::move(h.readonly_fd)));
1016 }
1017#endif
1018}
1019
1020bool ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Read(
1021 const base::Pickle* m,
1022 base::PickleIterator* iter,
1023 param_type* r) {
1024 bool valid;
1025 if (!ReadParam(m, iter, &valid))
1026 return false;
1027 if (!valid) {
1028 *r = base::subtle::PlatformSharedMemoryRegion();
1029 return true;
1030 }
1031
1032 base::subtle::PlatformSharedMemoryRegion::Mode mode;
1033 uint64_t shm_size;
1034 base::UnguessableToken guid;
1035 if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &shm_size) ||
1036 !base::IsValueInRangeForNumericType<size_t>(shm_size) ||
1037 !ReadParam(m, iter, &guid)) {
1038 return false;
1039 }
1040 size_t size = static_cast<size_t>(shm_size);
1041
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091042#if defined(OS_WIN)
1043 HandleWin handle_win;
1044 if (!ReadParam(m, iter, &handle_win))
Alexandr Ilind497eee2018-04-19 22:50:541045 return false;
1046 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091047 base::win::ScopedHandle(handle_win.get_handle()), mode, size, guid);
Alexandr Ilind497eee2018-04-19 22:50:541048#elif defined(OS_FUCHSIA)
1049 HandleFuchsia handle_fuchsia;
1050 if (!ReadParam(m, iter, &handle_fuchsia))
1051 return false;
1052 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Wez157707d62018-07-10 22:48:471053 zx::vmo(handle_fuchsia.get_handle()), mode, size, guid);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091054#elif defined(OS_MACOSX) && !defined(OS_IOS)
1055 MachPortMac mach_port_mac;
1056 if (!ReadParam(m, iter, &mach_port_mac))
Alexandr Ilind497eee2018-04-19 22:50:541057 return false;
1058 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091059 base::mac::ScopedMachSendRight(mach_port_mac.get_mach_port()), mode, size,
1060 guid);
1061#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541062 scoped_refptr<base::Pickle::Attachment> attachment;
1063 if (!m->ReadAttachment(iter, &attachment))
1064 return false;
1065 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
1066 MessageAttachment::Type::PLATFORM_FILE) {
1067 return false;
1068 }
1069
1070#if defined(OS_ANDROID)
1071 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1072 base::ScopedFD(
1073 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1074 ->TakePlatformFile()),
1075 mode, size, guid);
1076#else
1077 scoped_refptr<base::Pickle::Attachment> readonly_attachment;
1078 if (mode == base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
1079 if (!m->ReadAttachment(iter, &readonly_attachment))
1080 return false;
1081
1082 if (static_cast<MessageAttachment*>(readonly_attachment.get())->GetType() !=
1083 MessageAttachment::Type::PLATFORM_FILE) {
1084 return false;
1085 }
1086 }
1087 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1088 base::subtle::ScopedFDPair(
1089 base::ScopedFD(
1090 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1091 ->TakePlatformFile()),
1092 readonly_attachment
1093 ? base::ScopedFD(static_cast<internal::PlatformFileAttachment*>(
1094 readonly_attachment.get())
1095 ->TakePlatformFile())
1096 : base::ScopedFD()),
1097 mode, size, guid);
1098#endif // defined(OS_ANDROID)
1099
1100#endif
1101
1102 return true;
1103}
1104
1105void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Log(
1106 const param_type& p,
1107 std::string* l) {
Wezb908e432018-09-05 17:35:221108#if defined(OS_FUCHSIA)
1109 l->append("Handle: ");
1110 LogParam(p.GetPlatformHandle()->get(), l);
1111#elif defined(OS_WIN)
Alexandr Ilind497eee2018-04-19 22:50:541112 l->append("Handle: ");
1113 LogParam(p.GetPlatformHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091114#elif defined(OS_MACOSX) && !defined(OS_IOS)
1115 l->append("Mach port: ");
1116 LogParam(p.GetPlatformHandle(), l);
Alexandr Ilind497eee2018-04-19 22:50:541117#elif defined(OS_ANDROID)
1118 l->append("FD: ");
1119 LogParam(p.GetPlatformHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091120#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541121 base::subtle::FDPair h = p.GetPlatformHandle();
1122 l->append("FD: ");
1123 LogParam(h.fd, l);
1124 l->append("Read-only FD: ");
1125 LogParam(h.readonly_fd, l);
1126#endif
1127
1128 l->append("Mode: ");
1129 LogParam(p.GetMode(), l);
1130 l->append("size: ");
1131 LogParam(static_cast<uint64_t>(p.GetSize()), l);
1132 l->append("GUID: ");
1133 LogParam(p.GetGUID(), l);
1134}
1135
1136void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Write(
1137 base::Pickle* m,
1138 const param_type& value) {
1139 DCHECK(static_cast<int>(value) >= 0 &&
1140 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue));
1141 m->WriteInt(static_cast<int>(value));
1142}
1143
1144bool ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Read(
1145 const base::Pickle* m,
1146 base::PickleIterator* iter,
1147 param_type* p) {
1148 int value;
1149 if (!iter->ReadInt(&value))
1150 return false;
1151 if (!(static_cast<int>(value) >= 0 &&
1152 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue))) {
1153 return false;
1154 }
1155 *p = static_cast<param_type>(value);
1156 return true;
1157}
1158
1159void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Log(
1160 const param_type& p,
1161 std::string* l) {
1162 LogParam(static_cast<int>(p), l);
1163}
1164
erikchend804e1052017-04-29 02:24:361165#if defined(OS_WIN)
erikchend804e1052017-04-29 02:24:361166void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
1167 const param_type& p) {
1168 m->WriteBool(p.IsValid());
1169 if (p.IsValid()) {
Wez51eaaad2017-08-09 05:51:381170 HandleWin handle_win(p.GetHandle());
erikchend804e1052017-04-29 02:24:361171 ParamTraits<HandleWin>::Write(m, handle_win);
1172 ::CloseHandle(p.GetHandle());
1173 }
1174}
1175
1176bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
1177 base::PickleIterator* iter,
1178 param_type* r) {
1179 bool is_valid;
1180 if (!iter->ReadBool(&is_valid))
1181 return false;
1182 if (!is_valid) {
1183 *r = PlatformFileForTransit();
1184 return true;
1185 }
1186
1187 HandleWin handle_win;
1188 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
1189 return false;
1190 *r = PlatformFileForTransit(handle_win.get_handle());
1191 return true;
1192}
1193
1194void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
1195 std::string* l) {
1196 LogParam(p.GetHandle(), l);
1197}
1198#endif // defined(OS_WIN)
1199
rockot502c94f2016-02-03 20:20:161200void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:551201 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:251202}
1203
rockot502c94f2016-02-03 20:20:161204bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251205 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:301206 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:551207 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:251208}
1209
[email protected]6d4b67a2013-02-10 04:49:301210void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
1211 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:251212}
1213
rockot502c94f2016-02-03 20:20:161214void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251215 WriteValue(m, &p, 0);
1216}
1217
rockot502c94f2016-02-03 20:20:161218bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251219 base::PickleIterator* iter,
1220 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:251221 int type;
jdoerriedc72ee942016-12-07 15:43:281222 if (!ReadParam(m, iter, &type) ||
1223 type != static_cast<int>(base::Value::Type::LIST))
[email protected]bf5aedf02012-06-04 21:18:251224 return false;
1225
1226 return ReadListValue(m, iter, r, 0);
1227}
1228
[email protected]ea5ef4c2013-06-13 22:50:271229void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251230 std::string json;
estade8d046462015-05-16 01:02:341231 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:251232 l->append(json);
1233}
1234
rockot502c94f2016-02-03 20:20:161235void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
[email protected]0238a162013-06-13 13:47:461236 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251237 WriteParam(m, p.string());
1238 WriteParam(m, p.is_null());
1239}
1240
rockot502c94f2016-02-03 20:20:161241bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251242 base::PickleIterator* iter,
[email protected]0238a162013-06-13 13:47:461243 param_type* r) {
[email protected]476dafb2013-12-03 00:39:261244 base::string16 string;
[email protected]bf5aedf02012-06-04 21:18:251245 if (!ReadParam(m, iter, &string))
1246 return false;
1247 bool is_null;
1248 if (!ReadParam(m, iter, &is_null))
1249 return false;
[email protected]0238a162013-06-13 13:47:461250 *r = base::NullableString16(string, is_null);
[email protected]bf5aedf02012-06-04 21:18:251251 return true;
1252}
1253
[email protected]0238a162013-06-13 13:47:461254void ParamTraits<base::NullableString16>::Log(const param_type& p,
1255 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251256 l->append("(");
1257 LogParam(p.string(), l);
1258 l->append(", ");
1259 LogParam(p.is_null(), l);
1260 l->append(")");
1261}
1262
rockot502c94f2016-02-03 20:20:161263void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:001264 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251265 WriteParam(m, p.size);
1266 WriteParam(m, p.is_directory);
1267 WriteParam(m, p.last_modified.ToDoubleT());
1268 WriteParam(m, p.last_accessed.ToDoubleT());
1269 WriteParam(m, p.creation_time.ToDoubleT());
1270}
1271
rockot502c94f2016-02-03 20:20:161272bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251273 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:001274 param_type* p) {
[email protected]481c3e82014-07-18 01:40:471275 double last_modified, last_accessed, creation_time;
1276 if (!ReadParam(m, iter, &p->size) ||
1277 !ReadParam(m, iter, &p->is_directory) ||
1278 !ReadParam(m, iter, &last_modified) ||
1279 !ReadParam(m, iter, &last_accessed) ||
1280 !ReadParam(m, iter, &creation_time))
1281 return false;
1282 p->last_modified = base::Time::FromDoubleT(last_modified);
1283 p->last_accessed = base::Time::FromDoubleT(last_accessed);
1284 p->creation_time = base::Time::FromDoubleT(creation_time);
1285 return true;
[email protected]bf5aedf02012-06-04 21:18:251286}
1287
[email protected]141bcc52014-01-27 21:36:001288void ParamTraits<base::File::Info>::Log(const param_type& p,
1289 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251290 l->append("(");
1291 LogParam(p.size, l);
1292 l->append(",");
1293 LogParam(p.is_directory, l);
1294 l->append(",");
1295 LogParam(p.last_modified.ToDoubleT(), l);
1296 l->append(",");
1297 LogParam(p.last_accessed.ToDoubleT(), l);
1298 l->append(",");
1299 LogParam(p.creation_time.ToDoubleT(), l);
1300 l->append(")");
1301}
1302
rockot502c94f2016-02-03 20:20:161303void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571304 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251305}
1306
rockot502c94f2016-02-03 20:20:161307bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251308 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251309 param_type* r) {
tfarina10a5c062015-09-04 18:47:571310 int64_t value;
1311 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:251312 return false;
1313 *r = base::Time::FromInternalValue(value);
1314 return true;
1315}
1316
1317void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571318 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251319}
1320
rockot502c94f2016-02-03 20:20:161321void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571322 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251323}
1324
rockot502c94f2016-02-03 20:20:161325bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251326 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251327 param_type* r) {
tfarina10a5c062015-09-04 18:47:571328 int64_t value;
1329 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251330 if (ret)
1331 *r = base::TimeDelta::FromInternalValue(value);
1332
1333 return ret;
1334}
1335
1336void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571337 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251338}
1339
rockot502c94f2016-02-03 20:20:161340void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571341 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251342}
1343
rockot502c94f2016-02-03 20:20:161344bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251345 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251346 param_type* r) {
tfarina10a5c062015-09-04 18:47:571347 int64_t value;
1348 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251349 if (ret)
1350 *r = base::TimeTicks::FromInternalValue(value);
1351
1352 return ret;
1353}
1354
1355void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571356 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251357}
1358
tguilbert4a5ac602016-09-19 21:11:251359// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1360// below should be updated.
1361static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1362 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1363
tguilbert4a5ac602016-09-19 21:11:251364void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1365 const param_type& p) {
1366 DCHECK(!p.is_empty());
1367
1368 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1369 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1370}
1371
1372bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1373 base::PickleIterator* iter,
1374 param_type* r) {
1375 uint64_t high, low;
1376 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1377 !ParamTraits<uint64_t>::Read(m, iter, &low))
1378 return false;
1379
1380 // Receiving a zeroed UnguessableToken is a security issue.
1381 if (high == 0 && low == 0)
1382 return false;
1383
1384 *r = base::UnguessableToken::Deserialize(high, low);
1385 return true;
1386}
1387
1388void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1389 std::string* l) {
1390 l->append(p.ToString());
1391}
1392
rockot502c94f2016-02-03 20:20:161393void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1394 const param_type& p) {
sammc9bf370c2016-11-14 03:29:081395#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241396 WriteParam(m, p.socket);
sammc9bf370c2016-11-14 03:29:081397#else
amistry36182522016-06-27 06:34:421398 WriteParam(m, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:081399#endif
[email protected]7a4de7a62010-08-17 18:38:241400}
1401
rockot502c94f2016-02-03 20:20:161402bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251403 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:241404 param_type* r) {
sammc9bf370c2016-11-14 03:29:081405#if defined(OS_NACL_SFI)
1406 return ReadParam(m, iter, &r->socket);
1407#else
1408 return ReadParam(m, iter, &r->mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241409#endif
[email protected]7a4de7a62010-08-17 18:38:241410}
1411
1412void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571413 std::string* l) {
sammc9bf370c2016-11-14 03:29:081414 l->append("ChannelHandle(");
1415#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241416 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
sammc9bf370c2016-11-14 03:29:081417#else
amistry36182522016-06-27 06:34:421418 LogParam(p.mojo_handle, l);
sammc9bf370c2016-11-14 03:29:081419#endif
[email protected]252cad62010-08-18 18:33:571420 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241421}
1422
rockot502c94f2016-02-03 20:20:161423void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301424 WriteParam(m, p.channel);
1425 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271426 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301427 WriteParam(m, p.flags);
1428 WriteParam(m, p.sent);
1429 WriteParam(m, p.receive);
1430 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451431 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301432 WriteParam(m, p.params);
1433}
1434
rockot502c94f2016-02-03 20:20:161435bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251436 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561437 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271438 return
[email protected]20f0487a2010-09-30 20:06:301439 ReadParam(m, iter, &r->channel) &&
1440 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271441 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301442 ReadParam(m, iter, &r->flags) &&
1443 ReadParam(m, iter, &r->sent) &&
1444 ReadParam(m, iter, &r->receive) &&
1445 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451446 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301447 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301448}
1449
[email protected]bf5aedf02012-06-04 21:18:251450void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1451 // Doesn't make sense to implement this!
1452}
1453
rockot502c94f2016-02-03 20:20:161454void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091455#if defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]34d48612012-06-29 00:05:041456 // We don't serialize the file descriptors in the nested message, so there
1457 // better not be any.
morrita1aa788c2015-01-31 05:45:421458 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041459#endif
1460
1461 // Don't just write out the message. This is used to send messages between
1462 // NaCl (Posix environment) and the browser (could be on Windows). The message
1463 // header formats differ between these systems (so does handle sharing, but
1464 // we already asserted we don't have any handles). So just write out the
1465 // parts of the header we use.
1466 //
1467 // Be careful also to use only explicitly-sized types. The NaCl environment
1468 // could be 64-bit and the host browser could be 32-bits. The nested message
1469 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1470 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:571471 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041472 m->WriteUInt32(p.type());
1473 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:571474 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:251475}
1476
rockot502c94f2016-02-03 20:20:161477bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251478 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251479 Message* r) {
tfarina10a5c062015-09-04 18:47:571480 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481481 if (!iter->ReadUInt32(&routing_id) ||
1482 !iter->ReadUInt32(&type) ||
1483 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251484 return false;
[email protected]34d48612012-06-29 00:05:041485
1486 int payload_size;
1487 const char* payload;
avi48fc13b2014-12-28 23:31:481488 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251489 return false;
[email protected]34d48612012-06-29 00:05:041490
tfarina10a5c062015-09-04 18:47:571491 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
Daniel Cheng0d89f9222017-09-22 05:05:071492 r->WriteBytes(payload, payload_size);
1493 return true;
[email protected]bf5aedf02012-06-04 21:18:251494}
1495
1496void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1497 l->append("<IPC::Message>");
1498}
1499
1500#if defined(OS_WIN)
1501// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031502// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161503void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031504 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251505}
1506
rockot502c94f2016-02-03 20:20:161507bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251508 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251509 param_type* r) {
tfarina10a5c062015-09-04 18:47:571510 int32_t temp;
avi48fc13b2014-12-28 23:31:481511 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251512 return false;
[email protected]4a635b72013-03-04 02:29:031513 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251514 return true;
1515}
1516
1517void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001518 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251519}
1520
rockot502c94f2016-02-03 20:20:161521void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251522 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1523}
1524
rockot502c94f2016-02-03 20:20:161525bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251526 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251527 param_type* r) {
1528 const char *data;
1529 int data_size = 0;
avi48fc13b2014-12-28 23:31:481530 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251531 if (result && data_size == sizeof(MSG)) {
1532 memcpy(r, data, sizeof(MSG));
1533 } else {
1534 result = false;
1535 NOTREACHED();
1536 }
1537
1538 return result;
1539}
1540
1541void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1542 l->append("<MSG>");
1543}
1544
1545#endif // OS_WIN
1546
[email protected]946d1b22009-07-22 23:57:211547} // namespace IPC