blob: 69ef2237dddf1eb4f03d70e4ff9ebd668430ed55 [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"
Hans Wennborg5f62968b2021-04-22 18:44:0514#include "base/notreached.h"
[email protected]4aa794a12013-06-11 06:32:1815#include "base/strings/string_number_conversions.h"
Lei Zhange02299a2021-04-26 23:12:2416#include "base/strings/stringprintf.h"
[email protected]906265872013-06-07 22:40:4517#include "base/strings/utf_string_conversions.h"
[email protected]b43e5562013-06-28 15:20:0218#include "base/time/time.h"
tguilbert4a5ac602016-09-19 21:11:2519#include "base/unguessable_token.h"
[email protected]946d1b22009-07-22 23:57:2120#include "base/values.h"
avi246998d82015-12-22 02:39:0421#include "build/build_config.h"
[email protected]bf5aedf02012-06-04 21:18:2522#include "ipc/ipc_channel_handle.h"
morrita1aa788c2015-01-31 05:45:4223#include "ipc/ipc_message_attachment.h"
morrita4b5c28e22015-01-14 21:17:0624#include "ipc/ipc_message_attachment_set.h"
amistry36182522016-06-27 06:34:4225#include "ipc/ipc_mojo_param_traits.h"
[email protected]bf5aedf02012-06-04 21:18:2526
Avi Drissman2b97d032020-07-30 03:02:2627#if defined(OS_MAC)
erikchenaf8299d2015-10-09 19:12:0628#include "ipc/mach_port_mac.h"
29#endif
30
morrita4b5c28e22015-01-14 21:17:0631#if defined(OS_WIN)
[email protected]2e02cfe82012-11-21 00:58:0032#include <tchar.h>
erikchen5ea2ab72015-09-25 22:34:3133#include "ipc/handle_win.h"
erikchend804e1052017-04-29 02:24:3634#include "ipc/ipc_platform_file.h"
Fabrice de Gans-Ribericbce4342018-05-07 20:02:0935#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
36#include "base/file_descriptor_posix.h"
37#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]7a4de7a62010-08-17 18:38:2438#endif
[email protected]946d1b22009-07-22 23:57:2139
Scott Graham3eebff02017-06-30 01:07:1040#if defined(OS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:4341#include "base/fuchsia/fuchsia_logging.h"
Sergey Ulanova97f3282019-04-17 01:27:3442#include "ipc/handle_attachment_fuchsia.h"
Scott Graham3eebff02017-06-30 01:07:1043#endif
44
Ken Rockot097248f02018-04-23 16:23:3445#if defined(OS_ANDROID)
46#include "base/android/scoped_hardware_buffer_handle.h"
47#include "ipc/ipc_mojo_handle_attachment.h"
48#include "mojo/public/cpp/system/message_pipe.h"
49#include "mojo/public/cpp/system/scope_to_message_pipe.h"
50#endif
51
[email protected]946d1b22009-07-22 23:57:2152namespace IPC {
53
[email protected]bf5aedf02012-06-04 21:18:2554namespace {
55
joaodasilva383b174a2017-01-10 09:55:3656const int kMaxRecursionDepth = 200;
[email protected]946d1b22009-07-22 23:57:2157
[email protected]bf5aedf02012-06-04 21:18:2558template<typename CharType>
59void LogBytes(const std::vector<CharType>& data, std::string* out) {
60#if defined(OS_WIN)
61 // Windows has a GUI for logging, which can handle arbitrary binary data.
62 for (size_t i = 0; i < data.size(); ++i)
63 out->push_back(data[i]);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:0964#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]bf5aedf02012-06-04 21:18:2565 // On POSIX, we log to stdout, which we assume can display ASCII.
66 static const size_t kMaxBytesToLog = 100;
67 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
68 if (isprint(data[i]))
69 out->push_back(data[i]);
70 else
[email protected]7d3cbc92013-03-18 22:33:0471 out->append(
72 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]bf5aedf02012-06-04 21:18:2573 }
74 if (data.size() > kMaxBytesToLog) {
[email protected]f8660f82013-03-30 17:29:2875 out->append(base::StringPrintf(
76 " and %u more bytes",
77 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
[email protected]bf5aedf02012-06-04 21:18:2578 }
79#endif
80}
[email protected]946d1b22009-07-22 23:57:2181
rockot502c94f2016-02-03 20:20:1682bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:2583 base::PickleIterator* iter,
Jeremy Roman2d8d7802020-06-11 22:08:2084 base::Value* value,
[email protected]bf5aedf02012-06-04 21:18:2585 int recursion);
[email protected]946d1b22009-07-22 23:57:2186
rockot502c94f2016-02-03 20:20:1687void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
[email protected]dbc761a2012-07-26 01:29:2188 bool result;
[email protected]946d1b22009-07-22 23:57:2189 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:3690 LOG(ERROR) << "Max recursion depth hit in WriteValue.";
[email protected]946d1b22009-07-22 23:57:2191 return;
92 }
93
jdoerrie76cee9c2017-10-06 22:42:4294 m->WriteInt(static_cast<int>(value->type()));
[email protected]946d1b22009-07-22 23:57:2195
jdoerrie76cee9c2017-10-06 22:42:4296 switch (value->type()) {
jdoerriedc72ee942016-12-07 15:43:2897 case base::Value::Type::NONE:
jdoerriee1b1f3a2019-03-16 04:08:0198 break;
jdoerriedc72ee942016-12-07 15:43:2899 case base::Value::Type::BOOLEAN: {
Ayu Ishii68ff2262021-04-21 01:17:40100 WriteParam(m, value->GetBool());
[email protected]946d1b22009-07-22 23:57:21101 break;
102 }
jdoerriedc72ee942016-12-07 15:43:28103 case base::Value::Type::INTEGER: {
Minoru Chikamune330d3372021-04-17 02:28:19104 DCHECK(value->is_int());
105 WriteParam(m, value->GetInt());
[email protected]946d1b22009-07-22 23:57:21106 break;
107 }
jdoerriedc72ee942016-12-07 15:43:28108 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21109 double val;
[email protected]dbc761a2012-07-26 01:29:21110 result = value->GetAsDouble(&val);
111 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21112 WriteParam(m, val);
113 break;
114 }
jdoerriedc72ee942016-12-07 15:43:28115 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21116 std::string val;
[email protected]dbc761a2012-07-26 01:29:21117 result = value->GetAsString(&val);
118 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21119 WriteParam(m, val);
120 break;
121 }
jdoerriedc72ee942016-12-07 15:43:28122 case base::Value::Type::BINARY: {
jdoerrie9970f20e2018-07-20 21:41:18123 m->WriteData(reinterpret_cast<const char*>(value->GetBlob().data()),
Chris Palmerc5ea9b92017-09-25 22:53:22124 base::checked_cast<int>(value->GetBlob().size()));
[email protected]e4dad9fb2009-10-06 18:15:58125 break;
[email protected]946d1b22009-07-22 23:57:21126 }
jdoerriedc72ee942016-12-07 15:43:28127 case base::Value::Type::DICTIONARY: {
[email protected]ea5ef4c2013-06-13 22:50:27128 const base::DictionaryValue* dict =
129 static_cast<const base::DictionaryValue*>(value);
[email protected]946d1b22009-07-22 23:57:21130
Chris Palmerc5ea9b92017-09-25 22:53:22131 WriteParam(m, base::checked_cast<int>(dict->size()));
[email protected]946d1b22009-07-22 23:57:21132
[email protected]ea5ef4c2013-06-13 22:50:27133 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
134 it.Advance()) {
[email protected]a899c0b02013-01-18 14:43:27135 WriteParam(m, it.key());
136 WriteValue(m, &it.value(), recursion + 1);
[email protected]946d1b22009-07-22 23:57:21137 }
138 break;
139 }
jdoerriedc72ee942016-12-07 15:43:28140 case base::Value::Type::LIST: {
[email protected]ea5ef4c2013-06-13 22:50:27141 const base::ListValue* list = static_cast<const base::ListValue*>(value);
Chris Palmerc5ea9b92017-09-25 22:53:22142 WriteParam(m, base::checked_cast<int>(list->GetSize()));
dchengcb60e702016-05-25 18:30:47143 for (const auto& entry : *list) {
jdoerriea5676c62017-04-11 18:09:14144 WriteValue(m, &entry, recursion + 1);
[email protected]946d1b22009-07-22 23:57:21145 }
146 break;
147 }
jdoerriee1b1f3a2019-03-16 04:08:01148
149 // TODO(crbug.com/859477): Remove after root cause is found.
150 default:
151 CHECK(false);
152 break;
[email protected]946d1b22009-07-22 23:57:21153 }
154}
155
156// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
157// object.
rockot502c94f2016-02-03 20:20:16158bool ReadDictionaryValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25159 base::PickleIterator* iter,
160 base::DictionaryValue* value,
161 int recursion) {
[email protected]946d1b22009-07-22 23:57:21162 int size;
163 if (!ReadParam(m, iter, &size))
164 return false;
165
Jan Wilken Dörrief961a372020-11-02 20:30:34166 std::vector<base::Value::LegacyDictStorage::value_type> entries;
Jeremy Roman2d8d7802020-06-11 22:08:20167 entries.resize(size);
168 for (auto& entry : entries) {
169 entry.second = std::make_unique<base::Value>();
170 if (!ReadParam(m, iter, &entry.first) ||
171 !ReadValue(m, iter, entry.second.get(), recursion + 1))
[email protected]946d1b22009-07-22 23:57:21172 return false;
[email protected]946d1b22009-07-22 23:57:21173 }
174
Jan Wilken Dörrief961a372020-11-02 20:30:34175 *value =
176 base::DictionaryValue(base::Value::LegacyDictStorage(std::move(entries)));
[email protected]946d1b22009-07-22 23:57:21177 return true;
178}
179
180// Helper for ReadValue that reads a ReadListValue into a pre-allocated
181// object.
rockot502c94f2016-02-03 20:20:16182bool ReadListValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25183 base::PickleIterator* iter,
184 base::ListValue* value,
185 int recursion) {
[email protected]946d1b22009-07-22 23:57:21186 int size;
187 if (!ReadParam(m, iter, &size))
188 return false;
189
Jeremy Roman2d8d7802020-06-11 22:08:20190 base::Value::ListStorage list_storage;
191 list_storage.resize(size);
192 for (base::Value& subval : list_storage) {
[email protected]946d1b22009-07-22 23:57:21193 if (!ReadValue(m, iter, &subval, recursion + 1))
194 return false;
[email protected]946d1b22009-07-22 23:57:21195 }
Jeremy Roman2d8d7802020-06-11 22:08:20196 *value = base::ListValue(std::move(list_storage));
[email protected]946d1b22009-07-22 23:57:21197 return true;
198}
199
rockot502c94f2016-02-03 20:20:16200bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25201 base::PickleIterator* iter,
Jeremy Roman2d8d7802020-06-11 22:08:20202 base::Value* value,
[email protected]bf5aedf02012-06-04 21:18:25203 int recursion) {
[email protected]946d1b22009-07-22 23:57:21204 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:36205 LOG(ERROR) << "Max recursion depth hit in ReadValue.";
[email protected]946d1b22009-07-22 23:57:21206 return false;
207 }
208
209 int type;
210 if (!ReadParam(m, iter, &type))
211 return false;
212
Devlin Cronin7178a5bd2021-02-02 02:56:47213 constexpr int kMinValueType = static_cast<int>(base::Value::Type::NONE);
214 constexpr int kMaxValueType = static_cast<int>(base::Value::Type::LIST);
215 if (type > kMaxValueType || type < kMinValueType)
216 return false;
217
jdoerriedc72ee942016-12-07 15:43:28218 switch (static_cast<base::Value::Type>(type)) {
219 case base::Value::Type::NONE:
Jeremy Roman2d8d7802020-06-11 22:08:20220 *value = base::Value();
jdoerriee067999a2017-04-07 06:39:00221 break;
jdoerriedc72ee942016-12-07 15:43:28222 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21223 bool val;
224 if (!ReadParam(m, iter, &val))
225 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20226 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21227 break;
228 }
jdoerriedc72ee942016-12-07 15:43:28229 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21230 int val;
231 if (!ReadParam(m, iter, &val))
232 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20233 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21234 break;
235 }
jdoerriedc72ee942016-12-07 15:43:28236 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21237 double val;
238 if (!ReadParam(m, iter, &val))
239 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20240 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21241 break;
242 }
jdoerriedc72ee942016-12-07 15:43:28243 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21244 std::string val;
245 if (!ReadParam(m, iter, &val))
246 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20247 *value = base::Value(std::move(val));
[email protected]946d1b22009-07-22 23:57:21248 break;
249 }
jdoerriedc72ee942016-12-07 15:43:28250 case base::Value::Type::BINARY: {
Jeremy Roman2d8d7802020-06-11 22:08:20251 base::span<const uint8_t> data;
252 if (!iter->ReadData(&data))
[email protected]e4dad9fb2009-10-06 18:15:58253 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20254 *value = base::Value(data);
[email protected]946d1b22009-07-22 23:57:21255 break;
256 }
jdoerriedc72ee942016-12-07 15:43:28257 case base::Value::Type::DICTIONARY: {
jdoerrief1e72e32017-04-26 16:23:55258 base::DictionaryValue val;
259 if (!ReadDictionaryValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21260 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20261 *value = std::move(val);
[email protected]946d1b22009-07-22 23:57:21262 break;
263 }
jdoerriedc72ee942016-12-07 15:43:28264 case base::Value::Type::LIST: {
jdoerrief1e72e32017-04-26 16:23:55265 base::ListValue val;
266 if (!ReadListValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21267 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20268 *value = std::move(val);
[email protected]946d1b22009-07-22 23:57:21269 break;
270 }
[email protected]e4dad9fb2009-10-06 18:15:58271 default:
Jan Wilken Dörrie271086b42019-06-13 20:03:41272 NOTREACHED();
jdoerriee1b1f3a2019-03-16 04:08:01273 return false;
[email protected]946d1b22009-07-22 23:57:21274 }
275
276 return true;
277}
278
[email protected]bf5aedf02012-06-04 21:18:25279} // namespace
280
281// -----------------------------------------------------------------------------
282
283LogData::LogData()
284 : routing_id(0),
285 type(0),
286 sent(0),
287 receive(0),
288 dispatch(0) {
289}
290
vmpstrbf0d713a2016-03-24 20:22:54291LogData::LogData(const LogData& other) = default;
292
Chris Watkins2d879af2017-11-30 02:11:59293LogData::~LogData() = default;
[email protected]bf5aedf02012-06-04 21:18:25294
[email protected]bf5aedf02012-06-04 21:18:25295void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
296 l->append(p ? "true" : "false");
297}
298
rockot502c94f2016-02-03 20:20:16299void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno19ecf1842015-10-30 00:46:20300 m->WriteBytes(&p, sizeof(param_type));
301}
302
rockot502c94f2016-02-03 20:20:16303bool ParamTraits<signed char>::Read(const base::Pickle* m,
304 base::PickleIterator* iter,
305 param_type* r) {
ortuno19ecf1842015-10-30 00:46:20306 const char* data;
307 if (!iter->ReadBytes(&data, sizeof(param_type)))
308 return false;
309 memcpy(r, data, sizeof(param_type));
310 return true;
311}
312
313void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38314 l->append(base::NumberToString(p));
ortuno19ecf1842015-10-30 00:46:20315}
316
rockot502c94f2016-02-03 20:20:16317void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28318 m->WriteBytes(&p, sizeof(param_type));
319}
320
rockot502c94f2016-02-03 20:20:16321bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25322 base::PickleIterator* iter,
323 param_type* r) {
[email protected]c1ee48d2013-07-12 23:12:28324 const char* data;
avi48fc13b2014-12-28 23:31:48325 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28326 return false;
327 memcpy(r, data, sizeof(param_type));
328 return true;
329}
330
331void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38332 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28333}
334
rockot502c94f2016-02-03 20:20:16335void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28336 m->WriteBytes(&p, sizeof(param_type));
337}
338
rockot502c94f2016-02-03 20:20:16339bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25340 base::PickleIterator* iter,
[email protected]c1ee48d2013-07-12 23:12:28341 param_type* r) {
342 const char* data;
avi48fc13b2014-12-28 23:31:48343 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28344 return false;
345 memcpy(r, data, sizeof(param_type));
346 return true;
347}
348
349void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09350 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28351}
352
[email protected]252cad62010-08-18 18:33:57353void ParamTraits<int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09354 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57355}
356
357void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09358 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57359}
360
Sean McAllister82700412020-08-19 20:10:35361#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
362 defined(OS_FUCHSIA) || (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]252cad62010-08-18 18:33:57363void ParamTraits<long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09364 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57365}
366
367void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09368 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57369}
jam03d8a782016-02-10 20:13:39370#endif
[email protected]252cad62010-08-18 18:33:57371
372void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09373 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57374}
375
376void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09377 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57378}
[email protected]7a4de7a62010-08-17 18:38:24379
[email protected]bf5aedf02012-06-04 21:18:25380void ParamTraits<float>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04381 l->append(base::StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24382}
383
rockot502c94f2016-02-03 20:20:16384void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
[email protected]48328ff2013-10-31 09:27:31385 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52386}
387
rockot502c94f2016-02-03 20:20:16388bool ParamTraits<double>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25389 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25390 param_type* r) {
391 const char *data;
avi48fc13b2014-12-28 23:31:48392 if (!iter->ReadBytes(&data, sizeof(*r))) {
[email protected]bf5aedf02012-06-04 21:18:25393 NOTREACHED();
394 return false;
395 }
396 memcpy(r, data, sizeof(param_type));
397 return true;
[email protected]d84e48b2010-10-21 22:04:52398}
399
[email protected]bf5aedf02012-06-04 21:18:25400void ParamTraits<double>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04401 l->append(base::StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04402}
403
[email protected]bf5aedf02012-06-04 21:18:25404
405void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
406 l->append(p);
[email protected]1d14f582011-09-02 20:42:04407}
408
Jan Wilken Dörrie739ccc212021-03-11 18:13:05409void ParamTraits<std::u16string>::Log(const param_type& p, std::string* l) {
[email protected]ad65a3e2013-12-25 18:18:01410 l->append(base::UTF16ToUTF8(p));
[email protected]bf5aedf02012-06-04 21:18:25411}
[email protected]bf5aedf02012-06-04 21:18:25412
Jan Wilken Dörrie6de7bd9a2021-03-03 16:51:23413#if defined(OS_WIN)
Jan Wilken Dörriecf5a66902020-12-07 20:51:31414bool ParamTraits<std::wstring>::Read(const base::Pickle* m,
415 base::PickleIterator* iter,
416 param_type* r) {
417 base::StringPiece16 piece16;
418 if (!iter->ReadStringPiece16(&piece16))
419 return false;
420
421 *r = base::AsWString(piece16);
422 return true;
423}
424
425void ParamTraits<std::wstring>::Log(const param_type& p, std::string* l) {
426 l->append(base::WideToUTF8(p));
427}
428#endif
429
rockot502c94f2016-02-03 20:20:16430void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
431 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25432 if (p.empty()) {
433 m->WriteData(NULL, 0);
434 } else {
Chris Palmerc5ea9b92017-09-25 22:53:22435 m->WriteData(&p.front(), base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25436 }
437}
438
rockot502c94f2016-02-03 20:20:16439bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25440 base::PickleIterator* iter,
441 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25442 const char *data;
443 int data_size = 0;
avi48fc13b2014-12-28 23:31:48444 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25445 return false;
446 r->resize(data_size);
447 if (data_size)
448 memcpy(&r->front(), data, data_size);
449 return true;
450}
451
452void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
453 LogBytes(p, l);
454}
455
rockot502c94f2016-02-03 20:20:16456void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
457 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25458 if (p.empty()) {
459 m->WriteData(NULL, 0);
460 } else {
461 m->WriteData(reinterpret_cast<const char*>(&p.front()),
Chris Palmerc5ea9b92017-09-25 22:53:22462 base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25463 }
464}
465
rockot502c94f2016-02-03 20:20:16466bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25467 base::PickleIterator* iter,
468 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25469 const char *data;
470 int data_size = 0;
avi48fc13b2014-12-28 23:31:48471 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25472 return false;
473 r->resize(data_size);
474 if (data_size)
475 memcpy(&r->front(), data, data_size);
476 return true;
477}
478
479void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
480 std::string* l) {
481 LogBytes(p, l);
482}
483
rockot502c94f2016-02-03 20:20:16484void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
485 const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22486 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]d4124852013-03-20 20:25:00487 // Cast to bool below is required because libc++'s
488 // vector<bool>::const_reference is different from bool, and we want to avoid
489 // writing an extra specialization of ParamTraits for it.
[email protected]bf5aedf02012-06-04 21:18:25490 for (size_t i = 0; i < p.size(); i++)
[email protected]d4124852013-03-20 20:25:00491 WriteParam(m, static_cast<bool>(p[i]));
[email protected]bf5aedf02012-06-04 21:18:25492}
493
rockot502c94f2016-02-03 20:20:16494bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25495 base::PickleIterator* iter,
496 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25497 int size;
498 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48499 if (!iter->ReadLength(&size))
[email protected]bf5aedf02012-06-04 21:18:25500 return false;
501 r->resize(size);
502 for (int i = 0; i < size; i++) {
503 bool value;
504 if (!ReadParam(m, iter, &value))
505 return false;
506 (*r)[i] = value;
507 }
508 return true;
509}
510
511void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
512 for (size_t i = 0; i < p.size(); ++i) {
513 if (i != 0)
514 l->push_back(' ');
[email protected]d4124852013-03-20 20:25:00515 LogParam(static_cast<bool>(p[i]), l);
[email protected]bf5aedf02012-06-04 21:18:25516 }
[email protected]d84e48b2010-10-21 22:04:52517}
518
rockot502c94f2016-02-03 20:20:16519void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
[email protected]ea5ef4c2013-06-13 22:50:27520 const param_type& p) {
[email protected]946d1b22009-07-22 23:57:21521 WriteValue(m, &p, 0);
522}
523
rockot502c94f2016-02-03 20:20:16524bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25525 base::PickleIterator* iter,
526 param_type* r) {
[email protected]946d1b22009-07-22 23:57:21527 int type;
jdoerriedc72ee942016-12-07 15:43:28528 if (!ReadParam(m, iter, &type) ||
529 type != static_cast<int>(base::Value::Type::DICTIONARY))
[email protected]946d1b22009-07-22 23:57:21530 return false;
531
532 return ReadDictionaryValue(m, iter, r, 0);
533}
534
[email protected]ea5ef4c2013-06-13 22:50:27535void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
536 std::string* l) {
[email protected]946d1b22009-07-22 23:57:21537 std::string json;
estade8d046462015-05-16 01:02:34538 base::JSONWriter::Write(p, &json);
[email protected]252cad62010-08-18 18:33:57539 l->append(json);
[email protected]946d1b22009-07-22 23:57:21540}
541
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09542#if defined(OS_POSIX) || defined(OS_FUCHSIA)
rockot502c94f2016-02-03 20:20:16543void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
544 const param_type& p) {
erikchen14525202017-05-06 19:16:51545 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06546 // nacl_message_scanner.cc:WriteHandle().
[email protected]7a4de7a62010-08-17 18:38:24547 const bool valid = p.fd >= 0;
548 WriteParam(m, valid);
549
morrita96693852014-09-24 20:11:45550 if (!valid)
551 return;
552
553 if (p.auto_close) {
morrita1aa788c2015-01-31 05:45:42554 if (!m->WriteAttachment(
555 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
morrita96693852014-09-24 20:11:45556 NOTREACHED();
557 } else {
morrita1aa788c2015-01-31 05:45:42558 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
[email protected]7a4de7a62010-08-17 18:38:24559 NOTREACHED();
560 }
561}
562
rockot502c94f2016-02-03 20:20:16563bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25564 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24565 param_type* r) {
morrita96693852014-09-24 20:11:45566 *r = base::FileDescriptor();
567
[email protected]7a4de7a62010-08-17 18:38:24568 bool valid;
569 if (!ReadParam(m, iter, &valid))
570 return false;
571
morrita96693852014-09-24 20:11:45572 if (!valid)
[email protected]7a4de7a62010-08-17 18:38:24573 return true;
[email protected]7a4de7a62010-08-17 18:38:24574
rockot502c94f2016-02-03 20:20:16575 scoped_refptr<base::Pickle::Attachment> attachment;
morrita1aa788c2015-01-31 05:45:42576 if (!m->ReadAttachment(iter, &attachment))
morrita96693852014-09-24 20:11:45577 return false;
578
sammc6ed3efb2016-11-23 03:17:35579 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
580 MessageAttachment::Type::PLATFORM_FILE) {
581 return false;
582 }
583
rockot502c94f2016-02-03 20:20:16584 *r = base::FileDescriptor(
sammc6ed3efb2016-11-23 03:17:35585 static_cast<internal::PlatformFileAttachment*>(attachment.get())
586 ->TakePlatformFile(),
rockot502c94f2016-02-03 20:20:16587 true);
morrita96693852014-09-24 20:11:45588 return true;
[email protected]7a4de7a62010-08-17 18:38:24589}
590
591void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57592 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24593 if (p.auto_close) {
[email protected]7d3cbc92013-03-18 22:33:04594 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24595 } else {
[email protected]7d3cbc92013-03-18 22:33:04596 l->append(base::StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24597 }
598}
Sergey Ulanovac89bb92019-03-22 18:46:49599
600void ParamTraits<base::ScopedFD>::Write(base::Pickle* m, const param_type& p) {
601 // This serialization must be kept in sync with
602 // nacl_message_scanner.cc:WriteHandle().
603 const bool valid = p.is_valid();
604 WriteParam(m, valid);
605
606 if (!valid)
607 return;
608
609 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
610 std::move(const_cast<param_type&>(p))))) {
611 NOTREACHED();
612 }
613}
614
615bool ParamTraits<base::ScopedFD>::Read(const base::Pickle* m,
616 base::PickleIterator* iter,
617 param_type* r) {
618 r->reset();
619
620 bool valid;
621 if (!ReadParam(m, iter, &valid))
622 return false;
623
624 if (!valid)
625 return true;
626
627 scoped_refptr<base::Pickle::Attachment> attachment;
628 if (!m->ReadAttachment(iter, &attachment))
629 return false;
630
631 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
632 MessageAttachment::Type::PLATFORM_FILE) {
633 return false;
634 }
635
636 *r = base::ScopedFD(
637 static_cast<internal::PlatformFileAttachment*>(attachment.get())
638 ->TakePlatformFile());
639 return true;
640}
641
642void ParamTraits<base::ScopedFD>::Log(const param_type& p, std::string* l) {
643 l->append(base::StringPrintf("ScopedFD(%d)", p.get()));
644}
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09645#endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]7a4de7a62010-08-17 18:38:24646
Robert Sesek02910662020-02-28 20:15:51647#if defined(OS_WIN)
648void ParamTraits<base::win::ScopedHandle>::Write(base::Pickle* m,
649 const param_type& p) {
650 const bool valid = p.IsValid();
651 WriteParam(m, valid);
652 if (!valid)
653 return;
654
655 HandleWin handle(p.Get());
656 WriteParam(m, handle);
657}
658
659bool ParamTraits<base::win::ScopedHandle>::Read(const base::Pickle* m,
660 base::PickleIterator* iter,
661 param_type* r) {
662 r->Close();
663
664 bool valid;
665 if (!ReadParam(m, iter, &valid))
666 return false;
667 if (!valid)
668 return true;
669
670 HandleWin handle;
671 if (!ReadParam(m, iter, &handle))
672 return false;
673
674 r->Set(handle.get_handle());
675 return true;
676}
677
678void ParamTraits<base::win::ScopedHandle>::Log(const param_type& p,
679 std::string* l) {
680 l->append(base::StringPrintf("ScopedHandle(%p)", p.Get()));
681}
682#endif // defined(OS_WIN)
683
Sergey Ulanova97f3282019-04-17 01:27:34684#if defined(OS_FUCHSIA)
685void ParamTraits<zx::vmo>::Write(base::Pickle* m, const param_type& p) {
686 // This serialization must be kept in sync with
687 // nacl_message_scanner.cc:WriteHandle().
688 const bool valid = p.is_valid();
689 WriteParam(m, valid);
690
691 if (!valid)
692 return;
693
694 if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
Sergey Ulanov04367c72019-06-21 15:51:43695 std::move(const_cast<param_type&>(p))))) {
Sergey Ulanova97f3282019-04-17 01:27:34696 NOTREACHED();
697 }
698}
699
700bool ParamTraits<zx::vmo>::Read(const base::Pickle* m,
701 base::PickleIterator* iter,
702 param_type* r) {
703 r->reset();
704
705 bool valid;
706 if (!ReadParam(m, iter, &valid))
707 return false;
708
709 if (!valid)
710 return true;
711
712 scoped_refptr<base::Pickle::Attachment> attachment;
713 if (!m->ReadAttachment(iter, &attachment))
714 return false;
715
716 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
717 MessageAttachment::Type::FUCHSIA_HANDLE) {
718 return false;
719 }
720
721 *r = zx::vmo(static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
722 ->Take());
723 return true;
724}
725
726void ParamTraits<zx::vmo>::Log(const param_type& p, std::string* l) {
727 l->append("ZirconVMO");
728}
Sergey Ulanov7b343ff2019-08-15 07:52:37729
730void ParamTraits<zx::channel>::Write(base::Pickle* m, const param_type& p) {
731 // This serialization must be kept in sync with
732 // nacl_message_scanner.cc:WriteHandle().
733 const bool valid = p.is_valid();
734 WriteParam(m, valid);
735
736 if (!valid)
737 return;
738
739 if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
740 std::move(const_cast<param_type&>(p))))) {
741 NOTREACHED();
742 }
743}
744
745bool ParamTraits<zx::channel>::Read(const base::Pickle* m,
746 base::PickleIterator* iter,
747 param_type* r) {
748 r->reset();
749
750 bool valid;
751 if (!ReadParam(m, iter, &valid))
752 return false;
753
754 if (!valid)
755 return true;
756
757 scoped_refptr<base::Pickle::Attachment> attachment;
758 if (!m->ReadAttachment(iter, &attachment))
759 return false;
760
761 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
762 MessageAttachment::Type::FUCHSIA_HANDLE) {
763 return false;
764 }
765
766 *r = zx::channel(
767 static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
768 ->Take());
769 return true;
770}
771
772void ParamTraits<zx::channel>::Log(const param_type& p, std::string* l) {
773 l->append("ZirconChannel");
774}
Sergey Ulanova97f3282019-04-17 01:27:34775#endif // defined(OS_FUCHSIA)
776
Klaus Weidner3824a8882017-11-03 06:24:57777#if defined(OS_ANDROID)
Alexandr Ilin0443a8f2018-07-20 20:14:50778void ParamTraits<base::android::ScopedHardwareBufferHandle>::Write(
779 base::Pickle* m,
780 const param_type& p) {
781 const bool is_valid = p.is_valid();
Ken Rockot097248f02018-04-23 16:23:34782 WriteParam(m, is_valid);
783 if (!is_valid)
784 return;
785
Ken Rockot097248f02018-04-23 16:23:34786 // We must keep a ref to the AHardwareBuffer alive until the receiver has
787 // acquired its own reference. We do this by sending a message pipe handle
788 // along with the buffer. When the receiver deserializes (or even if they
789 // die without ever reading the message) their end of the pipe will be
790 // closed. We will eventually detect this and release the AHB reference.
791 mojo::MessagePipe tracking_pipe;
792 m->WriteAttachment(new internal::MojoHandleAttachment(
793 mojo::ScopedHandle::From(std::move(tracking_pipe.handle0))));
Alexandr Ilin0443a8f2018-07-20 20:14:50794 WriteParam(m, base::FileDescriptor(p.SerializeAsFileDescriptor().release(),
795 true /* auto_close */));
Ken Rockot097248f02018-04-23 16:23:34796
797 // Pass ownership of the input handle to our tracking pipe to keep the AHB
798 // alive long enough to be deserialized by the receiver.
Alexandr Ilin0443a8f2018-07-20 20:14:50799 mojo::ScopeToMessagePipe(std::move(const_cast<param_type&>(p)),
800 std::move(tracking_pipe.handle1));
Klaus Weidner3824a8882017-11-03 06:24:57801}
802
Alexandr Ilin0443a8f2018-07-20 20:14:50803bool ParamTraits<base::android::ScopedHardwareBufferHandle>::Read(
804 const base::Pickle* m,
805 base::PickleIterator* iter,
806 param_type* r) {
807 *r = base::android::ScopedHardwareBufferHandle();
Ken Rockot097248f02018-04-23 16:23:34808
809 bool is_valid;
810 if (!ReadParam(m, iter, &is_valid))
Klaus Weidner3824a8882017-11-03 06:24:57811 return false;
Ken Rockot097248f02018-04-23 16:23:34812 if (!is_valid)
813 return true;
814
815 scoped_refptr<base::Pickle::Attachment> tracking_pipe_attachment;
816 if (!m->ReadAttachment(iter, &tracking_pipe_attachment))
Klaus Weidner3824a8882017-11-03 06:24:57817 return false;
Ken Rockot097248f02018-04-23 16:23:34818
819 // We keep this alive until the AHB is safely deserialized below. When this
820 // goes out of scope, the sender holding the other end of this pipe will treat
821 // this handle closure as a signal that it's safe to release their AHB
822 // keepalive ref.
823 mojo::ScopedHandle tracking_pipe =
824 static_cast<MessageAttachment*>(tracking_pipe_attachment.get())
825 ->TakeMojoHandle();
826
827 base::FileDescriptor descriptor;
828 if (!ReadParam(m, iter, &descriptor))
829 return false;
830
831 // NOTE: It is valid to deserialize an invalid FileDescriptor, so the success
832 // of |ReadParam()| above does not imply that |descriptor| is valid.
833 base::ScopedFD scoped_fd(descriptor.fd);
834 if (!scoped_fd.is_valid())
835 return false;
836
837 *r = base::android::ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(
Alexandr Ilin0443a8f2018-07-20 20:14:50838 std::move(scoped_fd));
Klaus Weidner3824a8882017-11-03 06:24:57839 return true;
840}
841
Alexandr Ilin0443a8f2018-07-20 20:14:50842void ParamTraits<base::android::ScopedHardwareBufferHandle>::Log(
843 const param_type& p,
844 std::string* l) {
845 l->append(base::StringPrintf("base::android::ScopedHardwareBufferHandle(%p)",
846 p.get()));
Klaus Weidner3824a8882017-11-03 06:24:57847}
Ken Rockot097248f02018-04-23 16:23:34848#endif // defined(OS_ANDROID)
Klaus Weidner3824a8882017-11-03 06:24:57849
Alexandr Ilind497eee2018-04-19 22:50:54850void ParamTraits<base::ReadOnlySharedMemoryRegion>::Write(base::Pickle* m,
851 const param_type& p) {
852 base::subtle::PlatformSharedMemoryRegion handle =
853 base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
854 std::move(const_cast<param_type&>(p)));
855 WriteParam(m, std::move(handle));
856}
857
858bool ParamTraits<base::ReadOnlySharedMemoryRegion>::Read(
859 const base::Pickle* m,
860 base::PickleIterator* iter,
861 param_type* r) {
862 base::subtle::PlatformSharedMemoryRegion handle;
863 if (!ReadParam(m, iter, &handle))
864 return false;
865
866 *r = base::ReadOnlySharedMemoryRegion::Deserialize(std::move(handle));
867 return true;
868}
869
870void ParamTraits<base::ReadOnlySharedMemoryRegion>::Log(const param_type& p,
871 std::string* l) {
872 *l = "<base::ReadOnlySharedMemoryRegion>";
873 // TODO(alexilin): currently there is no way to access underlying handle
874 // without destructing a ReadOnlySharedMemoryRegion instance.
875}
876
877void ParamTraits<base::WritableSharedMemoryRegion>::Write(base::Pickle* m,
878 const param_type& p) {
879 base::subtle::PlatformSharedMemoryRegion handle =
880 base::WritableSharedMemoryRegion::TakeHandleForSerialization(
881 std::move(const_cast<param_type&>(p)));
882 WriteParam(m, std::move(handle));
883}
884
885bool ParamTraits<base::WritableSharedMemoryRegion>::Read(
886 const base::Pickle* m,
887 base::PickleIterator* iter,
888 param_type* r) {
889 base::subtle::PlatformSharedMemoryRegion handle;
890 if (!ReadParam(m, iter, &handle))
891 return false;
892
893 *r = base::WritableSharedMemoryRegion::Deserialize(std::move(handle));
894 return true;
895}
896
897void ParamTraits<base::WritableSharedMemoryRegion>::Log(const param_type& p,
898 std::string* l) {
899 *l = "<base::WritableSharedMemoryRegion>";
900 // TODO(alexilin): currently there is no way to access underlying handle
901 // without destructing a ReadOnlySharedMemoryRegion instance.
902}
903
904void ParamTraits<base::UnsafeSharedMemoryRegion>::Write(base::Pickle* m,
905 const param_type& p) {
906 base::subtle::PlatformSharedMemoryRegion handle =
907 base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
908 std::move(const_cast<param_type&>(p)));
909 WriteParam(m, std::move(handle));
910}
911
912bool ParamTraits<base::UnsafeSharedMemoryRegion>::Read(
913 const base::Pickle* m,
914 base::PickleIterator* iter,
915 param_type* r) {
916 base::subtle::PlatformSharedMemoryRegion handle;
917 if (!ReadParam(m, iter, &handle))
918 return false;
919
920 *r = base::UnsafeSharedMemoryRegion::Deserialize(std::move(handle));
921 return true;
922}
923
924void ParamTraits<base::UnsafeSharedMemoryRegion>::Log(const param_type& p,
925 std::string* l) {
926 *l = "<base::UnsafeSharedMemoryRegion>";
927 // TODO(alexilin): currently there is no way to access underlying handle
928 // without destructing a ReadOnlySharedMemoryRegion instance.
929}
930
931void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Write(
932 base::Pickle* m,
933 const param_type& p) {
Alexandr Ilinebab9da2018-06-01 02:37:47934 // This serialization must be kept in sync with
935 // nacl_message_scanner.cc::WriteHandle().
Alexandr Ilind497eee2018-04-19 22:50:54936 const bool valid = p.IsValid();
937 WriteParam(m, valid);
938
939 if (!valid)
940 return;
941
942 WriteParam(m, p.GetMode());
943 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
944 WriteParam(m, p.GetGUID());
945
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09946#if defined(OS_WIN)
947 base::win::ScopedHandle h = const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54948 HandleWin handle_win(h.Get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09949 WriteParam(m, handle_win);
Alexandr Ilind497eee2018-04-19 22:50:54950#elif defined(OS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:43951 zx::vmo vmo = const_cast<param_type&>(p).PassPlatformHandle();
952 WriteParam(m, vmo);
Avi Drissman2b97d032020-07-30 03:02:26953#elif defined(OS_MAC)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09954 base::mac::ScopedMachSendRight h =
955 const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54956 MachPortMac mach_port_mac(h.get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09957 WriteParam(m, mach_port_mac);
Alexandr Ilind497eee2018-04-19 22:50:54958#elif defined(OS_ANDROID)
959 m->WriteAttachment(new internal::PlatformFileAttachment(
960 base::ScopedFD(const_cast<param_type&>(p).PassPlatformHandle())));
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09961#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:54962 base::subtle::ScopedFDPair h =
963 const_cast<param_type&>(p).PassPlatformHandle();
964 m->WriteAttachment(new internal::PlatformFileAttachment(std::move(h.fd)));
965 if (p.GetMode() ==
966 base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
967 m->WriteAttachment(
968 new internal::PlatformFileAttachment(std::move(h.readonly_fd)));
969 }
970#endif
971}
972
973bool ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Read(
974 const base::Pickle* m,
975 base::PickleIterator* iter,
976 param_type* r) {
977 bool valid;
978 if (!ReadParam(m, iter, &valid))
979 return false;
980 if (!valid) {
981 *r = base::subtle::PlatformSharedMemoryRegion();
982 return true;
983 }
984
985 base::subtle::PlatformSharedMemoryRegion::Mode mode;
986 uint64_t shm_size;
987 base::UnguessableToken guid;
988 if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &shm_size) ||
989 !base::IsValueInRangeForNumericType<size_t>(shm_size) ||
990 !ReadParam(m, iter, &guid)) {
991 return false;
992 }
993 size_t size = static_cast<size_t>(shm_size);
994
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09995#if defined(OS_WIN)
996 HandleWin handle_win;
997 if (!ReadParam(m, iter, &handle_win))
Alexandr Ilind497eee2018-04-19 22:50:54998 return false;
999 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091000 base::win::ScopedHandle(handle_win.get_handle()), mode, size, guid);
Alexandr Ilind497eee2018-04-19 22:50:541001#elif defined(OS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:431002 zx::vmo vmo;
1003 if (!ReadParam(m, iter, &vmo))
Alexandr Ilind497eee2018-04-19 22:50:541004 return false;
Sergey Ulanov04367c72019-06-21 15:51:431005 *r = base::subtle::PlatformSharedMemoryRegion::Take(std::move(vmo), mode,
1006 size, guid);
Avi Drissman2b97d032020-07-30 03:02:261007#elif defined(OS_MAC)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091008 MachPortMac mach_port_mac;
1009 if (!ReadParam(m, iter, &mach_port_mac))
Alexandr Ilind497eee2018-04-19 22:50:541010 return false;
1011 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091012 base::mac::ScopedMachSendRight(mach_port_mac.get_mach_port()), mode, size,
1013 guid);
1014#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541015 scoped_refptr<base::Pickle::Attachment> attachment;
1016 if (!m->ReadAttachment(iter, &attachment))
1017 return false;
1018 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
1019 MessageAttachment::Type::PLATFORM_FILE) {
1020 return false;
1021 }
1022
1023#if defined(OS_ANDROID)
1024 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1025 base::ScopedFD(
1026 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1027 ->TakePlatformFile()),
1028 mode, size, guid);
1029#else
1030 scoped_refptr<base::Pickle::Attachment> readonly_attachment;
1031 if (mode == base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
1032 if (!m->ReadAttachment(iter, &readonly_attachment))
1033 return false;
1034
1035 if (static_cast<MessageAttachment*>(readonly_attachment.get())->GetType() !=
1036 MessageAttachment::Type::PLATFORM_FILE) {
1037 return false;
1038 }
1039 }
1040 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1041 base::subtle::ScopedFDPair(
1042 base::ScopedFD(
1043 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1044 ->TakePlatformFile()),
1045 readonly_attachment
1046 ? base::ScopedFD(static_cast<internal::PlatformFileAttachment*>(
1047 readonly_attachment.get())
1048 ->TakePlatformFile())
1049 : base::ScopedFD()),
1050 mode, size, guid);
1051#endif // defined(OS_ANDROID)
1052
1053#endif
1054
1055 return true;
1056}
1057
1058void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Log(
1059 const param_type& p,
1060 std::string* l) {
Wezb908e432018-09-05 17:35:221061#if defined(OS_FUCHSIA)
1062 l->append("Handle: ");
1063 LogParam(p.GetPlatformHandle()->get(), l);
1064#elif defined(OS_WIN)
Alexandr Ilind497eee2018-04-19 22:50:541065 l->append("Handle: ");
1066 LogParam(p.GetPlatformHandle(), l);
Avi Drissman2b97d032020-07-30 03:02:261067#elif defined(OS_MAC)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091068 l->append("Mach port: ");
1069 LogParam(p.GetPlatformHandle(), l);
Alexandr Ilind497eee2018-04-19 22:50:541070#elif defined(OS_ANDROID)
1071 l->append("FD: ");
1072 LogParam(p.GetPlatformHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091073#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541074 base::subtle::FDPair h = p.GetPlatformHandle();
1075 l->append("FD: ");
1076 LogParam(h.fd, l);
1077 l->append("Read-only FD: ");
1078 LogParam(h.readonly_fd, l);
1079#endif
1080
1081 l->append("Mode: ");
1082 LogParam(p.GetMode(), l);
1083 l->append("size: ");
1084 LogParam(static_cast<uint64_t>(p.GetSize()), l);
1085 l->append("GUID: ");
1086 LogParam(p.GetGUID(), l);
1087}
1088
1089void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Write(
1090 base::Pickle* m,
1091 const param_type& value) {
1092 DCHECK(static_cast<int>(value) >= 0 &&
1093 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue));
1094 m->WriteInt(static_cast<int>(value));
1095}
1096
1097bool ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Read(
1098 const base::Pickle* m,
1099 base::PickleIterator* iter,
1100 param_type* p) {
1101 int value;
1102 if (!iter->ReadInt(&value))
1103 return false;
1104 if (!(static_cast<int>(value) >= 0 &&
1105 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue))) {
1106 return false;
1107 }
1108 *p = static_cast<param_type>(value);
1109 return true;
1110}
1111
1112void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Log(
1113 const param_type& p,
1114 std::string* l) {
1115 LogParam(static_cast<int>(p), l);
1116}
1117
erikchend804e1052017-04-29 02:24:361118#if defined(OS_WIN)
erikchend804e1052017-04-29 02:24:361119void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
1120 const param_type& p) {
1121 m->WriteBool(p.IsValid());
1122 if (p.IsValid()) {
Wez51eaaad2017-08-09 05:51:381123 HandleWin handle_win(p.GetHandle());
erikchend804e1052017-04-29 02:24:361124 ParamTraits<HandleWin>::Write(m, handle_win);
1125 ::CloseHandle(p.GetHandle());
1126 }
1127}
1128
1129bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
1130 base::PickleIterator* iter,
1131 param_type* r) {
1132 bool is_valid;
1133 if (!iter->ReadBool(&is_valid))
1134 return false;
1135 if (!is_valid) {
1136 *r = PlatformFileForTransit();
1137 return true;
1138 }
1139
1140 HandleWin handle_win;
1141 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
1142 return false;
1143 *r = PlatformFileForTransit(handle_win.get_handle());
1144 return true;
1145}
1146
1147void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
1148 std::string* l) {
1149 LogParam(p.GetHandle(), l);
1150}
1151#endif // defined(OS_WIN)
1152
rockot502c94f2016-02-03 20:20:161153void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:551154 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:251155}
1156
rockot502c94f2016-02-03 20:20:161157bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251158 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:301159 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:551160 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:251161}
1162
[email protected]6d4b67a2013-02-10 04:49:301163void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
1164 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:251165}
1166
rockot502c94f2016-02-03 20:20:161167void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251168 WriteValue(m, &p, 0);
1169}
1170
rockot502c94f2016-02-03 20:20:161171bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251172 base::PickleIterator* iter,
1173 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:251174 int type;
jdoerriedc72ee942016-12-07 15:43:281175 if (!ReadParam(m, iter, &type) ||
1176 type != static_cast<int>(base::Value::Type::LIST))
[email protected]bf5aedf02012-06-04 21:18:251177 return false;
1178
1179 return ReadListValue(m, iter, r, 0);
1180}
1181
[email protected]ea5ef4c2013-06-13 22:50:271182void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251183 std::string json;
estade8d046462015-05-16 01:02:341184 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:251185 l->append(json);
1186}
1187
Devlin Cronin7178a5bd2021-02-02 02:56:471188void ParamTraits<base::Value>::Write(base::Pickle* m, const param_type& p) {
1189 WriteValue(m, &p, 0);
1190}
1191
1192bool ParamTraits<base::Value>::Read(const base::Pickle* m,
1193 base::PickleIterator* iter,
1194 param_type* r) {
1195 return ReadValue(m, iter, r, 0);
1196}
1197
1198void ParamTraits<base::Value>::Log(const param_type& p, std::string* l) {
1199 std::string json;
1200 base::JSONWriter::Write(p, &json);
1201 l->append(json);
1202}
1203
rockot502c94f2016-02-03 20:20:161204void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:001205 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251206 WriteParam(m, p.size);
1207 WriteParam(m, p.is_directory);
1208 WriteParam(m, p.last_modified.ToDoubleT());
1209 WriteParam(m, p.last_accessed.ToDoubleT());
1210 WriteParam(m, p.creation_time.ToDoubleT());
1211}
1212
rockot502c94f2016-02-03 20:20:161213bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251214 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:001215 param_type* p) {
[email protected]481c3e82014-07-18 01:40:471216 double last_modified, last_accessed, creation_time;
1217 if (!ReadParam(m, iter, &p->size) ||
1218 !ReadParam(m, iter, &p->is_directory) ||
1219 !ReadParam(m, iter, &last_modified) ||
1220 !ReadParam(m, iter, &last_accessed) ||
1221 !ReadParam(m, iter, &creation_time))
1222 return false;
1223 p->last_modified = base::Time::FromDoubleT(last_modified);
1224 p->last_accessed = base::Time::FromDoubleT(last_accessed);
1225 p->creation_time = base::Time::FromDoubleT(creation_time);
1226 return true;
[email protected]bf5aedf02012-06-04 21:18:251227}
1228
[email protected]141bcc52014-01-27 21:36:001229void ParamTraits<base::File::Info>::Log(const param_type& p,
1230 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251231 l->append("(");
1232 LogParam(p.size, l);
1233 l->append(",");
1234 LogParam(p.is_directory, l);
1235 l->append(",");
1236 LogParam(p.last_modified.ToDoubleT(), l);
1237 l->append(",");
1238 LogParam(p.last_accessed.ToDoubleT(), l);
1239 l->append(",");
1240 LogParam(p.creation_time.ToDoubleT(), l);
1241 l->append(")");
1242}
1243
rockot502c94f2016-02-03 20:20:161244void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571245 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251246}
1247
rockot502c94f2016-02-03 20:20:161248bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251249 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251250 param_type* r) {
tfarina10a5c062015-09-04 18:47:571251 int64_t value;
1252 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:251253 return false;
1254 *r = base::Time::FromInternalValue(value);
1255 return true;
1256}
1257
1258void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571259 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251260}
1261
rockot502c94f2016-02-03 20:20:161262void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571263 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251264}
1265
rockot502c94f2016-02-03 20:20:161266bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251267 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251268 param_type* r) {
tfarina10a5c062015-09-04 18:47:571269 int64_t value;
1270 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251271 if (ret)
1272 *r = base::TimeDelta::FromInternalValue(value);
1273
1274 return ret;
1275}
1276
1277void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571278 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251279}
1280
rockot502c94f2016-02-03 20:20:161281void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571282 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251283}
1284
rockot502c94f2016-02-03 20:20:161285bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251286 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251287 param_type* r) {
tfarina10a5c062015-09-04 18:47:571288 int64_t value;
1289 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251290 if (ret)
1291 *r = base::TimeTicks::FromInternalValue(value);
1292
1293 return ret;
1294}
1295
1296void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571297 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251298}
1299
tguilbert4a5ac602016-09-19 21:11:251300// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1301// below should be updated.
1302static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1303 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1304
tguilbert4a5ac602016-09-19 21:11:251305void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1306 const param_type& p) {
1307 DCHECK(!p.is_empty());
1308
1309 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1310 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1311}
1312
1313bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1314 base::PickleIterator* iter,
1315 param_type* r) {
1316 uint64_t high, low;
1317 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1318 !ParamTraits<uint64_t>::Read(m, iter, &low))
1319 return false;
1320
1321 // Receiving a zeroed UnguessableToken is a security issue.
1322 if (high == 0 && low == 0)
1323 return false;
1324
1325 *r = base::UnguessableToken::Deserialize(high, low);
1326 return true;
1327}
1328
1329void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1330 std::string* l) {
1331 l->append(p.ToString());
1332}
1333
rockot502c94f2016-02-03 20:20:161334void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1335 const param_type& p) {
sammc9bf370c2016-11-14 03:29:081336#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241337 WriteParam(m, p.socket);
sammc9bf370c2016-11-14 03:29:081338#else
amistry36182522016-06-27 06:34:421339 WriteParam(m, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:081340#endif
[email protected]7a4de7a62010-08-17 18:38:241341}
1342
rockot502c94f2016-02-03 20:20:161343bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251344 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:241345 param_type* r) {
sammc9bf370c2016-11-14 03:29:081346#if defined(OS_NACL_SFI)
1347 return ReadParam(m, iter, &r->socket);
1348#else
1349 return ReadParam(m, iter, &r->mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241350#endif
[email protected]7a4de7a62010-08-17 18:38:241351}
1352
1353void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571354 std::string* l) {
sammc9bf370c2016-11-14 03:29:081355 l->append("ChannelHandle(");
1356#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241357 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
sammc9bf370c2016-11-14 03:29:081358#else
amistry36182522016-06-27 06:34:421359 LogParam(p.mojo_handle, l);
sammc9bf370c2016-11-14 03:29:081360#endif
[email protected]252cad62010-08-18 18:33:571361 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241362}
1363
rockot502c94f2016-02-03 20:20:161364void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301365 WriteParam(m, p.channel);
1366 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271367 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301368 WriteParam(m, p.flags);
1369 WriteParam(m, p.sent);
1370 WriteParam(m, p.receive);
1371 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451372 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301373 WriteParam(m, p.params);
1374}
1375
rockot502c94f2016-02-03 20:20:161376bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251377 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561378 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271379 return
[email protected]20f0487a2010-09-30 20:06:301380 ReadParam(m, iter, &r->channel) &&
1381 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271382 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301383 ReadParam(m, iter, &r->flags) &&
1384 ReadParam(m, iter, &r->sent) &&
1385 ReadParam(m, iter, &r->receive) &&
1386 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451387 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301388 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301389}
1390
[email protected]bf5aedf02012-06-04 21:18:251391void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1392 // Doesn't make sense to implement this!
1393}
1394
rockot502c94f2016-02-03 20:20:161395void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091396#if defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]34d48612012-06-29 00:05:041397 // We don't serialize the file descriptors in the nested message, so there
1398 // better not be any.
morrita1aa788c2015-01-31 05:45:421399 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041400#endif
1401
1402 // Don't just write out the message. This is used to send messages between
1403 // NaCl (Posix environment) and the browser (could be on Windows). The message
1404 // header formats differ between these systems (so does handle sharing, but
1405 // we already asserted we don't have any handles). So just write out the
1406 // parts of the header we use.
1407 //
1408 // Be careful also to use only explicitly-sized types. The NaCl environment
1409 // could be 64-bit and the host browser could be 32-bits. The nested message
1410 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1411 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:571412 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041413 m->WriteUInt32(p.type());
1414 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:571415 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:251416}
1417
rockot502c94f2016-02-03 20:20:161418bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251419 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251420 Message* r) {
tfarina10a5c062015-09-04 18:47:571421 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481422 if (!iter->ReadUInt32(&routing_id) ||
1423 !iter->ReadUInt32(&type) ||
1424 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251425 return false;
[email protected]34d48612012-06-29 00:05:041426
1427 int payload_size;
1428 const char* payload;
avi48fc13b2014-12-28 23:31:481429 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251430 return false;
[email protected]34d48612012-06-29 00:05:041431
tfarina10a5c062015-09-04 18:47:571432 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
Daniel Cheng0d89f9222017-09-22 05:05:071433 r->WriteBytes(payload, payload_size);
1434 return true;
[email protected]bf5aedf02012-06-04 21:18:251435}
1436
1437void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1438 l->append("<IPC::Message>");
1439}
1440
1441#if defined(OS_WIN)
1442// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031443// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161444void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031445 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251446}
1447
rockot502c94f2016-02-03 20:20:161448bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251449 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251450 param_type* r) {
tfarina10a5c062015-09-04 18:47:571451 int32_t temp;
avi48fc13b2014-12-28 23:31:481452 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251453 return false;
[email protected]4a635b72013-03-04 02:29:031454 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251455 return true;
1456}
1457
1458void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001459 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251460}
1461
rockot502c94f2016-02-03 20:20:161462void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251463 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1464}
1465
rockot502c94f2016-02-03 20:20:161466bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251467 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251468 param_type* r) {
1469 const char *data;
1470 int data_size = 0;
avi48fc13b2014-12-28 23:31:481471 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251472 if (result && data_size == sizeof(MSG)) {
1473 memcpy(r, data, sizeof(MSG));
1474 } else {
1475 result = false;
1476 NOTREACHED();
1477 }
1478
1479 return result;
1480}
1481
1482void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1483 l->append("<MSG>");
1484}
1485
1486#endif // OS_WIN
1487
[email protected]946d1b22009-07-22 23:57:211488} // namespace IPC