blob: ec2d60e3450fcfc9a5a2acd1b3f8e458e1851e23 [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"
Hans Wennborg24397592020-06-17 16:58:5012#include "base/logging.h"
jdoerrief1e72e32017-04-26 16:23:5513#include "base/memory/ptr_util.h"
[email protected]0238a162013-06-13 13:47:4614#include "base/strings/nullable_string16.h"
[email protected]4aa794a12013-06-11 06:32:1815#include "base/strings/string_number_conversions.h"
[email protected]906265872013-06-07 22:40:4516#include "base/strings/utf_string_conversions.h"
[email protected]b43e5562013-06-28 15:20:0217#include "base/time/time.h"
tguilbert4a5ac602016-09-19 21:11:2518#include "base/unguessable_token.h"
[email protected]946d1b22009-07-22 23:57:2119#include "base/values.h"
avi246998d82015-12-22 02:39:0420#include "build/build_config.h"
[email protected]bf5aedf02012-06-04 21:18:2521#include "ipc/ipc_channel_handle.h"
morrita1aa788c2015-01-31 05:45:4222#include "ipc/ipc_message_attachment.h"
morrita4b5c28e22015-01-14 21:17:0623#include "ipc/ipc_message_attachment_set.h"
amistry36182522016-06-27 06:34:4224#include "ipc/ipc_mojo_param_traits.h"
[email protected]bf5aedf02012-06-04 21:18:2525
Avi Drissman2b97d032020-07-30 03:02:2626#if defined(OS_MAC)
erikchenaf8299d2015-10-09 19:12:0627#include "ipc/mach_port_mac.h"
28#endif
29
morrita4b5c28e22015-01-14 21:17:0630#if defined(OS_WIN)
[email protected]2e02cfe82012-11-21 00:58:0031#include <tchar.h>
erikchen5ea2ab72015-09-25 22:34:3132#include "ipc/handle_win.h"
erikchend804e1052017-04-29 02:24:3633#include "ipc/ipc_platform_file.h"
Fabrice de Gans-Ribericbce4342018-05-07 20:02:0934#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
35#include "base/file_descriptor_posix.h"
36#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]7a4de7a62010-08-17 18:38:2437#endif
[email protected]946d1b22009-07-22 23:57:2138
Scott Graham3eebff02017-06-30 01:07:1039#if defined(OS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:4340#include "base/fuchsia/fuchsia_logging.h"
Sergey Ulanova97f3282019-04-17 01:27:3441#include "ipc/handle_attachment_fuchsia.h"
Scott Graham3eebff02017-06-30 01:07:1042#endif
43
Ken Rockot097248f02018-04-23 16:23:3444#if defined(OS_ANDROID)
45#include "base/android/scoped_hardware_buffer_handle.h"
46#include "ipc/ipc_mojo_handle_attachment.h"
47#include "mojo/public/cpp/system/message_pipe.h"
48#include "mojo/public/cpp/system/scope_to_message_pipe.h"
49#endif
50
[email protected]946d1b22009-07-22 23:57:2151namespace IPC {
52
[email protected]bf5aedf02012-06-04 21:18:2553namespace {
54
joaodasilva383b174a2017-01-10 09:55:3655const int kMaxRecursionDepth = 200;
[email protected]946d1b22009-07-22 23:57:2156
[email protected]bf5aedf02012-06-04 21:18:2557template<typename CharType>
58void LogBytes(const std::vector<CharType>& data, std::string* out) {
59#if defined(OS_WIN)
60 // Windows has a GUI for logging, which can handle arbitrary binary data.
61 for (size_t i = 0; i < data.size(); ++i)
62 out->push_back(data[i]);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:0963#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]bf5aedf02012-06-04 21:18:2564 // On POSIX, we log to stdout, which we assume can display ASCII.
65 static const size_t kMaxBytesToLog = 100;
66 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
67 if (isprint(data[i]))
68 out->push_back(data[i]);
69 else
[email protected]7d3cbc92013-03-18 22:33:0470 out->append(
71 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]bf5aedf02012-06-04 21:18:2572 }
73 if (data.size() > kMaxBytesToLog) {
[email protected]f8660f82013-03-30 17:29:2874 out->append(base::StringPrintf(
75 " and %u more bytes",
76 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
[email protected]bf5aedf02012-06-04 21:18:2577 }
78#endif
79}
[email protected]946d1b22009-07-22 23:57:2180
rockot502c94f2016-02-03 20:20:1681bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:2582 base::PickleIterator* iter,
Jeremy Roman2d8d7802020-06-11 22:08:2083 base::Value* value,
[email protected]bf5aedf02012-06-04 21:18:2584 int recursion);
[email protected]946d1b22009-07-22 23:57:2185
rockot502c94f2016-02-03 20:20:1686void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
[email protected]dbc761a2012-07-26 01:29:2187 bool result;
[email protected]946d1b22009-07-22 23:57:2188 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:3689 LOG(ERROR) << "Max recursion depth hit in WriteValue.";
[email protected]946d1b22009-07-22 23:57:2190 return;
91 }
92
jdoerrie76cee9c2017-10-06 22:42:4293 m->WriteInt(static_cast<int>(value->type()));
[email protected]946d1b22009-07-22 23:57:2194
jdoerrie76cee9c2017-10-06 22:42:4295 switch (value->type()) {
jdoerriedc72ee942016-12-07 15:43:2896 case base::Value::Type::NONE:
jdoerriee1b1f3a2019-03-16 04:08:0197 break;
jdoerriedc72ee942016-12-07 15:43:2898 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:2199 bool val;
[email protected]dbc761a2012-07-26 01:29:21100 result = value->GetAsBoolean(&val);
101 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21102 WriteParam(m, val);
103 break;
104 }
jdoerriedc72ee942016-12-07 15:43:28105 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21106 int val;
[email protected]dbc761a2012-07-26 01:29:21107 result = value->GetAsInteger(&val);
108 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21109 WriteParam(m, val);
110 break;
111 }
jdoerriedc72ee942016-12-07 15:43:28112 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21113 double val;
[email protected]dbc761a2012-07-26 01:29:21114 result = value->GetAsDouble(&val);
115 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21116 WriteParam(m, val);
117 break;
118 }
jdoerriedc72ee942016-12-07 15:43:28119 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21120 std::string val;
[email protected]dbc761a2012-07-26 01:29:21121 result = value->GetAsString(&val);
122 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21123 WriteParam(m, val);
124 break;
125 }
jdoerriedc72ee942016-12-07 15:43:28126 case base::Value::Type::BINARY: {
jdoerrie9970f20e2018-07-20 21:41:18127 m->WriteData(reinterpret_cast<const char*>(value->GetBlob().data()),
Chris Palmerc5ea9b92017-09-25 22:53:22128 base::checked_cast<int>(value->GetBlob().size()));
[email protected]e4dad9fb2009-10-06 18:15:58129 break;
[email protected]946d1b22009-07-22 23:57:21130 }
jdoerriedc72ee942016-12-07 15:43:28131 case base::Value::Type::DICTIONARY: {
[email protected]ea5ef4c2013-06-13 22:50:27132 const base::DictionaryValue* dict =
133 static_cast<const base::DictionaryValue*>(value);
[email protected]946d1b22009-07-22 23:57:21134
Chris Palmerc5ea9b92017-09-25 22:53:22135 WriteParam(m, base::checked_cast<int>(dict->size()));
[email protected]946d1b22009-07-22 23:57:21136
[email protected]ea5ef4c2013-06-13 22:50:27137 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
138 it.Advance()) {
[email protected]a899c0b02013-01-18 14:43:27139 WriteParam(m, it.key());
140 WriteValue(m, &it.value(), recursion + 1);
[email protected]946d1b22009-07-22 23:57:21141 }
142 break;
143 }
jdoerriedc72ee942016-12-07 15:43:28144 case base::Value::Type::LIST: {
[email protected]ea5ef4c2013-06-13 22:50:27145 const base::ListValue* list = static_cast<const base::ListValue*>(value);
Chris Palmerc5ea9b92017-09-25 22:53:22146 WriteParam(m, base::checked_cast<int>(list->GetSize()));
dchengcb60e702016-05-25 18:30:47147 for (const auto& entry : *list) {
jdoerriea5676c62017-04-11 18:09:14148 WriteValue(m, &entry, recursion + 1);
[email protected]946d1b22009-07-22 23:57:21149 }
150 break;
151 }
jdoerriee1b1f3a2019-03-16 04:08:01152
153 // TODO(crbug.com/859477): Remove after root cause is found.
154 default:
155 CHECK(false);
156 break;
[email protected]946d1b22009-07-22 23:57:21157 }
158}
159
160// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
161// object.
rockot502c94f2016-02-03 20:20:16162bool ReadDictionaryValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25163 base::PickleIterator* iter,
164 base::DictionaryValue* value,
165 int recursion) {
[email protected]946d1b22009-07-22 23:57:21166 int size;
167 if (!ReadParam(m, iter, &size))
168 return false;
169
Jan Wilken Dörrief961a372020-11-02 20:30:34170 std::vector<base::Value::LegacyDictStorage::value_type> entries;
Jeremy Roman2d8d7802020-06-11 22:08:20171 entries.resize(size);
172 for (auto& entry : entries) {
173 entry.second = std::make_unique<base::Value>();
174 if (!ReadParam(m, iter, &entry.first) ||
175 !ReadValue(m, iter, entry.second.get(), recursion + 1))
[email protected]946d1b22009-07-22 23:57:21176 return false;
[email protected]946d1b22009-07-22 23:57:21177 }
178
Jan Wilken Dörrief961a372020-11-02 20:30:34179 *value =
180 base::DictionaryValue(base::Value::LegacyDictStorage(std::move(entries)));
[email protected]946d1b22009-07-22 23:57:21181 return true;
182}
183
184// Helper for ReadValue that reads a ReadListValue into a pre-allocated
185// object.
rockot502c94f2016-02-03 20:20:16186bool ReadListValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25187 base::PickleIterator* iter,
188 base::ListValue* value,
189 int recursion) {
[email protected]946d1b22009-07-22 23:57:21190 int size;
191 if (!ReadParam(m, iter, &size))
192 return false;
193
Jeremy Roman2d8d7802020-06-11 22:08:20194 base::Value::ListStorage list_storage;
195 list_storage.resize(size);
196 for (base::Value& subval : list_storage) {
[email protected]946d1b22009-07-22 23:57:21197 if (!ReadValue(m, iter, &subval, recursion + 1))
198 return false;
[email protected]946d1b22009-07-22 23:57:21199 }
Jeremy Roman2d8d7802020-06-11 22:08:20200 *value = base::ListValue(std::move(list_storage));
[email protected]946d1b22009-07-22 23:57:21201 return true;
202}
203
rockot502c94f2016-02-03 20:20:16204bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25205 base::PickleIterator* iter,
Jeremy Roman2d8d7802020-06-11 22:08:20206 base::Value* value,
[email protected]bf5aedf02012-06-04 21:18:25207 int recursion) {
[email protected]946d1b22009-07-22 23:57:21208 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:36209 LOG(ERROR) << "Max recursion depth hit in ReadValue.";
[email protected]946d1b22009-07-22 23:57:21210 return false;
211 }
212
213 int type;
214 if (!ReadParam(m, iter, &type))
215 return false;
216
jdoerriedc72ee942016-12-07 15:43:28217 switch (static_cast<base::Value::Type>(type)) {
218 case base::Value::Type::NONE:
Jeremy Roman2d8d7802020-06-11 22:08:20219 *value = base::Value();
jdoerriee067999a2017-04-07 06:39:00220 break;
jdoerriedc72ee942016-12-07 15:43:28221 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21222 bool val;
223 if (!ReadParam(m, iter, &val))
224 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20225 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21226 break;
227 }
jdoerriedc72ee942016-12-07 15:43:28228 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21229 int val;
230 if (!ReadParam(m, iter, &val))
231 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20232 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21233 break;
234 }
jdoerriedc72ee942016-12-07 15:43:28235 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21236 double val;
237 if (!ReadParam(m, iter, &val))
238 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20239 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21240 break;
241 }
jdoerriedc72ee942016-12-07 15:43:28242 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21243 std::string val;
244 if (!ReadParam(m, iter, &val))
245 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20246 *value = base::Value(std::move(val));
[email protected]946d1b22009-07-22 23:57:21247 break;
248 }
jdoerriedc72ee942016-12-07 15:43:28249 case base::Value::Type::BINARY: {
Jeremy Roman2d8d7802020-06-11 22:08:20250 base::span<const uint8_t> data;
251 if (!iter->ReadData(&data))
[email protected]e4dad9fb2009-10-06 18:15:58252 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20253 *value = base::Value(data);
[email protected]946d1b22009-07-22 23:57:21254 break;
255 }
jdoerriedc72ee942016-12-07 15:43:28256 case base::Value::Type::DICTIONARY: {
jdoerrief1e72e32017-04-26 16:23:55257 base::DictionaryValue val;
258 if (!ReadDictionaryValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21259 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20260 *value = std::move(val);
[email protected]946d1b22009-07-22 23:57:21261 break;
262 }
jdoerriedc72ee942016-12-07 15:43:28263 case base::Value::Type::LIST: {
jdoerrief1e72e32017-04-26 16:23:55264 base::ListValue val;
265 if (!ReadListValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21266 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20267 *value = std::move(val);
[email protected]946d1b22009-07-22 23:57:21268 break;
269 }
[email protected]e4dad9fb2009-10-06 18:15:58270 default:
Jan Wilken Dörrie271086b42019-06-13 20:03:41271 NOTREACHED();
jdoerriee1b1f3a2019-03-16 04:08:01272 return false;
[email protected]946d1b22009-07-22 23:57:21273 }
274
275 return true;
276}
277
[email protected]bf5aedf02012-06-04 21:18:25278} // namespace
279
280// -----------------------------------------------------------------------------
281
282LogData::LogData()
283 : routing_id(0),
284 type(0),
285 sent(0),
286 receive(0),
287 dispatch(0) {
288}
289
vmpstrbf0d713a2016-03-24 20:22:54290LogData::LogData(const LogData& other) = default;
291
Chris Watkins2d879af2017-11-30 02:11:59292LogData::~LogData() = default;
[email protected]bf5aedf02012-06-04 21:18:25293
[email protected]bf5aedf02012-06-04 21:18:25294void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
295 l->append(p ? "true" : "false");
296}
297
rockot502c94f2016-02-03 20:20:16298void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno19ecf1842015-10-30 00:46:20299 m->WriteBytes(&p, sizeof(param_type));
300}
301
rockot502c94f2016-02-03 20:20:16302bool ParamTraits<signed char>::Read(const base::Pickle* m,
303 base::PickleIterator* iter,
304 param_type* r) {
ortuno19ecf1842015-10-30 00:46:20305 const char* data;
306 if (!iter->ReadBytes(&data, sizeof(param_type)))
307 return false;
308 memcpy(r, data, sizeof(param_type));
309 return true;
310}
311
312void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38313 l->append(base::NumberToString(p));
ortuno19ecf1842015-10-30 00:46:20314}
315
rockot502c94f2016-02-03 20:20:16316void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28317 m->WriteBytes(&p, sizeof(param_type));
318}
319
rockot502c94f2016-02-03 20:20:16320bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25321 base::PickleIterator* iter,
322 param_type* r) {
[email protected]c1ee48d2013-07-12 23:12:28323 const char* data;
avi48fc13b2014-12-28 23:31:48324 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28325 return false;
326 memcpy(r, data, sizeof(param_type));
327 return true;
328}
329
330void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38331 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28332}
333
rockot502c94f2016-02-03 20:20:16334void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28335 m->WriteBytes(&p, sizeof(param_type));
336}
337
rockot502c94f2016-02-03 20:20:16338bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25339 base::PickleIterator* iter,
[email protected]c1ee48d2013-07-12 23:12:28340 param_type* r) {
341 const char* data;
avi48fc13b2014-12-28 23:31:48342 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28343 return false;
344 memcpy(r, data, sizeof(param_type));
345 return true;
346}
347
348void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09349 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28350}
351
[email protected]252cad62010-08-18 18:33:57352void ParamTraits<int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09353 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57354}
355
356void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09357 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57358}
359
Sean McAllister82700412020-08-19 20:10:35360#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
361 defined(OS_FUCHSIA) || (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]252cad62010-08-18 18:33:57362void ParamTraits<long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09363 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57364}
365
366void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09367 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57368}
jam03d8a782016-02-10 20:13:39369#endif
[email protected]252cad62010-08-18 18:33:57370
371void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09372 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57373}
374
375void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09376 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57377}
[email protected]7a4de7a62010-08-17 18:38:24378
[email protected]bf5aedf02012-06-04 21:18:25379void ParamTraits<float>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04380 l->append(base::StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24381}
382
rockot502c94f2016-02-03 20:20:16383void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
[email protected]48328ff2013-10-31 09:27:31384 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52385}
386
rockot502c94f2016-02-03 20:20:16387bool ParamTraits<double>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25388 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25389 param_type* r) {
390 const char *data;
avi48fc13b2014-12-28 23:31:48391 if (!iter->ReadBytes(&data, sizeof(*r))) {
[email protected]bf5aedf02012-06-04 21:18:25392 NOTREACHED();
393 return false;
394 }
395 memcpy(r, data, sizeof(param_type));
396 return true;
[email protected]d84e48b2010-10-21 22:04:52397}
398
[email protected]bf5aedf02012-06-04 21:18:25399void ParamTraits<double>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04400 l->append(base::StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04401}
402
[email protected]bf5aedf02012-06-04 21:18:25403
404void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
405 l->append(p);
[email protected]1d14f582011-09-02 20:42:04406}
407
[email protected]476dafb2013-12-03 00:39:26408void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
[email protected]ad65a3e2013-12-25 18:18:01409 l->append(base::UTF16ToUTF8(p));
[email protected]bf5aedf02012-06-04 21:18:25410}
[email protected]bf5aedf02012-06-04 21:18:25411
Jan Wilken Dörriecf5a66902020-12-07 20:51:31412#if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
413bool ParamTraits<std::wstring>::Read(const base::Pickle* m,
414 base::PickleIterator* iter,
415 param_type* r) {
416 base::StringPiece16 piece16;
417 if (!iter->ReadStringPiece16(&piece16))
418 return false;
419
420 *r = base::AsWString(piece16);
421 return true;
422}
423
424void ParamTraits<std::wstring>::Log(const param_type& p, std::string* l) {
425 l->append(base::WideToUTF8(p));
426}
427#endif
428
rockot502c94f2016-02-03 20:20:16429void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
430 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25431 if (p.empty()) {
432 m->WriteData(NULL, 0);
433 } else {
Chris Palmerc5ea9b92017-09-25 22:53:22434 m->WriteData(&p.front(), base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25435 }
436}
437
rockot502c94f2016-02-03 20:20:16438bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25439 base::PickleIterator* iter,
440 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25441 const char *data;
442 int data_size = 0;
avi48fc13b2014-12-28 23:31:48443 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25444 return false;
445 r->resize(data_size);
446 if (data_size)
447 memcpy(&r->front(), data, data_size);
448 return true;
449}
450
451void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
452 LogBytes(p, l);
453}
454
rockot502c94f2016-02-03 20:20:16455void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
456 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25457 if (p.empty()) {
458 m->WriteData(NULL, 0);
459 } else {
460 m->WriteData(reinterpret_cast<const char*>(&p.front()),
Chris Palmerc5ea9b92017-09-25 22:53:22461 base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25462 }
463}
464
rockot502c94f2016-02-03 20:20:16465bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25466 base::PickleIterator* iter,
467 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25468 const char *data;
469 int data_size = 0;
avi48fc13b2014-12-28 23:31:48470 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25471 return false;
472 r->resize(data_size);
473 if (data_size)
474 memcpy(&r->front(), data, data_size);
475 return true;
476}
477
478void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
479 std::string* l) {
480 LogBytes(p, l);
481}
482
rockot502c94f2016-02-03 20:20:16483void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
484 const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22485 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]d4124852013-03-20 20:25:00486 // Cast to bool below is required because libc++'s
487 // vector<bool>::const_reference is different from bool, and we want to avoid
488 // writing an extra specialization of ParamTraits for it.
[email protected]bf5aedf02012-06-04 21:18:25489 for (size_t i = 0; i < p.size(); i++)
[email protected]d4124852013-03-20 20:25:00490 WriteParam(m, static_cast<bool>(p[i]));
[email protected]bf5aedf02012-06-04 21:18:25491}
492
rockot502c94f2016-02-03 20:20:16493bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25494 base::PickleIterator* iter,
495 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25496 int size;
497 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48498 if (!iter->ReadLength(&size))
[email protected]bf5aedf02012-06-04 21:18:25499 return false;
500 r->resize(size);
501 for (int i = 0; i < size; i++) {
502 bool value;
503 if (!ReadParam(m, iter, &value))
504 return false;
505 (*r)[i] = value;
506 }
507 return true;
508}
509
510void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
511 for (size_t i = 0; i < p.size(); ++i) {
512 if (i != 0)
513 l->push_back(' ');
[email protected]d4124852013-03-20 20:25:00514 LogParam(static_cast<bool>(p[i]), l);
[email protected]bf5aedf02012-06-04 21:18:25515 }
[email protected]d84e48b2010-10-21 22:04:52516}
517
rockot502c94f2016-02-03 20:20:16518void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
[email protected]ea5ef4c2013-06-13 22:50:27519 const param_type& p) {
[email protected]946d1b22009-07-22 23:57:21520 WriteValue(m, &p, 0);
521}
522
rockot502c94f2016-02-03 20:20:16523bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25524 base::PickleIterator* iter,
525 param_type* r) {
[email protected]946d1b22009-07-22 23:57:21526 int type;
jdoerriedc72ee942016-12-07 15:43:28527 if (!ReadParam(m, iter, &type) ||
528 type != static_cast<int>(base::Value::Type::DICTIONARY))
[email protected]946d1b22009-07-22 23:57:21529 return false;
530
531 return ReadDictionaryValue(m, iter, r, 0);
532}
533
[email protected]ea5ef4c2013-06-13 22:50:27534void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
535 std::string* l) {
[email protected]946d1b22009-07-22 23:57:21536 std::string json;
estade8d046462015-05-16 01:02:34537 base::JSONWriter::Write(p, &json);
[email protected]252cad62010-08-18 18:33:57538 l->append(json);
[email protected]946d1b22009-07-22 23:57:21539}
540
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09541#if defined(OS_POSIX) || defined(OS_FUCHSIA)
rockot502c94f2016-02-03 20:20:16542void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
543 const param_type& p) {
erikchen14525202017-05-06 19:16:51544 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06545 // nacl_message_scanner.cc:WriteHandle().
[email protected]7a4de7a62010-08-17 18:38:24546 const bool valid = p.fd >= 0;
547 WriteParam(m, valid);
548
morrita96693852014-09-24 20:11:45549 if (!valid)
550 return;
551
552 if (p.auto_close) {
morrita1aa788c2015-01-31 05:45:42553 if (!m->WriteAttachment(
554 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
morrita96693852014-09-24 20:11:45555 NOTREACHED();
556 } else {
morrita1aa788c2015-01-31 05:45:42557 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
[email protected]7a4de7a62010-08-17 18:38:24558 NOTREACHED();
559 }
560}
561
rockot502c94f2016-02-03 20:20:16562bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25563 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24564 param_type* r) {
morrita96693852014-09-24 20:11:45565 *r = base::FileDescriptor();
566
[email protected]7a4de7a62010-08-17 18:38:24567 bool valid;
568 if (!ReadParam(m, iter, &valid))
569 return false;
570
morrita96693852014-09-24 20:11:45571 if (!valid)
[email protected]7a4de7a62010-08-17 18:38:24572 return true;
[email protected]7a4de7a62010-08-17 18:38:24573
rockot502c94f2016-02-03 20:20:16574 scoped_refptr<base::Pickle::Attachment> attachment;
morrita1aa788c2015-01-31 05:45:42575 if (!m->ReadAttachment(iter, &attachment))
morrita96693852014-09-24 20:11:45576 return false;
577
sammc6ed3efb2016-11-23 03:17:35578 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
579 MessageAttachment::Type::PLATFORM_FILE) {
580 return false;
581 }
582
rockot502c94f2016-02-03 20:20:16583 *r = base::FileDescriptor(
sammc6ed3efb2016-11-23 03:17:35584 static_cast<internal::PlatformFileAttachment*>(attachment.get())
585 ->TakePlatformFile(),
rockot502c94f2016-02-03 20:20:16586 true);
morrita96693852014-09-24 20:11:45587 return true;
[email protected]7a4de7a62010-08-17 18:38:24588}
589
590void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57591 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24592 if (p.auto_close) {
[email protected]7d3cbc92013-03-18 22:33:04593 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24594 } else {
[email protected]7d3cbc92013-03-18 22:33:04595 l->append(base::StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24596 }
597}
Sergey Ulanovac89bb92019-03-22 18:46:49598
599void ParamTraits<base::ScopedFD>::Write(base::Pickle* m, const param_type& p) {
600 // This serialization must be kept in sync with
601 // nacl_message_scanner.cc:WriteHandle().
602 const bool valid = p.is_valid();
603 WriteParam(m, valid);
604
605 if (!valid)
606 return;
607
608 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
609 std::move(const_cast<param_type&>(p))))) {
610 NOTREACHED();
611 }
612}
613
614bool ParamTraits<base::ScopedFD>::Read(const base::Pickle* m,
615 base::PickleIterator* iter,
616 param_type* r) {
617 r->reset();
618
619 bool valid;
620 if (!ReadParam(m, iter, &valid))
621 return false;
622
623 if (!valid)
624 return true;
625
626 scoped_refptr<base::Pickle::Attachment> attachment;
627 if (!m->ReadAttachment(iter, &attachment))
628 return false;
629
630 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
631 MessageAttachment::Type::PLATFORM_FILE) {
632 return false;
633 }
634
635 *r = base::ScopedFD(
636 static_cast<internal::PlatformFileAttachment*>(attachment.get())
637 ->TakePlatformFile());
638 return true;
639}
640
641void ParamTraits<base::ScopedFD>::Log(const param_type& p, std::string* l) {
642 l->append(base::StringPrintf("ScopedFD(%d)", p.get()));
643}
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09644#endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]7a4de7a62010-08-17 18:38:24645
Robert Sesek02910662020-02-28 20:15:51646#if defined(OS_WIN)
647void ParamTraits<base::win::ScopedHandle>::Write(base::Pickle* m,
648 const param_type& p) {
649 const bool valid = p.IsValid();
650 WriteParam(m, valid);
651 if (!valid)
652 return;
653
654 HandleWin handle(p.Get());
655 WriteParam(m, handle);
656}
657
658bool ParamTraits<base::win::ScopedHandle>::Read(const base::Pickle* m,
659 base::PickleIterator* iter,
660 param_type* r) {
661 r->Close();
662
663 bool valid;
664 if (!ReadParam(m, iter, &valid))
665 return false;
666 if (!valid)
667 return true;
668
669 HandleWin handle;
670 if (!ReadParam(m, iter, &handle))
671 return false;
672
673 r->Set(handle.get_handle());
674 return true;
675}
676
677void ParamTraits<base::win::ScopedHandle>::Log(const param_type& p,
678 std::string* l) {
679 l->append(base::StringPrintf("ScopedHandle(%p)", p.Get()));
680}
681#endif // defined(OS_WIN)
682
Sergey Ulanova97f3282019-04-17 01:27:34683#if defined(OS_FUCHSIA)
684void ParamTraits<zx::vmo>::Write(base::Pickle* m, const param_type& p) {
685 // This serialization must be kept in sync with
686 // nacl_message_scanner.cc:WriteHandle().
687 const bool valid = p.is_valid();
688 WriteParam(m, valid);
689
690 if (!valid)
691 return;
692
693 if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
Sergey Ulanov04367c72019-06-21 15:51:43694 std::move(const_cast<param_type&>(p))))) {
Sergey Ulanova97f3282019-04-17 01:27:34695 NOTREACHED();
696 }
697}
698
699bool ParamTraits<zx::vmo>::Read(const base::Pickle* m,
700 base::PickleIterator* iter,
701 param_type* r) {
702 r->reset();
703
704 bool valid;
705 if (!ReadParam(m, iter, &valid))
706 return false;
707
708 if (!valid)
709 return true;
710
711 scoped_refptr<base::Pickle::Attachment> attachment;
712 if (!m->ReadAttachment(iter, &attachment))
713 return false;
714
715 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
716 MessageAttachment::Type::FUCHSIA_HANDLE) {
717 return false;
718 }
719
720 *r = zx::vmo(static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
721 ->Take());
722 return true;
723}
724
725void ParamTraits<zx::vmo>::Log(const param_type& p, std::string* l) {
726 l->append("ZirconVMO");
727}
Sergey Ulanov7b343ff2019-08-15 07:52:37728
729void ParamTraits<zx::channel>::Write(base::Pickle* m, const param_type& p) {
730 // This serialization must be kept in sync with
731 // nacl_message_scanner.cc:WriteHandle().
732 const bool valid = p.is_valid();
733 WriteParam(m, valid);
734
735 if (!valid)
736 return;
737
738 if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
739 std::move(const_cast<param_type&>(p))))) {
740 NOTREACHED();
741 }
742}
743
744bool ParamTraits<zx::channel>::Read(const base::Pickle* m,
745 base::PickleIterator* iter,
746 param_type* r) {
747 r->reset();
748
749 bool valid;
750 if (!ReadParam(m, iter, &valid))
751 return false;
752
753 if (!valid)
754 return true;
755
756 scoped_refptr<base::Pickle::Attachment> attachment;
757 if (!m->ReadAttachment(iter, &attachment))
758 return false;
759
760 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
761 MessageAttachment::Type::FUCHSIA_HANDLE) {
762 return false;
763 }
764
765 *r = zx::channel(
766 static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
767 ->Take());
768 return true;
769}
770
771void ParamTraits<zx::channel>::Log(const param_type& p, std::string* l) {
772 l->append("ZirconChannel");
773}
Sergey Ulanova97f3282019-04-17 01:27:34774#endif // defined(OS_FUCHSIA)
775
Klaus Weidner3824a8882017-11-03 06:24:57776#if defined(OS_ANDROID)
Alexandr Ilin0443a8f2018-07-20 20:14:50777void ParamTraits<base::android::ScopedHardwareBufferHandle>::Write(
778 base::Pickle* m,
779 const param_type& p) {
780 const bool is_valid = p.is_valid();
Ken Rockot097248f02018-04-23 16:23:34781 WriteParam(m, is_valid);
782 if (!is_valid)
783 return;
784
Ken Rockot097248f02018-04-23 16:23:34785 // We must keep a ref to the AHardwareBuffer alive until the receiver has
786 // acquired its own reference. We do this by sending a message pipe handle
787 // along with the buffer. When the receiver deserializes (or even if they
788 // die without ever reading the message) their end of the pipe will be
789 // closed. We will eventually detect this and release the AHB reference.
790 mojo::MessagePipe tracking_pipe;
791 m->WriteAttachment(new internal::MojoHandleAttachment(
792 mojo::ScopedHandle::From(std::move(tracking_pipe.handle0))));
Alexandr Ilin0443a8f2018-07-20 20:14:50793 WriteParam(m, base::FileDescriptor(p.SerializeAsFileDescriptor().release(),
794 true /* auto_close */));
Ken Rockot097248f02018-04-23 16:23:34795
796 // Pass ownership of the input handle to our tracking pipe to keep the AHB
797 // alive long enough to be deserialized by the receiver.
Alexandr Ilin0443a8f2018-07-20 20:14:50798 mojo::ScopeToMessagePipe(std::move(const_cast<param_type&>(p)),
799 std::move(tracking_pipe.handle1));
Klaus Weidner3824a8882017-11-03 06:24:57800}
801
Alexandr Ilin0443a8f2018-07-20 20:14:50802bool ParamTraits<base::android::ScopedHardwareBufferHandle>::Read(
803 const base::Pickle* m,
804 base::PickleIterator* iter,
805 param_type* r) {
806 *r = base::android::ScopedHardwareBufferHandle();
Ken Rockot097248f02018-04-23 16:23:34807
808 bool is_valid;
809 if (!ReadParam(m, iter, &is_valid))
Klaus Weidner3824a8882017-11-03 06:24:57810 return false;
Ken Rockot097248f02018-04-23 16:23:34811 if (!is_valid)
812 return true;
813
814 scoped_refptr<base::Pickle::Attachment> tracking_pipe_attachment;
815 if (!m->ReadAttachment(iter, &tracking_pipe_attachment))
Klaus Weidner3824a8882017-11-03 06:24:57816 return false;
Ken Rockot097248f02018-04-23 16:23:34817
818 // We keep this alive until the AHB is safely deserialized below. When this
819 // goes out of scope, the sender holding the other end of this pipe will treat
820 // this handle closure as a signal that it's safe to release their AHB
821 // keepalive ref.
822 mojo::ScopedHandle tracking_pipe =
823 static_cast<MessageAttachment*>(tracking_pipe_attachment.get())
824 ->TakeMojoHandle();
825
826 base::FileDescriptor descriptor;
827 if (!ReadParam(m, iter, &descriptor))
828 return false;
829
830 // NOTE: It is valid to deserialize an invalid FileDescriptor, so the success
831 // of |ReadParam()| above does not imply that |descriptor| is valid.
832 base::ScopedFD scoped_fd(descriptor.fd);
833 if (!scoped_fd.is_valid())
834 return false;
835
836 *r = base::android::ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(
Alexandr Ilin0443a8f2018-07-20 20:14:50837 std::move(scoped_fd));
Klaus Weidner3824a8882017-11-03 06:24:57838 return true;
839}
840
Alexandr Ilin0443a8f2018-07-20 20:14:50841void ParamTraits<base::android::ScopedHardwareBufferHandle>::Log(
842 const param_type& p,
843 std::string* l) {
844 l->append(base::StringPrintf("base::android::ScopedHardwareBufferHandle(%p)",
845 p.get()));
Klaus Weidner3824a8882017-11-03 06:24:57846}
Ken Rockot097248f02018-04-23 16:23:34847#endif // defined(OS_ANDROID)
Klaus Weidner3824a8882017-11-03 06:24:57848
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)
Sergey Ulanov04367c72019-06-21 15:51:43950 zx::vmo vmo = const_cast<param_type&>(p).PassPlatformHandle();
951 WriteParam(m, vmo);
Avi Drissman2b97d032020-07-30 03:02:26952#elif defined(OS_MAC)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09953 base::mac::ScopedMachSendRight h =
954 const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54955 MachPortMac mach_port_mac(h.get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09956 WriteParam(m, mach_port_mac);
Alexandr Ilind497eee2018-04-19 22:50:54957#elif defined(OS_ANDROID)
958 m->WriteAttachment(new internal::PlatformFileAttachment(
959 base::ScopedFD(const_cast<param_type&>(p).PassPlatformHandle())));
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09960#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:54961 base::subtle::ScopedFDPair h =
962 const_cast<param_type&>(p).PassPlatformHandle();
963 m->WriteAttachment(new internal::PlatformFileAttachment(std::move(h.fd)));
964 if (p.GetMode() ==
965 base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
966 m->WriteAttachment(
967 new internal::PlatformFileAttachment(std::move(h.readonly_fd)));
968 }
969#endif
970}
971
972bool ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Read(
973 const base::Pickle* m,
974 base::PickleIterator* iter,
975 param_type* r) {
976 bool valid;
977 if (!ReadParam(m, iter, &valid))
978 return false;
979 if (!valid) {
980 *r = base::subtle::PlatformSharedMemoryRegion();
981 return true;
982 }
983
984 base::subtle::PlatformSharedMemoryRegion::Mode mode;
985 uint64_t shm_size;
986 base::UnguessableToken guid;
987 if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &shm_size) ||
988 !base::IsValueInRangeForNumericType<size_t>(shm_size) ||
989 !ReadParam(m, iter, &guid)) {
990 return false;
991 }
992 size_t size = static_cast<size_t>(shm_size);
993
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09994#if defined(OS_WIN)
995 HandleWin handle_win;
996 if (!ReadParam(m, iter, &handle_win))
Alexandr Ilind497eee2018-04-19 22:50:54997 return false;
998 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09999 base::win::ScopedHandle(handle_win.get_handle()), mode, size, guid);
Alexandr Ilind497eee2018-04-19 22:50:541000#elif defined(OS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:431001 zx::vmo vmo;
1002 if (!ReadParam(m, iter, &vmo))
Alexandr Ilind497eee2018-04-19 22:50:541003 return false;
Sergey Ulanov04367c72019-06-21 15:51:431004 *r = base::subtle::PlatformSharedMemoryRegion::Take(std::move(vmo), mode,
1005 size, guid);
Avi Drissman2b97d032020-07-30 03:02:261006#elif defined(OS_MAC)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091007 MachPortMac mach_port_mac;
1008 if (!ReadParam(m, iter, &mach_port_mac))
Alexandr Ilind497eee2018-04-19 22:50:541009 return false;
1010 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091011 base::mac::ScopedMachSendRight(mach_port_mac.get_mach_port()), mode, size,
1012 guid);
1013#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541014 scoped_refptr<base::Pickle::Attachment> attachment;
1015 if (!m->ReadAttachment(iter, &attachment))
1016 return false;
1017 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
1018 MessageAttachment::Type::PLATFORM_FILE) {
1019 return false;
1020 }
1021
1022#if defined(OS_ANDROID)
1023 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1024 base::ScopedFD(
1025 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1026 ->TakePlatformFile()),
1027 mode, size, guid);
1028#else
1029 scoped_refptr<base::Pickle::Attachment> readonly_attachment;
1030 if (mode == base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
1031 if (!m->ReadAttachment(iter, &readonly_attachment))
1032 return false;
1033
1034 if (static_cast<MessageAttachment*>(readonly_attachment.get())->GetType() !=
1035 MessageAttachment::Type::PLATFORM_FILE) {
1036 return false;
1037 }
1038 }
1039 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1040 base::subtle::ScopedFDPair(
1041 base::ScopedFD(
1042 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1043 ->TakePlatformFile()),
1044 readonly_attachment
1045 ? base::ScopedFD(static_cast<internal::PlatformFileAttachment*>(
1046 readonly_attachment.get())
1047 ->TakePlatformFile())
1048 : base::ScopedFD()),
1049 mode, size, guid);
1050#endif // defined(OS_ANDROID)
1051
1052#endif
1053
1054 return true;
1055}
1056
1057void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Log(
1058 const param_type& p,
1059 std::string* l) {
Wezb908e432018-09-05 17:35:221060#if defined(OS_FUCHSIA)
1061 l->append("Handle: ");
1062 LogParam(p.GetPlatformHandle()->get(), l);
1063#elif defined(OS_WIN)
Alexandr Ilind497eee2018-04-19 22:50:541064 l->append("Handle: ");
1065 LogParam(p.GetPlatformHandle(), l);
Avi Drissman2b97d032020-07-30 03:02:261066#elif defined(OS_MAC)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091067 l->append("Mach port: ");
1068 LogParam(p.GetPlatformHandle(), l);
Alexandr Ilind497eee2018-04-19 22:50:541069#elif defined(OS_ANDROID)
1070 l->append("FD: ");
1071 LogParam(p.GetPlatformHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091072#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541073 base::subtle::FDPair h = p.GetPlatformHandle();
1074 l->append("FD: ");
1075 LogParam(h.fd, l);
1076 l->append("Read-only FD: ");
1077 LogParam(h.readonly_fd, l);
1078#endif
1079
1080 l->append("Mode: ");
1081 LogParam(p.GetMode(), l);
1082 l->append("size: ");
1083 LogParam(static_cast<uint64_t>(p.GetSize()), l);
1084 l->append("GUID: ");
1085 LogParam(p.GetGUID(), l);
1086}
1087
1088void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Write(
1089 base::Pickle* m,
1090 const param_type& value) {
1091 DCHECK(static_cast<int>(value) >= 0 &&
1092 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue));
1093 m->WriteInt(static_cast<int>(value));
1094}
1095
1096bool ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Read(
1097 const base::Pickle* m,
1098 base::PickleIterator* iter,
1099 param_type* p) {
1100 int value;
1101 if (!iter->ReadInt(&value))
1102 return false;
1103 if (!(static_cast<int>(value) >= 0 &&
1104 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue))) {
1105 return false;
1106 }
1107 *p = static_cast<param_type>(value);
1108 return true;
1109}
1110
1111void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Log(
1112 const param_type& p,
1113 std::string* l) {
1114 LogParam(static_cast<int>(p), l);
1115}
1116
erikchend804e1052017-04-29 02:24:361117#if defined(OS_WIN)
erikchend804e1052017-04-29 02:24:361118void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
1119 const param_type& p) {
1120 m->WriteBool(p.IsValid());
1121 if (p.IsValid()) {
Wez51eaaad2017-08-09 05:51:381122 HandleWin handle_win(p.GetHandle());
erikchend804e1052017-04-29 02:24:361123 ParamTraits<HandleWin>::Write(m, handle_win);
1124 ::CloseHandle(p.GetHandle());
1125 }
1126}
1127
1128bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
1129 base::PickleIterator* iter,
1130 param_type* r) {
1131 bool is_valid;
1132 if (!iter->ReadBool(&is_valid))
1133 return false;
1134 if (!is_valid) {
1135 *r = PlatformFileForTransit();
1136 return true;
1137 }
1138
1139 HandleWin handle_win;
1140 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
1141 return false;
1142 *r = PlatformFileForTransit(handle_win.get_handle());
1143 return true;
1144}
1145
1146void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
1147 std::string* l) {
1148 LogParam(p.GetHandle(), l);
1149}
1150#endif // defined(OS_WIN)
1151
rockot502c94f2016-02-03 20:20:161152void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:551153 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:251154}
1155
rockot502c94f2016-02-03 20:20:161156bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251157 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:301158 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:551159 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:251160}
1161
[email protected]6d4b67a2013-02-10 04:49:301162void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
1163 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:251164}
1165
rockot502c94f2016-02-03 20:20:161166void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251167 WriteValue(m, &p, 0);
1168}
1169
rockot502c94f2016-02-03 20:20:161170bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251171 base::PickleIterator* iter,
1172 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:251173 int type;
jdoerriedc72ee942016-12-07 15:43:281174 if (!ReadParam(m, iter, &type) ||
1175 type != static_cast<int>(base::Value::Type::LIST))
[email protected]bf5aedf02012-06-04 21:18:251176 return false;
1177
1178 return ReadListValue(m, iter, r, 0);
1179}
1180
[email protected]ea5ef4c2013-06-13 22:50:271181void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251182 std::string json;
estade8d046462015-05-16 01:02:341183 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:251184 l->append(json);
1185}
1186
rockot502c94f2016-02-03 20:20:161187void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
[email protected]0238a162013-06-13 13:47:461188 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251189 WriteParam(m, p.string());
1190 WriteParam(m, p.is_null());
1191}
1192
rockot502c94f2016-02-03 20:20:161193bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251194 base::PickleIterator* iter,
[email protected]0238a162013-06-13 13:47:461195 param_type* r) {
[email protected]476dafb2013-12-03 00:39:261196 base::string16 string;
[email protected]bf5aedf02012-06-04 21:18:251197 if (!ReadParam(m, iter, &string))
1198 return false;
1199 bool is_null;
1200 if (!ReadParam(m, iter, &is_null))
1201 return false;
[email protected]0238a162013-06-13 13:47:461202 *r = base::NullableString16(string, is_null);
[email protected]bf5aedf02012-06-04 21:18:251203 return true;
1204}
1205
[email protected]0238a162013-06-13 13:47:461206void ParamTraits<base::NullableString16>::Log(const param_type& p,
1207 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251208 l->append("(");
1209 LogParam(p.string(), l);
1210 l->append(", ");
1211 LogParam(p.is_null(), l);
1212 l->append(")");
1213}
1214
rockot502c94f2016-02-03 20:20:161215void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:001216 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251217 WriteParam(m, p.size);
1218 WriteParam(m, p.is_directory);
1219 WriteParam(m, p.last_modified.ToDoubleT());
1220 WriteParam(m, p.last_accessed.ToDoubleT());
1221 WriteParam(m, p.creation_time.ToDoubleT());
1222}
1223
rockot502c94f2016-02-03 20:20:161224bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251225 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:001226 param_type* p) {
[email protected]481c3e82014-07-18 01:40:471227 double last_modified, last_accessed, creation_time;
1228 if (!ReadParam(m, iter, &p->size) ||
1229 !ReadParam(m, iter, &p->is_directory) ||
1230 !ReadParam(m, iter, &last_modified) ||
1231 !ReadParam(m, iter, &last_accessed) ||
1232 !ReadParam(m, iter, &creation_time))
1233 return false;
1234 p->last_modified = base::Time::FromDoubleT(last_modified);
1235 p->last_accessed = base::Time::FromDoubleT(last_accessed);
1236 p->creation_time = base::Time::FromDoubleT(creation_time);
1237 return true;
[email protected]bf5aedf02012-06-04 21:18:251238}
1239
[email protected]141bcc52014-01-27 21:36:001240void ParamTraits<base::File::Info>::Log(const param_type& p,
1241 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251242 l->append("(");
1243 LogParam(p.size, l);
1244 l->append(",");
1245 LogParam(p.is_directory, l);
1246 l->append(",");
1247 LogParam(p.last_modified.ToDoubleT(), l);
1248 l->append(",");
1249 LogParam(p.last_accessed.ToDoubleT(), l);
1250 l->append(",");
1251 LogParam(p.creation_time.ToDoubleT(), l);
1252 l->append(")");
1253}
1254
rockot502c94f2016-02-03 20:20:161255void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571256 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251257}
1258
rockot502c94f2016-02-03 20:20:161259bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251260 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251261 param_type* r) {
tfarina10a5c062015-09-04 18:47:571262 int64_t value;
1263 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:251264 return false;
1265 *r = base::Time::FromInternalValue(value);
1266 return true;
1267}
1268
1269void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571270 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251271}
1272
rockot502c94f2016-02-03 20:20:161273void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571274 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251275}
1276
rockot502c94f2016-02-03 20:20:161277bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251278 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251279 param_type* r) {
tfarina10a5c062015-09-04 18:47:571280 int64_t value;
1281 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251282 if (ret)
1283 *r = base::TimeDelta::FromInternalValue(value);
1284
1285 return ret;
1286}
1287
1288void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571289 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251290}
1291
rockot502c94f2016-02-03 20:20:161292void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571293 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251294}
1295
rockot502c94f2016-02-03 20:20:161296bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251297 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251298 param_type* r) {
tfarina10a5c062015-09-04 18:47:571299 int64_t value;
1300 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251301 if (ret)
1302 *r = base::TimeTicks::FromInternalValue(value);
1303
1304 return ret;
1305}
1306
1307void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571308 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251309}
1310
tguilbert4a5ac602016-09-19 21:11:251311// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1312// below should be updated.
1313static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1314 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1315
tguilbert4a5ac602016-09-19 21:11:251316void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1317 const param_type& p) {
1318 DCHECK(!p.is_empty());
1319
1320 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1321 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1322}
1323
1324bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1325 base::PickleIterator* iter,
1326 param_type* r) {
1327 uint64_t high, low;
1328 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1329 !ParamTraits<uint64_t>::Read(m, iter, &low))
1330 return false;
1331
1332 // Receiving a zeroed UnguessableToken is a security issue.
1333 if (high == 0 && low == 0)
1334 return false;
1335
1336 *r = base::UnguessableToken::Deserialize(high, low);
1337 return true;
1338}
1339
1340void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1341 std::string* l) {
1342 l->append(p.ToString());
1343}
1344
rockot502c94f2016-02-03 20:20:161345void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1346 const param_type& p) {
sammc9bf370c2016-11-14 03:29:081347#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241348 WriteParam(m, p.socket);
sammc9bf370c2016-11-14 03:29:081349#else
amistry36182522016-06-27 06:34:421350 WriteParam(m, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:081351#endif
[email protected]7a4de7a62010-08-17 18:38:241352}
1353
rockot502c94f2016-02-03 20:20:161354bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251355 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:241356 param_type* r) {
sammc9bf370c2016-11-14 03:29:081357#if defined(OS_NACL_SFI)
1358 return ReadParam(m, iter, &r->socket);
1359#else
1360 return ReadParam(m, iter, &r->mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241361#endif
[email protected]7a4de7a62010-08-17 18:38:241362}
1363
1364void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571365 std::string* l) {
sammc9bf370c2016-11-14 03:29:081366 l->append("ChannelHandle(");
1367#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241368 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
sammc9bf370c2016-11-14 03:29:081369#else
amistry36182522016-06-27 06:34:421370 LogParam(p.mojo_handle, l);
sammc9bf370c2016-11-14 03:29:081371#endif
[email protected]252cad62010-08-18 18:33:571372 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241373}
1374
rockot502c94f2016-02-03 20:20:161375void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301376 WriteParam(m, p.channel);
1377 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271378 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301379 WriteParam(m, p.flags);
1380 WriteParam(m, p.sent);
1381 WriteParam(m, p.receive);
1382 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451383 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301384 WriteParam(m, p.params);
1385}
1386
rockot502c94f2016-02-03 20:20:161387bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251388 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561389 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271390 return
[email protected]20f0487a2010-09-30 20:06:301391 ReadParam(m, iter, &r->channel) &&
1392 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271393 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301394 ReadParam(m, iter, &r->flags) &&
1395 ReadParam(m, iter, &r->sent) &&
1396 ReadParam(m, iter, &r->receive) &&
1397 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451398 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301399 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301400}
1401
[email protected]bf5aedf02012-06-04 21:18:251402void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1403 // Doesn't make sense to implement this!
1404}
1405
rockot502c94f2016-02-03 20:20:161406void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091407#if defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]34d48612012-06-29 00:05:041408 // We don't serialize the file descriptors in the nested message, so there
1409 // better not be any.
morrita1aa788c2015-01-31 05:45:421410 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041411#endif
1412
1413 // Don't just write out the message. This is used to send messages between
1414 // NaCl (Posix environment) and the browser (could be on Windows). The message
1415 // header formats differ between these systems (so does handle sharing, but
1416 // we already asserted we don't have any handles). So just write out the
1417 // parts of the header we use.
1418 //
1419 // Be careful also to use only explicitly-sized types. The NaCl environment
1420 // could be 64-bit and the host browser could be 32-bits. The nested message
1421 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1422 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:571423 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041424 m->WriteUInt32(p.type());
1425 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:571426 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:251427}
1428
rockot502c94f2016-02-03 20:20:161429bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251430 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251431 Message* r) {
tfarina10a5c062015-09-04 18:47:571432 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481433 if (!iter->ReadUInt32(&routing_id) ||
1434 !iter->ReadUInt32(&type) ||
1435 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251436 return false;
[email protected]34d48612012-06-29 00:05:041437
1438 int payload_size;
1439 const char* payload;
avi48fc13b2014-12-28 23:31:481440 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251441 return false;
[email protected]34d48612012-06-29 00:05:041442
tfarina10a5c062015-09-04 18:47:571443 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
Daniel Cheng0d89f9222017-09-22 05:05:071444 r->WriteBytes(payload, payload_size);
1445 return true;
[email protected]bf5aedf02012-06-04 21:18:251446}
1447
1448void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1449 l->append("<IPC::Message>");
1450}
1451
1452#if defined(OS_WIN)
1453// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031454// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161455void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031456 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251457}
1458
rockot502c94f2016-02-03 20:20:161459bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251460 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251461 param_type* r) {
tfarina10a5c062015-09-04 18:47:571462 int32_t temp;
avi48fc13b2014-12-28 23:31:481463 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251464 return false;
[email protected]4a635b72013-03-04 02:29:031465 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251466 return true;
1467}
1468
1469void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001470 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251471}
1472
rockot502c94f2016-02-03 20:20:161473void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251474 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1475}
1476
rockot502c94f2016-02-03 20:20:161477bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251478 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251479 param_type* r) {
1480 const char *data;
1481 int data_size = 0;
avi48fc13b2014-12-28 23:31:481482 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251483 if (result && data_size == sizeof(MSG)) {
1484 memcpy(r, data, sizeof(MSG));
1485 } else {
1486 result = false;
1487 NOTREACHED();
1488 }
1489
1490 return result;
1491}
1492
1493void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1494 l->append("<MSG>");
1495}
1496
1497#endif // OS_WIN
1498
[email protected]946d1b22009-07-22 23:57:211499} // namespace IPC