blob: 07a9405034f7f951c355724a89613d63f60316b8 [file] [log] [blame]
[email protected]a7c03d4f32012-01-24 02:36:051// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]946d1b22009-07-22 23:57:212// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ipc/ipc_message_utils.h"
6
avi246998d82015-12-22 02:39:047#include <stddef.h>
8#include <stdint.h>
9
[email protected]57999812013-02-24 05:40:5210#include "base/files/file_path.h"
[email protected]93d49d72009-10-23 20:00:2011#include "base/json/json_writer.h"
Hans Wennborg24397592020-06-17 16:58:5012#include "base/logging.h"
jdoerrief1e72e32017-04-26 16:23:5513#include "base/memory/ptr_util.h"
[email protected]0238a162013-06-13 13:47:4614#include "base/strings/nullable_string16.h"
[email protected]4aa794a12013-06-11 06:32:1815#include "base/strings/string_number_conversions.h"
[email protected]906265872013-06-07 22:40:4516#include "base/strings/utf_string_conversions.h"
[email protected]b43e5562013-06-28 15:20:0217#include "base/time/time.h"
tguilbert4a5ac602016-09-19 21:11:2518#include "base/unguessable_token.h"
[email protected]946d1b22009-07-22 23:57:2119#include "base/values.h"
avi246998d82015-12-22 02:39:0420#include "build/build_config.h"
[email protected]bf5aedf02012-06-04 21:18:2521#include "ipc/ipc_channel_handle.h"
morrita1aa788c2015-01-31 05:45:4222#include "ipc/ipc_message_attachment.h"
morrita4b5c28e22015-01-14 21:17:0623#include "ipc/ipc_message_attachment_set.h"
amistry36182522016-06-27 06:34:4224#include "ipc/ipc_mojo_param_traits.h"
[email protected]bf5aedf02012-06-04 21:18:2525
Avi Drissman2b97d032020-07-30 03:02:2626#if defined(OS_MAC)
erikchenaf8299d2015-10-09 19:12:0627#include "ipc/mach_port_mac.h"
28#endif
29
morrita4b5c28e22015-01-14 21:17:0630#if defined(OS_WIN)
[email protected]2e02cfe82012-11-21 00:58:0031#include <tchar.h>
erikchen5ea2ab72015-09-25 22:34:3132#include "ipc/handle_win.h"
erikchend804e1052017-04-29 02:24:3633#include "ipc/ipc_platform_file.h"
Fabrice de Gans-Ribericbce4342018-05-07 20:02:0934#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
35#include "base/file_descriptor_posix.h"
36#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]7a4de7a62010-08-17 18:38:2437#endif
[email protected]946d1b22009-07-22 23:57:2138
Scott Graham3eebff02017-06-30 01:07:1039#if defined(OS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:4340#include "base/fuchsia/fuchsia_logging.h"
Sergey Ulanova97f3282019-04-17 01:27:3441#include "ipc/handle_attachment_fuchsia.h"
Scott Graham3eebff02017-06-30 01:07:1042#endif
43
Ken Rockot097248f02018-04-23 16:23:3444#if defined(OS_ANDROID)
45#include "base/android/scoped_hardware_buffer_handle.h"
46#include "ipc/ipc_mojo_handle_attachment.h"
47#include "mojo/public/cpp/system/message_pipe.h"
48#include "mojo/public/cpp/system/scope_to_message_pipe.h"
49#endif
50
[email protected]946d1b22009-07-22 23:57:2151namespace IPC {
52
[email protected]bf5aedf02012-06-04 21:18:2553namespace {
54
joaodasilva383b174a2017-01-10 09:55:3655const int kMaxRecursionDepth = 200;
[email protected]946d1b22009-07-22 23:57:2156
[email protected]bf5aedf02012-06-04 21:18:2557template<typename CharType>
58void LogBytes(const std::vector<CharType>& data, std::string* out) {
59#if defined(OS_WIN)
60 // Windows has a GUI for logging, which can handle arbitrary binary data.
61 for (size_t i = 0; i < data.size(); ++i)
62 out->push_back(data[i]);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:0963#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]bf5aedf02012-06-04 21:18:2564 // On POSIX, we log to stdout, which we assume can display ASCII.
65 static const size_t kMaxBytesToLog = 100;
66 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
67 if (isprint(data[i]))
68 out->push_back(data[i]);
69 else
[email protected]7d3cbc92013-03-18 22:33:0470 out->append(
71 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]bf5aedf02012-06-04 21:18:2572 }
73 if (data.size() > kMaxBytesToLog) {
[email protected]f8660f82013-03-30 17:29:2874 out->append(base::StringPrintf(
75 " and %u more bytes",
76 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
[email protected]bf5aedf02012-06-04 21:18:2577 }
78#endif
79}
[email protected]946d1b22009-07-22 23:57:2180
rockot502c94f2016-02-03 20:20:1681bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:2582 base::PickleIterator* iter,
Jeremy Roman2d8d7802020-06-11 22:08:2083 base::Value* value,
[email protected]bf5aedf02012-06-04 21:18:2584 int recursion);
[email protected]946d1b22009-07-22 23:57:2185
rockot502c94f2016-02-03 20:20:1686void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
[email protected]dbc761a2012-07-26 01:29:2187 bool result;
[email protected]946d1b22009-07-22 23:57:2188 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:3689 LOG(ERROR) << "Max recursion depth hit in WriteValue.";
[email protected]946d1b22009-07-22 23:57:2190 return;
91 }
92
jdoerrie76cee9c2017-10-06 22:42:4293 m->WriteInt(static_cast<int>(value->type()));
[email protected]946d1b22009-07-22 23:57:2194
jdoerrie76cee9c2017-10-06 22:42:4295 switch (value->type()) {
jdoerriedc72ee942016-12-07 15:43:2896 case base::Value::Type::NONE:
jdoerriee1b1f3a2019-03-16 04:08:0197 break;
jdoerriedc72ee942016-12-07 15:43:2898 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:2199 bool val;
[email protected]dbc761a2012-07-26 01:29:21100 result = value->GetAsBoolean(&val);
101 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21102 WriteParam(m, val);
103 break;
104 }
jdoerriedc72ee942016-12-07 15:43:28105 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21106 int val;
[email protected]dbc761a2012-07-26 01:29:21107 result = value->GetAsInteger(&val);
108 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21109 WriteParam(m, val);
110 break;
111 }
jdoerriedc72ee942016-12-07 15:43:28112 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21113 double val;
[email protected]dbc761a2012-07-26 01:29:21114 result = value->GetAsDouble(&val);
115 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21116 WriteParam(m, val);
117 break;
118 }
jdoerriedc72ee942016-12-07 15:43:28119 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21120 std::string val;
[email protected]dbc761a2012-07-26 01:29:21121 result = value->GetAsString(&val);
122 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21123 WriteParam(m, val);
124 break;
125 }
jdoerriedc72ee942016-12-07 15:43:28126 case base::Value::Type::BINARY: {
jdoerrie9970f20e2018-07-20 21:41:18127 m->WriteData(reinterpret_cast<const char*>(value->GetBlob().data()),
Chris Palmerc5ea9b92017-09-25 22:53:22128 base::checked_cast<int>(value->GetBlob().size()));
[email protected]e4dad9fb2009-10-06 18:15:58129 break;
[email protected]946d1b22009-07-22 23:57:21130 }
jdoerriedc72ee942016-12-07 15:43:28131 case base::Value::Type::DICTIONARY: {
[email protected]ea5ef4c2013-06-13 22:50:27132 const base::DictionaryValue* dict =
133 static_cast<const base::DictionaryValue*>(value);
[email protected]946d1b22009-07-22 23:57:21134
Chris Palmerc5ea9b92017-09-25 22:53:22135 WriteParam(m, base::checked_cast<int>(dict->size()));
[email protected]946d1b22009-07-22 23:57:21136
[email protected]ea5ef4c2013-06-13 22:50:27137 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
138 it.Advance()) {
[email protected]a899c0b02013-01-18 14:43:27139 WriteParam(m, it.key());
140 WriteValue(m, &it.value(), recursion + 1);
[email protected]946d1b22009-07-22 23:57:21141 }
142 break;
143 }
jdoerriedc72ee942016-12-07 15:43:28144 case base::Value::Type::LIST: {
[email protected]ea5ef4c2013-06-13 22:50:27145 const base::ListValue* list = static_cast<const base::ListValue*>(value);
Chris Palmerc5ea9b92017-09-25 22:53:22146 WriteParam(m, base::checked_cast<int>(list->GetSize()));
dchengcb60e702016-05-25 18:30:47147 for (const auto& entry : *list) {
jdoerriea5676c62017-04-11 18:09:14148 WriteValue(m, &entry, recursion + 1);
[email protected]946d1b22009-07-22 23:57:21149 }
150 break;
151 }
jdoerriee1b1f3a2019-03-16 04:08:01152
153 // TODO(crbug.com/859477): Remove after root cause is found.
154 default:
155 CHECK(false);
156 break;
[email protected]946d1b22009-07-22 23:57:21157 }
158}
159
160// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
161// object.
rockot502c94f2016-02-03 20:20:16162bool ReadDictionaryValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25163 base::PickleIterator* iter,
164 base::DictionaryValue* value,
165 int recursion) {
[email protected]946d1b22009-07-22 23:57:21166 int size;
167 if (!ReadParam(m, iter, &size))
168 return false;
169
Jan Wilken Dörrief961a372020-11-02 20:30:34170 std::vector<base::Value::LegacyDictStorage::value_type> entries;
Jeremy Roman2d8d7802020-06-11 22:08:20171 entries.resize(size);
172 for (auto& entry : entries) {
173 entry.second = std::make_unique<base::Value>();
174 if (!ReadParam(m, iter, &entry.first) ||
175 !ReadValue(m, iter, entry.second.get(), recursion + 1))
[email protected]946d1b22009-07-22 23:57:21176 return false;
[email protected]946d1b22009-07-22 23:57:21177 }
178
Jan Wilken Dörrief961a372020-11-02 20:30:34179 *value =
180 base::DictionaryValue(base::Value::LegacyDictStorage(std::move(entries)));
[email protected]946d1b22009-07-22 23:57:21181 return true;
182}
183
184// Helper for ReadValue that reads a ReadListValue into a pre-allocated
185// object.
rockot502c94f2016-02-03 20:20:16186bool ReadListValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25187 base::PickleIterator* iter,
188 base::ListValue* value,
189 int recursion) {
[email protected]946d1b22009-07-22 23:57:21190 int size;
191 if (!ReadParam(m, iter, &size))
192 return false;
193
Jeremy Roman2d8d7802020-06-11 22:08:20194 base::Value::ListStorage list_storage;
195 list_storage.resize(size);
196 for (base::Value& subval : list_storage) {
[email protected]946d1b22009-07-22 23:57:21197 if (!ReadValue(m, iter, &subval, recursion + 1))
198 return false;
[email protected]946d1b22009-07-22 23:57:21199 }
Jeremy Roman2d8d7802020-06-11 22:08:20200 *value = base::ListValue(std::move(list_storage));
[email protected]946d1b22009-07-22 23:57:21201 return true;
202}
203
rockot502c94f2016-02-03 20:20:16204bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25205 base::PickleIterator* iter,
Jeremy Roman2d8d7802020-06-11 22:08:20206 base::Value* value,
[email protected]bf5aedf02012-06-04 21:18:25207 int recursion) {
[email protected]946d1b22009-07-22 23:57:21208 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:36209 LOG(ERROR) << "Max recursion depth hit in ReadValue.";
[email protected]946d1b22009-07-22 23:57:21210 return false;
211 }
212
213 int type;
214 if (!ReadParam(m, iter, &type))
215 return false;
216
jdoerriedc72ee942016-12-07 15:43:28217 switch (static_cast<base::Value::Type>(type)) {
218 case base::Value::Type::NONE:
Jeremy Roman2d8d7802020-06-11 22:08:20219 *value = base::Value();
jdoerriee067999a2017-04-07 06:39:00220 break;
jdoerriedc72ee942016-12-07 15:43:28221 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21222 bool val;
223 if (!ReadParam(m, iter, &val))
224 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20225 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21226 break;
227 }
jdoerriedc72ee942016-12-07 15:43:28228 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21229 int val;
230 if (!ReadParam(m, iter, &val))
231 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20232 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21233 break;
234 }
jdoerriedc72ee942016-12-07 15:43:28235 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21236 double val;
237 if (!ReadParam(m, iter, &val))
238 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20239 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21240 break;
241 }
jdoerriedc72ee942016-12-07 15:43:28242 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21243 std::string val;
244 if (!ReadParam(m, iter, &val))
245 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20246 *value = base::Value(std::move(val));
[email protected]946d1b22009-07-22 23:57:21247 break;
248 }
jdoerriedc72ee942016-12-07 15:43:28249 case base::Value::Type::BINARY: {
Jeremy Roman2d8d7802020-06-11 22:08:20250 base::span<const uint8_t> data;
251 if (!iter->ReadData(&data))
[email protected]e4dad9fb2009-10-06 18:15:58252 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20253 *value = base::Value(data);
[email protected]946d1b22009-07-22 23:57:21254 break;
255 }
jdoerriedc72ee942016-12-07 15:43:28256 case base::Value::Type::DICTIONARY: {
jdoerrief1e72e32017-04-26 16:23:55257 base::DictionaryValue val;
258 if (!ReadDictionaryValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21259 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20260 *value = std::move(val);
[email protected]946d1b22009-07-22 23:57:21261 break;
262 }
jdoerriedc72ee942016-12-07 15:43:28263 case base::Value::Type::LIST: {
jdoerrief1e72e32017-04-26 16:23:55264 base::ListValue val;
265 if (!ReadListValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21266 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20267 *value = std::move(val);
[email protected]946d1b22009-07-22 23:57:21268 break;
269 }
[email protected]e4dad9fb2009-10-06 18:15:58270 default:
Jan Wilken Dörrie271086b42019-06-13 20:03:41271 NOTREACHED();
jdoerriee1b1f3a2019-03-16 04:08:01272 return false;
[email protected]946d1b22009-07-22 23:57:21273 }
274
275 return true;
276}
277
[email protected]bf5aedf02012-06-04 21:18:25278} // namespace
279
280// -----------------------------------------------------------------------------
281
282LogData::LogData()
283 : routing_id(0),
284 type(0),
285 sent(0),
286 receive(0),
287 dispatch(0) {
288}
289
vmpstrbf0d713a2016-03-24 20:22:54290LogData::LogData(const LogData& other) = default;
291
Chris Watkins2d879af2017-11-30 02:11:59292LogData::~LogData() = default;
[email protected]bf5aedf02012-06-04 21:18:25293
[email protected]bf5aedf02012-06-04 21:18:25294void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
295 l->append(p ? "true" : "false");
296}
297
rockot502c94f2016-02-03 20:20:16298void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno19ecf1842015-10-30 00:46:20299 m->WriteBytes(&p, sizeof(param_type));
300}
301
rockot502c94f2016-02-03 20:20:16302bool ParamTraits<signed char>::Read(const base::Pickle* m,
303 base::PickleIterator* iter,
304 param_type* r) {
ortuno19ecf1842015-10-30 00:46:20305 const char* data;
306 if (!iter->ReadBytes(&data, sizeof(param_type)))
307 return false;
308 memcpy(r, data, sizeof(param_type));
309 return true;
310}
311
312void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38313 l->append(base::NumberToString(p));
ortuno19ecf1842015-10-30 00:46:20314}
315
rockot502c94f2016-02-03 20:20:16316void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28317 m->WriteBytes(&p, sizeof(param_type));
318}
319
rockot502c94f2016-02-03 20:20:16320bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25321 base::PickleIterator* iter,
322 param_type* r) {
[email protected]c1ee48d2013-07-12 23:12:28323 const char* data;
avi48fc13b2014-12-28 23:31:48324 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28325 return false;
326 memcpy(r, data, sizeof(param_type));
327 return true;
328}
329
330void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38331 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28332}
333
rockot502c94f2016-02-03 20:20:16334void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28335 m->WriteBytes(&p, sizeof(param_type));
336}
337
rockot502c94f2016-02-03 20:20:16338bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25339 base::PickleIterator* iter,
[email protected]c1ee48d2013-07-12 23:12:28340 param_type* r) {
341 const char* data;
avi48fc13b2014-12-28 23:31:48342 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28343 return false;
344 memcpy(r, data, sizeof(param_type));
345 return true;
346}
347
348void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09349 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28350}
351
[email protected]252cad62010-08-18 18:33:57352void ParamTraits<int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09353 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57354}
355
356void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09357 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57358}
359
Sean McAllister82700412020-08-19 20:10:35360#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
361 defined(OS_FUCHSIA) || (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]252cad62010-08-18 18:33:57362void ParamTraits<long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09363 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57364}
365
366void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09367 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57368}
jam03d8a782016-02-10 20:13:39369#endif
[email protected]252cad62010-08-18 18:33:57370
371void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09372 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57373}
374
375void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09376 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57377}
[email protected]7a4de7a62010-08-17 18:38:24378
[email protected]bf5aedf02012-06-04 21:18:25379void ParamTraits<float>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04380 l->append(base::StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24381}
382
rockot502c94f2016-02-03 20:20:16383void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
[email protected]48328ff2013-10-31 09:27:31384 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52385}
386
rockot502c94f2016-02-03 20:20:16387bool ParamTraits<double>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25388 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25389 param_type* r) {
390 const char *data;
avi48fc13b2014-12-28 23:31:48391 if (!iter->ReadBytes(&data, sizeof(*r))) {
[email protected]bf5aedf02012-06-04 21:18:25392 NOTREACHED();
393 return false;
394 }
395 memcpy(r, data, sizeof(param_type));
396 return true;
[email protected]d84e48b2010-10-21 22:04:52397}
398
[email protected]bf5aedf02012-06-04 21:18:25399void ParamTraits<double>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04400 l->append(base::StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04401}
402
[email protected]bf5aedf02012-06-04 21:18:25403
404void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
405 l->append(p);
[email protected]1d14f582011-09-02 20:42:04406}
407
[email protected]476dafb2013-12-03 00:39:26408void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
[email protected]ad65a3e2013-12-25 18:18:01409 l->append(base::UTF16ToUTF8(p));
[email protected]bf5aedf02012-06-04 21:18:25410}
[email protected]bf5aedf02012-06-04 21:18:25411
rockot502c94f2016-02-03 20:20:16412void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
413 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25414 if (p.empty()) {
415 m->WriteData(NULL, 0);
416 } else {
Chris Palmerc5ea9b92017-09-25 22:53:22417 m->WriteData(&p.front(), base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25418 }
419}
420
rockot502c94f2016-02-03 20:20:16421bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25422 base::PickleIterator* iter,
423 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25424 const char *data;
425 int data_size = 0;
avi48fc13b2014-12-28 23:31:48426 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25427 return false;
428 r->resize(data_size);
429 if (data_size)
430 memcpy(&r->front(), data, data_size);
431 return true;
432}
433
434void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
435 LogBytes(p, l);
436}
437
rockot502c94f2016-02-03 20:20:16438void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
439 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25440 if (p.empty()) {
441 m->WriteData(NULL, 0);
442 } else {
443 m->WriteData(reinterpret_cast<const char*>(&p.front()),
Chris Palmerc5ea9b92017-09-25 22:53:22444 base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25445 }
446}
447
rockot502c94f2016-02-03 20:20:16448bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25449 base::PickleIterator* iter,
450 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25451 const char *data;
452 int data_size = 0;
avi48fc13b2014-12-28 23:31:48453 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25454 return false;
455 r->resize(data_size);
456 if (data_size)
457 memcpy(&r->front(), data, data_size);
458 return true;
459}
460
461void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
462 std::string* l) {
463 LogBytes(p, l);
464}
465
rockot502c94f2016-02-03 20:20:16466void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
467 const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22468 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]d4124852013-03-20 20:25:00469 // Cast to bool below is required because libc++'s
470 // vector<bool>::const_reference is different from bool, and we want to avoid
471 // writing an extra specialization of ParamTraits for it.
[email protected]bf5aedf02012-06-04 21:18:25472 for (size_t i = 0; i < p.size(); i++)
[email protected]d4124852013-03-20 20:25:00473 WriteParam(m, static_cast<bool>(p[i]));
[email protected]bf5aedf02012-06-04 21:18:25474}
475
rockot502c94f2016-02-03 20:20:16476bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25477 base::PickleIterator* iter,
478 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25479 int size;
480 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48481 if (!iter->ReadLength(&size))
[email protected]bf5aedf02012-06-04 21:18:25482 return false;
483 r->resize(size);
484 for (int i = 0; i < size; i++) {
485 bool value;
486 if (!ReadParam(m, iter, &value))
487 return false;
488 (*r)[i] = value;
489 }
490 return true;
491}
492
493void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
494 for (size_t i = 0; i < p.size(); ++i) {
495 if (i != 0)
496 l->push_back(' ');
[email protected]d4124852013-03-20 20:25:00497 LogParam(static_cast<bool>(p[i]), l);
[email protected]bf5aedf02012-06-04 21:18:25498 }
[email protected]d84e48b2010-10-21 22:04:52499}
500
rockot502c94f2016-02-03 20:20:16501void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
[email protected]ea5ef4c2013-06-13 22:50:27502 const param_type& p) {
[email protected]946d1b22009-07-22 23:57:21503 WriteValue(m, &p, 0);
504}
505
rockot502c94f2016-02-03 20:20:16506bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25507 base::PickleIterator* iter,
508 param_type* r) {
[email protected]946d1b22009-07-22 23:57:21509 int type;
jdoerriedc72ee942016-12-07 15:43:28510 if (!ReadParam(m, iter, &type) ||
511 type != static_cast<int>(base::Value::Type::DICTIONARY))
[email protected]946d1b22009-07-22 23:57:21512 return false;
513
514 return ReadDictionaryValue(m, iter, r, 0);
515}
516
[email protected]ea5ef4c2013-06-13 22:50:27517void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
518 std::string* l) {
[email protected]946d1b22009-07-22 23:57:21519 std::string json;
estade8d046462015-05-16 01:02:34520 base::JSONWriter::Write(p, &json);
[email protected]252cad62010-08-18 18:33:57521 l->append(json);
[email protected]946d1b22009-07-22 23:57:21522}
523
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09524#if defined(OS_POSIX) || defined(OS_FUCHSIA)
rockot502c94f2016-02-03 20:20:16525void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
526 const param_type& p) {
erikchen14525202017-05-06 19:16:51527 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06528 // nacl_message_scanner.cc:WriteHandle().
[email protected]7a4de7a62010-08-17 18:38:24529 const bool valid = p.fd >= 0;
530 WriteParam(m, valid);
531
morrita96693852014-09-24 20:11:45532 if (!valid)
533 return;
534
535 if (p.auto_close) {
morrita1aa788c2015-01-31 05:45:42536 if (!m->WriteAttachment(
537 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
morrita96693852014-09-24 20:11:45538 NOTREACHED();
539 } else {
morrita1aa788c2015-01-31 05:45:42540 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
[email protected]7a4de7a62010-08-17 18:38:24541 NOTREACHED();
542 }
543}
544
rockot502c94f2016-02-03 20:20:16545bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25546 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24547 param_type* r) {
morrita96693852014-09-24 20:11:45548 *r = base::FileDescriptor();
549
[email protected]7a4de7a62010-08-17 18:38:24550 bool valid;
551 if (!ReadParam(m, iter, &valid))
552 return false;
553
morrita96693852014-09-24 20:11:45554 if (!valid)
[email protected]7a4de7a62010-08-17 18:38:24555 return true;
[email protected]7a4de7a62010-08-17 18:38:24556
rockot502c94f2016-02-03 20:20:16557 scoped_refptr<base::Pickle::Attachment> attachment;
morrita1aa788c2015-01-31 05:45:42558 if (!m->ReadAttachment(iter, &attachment))
morrita96693852014-09-24 20:11:45559 return false;
560
sammc6ed3efb2016-11-23 03:17:35561 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
562 MessageAttachment::Type::PLATFORM_FILE) {
563 return false;
564 }
565
rockot502c94f2016-02-03 20:20:16566 *r = base::FileDescriptor(
sammc6ed3efb2016-11-23 03:17:35567 static_cast<internal::PlatformFileAttachment*>(attachment.get())
568 ->TakePlatformFile(),
rockot502c94f2016-02-03 20:20:16569 true);
morrita96693852014-09-24 20:11:45570 return true;
[email protected]7a4de7a62010-08-17 18:38:24571}
572
573void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57574 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24575 if (p.auto_close) {
[email protected]7d3cbc92013-03-18 22:33:04576 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24577 } else {
[email protected]7d3cbc92013-03-18 22:33:04578 l->append(base::StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24579 }
580}
Sergey Ulanovac89bb92019-03-22 18:46:49581
582void ParamTraits<base::ScopedFD>::Write(base::Pickle* m, const param_type& p) {
583 // This serialization must be kept in sync with
584 // nacl_message_scanner.cc:WriteHandle().
585 const bool valid = p.is_valid();
586 WriteParam(m, valid);
587
588 if (!valid)
589 return;
590
591 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
592 std::move(const_cast<param_type&>(p))))) {
593 NOTREACHED();
594 }
595}
596
597bool ParamTraits<base::ScopedFD>::Read(const base::Pickle* m,
598 base::PickleIterator* iter,
599 param_type* r) {
600 r->reset();
601
602 bool valid;
603 if (!ReadParam(m, iter, &valid))
604 return false;
605
606 if (!valid)
607 return true;
608
609 scoped_refptr<base::Pickle::Attachment> attachment;
610 if (!m->ReadAttachment(iter, &attachment))
611 return false;
612
613 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
614 MessageAttachment::Type::PLATFORM_FILE) {
615 return false;
616 }
617
618 *r = base::ScopedFD(
619 static_cast<internal::PlatformFileAttachment*>(attachment.get())
620 ->TakePlatformFile());
621 return true;
622}
623
624void ParamTraits<base::ScopedFD>::Log(const param_type& p, std::string* l) {
625 l->append(base::StringPrintf("ScopedFD(%d)", p.get()));
626}
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09627#endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]7a4de7a62010-08-17 18:38:24628
Robert Sesek02910662020-02-28 20:15:51629#if defined(OS_WIN)
630void ParamTraits<base::win::ScopedHandle>::Write(base::Pickle* m,
631 const param_type& p) {
632 const bool valid = p.IsValid();
633 WriteParam(m, valid);
634 if (!valid)
635 return;
636
637 HandleWin handle(p.Get());
638 WriteParam(m, handle);
639}
640
641bool ParamTraits<base::win::ScopedHandle>::Read(const base::Pickle* m,
642 base::PickleIterator* iter,
643 param_type* r) {
644 r->Close();
645
646 bool valid;
647 if (!ReadParam(m, iter, &valid))
648 return false;
649 if (!valid)
650 return true;
651
652 HandleWin handle;
653 if (!ReadParam(m, iter, &handle))
654 return false;
655
656 r->Set(handle.get_handle());
657 return true;
658}
659
660void ParamTraits<base::win::ScopedHandle>::Log(const param_type& p,
661 std::string* l) {
662 l->append(base::StringPrintf("ScopedHandle(%p)", p.Get()));
663}
664#endif // defined(OS_WIN)
665
Sergey Ulanova97f3282019-04-17 01:27:34666#if defined(OS_FUCHSIA)
667void ParamTraits<zx::vmo>::Write(base::Pickle* m, const param_type& p) {
668 // This serialization must be kept in sync with
669 // nacl_message_scanner.cc:WriteHandle().
670 const bool valid = p.is_valid();
671 WriteParam(m, valid);
672
673 if (!valid)
674 return;
675
676 if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
Sergey Ulanov04367c72019-06-21 15:51:43677 std::move(const_cast<param_type&>(p))))) {
Sergey Ulanova97f3282019-04-17 01:27:34678 NOTREACHED();
679 }
680}
681
682bool ParamTraits<zx::vmo>::Read(const base::Pickle* m,
683 base::PickleIterator* iter,
684 param_type* r) {
685 r->reset();
686
687 bool valid;
688 if (!ReadParam(m, iter, &valid))
689 return false;
690
691 if (!valid)
692 return true;
693
694 scoped_refptr<base::Pickle::Attachment> attachment;
695 if (!m->ReadAttachment(iter, &attachment))
696 return false;
697
698 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
699 MessageAttachment::Type::FUCHSIA_HANDLE) {
700 return false;
701 }
702
703 *r = zx::vmo(static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
704 ->Take());
705 return true;
706}
707
708void ParamTraits<zx::vmo>::Log(const param_type& p, std::string* l) {
709 l->append("ZirconVMO");
710}
Sergey Ulanov7b343ff2019-08-15 07:52:37711
712void ParamTraits<zx::channel>::Write(base::Pickle* m, const param_type& p) {
713 // This serialization must be kept in sync with
714 // nacl_message_scanner.cc:WriteHandle().
715 const bool valid = p.is_valid();
716 WriteParam(m, valid);
717
718 if (!valid)
719 return;
720
721 if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
722 std::move(const_cast<param_type&>(p))))) {
723 NOTREACHED();
724 }
725}
726
727bool ParamTraits<zx::channel>::Read(const base::Pickle* m,
728 base::PickleIterator* iter,
729 param_type* r) {
730 r->reset();
731
732 bool valid;
733 if (!ReadParam(m, iter, &valid))
734 return false;
735
736 if (!valid)
737 return true;
738
739 scoped_refptr<base::Pickle::Attachment> attachment;
740 if (!m->ReadAttachment(iter, &attachment))
741 return false;
742
743 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
744 MessageAttachment::Type::FUCHSIA_HANDLE) {
745 return false;
746 }
747
748 *r = zx::channel(
749 static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
750 ->Take());
751 return true;
752}
753
754void ParamTraits<zx::channel>::Log(const param_type& p, std::string* l) {
755 l->append("ZirconChannel");
756}
Sergey Ulanova97f3282019-04-17 01:27:34757#endif // defined(OS_FUCHSIA)
758
Klaus Weidner3824a8882017-11-03 06:24:57759#if defined(OS_ANDROID)
Alexandr Ilin0443a8f2018-07-20 20:14:50760void ParamTraits<base::android::ScopedHardwareBufferHandle>::Write(
761 base::Pickle* m,
762 const param_type& p) {
763 const bool is_valid = p.is_valid();
Ken Rockot097248f02018-04-23 16:23:34764 WriteParam(m, is_valid);
765 if (!is_valid)
766 return;
767
Ken Rockot097248f02018-04-23 16:23:34768 // We must keep a ref to the AHardwareBuffer alive until the receiver has
769 // acquired its own reference. We do this by sending a message pipe handle
770 // along with the buffer. When the receiver deserializes (or even if they
771 // die without ever reading the message) their end of the pipe will be
772 // closed. We will eventually detect this and release the AHB reference.
773 mojo::MessagePipe tracking_pipe;
774 m->WriteAttachment(new internal::MojoHandleAttachment(
775 mojo::ScopedHandle::From(std::move(tracking_pipe.handle0))));
Alexandr Ilin0443a8f2018-07-20 20:14:50776 WriteParam(m, base::FileDescriptor(p.SerializeAsFileDescriptor().release(),
777 true /* auto_close */));
Ken Rockot097248f02018-04-23 16:23:34778
779 // Pass ownership of the input handle to our tracking pipe to keep the AHB
780 // alive long enough to be deserialized by the receiver.
Alexandr Ilin0443a8f2018-07-20 20:14:50781 mojo::ScopeToMessagePipe(std::move(const_cast<param_type&>(p)),
782 std::move(tracking_pipe.handle1));
Klaus Weidner3824a8882017-11-03 06:24:57783}
784
Alexandr Ilin0443a8f2018-07-20 20:14:50785bool ParamTraits<base::android::ScopedHardwareBufferHandle>::Read(
786 const base::Pickle* m,
787 base::PickleIterator* iter,
788 param_type* r) {
789 *r = base::android::ScopedHardwareBufferHandle();
Ken Rockot097248f02018-04-23 16:23:34790
791 bool is_valid;
792 if (!ReadParam(m, iter, &is_valid))
Klaus Weidner3824a8882017-11-03 06:24:57793 return false;
Ken Rockot097248f02018-04-23 16:23:34794 if (!is_valid)
795 return true;
796
797 scoped_refptr<base::Pickle::Attachment> tracking_pipe_attachment;
798 if (!m->ReadAttachment(iter, &tracking_pipe_attachment))
Klaus Weidner3824a8882017-11-03 06:24:57799 return false;
Ken Rockot097248f02018-04-23 16:23:34800
801 // We keep this alive until the AHB is safely deserialized below. When this
802 // goes out of scope, the sender holding the other end of this pipe will treat
803 // this handle closure as a signal that it's safe to release their AHB
804 // keepalive ref.
805 mojo::ScopedHandle tracking_pipe =
806 static_cast<MessageAttachment*>(tracking_pipe_attachment.get())
807 ->TakeMojoHandle();
808
809 base::FileDescriptor descriptor;
810 if (!ReadParam(m, iter, &descriptor))
811 return false;
812
813 // NOTE: It is valid to deserialize an invalid FileDescriptor, so the success
814 // of |ReadParam()| above does not imply that |descriptor| is valid.
815 base::ScopedFD scoped_fd(descriptor.fd);
816 if (!scoped_fd.is_valid())
817 return false;
818
819 *r = base::android::ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(
Alexandr Ilin0443a8f2018-07-20 20:14:50820 std::move(scoped_fd));
Klaus Weidner3824a8882017-11-03 06:24:57821 return true;
822}
823
Alexandr Ilin0443a8f2018-07-20 20:14:50824void ParamTraits<base::android::ScopedHardwareBufferHandle>::Log(
825 const param_type& p,
826 std::string* l) {
827 l->append(base::StringPrintf("base::android::ScopedHardwareBufferHandle(%p)",
828 p.get()));
Klaus Weidner3824a8882017-11-03 06:24:57829}
Ken Rockot097248f02018-04-23 16:23:34830#endif // defined(OS_ANDROID)
Klaus Weidner3824a8882017-11-03 06:24:57831
Alexandr Ilind497eee2018-04-19 22:50:54832void ParamTraits<base::ReadOnlySharedMemoryRegion>::Write(base::Pickle* m,
833 const param_type& p) {
834 base::subtle::PlatformSharedMemoryRegion handle =
835 base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
836 std::move(const_cast<param_type&>(p)));
837 WriteParam(m, std::move(handle));
838}
839
840bool ParamTraits<base::ReadOnlySharedMemoryRegion>::Read(
841 const base::Pickle* m,
842 base::PickleIterator* iter,
843 param_type* r) {
844 base::subtle::PlatformSharedMemoryRegion handle;
845 if (!ReadParam(m, iter, &handle))
846 return false;
847
848 *r = base::ReadOnlySharedMemoryRegion::Deserialize(std::move(handle));
849 return true;
850}
851
852void ParamTraits<base::ReadOnlySharedMemoryRegion>::Log(const param_type& p,
853 std::string* l) {
854 *l = "<base::ReadOnlySharedMemoryRegion>";
855 // TODO(alexilin): currently there is no way to access underlying handle
856 // without destructing a ReadOnlySharedMemoryRegion instance.
857}
858
859void ParamTraits<base::WritableSharedMemoryRegion>::Write(base::Pickle* m,
860 const param_type& p) {
861 base::subtle::PlatformSharedMemoryRegion handle =
862 base::WritableSharedMemoryRegion::TakeHandleForSerialization(
863 std::move(const_cast<param_type&>(p)));
864 WriteParam(m, std::move(handle));
865}
866
867bool ParamTraits<base::WritableSharedMemoryRegion>::Read(
868 const base::Pickle* m,
869 base::PickleIterator* iter,
870 param_type* r) {
871 base::subtle::PlatformSharedMemoryRegion handle;
872 if (!ReadParam(m, iter, &handle))
873 return false;
874
875 *r = base::WritableSharedMemoryRegion::Deserialize(std::move(handle));
876 return true;
877}
878
879void ParamTraits<base::WritableSharedMemoryRegion>::Log(const param_type& p,
880 std::string* l) {
881 *l = "<base::WritableSharedMemoryRegion>";
882 // TODO(alexilin): currently there is no way to access underlying handle
883 // without destructing a ReadOnlySharedMemoryRegion instance.
884}
885
886void ParamTraits<base::UnsafeSharedMemoryRegion>::Write(base::Pickle* m,
887 const param_type& p) {
888 base::subtle::PlatformSharedMemoryRegion handle =
889 base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
890 std::move(const_cast<param_type&>(p)));
891 WriteParam(m, std::move(handle));
892}
893
894bool ParamTraits<base::UnsafeSharedMemoryRegion>::Read(
895 const base::Pickle* m,
896 base::PickleIterator* iter,
897 param_type* r) {
898 base::subtle::PlatformSharedMemoryRegion handle;
899 if (!ReadParam(m, iter, &handle))
900 return false;
901
902 *r = base::UnsafeSharedMemoryRegion::Deserialize(std::move(handle));
903 return true;
904}
905
906void ParamTraits<base::UnsafeSharedMemoryRegion>::Log(const param_type& p,
907 std::string* l) {
908 *l = "<base::UnsafeSharedMemoryRegion>";
909 // TODO(alexilin): currently there is no way to access underlying handle
910 // without destructing a ReadOnlySharedMemoryRegion instance.
911}
912
913void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Write(
914 base::Pickle* m,
915 const param_type& p) {
Alexandr Ilinebab9da2018-06-01 02:37:47916 // This serialization must be kept in sync with
917 // nacl_message_scanner.cc::WriteHandle().
Alexandr Ilind497eee2018-04-19 22:50:54918 const bool valid = p.IsValid();
919 WriteParam(m, valid);
920
921 if (!valid)
922 return;
923
924 WriteParam(m, p.GetMode());
925 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
926 WriteParam(m, p.GetGUID());
927
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09928#if defined(OS_WIN)
929 base::win::ScopedHandle h = const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54930 HandleWin handle_win(h.Get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09931 WriteParam(m, handle_win);
Alexandr Ilind497eee2018-04-19 22:50:54932#elif defined(OS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:43933 zx::vmo vmo = const_cast<param_type&>(p).PassPlatformHandle();
934 WriteParam(m, vmo);
Avi Drissman2b97d032020-07-30 03:02:26935#elif defined(OS_MAC)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09936 base::mac::ScopedMachSendRight h =
937 const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54938 MachPortMac mach_port_mac(h.get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09939 WriteParam(m, mach_port_mac);
Alexandr Ilind497eee2018-04-19 22:50:54940#elif defined(OS_ANDROID)
941 m->WriteAttachment(new internal::PlatformFileAttachment(
942 base::ScopedFD(const_cast<param_type&>(p).PassPlatformHandle())));
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09943#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:54944 base::subtle::ScopedFDPair h =
945 const_cast<param_type&>(p).PassPlatformHandle();
946 m->WriteAttachment(new internal::PlatformFileAttachment(std::move(h.fd)));
947 if (p.GetMode() ==
948 base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
949 m->WriteAttachment(
950 new internal::PlatformFileAttachment(std::move(h.readonly_fd)));
951 }
952#endif
953}
954
955bool ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Read(
956 const base::Pickle* m,
957 base::PickleIterator* iter,
958 param_type* r) {
959 bool valid;
960 if (!ReadParam(m, iter, &valid))
961 return false;
962 if (!valid) {
963 *r = base::subtle::PlatformSharedMemoryRegion();
964 return true;
965 }
966
967 base::subtle::PlatformSharedMemoryRegion::Mode mode;
968 uint64_t shm_size;
969 base::UnguessableToken guid;
970 if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &shm_size) ||
971 !base::IsValueInRangeForNumericType<size_t>(shm_size) ||
972 !ReadParam(m, iter, &guid)) {
973 return false;
974 }
975 size_t size = static_cast<size_t>(shm_size);
976
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09977#if defined(OS_WIN)
978 HandleWin handle_win;
979 if (!ReadParam(m, iter, &handle_win))
Alexandr Ilind497eee2018-04-19 22:50:54980 return false;
981 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09982 base::win::ScopedHandle(handle_win.get_handle()), mode, size, guid);
Alexandr Ilind497eee2018-04-19 22:50:54983#elif defined(OS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:43984 zx::vmo vmo;
985 if (!ReadParam(m, iter, &vmo))
Alexandr Ilind497eee2018-04-19 22:50:54986 return false;
Sergey Ulanov04367c72019-06-21 15:51:43987 *r = base::subtle::PlatformSharedMemoryRegion::Take(std::move(vmo), mode,
988 size, guid);
Avi Drissman2b97d032020-07-30 03:02:26989#elif defined(OS_MAC)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09990 MachPortMac mach_port_mac;
991 if (!ReadParam(m, iter, &mach_port_mac))
Alexandr Ilind497eee2018-04-19 22:50:54992 return false;
993 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09994 base::mac::ScopedMachSendRight(mach_port_mac.get_mach_port()), mode, size,
995 guid);
996#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:54997 scoped_refptr<base::Pickle::Attachment> attachment;
998 if (!m->ReadAttachment(iter, &attachment))
999 return false;
1000 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
1001 MessageAttachment::Type::PLATFORM_FILE) {
1002 return false;
1003 }
1004
1005#if defined(OS_ANDROID)
1006 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1007 base::ScopedFD(
1008 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1009 ->TakePlatformFile()),
1010 mode, size, guid);
1011#else
1012 scoped_refptr<base::Pickle::Attachment> readonly_attachment;
1013 if (mode == base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
1014 if (!m->ReadAttachment(iter, &readonly_attachment))
1015 return false;
1016
1017 if (static_cast<MessageAttachment*>(readonly_attachment.get())->GetType() !=
1018 MessageAttachment::Type::PLATFORM_FILE) {
1019 return false;
1020 }
1021 }
1022 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1023 base::subtle::ScopedFDPair(
1024 base::ScopedFD(
1025 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1026 ->TakePlatformFile()),
1027 readonly_attachment
1028 ? base::ScopedFD(static_cast<internal::PlatformFileAttachment*>(
1029 readonly_attachment.get())
1030 ->TakePlatformFile())
1031 : base::ScopedFD()),
1032 mode, size, guid);
1033#endif // defined(OS_ANDROID)
1034
1035#endif
1036
1037 return true;
1038}
1039
1040void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Log(
1041 const param_type& p,
1042 std::string* l) {
Wezb908e432018-09-05 17:35:221043#if defined(OS_FUCHSIA)
1044 l->append("Handle: ");
1045 LogParam(p.GetPlatformHandle()->get(), l);
1046#elif defined(OS_WIN)
Alexandr Ilind497eee2018-04-19 22:50:541047 l->append("Handle: ");
1048 LogParam(p.GetPlatformHandle(), l);
Avi Drissman2b97d032020-07-30 03:02:261049#elif defined(OS_MAC)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091050 l->append("Mach port: ");
1051 LogParam(p.GetPlatformHandle(), l);
Alexandr Ilind497eee2018-04-19 22:50:541052#elif defined(OS_ANDROID)
1053 l->append("FD: ");
1054 LogParam(p.GetPlatformHandle(), l);
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091055#elif defined(OS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541056 base::subtle::FDPair h = p.GetPlatformHandle();
1057 l->append("FD: ");
1058 LogParam(h.fd, l);
1059 l->append("Read-only FD: ");
1060 LogParam(h.readonly_fd, l);
1061#endif
1062
1063 l->append("Mode: ");
1064 LogParam(p.GetMode(), l);
1065 l->append("size: ");
1066 LogParam(static_cast<uint64_t>(p.GetSize()), l);
1067 l->append("GUID: ");
1068 LogParam(p.GetGUID(), l);
1069}
1070
1071void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Write(
1072 base::Pickle* m,
1073 const param_type& value) {
1074 DCHECK(static_cast<int>(value) >= 0 &&
1075 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue));
1076 m->WriteInt(static_cast<int>(value));
1077}
1078
1079bool ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Read(
1080 const base::Pickle* m,
1081 base::PickleIterator* iter,
1082 param_type* p) {
1083 int value;
1084 if (!iter->ReadInt(&value))
1085 return false;
1086 if (!(static_cast<int>(value) >= 0 &&
1087 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue))) {
1088 return false;
1089 }
1090 *p = static_cast<param_type>(value);
1091 return true;
1092}
1093
1094void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Log(
1095 const param_type& p,
1096 std::string* l) {
1097 LogParam(static_cast<int>(p), l);
1098}
1099
erikchend804e1052017-04-29 02:24:361100#if defined(OS_WIN)
erikchend804e1052017-04-29 02:24:361101void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
1102 const param_type& p) {
1103 m->WriteBool(p.IsValid());
1104 if (p.IsValid()) {
Wez51eaaad2017-08-09 05:51:381105 HandleWin handle_win(p.GetHandle());
erikchend804e1052017-04-29 02:24:361106 ParamTraits<HandleWin>::Write(m, handle_win);
1107 ::CloseHandle(p.GetHandle());
1108 }
1109}
1110
1111bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
1112 base::PickleIterator* iter,
1113 param_type* r) {
1114 bool is_valid;
1115 if (!iter->ReadBool(&is_valid))
1116 return false;
1117 if (!is_valid) {
1118 *r = PlatformFileForTransit();
1119 return true;
1120 }
1121
1122 HandleWin handle_win;
1123 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
1124 return false;
1125 *r = PlatformFileForTransit(handle_win.get_handle());
1126 return true;
1127}
1128
1129void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
1130 std::string* l) {
1131 LogParam(p.GetHandle(), l);
1132}
1133#endif // defined(OS_WIN)
1134
rockot502c94f2016-02-03 20:20:161135void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:551136 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:251137}
1138
rockot502c94f2016-02-03 20:20:161139bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251140 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:301141 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:551142 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:251143}
1144
[email protected]6d4b67a2013-02-10 04:49:301145void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
1146 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:251147}
1148
rockot502c94f2016-02-03 20:20:161149void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251150 WriteValue(m, &p, 0);
1151}
1152
rockot502c94f2016-02-03 20:20:161153bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251154 base::PickleIterator* iter,
1155 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:251156 int type;
jdoerriedc72ee942016-12-07 15:43:281157 if (!ReadParam(m, iter, &type) ||
1158 type != static_cast<int>(base::Value::Type::LIST))
[email protected]bf5aedf02012-06-04 21:18:251159 return false;
1160
1161 return ReadListValue(m, iter, r, 0);
1162}
1163
[email protected]ea5ef4c2013-06-13 22:50:271164void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251165 std::string json;
estade8d046462015-05-16 01:02:341166 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:251167 l->append(json);
1168}
1169
rockot502c94f2016-02-03 20:20:161170void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
[email protected]0238a162013-06-13 13:47:461171 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251172 WriteParam(m, p.string());
1173 WriteParam(m, p.is_null());
1174}
1175
rockot502c94f2016-02-03 20:20:161176bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251177 base::PickleIterator* iter,
[email protected]0238a162013-06-13 13:47:461178 param_type* r) {
[email protected]476dafb2013-12-03 00:39:261179 base::string16 string;
[email protected]bf5aedf02012-06-04 21:18:251180 if (!ReadParam(m, iter, &string))
1181 return false;
1182 bool is_null;
1183 if (!ReadParam(m, iter, &is_null))
1184 return false;
[email protected]0238a162013-06-13 13:47:461185 *r = base::NullableString16(string, is_null);
[email protected]bf5aedf02012-06-04 21:18:251186 return true;
1187}
1188
[email protected]0238a162013-06-13 13:47:461189void ParamTraits<base::NullableString16>::Log(const param_type& p,
1190 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251191 l->append("(");
1192 LogParam(p.string(), l);
1193 l->append(", ");
1194 LogParam(p.is_null(), l);
1195 l->append(")");
1196}
1197
rockot502c94f2016-02-03 20:20:161198void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:001199 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251200 WriteParam(m, p.size);
1201 WriteParam(m, p.is_directory);
1202 WriteParam(m, p.last_modified.ToDoubleT());
1203 WriteParam(m, p.last_accessed.ToDoubleT());
1204 WriteParam(m, p.creation_time.ToDoubleT());
1205}
1206
rockot502c94f2016-02-03 20:20:161207bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251208 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:001209 param_type* p) {
[email protected]481c3e82014-07-18 01:40:471210 double last_modified, last_accessed, creation_time;
1211 if (!ReadParam(m, iter, &p->size) ||
1212 !ReadParam(m, iter, &p->is_directory) ||
1213 !ReadParam(m, iter, &last_modified) ||
1214 !ReadParam(m, iter, &last_accessed) ||
1215 !ReadParam(m, iter, &creation_time))
1216 return false;
1217 p->last_modified = base::Time::FromDoubleT(last_modified);
1218 p->last_accessed = base::Time::FromDoubleT(last_accessed);
1219 p->creation_time = base::Time::FromDoubleT(creation_time);
1220 return true;
[email protected]bf5aedf02012-06-04 21:18:251221}
1222
[email protected]141bcc52014-01-27 21:36:001223void ParamTraits<base::File::Info>::Log(const param_type& p,
1224 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251225 l->append("(");
1226 LogParam(p.size, l);
1227 l->append(",");
1228 LogParam(p.is_directory, l);
1229 l->append(",");
1230 LogParam(p.last_modified.ToDoubleT(), l);
1231 l->append(",");
1232 LogParam(p.last_accessed.ToDoubleT(), l);
1233 l->append(",");
1234 LogParam(p.creation_time.ToDoubleT(), l);
1235 l->append(")");
1236}
1237
rockot502c94f2016-02-03 20:20:161238void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571239 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251240}
1241
rockot502c94f2016-02-03 20:20:161242bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251243 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251244 param_type* r) {
tfarina10a5c062015-09-04 18:47:571245 int64_t value;
1246 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:251247 return false;
1248 *r = base::Time::FromInternalValue(value);
1249 return true;
1250}
1251
1252void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571253 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251254}
1255
rockot502c94f2016-02-03 20:20:161256void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571257 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251258}
1259
rockot502c94f2016-02-03 20:20:161260bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251261 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251262 param_type* r) {
tfarina10a5c062015-09-04 18:47:571263 int64_t value;
1264 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251265 if (ret)
1266 *r = base::TimeDelta::FromInternalValue(value);
1267
1268 return ret;
1269}
1270
1271void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571272 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251273}
1274
rockot502c94f2016-02-03 20:20:161275void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571276 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251277}
1278
rockot502c94f2016-02-03 20:20:161279bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251280 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251281 param_type* r) {
tfarina10a5c062015-09-04 18:47:571282 int64_t value;
1283 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251284 if (ret)
1285 *r = base::TimeTicks::FromInternalValue(value);
1286
1287 return ret;
1288}
1289
1290void ParamTraits<base::TimeTicks>::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
tguilbert4a5ac602016-09-19 21:11:251294// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1295// below should be updated.
1296static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1297 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1298
tguilbert4a5ac602016-09-19 21:11:251299void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1300 const param_type& p) {
1301 DCHECK(!p.is_empty());
1302
1303 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1304 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1305}
1306
1307bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1308 base::PickleIterator* iter,
1309 param_type* r) {
1310 uint64_t high, low;
1311 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1312 !ParamTraits<uint64_t>::Read(m, iter, &low))
1313 return false;
1314
1315 // Receiving a zeroed UnguessableToken is a security issue.
1316 if (high == 0 && low == 0)
1317 return false;
1318
1319 *r = base::UnguessableToken::Deserialize(high, low);
1320 return true;
1321}
1322
1323void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1324 std::string* l) {
1325 l->append(p.ToString());
1326}
1327
rockot502c94f2016-02-03 20:20:161328void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1329 const param_type& p) {
sammc9bf370c2016-11-14 03:29:081330#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241331 WriteParam(m, p.socket);
sammc9bf370c2016-11-14 03:29:081332#else
amistry36182522016-06-27 06:34:421333 WriteParam(m, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:081334#endif
[email protected]7a4de7a62010-08-17 18:38:241335}
1336
rockot502c94f2016-02-03 20:20:161337bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251338 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:241339 param_type* r) {
sammc9bf370c2016-11-14 03:29:081340#if defined(OS_NACL_SFI)
1341 return ReadParam(m, iter, &r->socket);
1342#else
1343 return ReadParam(m, iter, &r->mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241344#endif
[email protected]7a4de7a62010-08-17 18:38:241345}
1346
1347void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571348 std::string* l) {
sammc9bf370c2016-11-14 03:29:081349 l->append("ChannelHandle(");
1350#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241351 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
sammc9bf370c2016-11-14 03:29:081352#else
amistry36182522016-06-27 06:34:421353 LogParam(p.mojo_handle, l);
sammc9bf370c2016-11-14 03:29:081354#endif
[email protected]252cad62010-08-18 18:33:571355 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241356}
1357
rockot502c94f2016-02-03 20:20:161358void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301359 WriteParam(m, p.channel);
1360 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271361 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301362 WriteParam(m, p.flags);
1363 WriteParam(m, p.sent);
1364 WriteParam(m, p.receive);
1365 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451366 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301367 WriteParam(m, p.params);
1368}
1369
rockot502c94f2016-02-03 20:20:161370bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251371 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561372 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271373 return
[email protected]20f0487a2010-09-30 20:06:301374 ReadParam(m, iter, &r->channel) &&
1375 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271376 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301377 ReadParam(m, iter, &r->flags) &&
1378 ReadParam(m, iter, &r->sent) &&
1379 ReadParam(m, iter, &r->receive) &&
1380 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451381 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301382 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301383}
1384
[email protected]bf5aedf02012-06-04 21:18:251385void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1386 // Doesn't make sense to implement this!
1387}
1388
rockot502c94f2016-02-03 20:20:161389void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091390#if defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]34d48612012-06-29 00:05:041391 // We don't serialize the file descriptors in the nested message, so there
1392 // better not be any.
morrita1aa788c2015-01-31 05:45:421393 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041394#endif
1395
1396 // Don't just write out the message. This is used to send messages between
1397 // NaCl (Posix environment) and the browser (could be on Windows). The message
1398 // header formats differ between these systems (so does handle sharing, but
1399 // we already asserted we don't have any handles). So just write out the
1400 // parts of the header we use.
1401 //
1402 // Be careful also to use only explicitly-sized types. The NaCl environment
1403 // could be 64-bit and the host browser could be 32-bits. The nested message
1404 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1405 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:571406 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041407 m->WriteUInt32(p.type());
1408 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:571409 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:251410}
1411
rockot502c94f2016-02-03 20:20:161412bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251413 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251414 Message* r) {
tfarina10a5c062015-09-04 18:47:571415 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481416 if (!iter->ReadUInt32(&routing_id) ||
1417 !iter->ReadUInt32(&type) ||
1418 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251419 return false;
[email protected]34d48612012-06-29 00:05:041420
1421 int payload_size;
1422 const char* payload;
avi48fc13b2014-12-28 23:31:481423 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251424 return false;
[email protected]34d48612012-06-29 00:05:041425
tfarina10a5c062015-09-04 18:47:571426 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
Daniel Cheng0d89f9222017-09-22 05:05:071427 r->WriteBytes(payload, payload_size);
1428 return true;
[email protected]bf5aedf02012-06-04 21:18:251429}
1430
1431void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1432 l->append("<IPC::Message>");
1433}
1434
1435#if defined(OS_WIN)
1436// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031437// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161438void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031439 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251440}
1441
rockot502c94f2016-02-03 20:20:161442bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251443 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251444 param_type* r) {
tfarina10a5c062015-09-04 18:47:571445 int32_t temp;
avi48fc13b2014-12-28 23:31:481446 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251447 return false;
[email protected]4a635b72013-03-04 02:29:031448 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251449 return true;
1450}
1451
1452void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001453 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251454}
1455
rockot502c94f2016-02-03 20:20:161456void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251457 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1458}
1459
rockot502c94f2016-02-03 20:20:161460bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251461 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251462 param_type* r) {
1463 const char *data;
1464 int data_size = 0;
avi48fc13b2014-12-28 23:31:481465 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251466 if (result && data_size == sizeof(MSG)) {
1467 memcpy(r, data, sizeof(MSG));
1468 } else {
1469 result = false;
1470 NOTREACHED();
1471 }
1472
1473 return result;
1474}
1475
1476void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1477 l->append("<MSG>");
1478}
1479
1480#endif // OS_WIN
1481
[email protected]946d1b22009-07-22 23:57:211482} // namespace IPC