blob: 8d6931b522dc07b7bcf013340a5f25ac534315e9 [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
Devlin Cronin7178a5bd2021-02-02 02:56:47217 constexpr int kMinValueType = static_cast<int>(base::Value::Type::NONE);
218 constexpr int kMaxValueType = static_cast<int>(base::Value::Type::LIST);
219 if (type > kMaxValueType || type < kMinValueType)
220 return false;
221
jdoerriedc72ee942016-12-07 15:43:28222 switch (static_cast<base::Value::Type>(type)) {
223 case base::Value::Type::NONE:
Jeremy Roman2d8d7802020-06-11 22:08:20224 *value = base::Value();
jdoerriee067999a2017-04-07 06:39:00225 break;
jdoerriedc72ee942016-12-07 15:43:28226 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21227 bool val;
228 if (!ReadParam(m, iter, &val))
229 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20230 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21231 break;
232 }
jdoerriedc72ee942016-12-07 15:43:28233 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21234 int val;
235 if (!ReadParam(m, iter, &val))
236 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20237 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21238 break;
239 }
jdoerriedc72ee942016-12-07 15:43:28240 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21241 double val;
242 if (!ReadParam(m, iter, &val))
243 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20244 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21245 break;
246 }
jdoerriedc72ee942016-12-07 15:43:28247 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21248 std::string val;
249 if (!ReadParam(m, iter, &val))
250 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20251 *value = base::Value(std::move(val));
[email protected]946d1b22009-07-22 23:57:21252 break;
253 }
jdoerriedc72ee942016-12-07 15:43:28254 case base::Value::Type::BINARY: {
Jeremy Roman2d8d7802020-06-11 22:08:20255 base::span<const uint8_t> data;
256 if (!iter->ReadData(&data))
[email protected]e4dad9fb2009-10-06 18:15:58257 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20258 *value = base::Value(data);
[email protected]946d1b22009-07-22 23:57:21259 break;
260 }
jdoerriedc72ee942016-12-07 15:43:28261 case base::Value::Type::DICTIONARY: {
jdoerrief1e72e32017-04-26 16:23:55262 base::DictionaryValue val;
263 if (!ReadDictionaryValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21264 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20265 *value = std::move(val);
[email protected]946d1b22009-07-22 23:57:21266 break;
267 }
jdoerriedc72ee942016-12-07 15:43:28268 case base::Value::Type::LIST: {
jdoerrief1e72e32017-04-26 16:23:55269 base::ListValue val;
270 if (!ReadListValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21271 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20272 *value = std::move(val);
[email protected]946d1b22009-07-22 23:57:21273 break;
274 }
[email protected]e4dad9fb2009-10-06 18:15:58275 default:
Jan Wilken Dörrie271086b42019-06-13 20:03:41276 NOTREACHED();
jdoerriee1b1f3a2019-03-16 04:08:01277 return false;
[email protected]946d1b22009-07-22 23:57:21278 }
279
280 return true;
281}
282
[email protected]bf5aedf02012-06-04 21:18:25283} // namespace
284
285// -----------------------------------------------------------------------------
286
287LogData::LogData()
288 : routing_id(0),
289 type(0),
290 sent(0),
291 receive(0),
292 dispatch(0) {
293}
294
vmpstrbf0d713a2016-03-24 20:22:54295LogData::LogData(const LogData& other) = default;
296
Chris Watkins2d879af2017-11-30 02:11:59297LogData::~LogData() = default;
[email protected]bf5aedf02012-06-04 21:18:25298
[email protected]bf5aedf02012-06-04 21:18:25299void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
300 l->append(p ? "true" : "false");
301}
302
rockot502c94f2016-02-03 20:20:16303void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno19ecf1842015-10-30 00:46:20304 m->WriteBytes(&p, sizeof(param_type));
305}
306
rockot502c94f2016-02-03 20:20:16307bool ParamTraits<signed char>::Read(const base::Pickle* m,
308 base::PickleIterator* iter,
309 param_type* r) {
ortuno19ecf1842015-10-30 00:46:20310 const char* data;
311 if (!iter->ReadBytes(&data, sizeof(param_type)))
312 return false;
313 memcpy(r, data, sizeof(param_type));
314 return true;
315}
316
317void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38318 l->append(base::NumberToString(p));
ortuno19ecf1842015-10-30 00:46:20319}
320
rockot502c94f2016-02-03 20:20:16321void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28322 m->WriteBytes(&p, sizeof(param_type));
323}
324
rockot502c94f2016-02-03 20:20:16325bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25326 base::PickleIterator* iter,
327 param_type* r) {
[email protected]c1ee48d2013-07-12 23:12:28328 const char* data;
avi48fc13b2014-12-28 23:31:48329 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28330 return false;
331 memcpy(r, data, sizeof(param_type));
332 return true;
333}
334
335void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38336 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28337}
338
rockot502c94f2016-02-03 20:20:16339void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28340 m->WriteBytes(&p, sizeof(param_type));
341}
342
rockot502c94f2016-02-03 20:20:16343bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25344 base::PickleIterator* iter,
[email protected]c1ee48d2013-07-12 23:12:28345 param_type* r) {
346 const char* data;
avi48fc13b2014-12-28 23:31:48347 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28348 return false;
349 memcpy(r, data, sizeof(param_type));
350 return true;
351}
352
353void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09354 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28355}
356
[email protected]252cad62010-08-18 18:33:57357void ParamTraits<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
361void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09362 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57363}
364
Sean McAllister82700412020-08-19 20:10:35365#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
366 defined(OS_FUCHSIA) || (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]252cad62010-08-18 18:33:57367void ParamTraits<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}
370
371void ParamTraits<unsigned 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}
jam03d8a782016-02-10 20:13:39374#endif
[email protected]252cad62010-08-18 18:33:57375
376void ParamTraits<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}
379
380void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09381 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57382}
[email protected]7a4de7a62010-08-17 18:38:24383
[email protected]bf5aedf02012-06-04 21:18:25384void ParamTraits<float>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04385 l->append(base::StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24386}
387
rockot502c94f2016-02-03 20:20:16388void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
[email protected]48328ff2013-10-31 09:27:31389 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52390}
391
rockot502c94f2016-02-03 20:20:16392bool ParamTraits<double>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25393 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25394 param_type* r) {
395 const char *data;
avi48fc13b2014-12-28 23:31:48396 if (!iter->ReadBytes(&data, sizeof(*r))) {
[email protected]bf5aedf02012-06-04 21:18:25397 NOTREACHED();
398 return false;
399 }
400 memcpy(r, data, sizeof(param_type));
401 return true;
[email protected]d84e48b2010-10-21 22:04:52402}
403
[email protected]bf5aedf02012-06-04 21:18:25404void ParamTraits<double>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04405 l->append(base::StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04406}
407
[email protected]bf5aedf02012-06-04 21:18:25408
409void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
410 l->append(p);
[email protected]1d14f582011-09-02 20:42:04411}
412
[email protected]476dafb2013-12-03 00:39:26413void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
[email protected]ad65a3e2013-12-25 18:18:01414 l->append(base::UTF16ToUTF8(p));
[email protected]bf5aedf02012-06-04 21:18:25415}
[email protected]bf5aedf02012-06-04 21:18:25416
Jan Wilken Dörriecf5a66902020-12-07 20:51:31417#if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
418bool ParamTraits<std::wstring>::Read(const base::Pickle* m,
419 base::PickleIterator* iter,
420 param_type* r) {
421 base::StringPiece16 piece16;
422 if (!iter->ReadStringPiece16(&piece16))
423 return false;
424
425 *r = base::AsWString(piece16);
426 return true;
427}
428
429void ParamTraits<std::wstring>::Log(const param_type& p, std::string* l) {
430 l->append(base::WideToUTF8(p));
431}
432#endif
433
rockot502c94f2016-02-03 20:20:16434void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
435 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25436 if (p.empty()) {
437 m->WriteData(NULL, 0);
438 } else {
Chris Palmerc5ea9b92017-09-25 22:53:22439 m->WriteData(&p.front(), base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25440 }
441}
442
rockot502c94f2016-02-03 20:20:16443bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25444 base::PickleIterator* iter,
445 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25446 const char *data;
447 int data_size = 0;
avi48fc13b2014-12-28 23:31:48448 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25449 return false;
450 r->resize(data_size);
451 if (data_size)
452 memcpy(&r->front(), data, data_size);
453 return true;
454}
455
456void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
457 LogBytes(p, l);
458}
459
rockot502c94f2016-02-03 20:20:16460void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
461 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25462 if (p.empty()) {
463 m->WriteData(NULL, 0);
464 } else {
465 m->WriteData(reinterpret_cast<const char*>(&p.front()),
Chris Palmerc5ea9b92017-09-25 22:53:22466 base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25467 }
468}
469
rockot502c94f2016-02-03 20:20:16470bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25471 base::PickleIterator* iter,
472 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25473 const char *data;
474 int data_size = 0;
avi48fc13b2014-12-28 23:31:48475 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25476 return false;
477 r->resize(data_size);
478 if (data_size)
479 memcpy(&r->front(), data, data_size);
480 return true;
481}
482
483void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
484 std::string* l) {
485 LogBytes(p, l);
486}
487
rockot502c94f2016-02-03 20:20:16488void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
489 const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22490 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]d4124852013-03-20 20:25:00491 // Cast to bool below is required because libc++'s
492 // vector<bool>::const_reference is different from bool, and we want to avoid
493 // writing an extra specialization of ParamTraits for it.
[email protected]bf5aedf02012-06-04 21:18:25494 for (size_t i = 0; i < p.size(); i++)
[email protected]d4124852013-03-20 20:25:00495 WriteParam(m, static_cast<bool>(p[i]));
[email protected]bf5aedf02012-06-04 21:18:25496}
497
rockot502c94f2016-02-03 20:20:16498bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25499 base::PickleIterator* iter,
500 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25501 int size;
502 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48503 if (!iter->ReadLength(&size))
[email protected]bf5aedf02012-06-04 21:18:25504 return false;
505 r->resize(size);
506 for (int i = 0; i < size; i++) {
507 bool value;
508 if (!ReadParam(m, iter, &value))
509 return false;
510 (*r)[i] = value;
511 }
512 return true;
513}
514
515void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
516 for (size_t i = 0; i < p.size(); ++i) {
517 if (i != 0)
518 l->push_back(' ');
[email protected]d4124852013-03-20 20:25:00519 LogParam(static_cast<bool>(p[i]), l);
[email protected]bf5aedf02012-06-04 21:18:25520 }
[email protected]d84e48b2010-10-21 22:04:52521}
522
rockot502c94f2016-02-03 20:20:16523void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
[email protected]ea5ef4c2013-06-13 22:50:27524 const param_type& p) {
[email protected]946d1b22009-07-22 23:57:21525 WriteValue(m, &p, 0);
526}
527
rockot502c94f2016-02-03 20:20:16528bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25529 base::PickleIterator* iter,
530 param_type* r) {
[email protected]946d1b22009-07-22 23:57:21531 int type;
jdoerriedc72ee942016-12-07 15:43:28532 if (!ReadParam(m, iter, &type) ||
533 type != static_cast<int>(base::Value::Type::DICTIONARY))
[email protected]946d1b22009-07-22 23:57:21534 return false;
535
536 return ReadDictionaryValue(m, iter, r, 0);
537}
538
[email protected]ea5ef4c2013-06-13 22:50:27539void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
540 std::string* l) {
[email protected]946d1b22009-07-22 23:57:21541 std::string json;
estade8d046462015-05-16 01:02:34542 base::JSONWriter::Write(p, &json);
[email protected]252cad62010-08-18 18:33:57543 l->append(json);
[email protected]946d1b22009-07-22 23:57:21544}
545
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09546#if defined(OS_POSIX) || defined(OS_FUCHSIA)
rockot502c94f2016-02-03 20:20:16547void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
548 const param_type& p) {
erikchen14525202017-05-06 19:16:51549 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06550 // nacl_message_scanner.cc:WriteHandle().
[email protected]7a4de7a62010-08-17 18:38:24551 const bool valid = p.fd >= 0;
552 WriteParam(m, valid);
553
morrita96693852014-09-24 20:11:45554 if (!valid)
555 return;
556
557 if (p.auto_close) {
morrita1aa788c2015-01-31 05:45:42558 if (!m->WriteAttachment(
559 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
morrita96693852014-09-24 20:11:45560 NOTREACHED();
561 } else {
morrita1aa788c2015-01-31 05:45:42562 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
[email protected]7a4de7a62010-08-17 18:38:24563 NOTREACHED();
564 }
565}
566
rockot502c94f2016-02-03 20:20:16567bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25568 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24569 param_type* r) {
morrita96693852014-09-24 20:11:45570 *r = base::FileDescriptor();
571
[email protected]7a4de7a62010-08-17 18:38:24572 bool valid;
573 if (!ReadParam(m, iter, &valid))
574 return false;
575
morrita96693852014-09-24 20:11:45576 if (!valid)
[email protected]7a4de7a62010-08-17 18:38:24577 return true;
[email protected]7a4de7a62010-08-17 18:38:24578
rockot502c94f2016-02-03 20:20:16579 scoped_refptr<base::Pickle::Attachment> attachment;
morrita1aa788c2015-01-31 05:45:42580 if (!m->ReadAttachment(iter, &attachment))
morrita96693852014-09-24 20:11:45581 return false;
582
sammc6ed3efb2016-11-23 03:17:35583 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
584 MessageAttachment::Type::PLATFORM_FILE) {
585 return false;
586 }
587
rockot502c94f2016-02-03 20:20:16588 *r = base::FileDescriptor(
sammc6ed3efb2016-11-23 03:17:35589 static_cast<internal::PlatformFileAttachment*>(attachment.get())
590 ->TakePlatformFile(),
rockot502c94f2016-02-03 20:20:16591 true);
morrita96693852014-09-24 20:11:45592 return true;
[email protected]7a4de7a62010-08-17 18:38:24593}
594
595void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57596 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24597 if (p.auto_close) {
[email protected]7d3cbc92013-03-18 22:33:04598 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24599 } else {
[email protected]7d3cbc92013-03-18 22:33:04600 l->append(base::StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24601 }
602}
Sergey Ulanovac89bb92019-03-22 18:46:49603
604void ParamTraits<base::ScopedFD>::Write(base::Pickle* m, const param_type& p) {
605 // This serialization must be kept in sync with
606 // nacl_message_scanner.cc:WriteHandle().
607 const bool valid = p.is_valid();
608 WriteParam(m, valid);
609
610 if (!valid)
611 return;
612
613 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
614 std::move(const_cast<param_type&>(p))))) {
615 NOTREACHED();
616 }
617}
618
619bool ParamTraits<base::ScopedFD>::Read(const base::Pickle* m,
620 base::PickleIterator* iter,
621 param_type* r) {
622 r->reset();
623
624 bool valid;
625 if (!ReadParam(m, iter, &valid))
626 return false;
627
628 if (!valid)
629 return true;
630
631 scoped_refptr<base::Pickle::Attachment> attachment;
632 if (!m->ReadAttachment(iter, &attachment))
633 return false;
634
635 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
636 MessageAttachment::Type::PLATFORM_FILE) {
637 return false;
638 }
639
640 *r = base::ScopedFD(
641 static_cast<internal::PlatformFileAttachment*>(attachment.get())
642 ->TakePlatformFile());
643 return true;
644}
645
646void ParamTraits<base::ScopedFD>::Log(const param_type& p, std::string* l) {
647 l->append(base::StringPrintf("ScopedFD(%d)", p.get()));
648}
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09649#endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]7a4de7a62010-08-17 18:38:24650
Robert Sesek02910662020-02-28 20:15:51651#if defined(OS_WIN)
652void ParamTraits<base::win::ScopedHandle>::Write(base::Pickle* m,
653 const param_type& p) {
654 const bool valid = p.IsValid();
655 WriteParam(m, valid);
656 if (!valid)
657 return;
658
659 HandleWin handle(p.Get());
660 WriteParam(m, handle);
661}
662
663bool ParamTraits<base::win::ScopedHandle>::Read(const base::Pickle* m,
664 base::PickleIterator* iter,
665 param_type* r) {
666 r->Close();
667
668 bool valid;
669 if (!ReadParam(m, iter, &valid))
670 return false;
671 if (!valid)
672 return true;
673
674 HandleWin handle;
675 if (!ReadParam(m, iter, &handle))
676 return false;
677
678 r->Set(handle.get_handle());
679 return true;
680}
681
682void ParamTraits<base::win::ScopedHandle>::Log(const param_type& p,
683 std::string* l) {
684 l->append(base::StringPrintf("ScopedHandle(%p)", p.Get()));
685}
686#endif // defined(OS_WIN)
687
Sergey Ulanova97f3282019-04-17 01:27:34688#if defined(OS_FUCHSIA)
689void ParamTraits<zx::vmo>::Write(base::Pickle* m, const param_type& p) {
690 // This serialization must be kept in sync with
691 // nacl_message_scanner.cc:WriteHandle().
692 const bool valid = p.is_valid();
693 WriteParam(m, valid);
694
695 if (!valid)
696 return;
697
698 if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
Sergey Ulanov04367c72019-06-21 15:51:43699 std::move(const_cast<param_type&>(p))))) {
Sergey Ulanova97f3282019-04-17 01:27:34700 NOTREACHED();
701 }
702}
703
704bool ParamTraits<zx::vmo>::Read(const base::Pickle* m,
705 base::PickleIterator* iter,
706 param_type* r) {
707 r->reset();
708
709 bool valid;
710 if (!ReadParam(m, iter, &valid))
711 return false;
712
713 if (!valid)
714 return true;
715
716 scoped_refptr<base::Pickle::Attachment> attachment;
717 if (!m->ReadAttachment(iter, &attachment))
718 return false;
719
720 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
721 MessageAttachment::Type::FUCHSIA_HANDLE) {
722 return false;
723 }
724
725 *r = zx::vmo(static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
726 ->Take());
727 return true;
728}
729
730void ParamTraits<zx::vmo>::Log(const param_type& p, std::string* l) {
731 l->append("ZirconVMO");
732}
Sergey Ulanov7b343ff2019-08-15 07:52:37733
734void ParamTraits<zx::channel>::Write(base::Pickle* m, const param_type& p) {
735 // This serialization must be kept in sync with
736 // nacl_message_scanner.cc:WriteHandle().
737 const bool valid = p.is_valid();
738 WriteParam(m, valid);
739
740 if (!valid)
741 return;
742
743 if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
744 std::move(const_cast<param_type&>(p))))) {
745 NOTREACHED();
746 }
747}
748
749bool ParamTraits<zx::channel>::Read(const base::Pickle* m,
750 base::PickleIterator* iter,
751 param_type* r) {
752 r->reset();
753
754 bool valid;
755 if (!ReadParam(m, iter, &valid))
756 return false;
757
758 if (!valid)
759 return true;
760
761 scoped_refptr<base::Pickle::Attachment> attachment;
762 if (!m->ReadAttachment(iter, &attachment))
763 return false;
764
765 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
766 MessageAttachment::Type::FUCHSIA_HANDLE) {
767 return false;
768 }
769
770 *r = zx::channel(
771 static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
772 ->Take());
773 return true;
774}
775
776void ParamTraits<zx::channel>::Log(const param_type& p, std::string* l) {
777 l->append("ZirconChannel");
778}
Sergey Ulanova97f3282019-04-17 01:27:34779#endif // defined(OS_FUCHSIA)
780
Klaus Weidner3824a8882017-11-03 06:24:57781#if defined(OS_ANDROID)
Alexandr Ilin0443a8f2018-07-20 20:14:50782void ParamTraits<base::android::ScopedHardwareBufferHandle>::Write(
783 base::Pickle* m,
784 const param_type& p) {
785 const bool is_valid = p.is_valid();
Ken Rockot097248f02018-04-23 16:23:34786 WriteParam(m, is_valid);
787 if (!is_valid)
788 return;
789
Ken Rockot097248f02018-04-23 16:23:34790 // We must keep a ref to the AHardwareBuffer alive until the receiver has
791 // acquired its own reference. We do this by sending a message pipe handle
792 // along with the buffer. When the receiver deserializes (or even if they
793 // die without ever reading the message) their end of the pipe will be
794 // closed. We will eventually detect this and release the AHB reference.
795 mojo::MessagePipe tracking_pipe;
796 m->WriteAttachment(new internal::MojoHandleAttachment(
797 mojo::ScopedHandle::From(std::move(tracking_pipe.handle0))));
Alexandr Ilin0443a8f2018-07-20 20:14:50798 WriteParam(m, base::FileDescriptor(p.SerializeAsFileDescriptor().release(),
799 true /* auto_close */));
Ken Rockot097248f02018-04-23 16:23:34800
801 // Pass ownership of the input handle to our tracking pipe to keep the AHB
802 // alive long enough to be deserialized by the receiver.
Alexandr Ilin0443a8f2018-07-20 20:14:50803 mojo::ScopeToMessagePipe(std::move(const_cast<param_type&>(p)),
804 std::move(tracking_pipe.handle1));
Klaus Weidner3824a8882017-11-03 06:24:57805}
806
Alexandr Ilin0443a8f2018-07-20 20:14:50807bool ParamTraits<base::android::ScopedHardwareBufferHandle>::Read(
808 const base::Pickle* m,
809 base::PickleIterator* iter,
810 param_type* r) {
811 *r = base::android::ScopedHardwareBufferHandle();
Ken Rockot097248f02018-04-23 16:23:34812
813 bool is_valid;
814 if (!ReadParam(m, iter, &is_valid))
Klaus Weidner3824a8882017-11-03 06:24:57815 return false;
Ken Rockot097248f02018-04-23 16:23:34816 if (!is_valid)
817 return true;
818
819 scoped_refptr<base::Pickle::Attachment> tracking_pipe_attachment;
820 if (!m->ReadAttachment(iter, &tracking_pipe_attachment))
Klaus Weidner3824a8882017-11-03 06:24:57821 return false;
Ken Rockot097248f02018-04-23 16:23:34822
823 // We keep this alive until the AHB is safely deserialized below. When this
824 // goes out of scope, the sender holding the other end of this pipe will treat
825 // this handle closure as a signal that it's safe to release their AHB
826 // keepalive ref.
827 mojo::ScopedHandle tracking_pipe =
828 static_cast<MessageAttachment*>(tracking_pipe_attachment.get())
829 ->TakeMojoHandle();
830
831 base::FileDescriptor descriptor;
832 if (!ReadParam(m, iter, &descriptor))
833 return false;
834
835 // NOTE: It is valid to deserialize an invalid FileDescriptor, so the success
836 // of |ReadParam()| above does not imply that |descriptor| is valid.
837 base::ScopedFD scoped_fd(descriptor.fd);
838 if (!scoped_fd.is_valid())
839 return false;
840
841 *r = base::android::ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(
Alexandr Ilin0443a8f2018-07-20 20:14:50842 std::move(scoped_fd));
Klaus Weidner3824a8882017-11-03 06:24:57843 return true;
844}
845
Alexandr Ilin0443a8f2018-07-20 20:14:50846void ParamTraits<base::android::ScopedHardwareBufferHandle>::Log(
847 const param_type& p,
848 std::string* l) {
849 l->append(base::StringPrintf("base::android::ScopedHardwareBufferHandle(%p)",
850 p.get()));
Klaus Weidner3824a8882017-11-03 06:24:57851}
Ken Rockot097248f02018-04-23 16:23:34852#endif // defined(OS_ANDROID)
Klaus Weidner3824a8882017-11-03 06:24:57853
Alexandr Ilind497eee2018-04-19 22:50:54854void ParamTraits<base::ReadOnlySharedMemoryRegion>::Write(base::Pickle* m,
855 const param_type& p) {
856 base::subtle::PlatformSharedMemoryRegion handle =
857 base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
858 std::move(const_cast<param_type&>(p)));
859 WriteParam(m, std::move(handle));
860}
861
862bool ParamTraits<base::ReadOnlySharedMemoryRegion>::Read(
863 const base::Pickle* m,
864 base::PickleIterator* iter,
865 param_type* r) {
866 base::subtle::PlatformSharedMemoryRegion handle;
867 if (!ReadParam(m, iter, &handle))
868 return false;
869
870 *r = base::ReadOnlySharedMemoryRegion::Deserialize(std::move(handle));
871 return true;
872}
873
874void ParamTraits<base::ReadOnlySharedMemoryRegion>::Log(const param_type& p,
875 std::string* l) {
876 *l = "<base::ReadOnlySharedMemoryRegion>";
877 // TODO(alexilin): currently there is no way to access underlying handle
878 // without destructing a ReadOnlySharedMemoryRegion instance.
879}
880
881void ParamTraits<base::WritableSharedMemoryRegion>::Write(base::Pickle* m,
882 const param_type& p) {
883 base::subtle::PlatformSharedMemoryRegion handle =
884 base::WritableSharedMemoryRegion::TakeHandleForSerialization(
885 std::move(const_cast<param_type&>(p)));
886 WriteParam(m, std::move(handle));
887}
888
889bool ParamTraits<base::WritableSharedMemoryRegion>::Read(
890 const base::Pickle* m,
891 base::PickleIterator* iter,
892 param_type* r) {
893 base::subtle::PlatformSharedMemoryRegion handle;
894 if (!ReadParam(m, iter, &handle))
895 return false;
896
897 *r = base::WritableSharedMemoryRegion::Deserialize(std::move(handle));
898 return true;
899}
900
901void ParamTraits<base::WritableSharedMemoryRegion>::Log(const param_type& p,
902 std::string* l) {
903 *l = "<base::WritableSharedMemoryRegion>";
904 // TODO(alexilin): currently there is no way to access underlying handle
905 // without destructing a ReadOnlySharedMemoryRegion instance.
906}
907
908void ParamTraits<base::UnsafeSharedMemoryRegion>::Write(base::Pickle* m,
909 const param_type& p) {
910 base::subtle::PlatformSharedMemoryRegion handle =
911 base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
912 std::move(const_cast<param_type&>(p)));
913 WriteParam(m, std::move(handle));
914}
915
916bool ParamTraits<base::UnsafeSharedMemoryRegion>::Read(
917 const base::Pickle* m,
918 base::PickleIterator* iter,
919 param_type* r) {
920 base::subtle::PlatformSharedMemoryRegion handle;
921 if (!ReadParam(m, iter, &handle))
922 return false;
923
924 *r = base::UnsafeSharedMemoryRegion::Deserialize(std::move(handle));
925 return true;
926}
927
928void ParamTraits<base::UnsafeSharedMemoryRegion>::Log(const param_type& p,
929 std::string* l) {
930 *l = "<base::UnsafeSharedMemoryRegion>";
931 // TODO(alexilin): currently there is no way to access underlying handle
932 // without destructing a ReadOnlySharedMemoryRegion instance.
933}
934
935void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Write(
936 base::Pickle* m,
937 const param_type& p) {
Alexandr Ilinebab9da2018-06-01 02:37:47938 // This serialization must be kept in sync with
939 // nacl_message_scanner.cc::WriteHandle().
Alexandr Ilind497eee2018-04-19 22:50:54940 const bool valid = p.IsValid();
941 WriteParam(m, valid);
942
943 if (!valid)
944 return;
945
946 WriteParam(m, p.GetMode());
947 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
948 WriteParam(m, p.GetGUID());
949
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09950#if defined(OS_WIN)
951 base::win::ScopedHandle h = const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54952 HandleWin handle_win(h.Get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09953 WriteParam(m, handle_win);
Alexandr Ilind497eee2018-04-19 22:50:54954#elif defined(OS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:43955 zx::vmo vmo = const_cast<param_type&>(p).PassPlatformHandle();
956 WriteParam(m, vmo);
Avi Drissman2b97d032020-07-30 03:02:26957#elif defined(OS_MAC)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09958 base::mac::ScopedMachSendRight h =
959 const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54960 MachPortMac mach_port_mac(h.get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09961 WriteParam(m, mach_port_mac);
Alexandr Ilind497eee2018-04-19 22:50:54962#elif defined(OS_ANDROID)
963 m->WriteAttachment(new internal::PlatformFileAttachment(
964 base::ScopedFD(const_cast<param_type&>(p).PassPlatformHandle())));
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09965#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:54966 base::subtle::ScopedFDPair h =
967 const_cast<param_type&>(p).PassPlatformHandle();
968 m->WriteAttachment(new internal::PlatformFileAttachment(std::move(h.fd)));
969 if (p.GetMode() ==
970 base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
971 m->WriteAttachment(
972 new internal::PlatformFileAttachment(std::move(h.readonly_fd)));
973 }
974#endif
975}
976
977bool ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Read(
978 const base::Pickle* m,
979 base::PickleIterator* iter,
980 param_type* r) {
981 bool valid;
982 if (!ReadParam(m, iter, &valid))
983 return false;
984 if (!valid) {
985 *r = base::subtle::PlatformSharedMemoryRegion();
986 return true;
987 }
988
989 base::subtle::PlatformSharedMemoryRegion::Mode mode;
990 uint64_t shm_size;
991 base::UnguessableToken guid;
992 if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &shm_size) ||
993 !base::IsValueInRangeForNumericType<size_t>(shm_size) ||
994 !ReadParam(m, iter, &guid)) {
995 return false;
996 }
997 size_t size = static_cast<size_t>(shm_size);
998
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09999#if defined(OS_WIN)
1000 HandleWin handle_win;
1001 if (!ReadParam(m, iter, &handle_win))
Alexandr Ilind497eee2018-04-19 22:50:541002 return false;
1003 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091004 base::win::ScopedHandle(handle_win.get_handle()), mode, size, guid);
Alexandr Ilind497eee2018-04-19 22:50:541005#elif defined(OS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:431006 zx::vmo vmo;
1007 if (!ReadParam(m, iter, &vmo))
Alexandr Ilind497eee2018-04-19 22:50:541008 return false;
Sergey Ulanov04367c72019-06-21 15:51:431009 *r = base::subtle::PlatformSharedMemoryRegion::Take(std::move(vmo), mode,
1010 size, guid);
Avi Drissman2b97d032020-07-30 03:02:261011#elif defined(OS_MAC)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091012 MachPortMac mach_port_mac;
1013 if (!ReadParam(m, iter, &mach_port_mac))
Alexandr Ilind497eee2018-04-19 22:50:541014 return false;
1015 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091016 base::mac::ScopedMachSendRight(mach_port_mac.get_mach_port()), mode, size,
1017 guid);
1018#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541019 scoped_refptr<base::Pickle::Attachment> attachment;
1020 if (!m->ReadAttachment(iter, &attachment))
1021 return false;
1022 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
1023 MessageAttachment::Type::PLATFORM_FILE) {
1024 return false;
1025 }
1026
1027#if defined(OS_ANDROID)
1028 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1029 base::ScopedFD(
1030 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1031 ->TakePlatformFile()),
1032 mode, size, guid);
1033#else
1034 scoped_refptr<base::Pickle::Attachment> readonly_attachment;
1035 if (mode == base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
1036 if (!m->ReadAttachment(iter, &readonly_attachment))
1037 return false;
1038
1039 if (static_cast<MessageAttachment*>(readonly_attachment.get())->GetType() !=
1040 MessageAttachment::Type::PLATFORM_FILE) {
1041 return false;
1042 }
1043 }
1044 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1045 base::subtle::ScopedFDPair(
1046 base::ScopedFD(
1047 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1048 ->TakePlatformFile()),
1049 readonly_attachment
1050 ? base::ScopedFD(static_cast<internal::PlatformFileAttachment*>(
1051 readonly_attachment.get())
1052 ->TakePlatformFile())
1053 : base::ScopedFD()),
1054 mode, size, guid);
1055#endif // defined(OS_ANDROID)
1056
1057#endif
1058
1059 return true;
1060}
1061
1062void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Log(
1063 const param_type& p,
1064 std::string* l) {
Wezb908e432018-09-05 17:35:221065#if defined(OS_FUCHSIA)
1066 l->append("Handle: ");
1067 LogParam(p.GetPlatformHandle()->get(), l);
1068#elif defined(OS_WIN)
Alexandr Ilind497eee2018-04-19 22:50:541069 l->append("Handle: ");
1070 LogParam(p.GetPlatformHandle(), l);
Avi Drissman2b97d032020-07-30 03:02:261071#elif defined(OS_MAC)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091072 l->append("Mach port: ");
1073 LogParam(p.GetPlatformHandle(), l);
Alexandr Ilind497eee2018-04-19 22:50:541074#elif defined(OS_ANDROID)
1075 l->append("FD: ");
1076 LogParam(p.GetPlatformHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091077#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541078 base::subtle::FDPair h = p.GetPlatformHandle();
1079 l->append("FD: ");
1080 LogParam(h.fd, l);
1081 l->append("Read-only FD: ");
1082 LogParam(h.readonly_fd, l);
1083#endif
1084
1085 l->append("Mode: ");
1086 LogParam(p.GetMode(), l);
1087 l->append("size: ");
1088 LogParam(static_cast<uint64_t>(p.GetSize()), l);
1089 l->append("GUID: ");
1090 LogParam(p.GetGUID(), l);
1091}
1092
1093void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Write(
1094 base::Pickle* m,
1095 const param_type& value) {
1096 DCHECK(static_cast<int>(value) >= 0 &&
1097 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue));
1098 m->WriteInt(static_cast<int>(value));
1099}
1100
1101bool ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Read(
1102 const base::Pickle* m,
1103 base::PickleIterator* iter,
1104 param_type* p) {
1105 int value;
1106 if (!iter->ReadInt(&value))
1107 return false;
1108 if (!(static_cast<int>(value) >= 0 &&
1109 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue))) {
1110 return false;
1111 }
1112 *p = static_cast<param_type>(value);
1113 return true;
1114}
1115
1116void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Log(
1117 const param_type& p,
1118 std::string* l) {
1119 LogParam(static_cast<int>(p), l);
1120}
1121
erikchend804e1052017-04-29 02:24:361122#if defined(OS_WIN)
erikchend804e1052017-04-29 02:24:361123void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
1124 const param_type& p) {
1125 m->WriteBool(p.IsValid());
1126 if (p.IsValid()) {
Wez51eaaad2017-08-09 05:51:381127 HandleWin handle_win(p.GetHandle());
erikchend804e1052017-04-29 02:24:361128 ParamTraits<HandleWin>::Write(m, handle_win);
1129 ::CloseHandle(p.GetHandle());
1130 }
1131}
1132
1133bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
1134 base::PickleIterator* iter,
1135 param_type* r) {
1136 bool is_valid;
1137 if (!iter->ReadBool(&is_valid))
1138 return false;
1139 if (!is_valid) {
1140 *r = PlatformFileForTransit();
1141 return true;
1142 }
1143
1144 HandleWin handle_win;
1145 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
1146 return false;
1147 *r = PlatformFileForTransit(handle_win.get_handle());
1148 return true;
1149}
1150
1151void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
1152 std::string* l) {
1153 LogParam(p.GetHandle(), l);
1154}
1155#endif // defined(OS_WIN)
1156
rockot502c94f2016-02-03 20:20:161157void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:551158 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:251159}
1160
rockot502c94f2016-02-03 20:20:161161bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251162 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:301163 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:551164 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:251165}
1166
[email protected]6d4b67a2013-02-10 04:49:301167void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
1168 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:251169}
1170
rockot502c94f2016-02-03 20:20:161171void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251172 WriteValue(m, &p, 0);
1173}
1174
rockot502c94f2016-02-03 20:20:161175bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251176 base::PickleIterator* iter,
1177 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:251178 int type;
jdoerriedc72ee942016-12-07 15:43:281179 if (!ReadParam(m, iter, &type) ||
1180 type != static_cast<int>(base::Value::Type::LIST))
[email protected]bf5aedf02012-06-04 21:18:251181 return false;
1182
1183 return ReadListValue(m, iter, r, 0);
1184}
1185
[email protected]ea5ef4c2013-06-13 22:50:271186void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251187 std::string json;
estade8d046462015-05-16 01:02:341188 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:251189 l->append(json);
1190}
1191
Devlin Cronin7178a5bd2021-02-02 02:56:471192void ParamTraits<base::Value>::Write(base::Pickle* m, const param_type& p) {
1193 WriteValue(m, &p, 0);
1194}
1195
1196bool ParamTraits<base::Value>::Read(const base::Pickle* m,
1197 base::PickleIterator* iter,
1198 param_type* r) {
1199 return ReadValue(m, iter, r, 0);
1200}
1201
1202void ParamTraits<base::Value>::Log(const param_type& p, std::string* l) {
1203 std::string json;
1204 base::JSONWriter::Write(p, &json);
1205 l->append(json);
1206}
1207
rockot502c94f2016-02-03 20:20:161208void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
[email protected]0238a162013-06-13 13:47:461209 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251210 WriteParam(m, p.string());
1211 WriteParam(m, p.is_null());
1212}
1213
rockot502c94f2016-02-03 20:20:161214bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251215 base::PickleIterator* iter,
[email protected]0238a162013-06-13 13:47:461216 param_type* r) {
[email protected]476dafb2013-12-03 00:39:261217 base::string16 string;
[email protected]bf5aedf02012-06-04 21:18:251218 if (!ReadParam(m, iter, &string))
1219 return false;
1220 bool is_null;
1221 if (!ReadParam(m, iter, &is_null))
1222 return false;
[email protected]0238a162013-06-13 13:47:461223 *r = base::NullableString16(string, is_null);
[email protected]bf5aedf02012-06-04 21:18:251224 return true;
1225}
1226
[email protected]0238a162013-06-13 13:47:461227void ParamTraits<base::NullableString16>::Log(const param_type& p,
1228 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251229 l->append("(");
1230 LogParam(p.string(), l);
1231 l->append(", ");
1232 LogParam(p.is_null(), l);
1233 l->append(")");
1234}
1235
rockot502c94f2016-02-03 20:20:161236void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:001237 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251238 WriteParam(m, p.size);
1239 WriteParam(m, p.is_directory);
1240 WriteParam(m, p.last_modified.ToDoubleT());
1241 WriteParam(m, p.last_accessed.ToDoubleT());
1242 WriteParam(m, p.creation_time.ToDoubleT());
1243}
1244
rockot502c94f2016-02-03 20:20:161245bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251246 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:001247 param_type* p) {
[email protected]481c3e82014-07-18 01:40:471248 double last_modified, last_accessed, creation_time;
1249 if (!ReadParam(m, iter, &p->size) ||
1250 !ReadParam(m, iter, &p->is_directory) ||
1251 !ReadParam(m, iter, &last_modified) ||
1252 !ReadParam(m, iter, &last_accessed) ||
1253 !ReadParam(m, iter, &creation_time))
1254 return false;
1255 p->last_modified = base::Time::FromDoubleT(last_modified);
1256 p->last_accessed = base::Time::FromDoubleT(last_accessed);
1257 p->creation_time = base::Time::FromDoubleT(creation_time);
1258 return true;
[email protected]bf5aedf02012-06-04 21:18:251259}
1260
[email protected]141bcc52014-01-27 21:36:001261void ParamTraits<base::File::Info>::Log(const param_type& p,
1262 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251263 l->append("(");
1264 LogParam(p.size, l);
1265 l->append(",");
1266 LogParam(p.is_directory, l);
1267 l->append(",");
1268 LogParam(p.last_modified.ToDoubleT(), l);
1269 l->append(",");
1270 LogParam(p.last_accessed.ToDoubleT(), l);
1271 l->append(",");
1272 LogParam(p.creation_time.ToDoubleT(), l);
1273 l->append(")");
1274}
1275
rockot502c94f2016-02-03 20:20:161276void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571277 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251278}
1279
rockot502c94f2016-02-03 20:20:161280bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251281 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251282 param_type* r) {
tfarina10a5c062015-09-04 18:47:571283 int64_t value;
1284 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:251285 return false;
1286 *r = base::Time::FromInternalValue(value);
1287 return true;
1288}
1289
1290void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571291 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251292}
1293
rockot502c94f2016-02-03 20:20:161294void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571295 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251296}
1297
rockot502c94f2016-02-03 20:20:161298bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251299 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251300 param_type* r) {
tfarina10a5c062015-09-04 18:47:571301 int64_t value;
1302 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251303 if (ret)
1304 *r = base::TimeDelta::FromInternalValue(value);
1305
1306 return ret;
1307}
1308
1309void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571310 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251311}
1312
rockot502c94f2016-02-03 20:20:161313void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571314 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251315}
1316
rockot502c94f2016-02-03 20:20:161317bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251318 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251319 param_type* r) {
tfarina10a5c062015-09-04 18:47:571320 int64_t value;
1321 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251322 if (ret)
1323 *r = base::TimeTicks::FromInternalValue(value);
1324
1325 return ret;
1326}
1327
1328void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571329 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251330}
1331
tguilbert4a5ac602016-09-19 21:11:251332// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1333// below should be updated.
1334static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1335 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1336
tguilbert4a5ac602016-09-19 21:11:251337void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1338 const param_type& p) {
1339 DCHECK(!p.is_empty());
1340
1341 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1342 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1343}
1344
1345bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1346 base::PickleIterator* iter,
1347 param_type* r) {
1348 uint64_t high, low;
1349 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1350 !ParamTraits<uint64_t>::Read(m, iter, &low))
1351 return false;
1352
1353 // Receiving a zeroed UnguessableToken is a security issue.
1354 if (high == 0 && low == 0)
1355 return false;
1356
1357 *r = base::UnguessableToken::Deserialize(high, low);
1358 return true;
1359}
1360
1361void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1362 std::string* l) {
1363 l->append(p.ToString());
1364}
1365
rockot502c94f2016-02-03 20:20:161366void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1367 const param_type& p) {
sammc9bf370c2016-11-14 03:29:081368#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241369 WriteParam(m, p.socket);
sammc9bf370c2016-11-14 03:29:081370#else
amistry36182522016-06-27 06:34:421371 WriteParam(m, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:081372#endif
[email protected]7a4de7a62010-08-17 18:38:241373}
1374
rockot502c94f2016-02-03 20:20:161375bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251376 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:241377 param_type* r) {
sammc9bf370c2016-11-14 03:29:081378#if defined(OS_NACL_SFI)
1379 return ReadParam(m, iter, &r->socket);
1380#else
1381 return ReadParam(m, iter, &r->mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241382#endif
[email protected]7a4de7a62010-08-17 18:38:241383}
1384
1385void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571386 std::string* l) {
sammc9bf370c2016-11-14 03:29:081387 l->append("ChannelHandle(");
1388#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241389 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
sammc9bf370c2016-11-14 03:29:081390#else
amistry36182522016-06-27 06:34:421391 LogParam(p.mojo_handle, l);
sammc9bf370c2016-11-14 03:29:081392#endif
[email protected]252cad62010-08-18 18:33:571393 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241394}
1395
rockot502c94f2016-02-03 20:20:161396void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301397 WriteParam(m, p.channel);
1398 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271399 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301400 WriteParam(m, p.flags);
1401 WriteParam(m, p.sent);
1402 WriteParam(m, p.receive);
1403 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451404 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301405 WriteParam(m, p.params);
1406}
1407
rockot502c94f2016-02-03 20:20:161408bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251409 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561410 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271411 return
[email protected]20f0487a2010-09-30 20:06:301412 ReadParam(m, iter, &r->channel) &&
1413 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271414 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301415 ReadParam(m, iter, &r->flags) &&
1416 ReadParam(m, iter, &r->sent) &&
1417 ReadParam(m, iter, &r->receive) &&
1418 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451419 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301420 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301421}
1422
[email protected]bf5aedf02012-06-04 21:18:251423void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1424 // Doesn't make sense to implement this!
1425}
1426
rockot502c94f2016-02-03 20:20:161427void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091428#if defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]34d48612012-06-29 00:05:041429 // We don't serialize the file descriptors in the nested message, so there
1430 // better not be any.
morrita1aa788c2015-01-31 05:45:421431 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041432#endif
1433
1434 // Don't just write out the message. This is used to send messages between
1435 // NaCl (Posix environment) and the browser (could be on Windows). The message
1436 // header formats differ between these systems (so does handle sharing, but
1437 // we already asserted we don't have any handles). So just write out the
1438 // parts of the header we use.
1439 //
1440 // Be careful also to use only explicitly-sized types. The NaCl environment
1441 // could be 64-bit and the host browser could be 32-bits. The nested message
1442 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1443 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:571444 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041445 m->WriteUInt32(p.type());
1446 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:571447 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:251448}
1449
rockot502c94f2016-02-03 20:20:161450bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251451 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251452 Message* r) {
tfarina10a5c062015-09-04 18:47:571453 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481454 if (!iter->ReadUInt32(&routing_id) ||
1455 !iter->ReadUInt32(&type) ||
1456 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251457 return false;
[email protected]34d48612012-06-29 00:05:041458
1459 int payload_size;
1460 const char* payload;
avi48fc13b2014-12-28 23:31:481461 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251462 return false;
[email protected]34d48612012-06-29 00:05:041463
tfarina10a5c062015-09-04 18:47:571464 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
Daniel Cheng0d89f9222017-09-22 05:05:071465 r->WriteBytes(payload, payload_size);
1466 return true;
[email protected]bf5aedf02012-06-04 21:18:251467}
1468
1469void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1470 l->append("<IPC::Message>");
1471}
1472
1473#if defined(OS_WIN)
1474// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031475// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161476void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031477 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251478}
1479
rockot502c94f2016-02-03 20:20:161480bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251481 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251482 param_type* r) {
tfarina10a5c062015-09-04 18:47:571483 int32_t temp;
avi48fc13b2014-12-28 23:31:481484 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251485 return false;
[email protected]4a635b72013-03-04 02:29:031486 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251487 return true;
1488}
1489
1490void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001491 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251492}
1493
rockot502c94f2016-02-03 20:20:161494void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251495 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1496}
1497
rockot502c94f2016-02-03 20:20:161498bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251499 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251500 param_type* r) {
1501 const char *data;
1502 int data_size = 0;
avi48fc13b2014-12-28 23:31:481503 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251504 if (result && data_size == sizeof(MSG)) {
1505 memcpy(r, data, sizeof(MSG));
1506 } else {
1507 result = false;
1508 NOTREACHED();
1509 }
1510
1511 return result;
1512}
1513
1514void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1515 l->append("<MSG>");
1516}
1517
1518#endif // OS_WIN
1519
[email protected]946d1b22009-07-22 23:57:211520} // namespace IPC