blob: e331ee4d8789bed5b2967d285acdda1b56c7d2ce [file] [log] [blame]
Avi Drissmanea1be232022-09-14 23:29:061// Copyright 2012 The Chromium Authors
[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
Arthur Sonzogni9967fb922024-07-18 18:36:225#ifdef UNSAFE_BUFFERS_BUILD
6// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
7#pragma allow_unsafe_buffers
8#endif
9
[email protected]946d1b22009-07-22 23:57:2110#include "ipc/ipc_message_utils.h"
11
avi246998d82015-12-22 02:39:0412#include <stddef.h>
13#include <stdint.h>
14
Hyowon Kimaf11d362023-12-21 02:15:0915#include <string_view>
Adam Ricec62d8052023-08-03 05:48:4416#include <type_traits>
17
[email protected]57999812013-02-24 05:40:5218#include "base/files/file_path.h"
[email protected]93d49d72009-10-23 20:00:2019#include "base/json/json_writer.h"
Hans Wennborg24397592020-06-17 16:58:5020#include "base/logging.h"
jdoerrief1e72e32017-04-26 16:23:5521#include "base/memory/ptr_util.h"
Hans Wennborg5f62968b2021-04-22 18:44:0522#include "base/notreached.h"
[email protected]4aa794a12013-06-11 06:32:1823#include "base/strings/string_number_conversions.h"
Lei Zhange02299a2021-04-26 23:12:2424#include "base/strings/stringprintf.h"
[email protected]906265872013-06-07 22:40:4525#include "base/strings/utf_string_conversions.h"
[email protected]b43e5562013-06-28 15:20:0226#include "base/time/time.h"
tguilbert4a5ac602016-09-19 21:11:2527#include "base/unguessable_token.h"
avi246998d82015-12-22 02:39:0428#include "build/build_config.h"
[email protected]bf5aedf02012-06-04 21:18:2529#include "ipc/ipc_channel_handle.h"
Lei Zhang5226db72022-01-25 03:38:5530#include "ipc/ipc_message.h"
morrita1aa788c2015-01-31 05:45:4231#include "ipc/ipc_message_attachment.h"
morrita4b5c28e22015-01-14 21:17:0632#include "ipc/ipc_message_attachment_set.h"
amistry36182522016-06-27 06:34:4233#include "ipc/ipc_mojo_param_traits.h"
Peter Kastinga9813a52023-08-03 18:50:4334#include "third_party/abseil-cpp/absl/strings/ascii.h"
[email protected]bf5aedf02012-06-04 21:18:2535
Ali Jumadff201a2022-05-31 23:51:4136#if BUILDFLAG(IS_APPLE)
erikchenaf8299d2015-10-09 19:12:0637#include "ipc/mach_port_mac.h"
38#endif
39
Xiaohan Wangab909b32022-01-12 17:57:3940#if BUILDFLAG(IS_WIN)
[email protected]2e02cfe82012-11-21 00:58:0041#include <tchar.h>
Takuto Ikutac8d6b16f2024-04-15 16:59:1942
erikchen5ea2ab72015-09-25 22:34:3143#include "ipc/handle_win.h"
erikchend804e1052017-04-29 02:24:3644#include "ipc/ipc_platform_file.h"
Xiaohan Wangab909b32022-01-12 17:57:3945#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:0946#include "base/file_descriptor_posix.h"
47#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]7a4de7a62010-08-17 18:38:2448#endif
[email protected]946d1b22009-07-22 23:57:2149
Xiaohan Wangab909b32022-01-12 17:57:3950#if BUILDFLAG(IS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:4351#include "base/fuchsia/fuchsia_logging.h"
Sergey Ulanova97f3282019-04-17 01:27:3452#include "ipc/handle_attachment_fuchsia.h"
Scott Graham3eebff02017-06-30 01:07:1053#endif
54
Xiaohan Wangab909b32022-01-12 17:57:3955#if BUILDFLAG(IS_ANDROID)
Ken Rockot097248f02018-04-23 16:23:3456#include "base/android/scoped_hardware_buffer_handle.h"
57#include "ipc/ipc_mojo_handle_attachment.h"
58#include "mojo/public/cpp/system/message_pipe.h"
59#include "mojo/public/cpp/system/scope_to_message_pipe.h"
60#endif
61
[email protected]946d1b22009-07-22 23:57:2162namespace IPC {
63
[email protected]bf5aedf02012-06-04 21:18:2564namespace {
65
joaodasilva383b174a2017-01-10 09:55:3666const int kMaxRecursionDepth = 200;
[email protected]946d1b22009-07-22 23:57:2167
[email protected]bf5aedf02012-06-04 21:18:2568template<typename CharType>
69void LogBytes(const std::vector<CharType>& data, std::string* out) {
Xiaohan Wangab909b32022-01-12 17:57:3970#if BUILDFLAG(IS_WIN)
[email protected]bf5aedf02012-06-04 21:18:2571 // Windows has a GUI for logging, which can handle arbitrary binary data.
72 for (size_t i = 0; i < data.size(); ++i)
73 out->push_back(data[i]);
Xiaohan Wangab909b32022-01-12 17:57:3974#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
[email protected]bf5aedf02012-06-04 21:18:2575 // On POSIX, we log to stdout, which we assume can display ASCII.
76 static const size_t kMaxBytesToLog = 100;
77 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
Peter Kastinga9813a52023-08-03 18:50:4378 if (absl::ascii_isprint(static_cast<unsigned char>(data[i]))) {
[email protected]bf5aedf02012-06-04 21:18:2579 out->push_back(data[i]);
Peter Kastinga9813a52023-08-03 18:50:4380 } else {
[email protected]7d3cbc92013-03-18 22:33:0481 out->append(
82 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
Peter Kastinga9813a52023-08-03 18:50:4383 }
[email protected]bf5aedf02012-06-04 21:18:2584 }
85 if (data.size() > kMaxBytesToLog) {
[email protected]f8660f82013-03-30 17:29:2886 out->append(base::StringPrintf(
87 " and %u more bytes",
88 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
[email protected]bf5aedf02012-06-04 21:18:2589 }
90#endif
91}
[email protected]946d1b22009-07-22 23:57:2192
Adam Ricec62d8052023-08-03 05:48:4493template <typename CharType>
94void WriteCharVector(base::Pickle* m, const std::vector<CharType>& p) {
95 static_assert(sizeof(CharType) == 1);
96 static_assert(std::is_integral_v<CharType>);
97 if (p.empty()) {
98 m->WriteData(nullptr, 0);
99 } else {
100 const char* data = reinterpret_cast<const char*>(p.data());
101 m->WriteData(data, p.size());
102 }
103}
104
105template <typename CharType>
106bool ReadCharVector(const base::Pickle* m,
107 base::PickleIterator* iter,
108 std::vector<CharType>* r) {
109 static_assert(sizeof(CharType) == 1);
110 static_assert(std::is_integral_v<CharType>);
111 const char* data;
112 size_t data_size = 0;
113 if (!iter->ReadData(&data, &data_size)) {
114 return false;
115 }
116 const CharType* begin = reinterpret_cast<const CharType*>(data);
117 const CharType* end = begin + data_size;
118 r->assign(begin, end);
119 return true;
120}
121
Fabrice de Gans43eebf702022-04-01 23:43:04122void WriteValue(const base::Value& value, int recursion, base::Pickle* pickle);
[email protected]946d1b22009-07-22 23:57:21123
Fabrice de Gans43eebf702022-04-01 23:43:04124void WriteDictValue(const base::Value::Dict& value,
125 int recursion,
126 base::Pickle* pickle) {
127 WriteParam(pickle, base::checked_cast<int>(value.size()));
128 for (const auto entry : value) {
129 WriteParam(pickle, entry.first);
130 WriteValue(entry.second, recursion + 1, pickle);
131 }
132}
133
134void WriteListValue(const base::Value::List& value,
135 int recursion,
136 base::Pickle* pickle) {
137 WriteParam(pickle, base::checked_cast<int>(value.size()));
138 for (const auto& entry : value) {
139 WriteValue(entry, recursion + 1, pickle);
140 }
141}
142
143void WriteValue(const base::Value& value, int recursion, base::Pickle* pickle) {
[email protected]dbc761a2012-07-26 01:29:21144 bool result;
[email protected]946d1b22009-07-22 23:57:21145 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:36146 LOG(ERROR) << "Max recursion depth hit in WriteValue.";
[email protected]946d1b22009-07-22 23:57:21147 return;
148 }
149
Fabrice de Gans43eebf702022-04-01 23:43:04150 pickle->WriteInt(static_cast<int>(value.type()));
[email protected]946d1b22009-07-22 23:57:21151
Fabrice de Gans43eebf702022-04-01 23:43:04152 switch (value.type()) {
jdoerriedc72ee942016-12-07 15:43:28153 case base::Value::Type::NONE:
jdoerriee1b1f3a2019-03-16 04:08:01154 break;
jdoerriedc72ee942016-12-07 15:43:28155 case base::Value::Type::BOOLEAN: {
Fabrice de Gans43eebf702022-04-01 23:43:04156 WriteParam(pickle, value.GetBool());
[email protected]946d1b22009-07-22 23:57:21157 break;
158 }
jdoerriedc72ee942016-12-07 15:43:28159 case base::Value::Type::INTEGER: {
Fabrice de Gans43eebf702022-04-01 23:43:04160 DCHECK(value.is_int());
161 WriteParam(pickle, value.GetInt());
[email protected]946d1b22009-07-22 23:57:21162 break;
163 }
jdoerriedc72ee942016-12-07 15:43:28164 case base::Value::Type::DOUBLE: {
Fabrice de Gans43eebf702022-04-01 23:43:04165 DCHECK(value.is_int() || value.is_double());
166 WriteParam(pickle, value.GetDouble());
[email protected]946d1b22009-07-22 23:57:21167 break;
168 }
jdoerriedc72ee942016-12-07 15:43:28169 case base::Value::Type::STRING: {
Fabrice de Gans43eebf702022-04-01 23:43:04170 const std::string* val = value.GetIfString();
Sammie Quondab84eba2021-08-18 02:34:48171 result = !!val;
[email protected]dbc761a2012-07-26 01:29:21172 DCHECK(result);
Fabrice de Gans43eebf702022-04-01 23:43:04173 WriteParam(pickle, *val);
[email protected]946d1b22009-07-22 23:57:21174 break;
175 }
jdoerriedc72ee942016-12-07 15:43:28176 case base::Value::Type::BINARY: {
Fabrice de Gans43eebf702022-04-01 23:43:04177 pickle->WriteData(reinterpret_cast<const char*>(value.GetBlob().data()),
Peter Kasting28b51cf2022-06-28 15:02:43178 value.GetBlob().size());
[email protected]e4dad9fb2009-10-06 18:15:58179 break;
[email protected]946d1b22009-07-22 23:57:21180 }
Fabrice de Gans43eebf702022-04-01 23:43:04181 case base::Value::Type::DICT: {
182 DCHECK(value.is_dict());
183 WriteDictValue(value.GetDict(), recursion, pickle);
[email protected]946d1b22009-07-22 23:57:21184 break;
185 }
jdoerriedc72ee942016-12-07 15:43:28186 case base::Value::Type::LIST: {
Fabrice de Gans43eebf702022-04-01 23:43:04187 DCHECK(value.is_list());
188 WriteListValue(value.GetList(), recursion, pickle);
[email protected]946d1b22009-07-22 23:57:21189 break;
190 }
191 }
192}
193
Fabrice de Gans43eebf702022-04-01 23:43:04194bool ReadValue(const base::Pickle* pickle,
brettwbd4d7112015-06-03 04:29:25195 base::PickleIterator* iter,
Fabrice de Gans43eebf702022-04-01 23:43:04196 int recursion,
197 base::Value* value);
198
199// Helper for ReadValue that reads a Value::Dict into a pre-allocated object.
200bool ReadDictValue(const base::Pickle* pickle,
201 base::PickleIterator* iter,
202 int recursion,
203 base::Value::Dict* value) {
204 int size;
205 if (!ReadParam(pickle, iter, &size))
206 return false;
207
208 for (int i = 0; i < size; i++) {
209 std::string key;
210 base::Value subvalue;
211 if (!ReadParam(pickle, iter, &key) ||
212 !ReadValue(pickle, iter, recursion + 1, &subvalue)) {
213 return false;
214 }
215 value->Set(key, std::move(subvalue));
216 }
217
218 return true;
219}
220
221// Helper for ReadValue that reads a Value::List into a pre-allocated object.
222bool ReadListValue(const base::Pickle* pickle,
223 base::PickleIterator* iter,
224 int recursion,
225 base::Value::List* value) {
226 int size;
227 if (!ReadParam(pickle, iter, &size))
228 return false;
229
230 value->reserve(size);
231 for (int i = 0; i < size; i++) {
232 base::Value subval;
233 if (!ReadValue(pickle, iter, recursion + 1, &subval))
234 return false;
235 value->Append(std::move(subval));
236 }
237 return true;
238}
239
240bool ReadValue(const base::Pickle* pickle,
241 base::PickleIterator* iter,
242 int recursion,
243 base::Value* value) {
[email protected]946d1b22009-07-22 23:57:21244 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:36245 LOG(ERROR) << "Max recursion depth hit in ReadValue.";
[email protected]946d1b22009-07-22 23:57:21246 return false;
247 }
248
249 int type;
Fabrice de Gans43eebf702022-04-01 23:43:04250 if (!ReadParam(pickle, iter, &type))
[email protected]946d1b22009-07-22 23:57:21251 return false;
252
Devlin Cronin7178a5bd2021-02-02 02:56:47253 constexpr int kMinValueType = static_cast<int>(base::Value::Type::NONE);
254 constexpr int kMaxValueType = static_cast<int>(base::Value::Type::LIST);
255 if (type > kMaxValueType || type < kMinValueType)
256 return false;
257
jdoerriedc72ee942016-12-07 15:43:28258 switch (static_cast<base::Value::Type>(type)) {
259 case base::Value::Type::NONE:
Jeremy Roman2d8d7802020-06-11 22:08:20260 *value = base::Value();
jdoerriee067999a2017-04-07 06:39:00261 break;
jdoerriedc72ee942016-12-07 15:43:28262 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21263 bool val;
Fabrice de Gans43eebf702022-04-01 23:43:04264 if (!ReadParam(pickle, iter, &val))
[email protected]946d1b22009-07-22 23:57:21265 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20266 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21267 break;
268 }
jdoerriedc72ee942016-12-07 15:43:28269 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21270 int val;
Fabrice de Gans43eebf702022-04-01 23:43:04271 if (!ReadParam(pickle, iter, &val))
[email protected]946d1b22009-07-22 23:57:21272 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20273 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21274 break;
275 }
jdoerriedc72ee942016-12-07 15:43:28276 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21277 double val;
Fabrice de Gans43eebf702022-04-01 23:43:04278 if (!ReadParam(pickle, iter, &val))
[email protected]946d1b22009-07-22 23:57:21279 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20280 *value = base::Value(val);
[email protected]946d1b22009-07-22 23:57:21281 break;
282 }
jdoerriedc72ee942016-12-07 15:43:28283 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21284 std::string val;
Fabrice de Gans43eebf702022-04-01 23:43:04285 if (!ReadParam(pickle, iter, &val))
[email protected]946d1b22009-07-22 23:57:21286 return false;
Jeremy Roman2d8d7802020-06-11 22:08:20287 *value = base::Value(std::move(val));
[email protected]946d1b22009-07-22 23:57:21288 break;
289 }
jdoerriedc72ee942016-12-07 15:43:28290 case base::Value::Type::BINARY: {
Arthur Sonzogni59ac8222023-11-10 09:46:54291 std::optional<base::span<const uint8_t>> data = iter->ReadData();
Claudio DeSouzac537f85d2023-03-02 18:42:52292 if (!data) {
[email protected]e4dad9fb2009-10-06 18:15:58293 return false;
Claudio DeSouzac537f85d2023-03-02 18:42:52294 }
295 *value = base::Value(*data);
[email protected]946d1b22009-07-22 23:57:21296 break;
297 }
Avi Drissmand2a736f2023-01-28 02:31:26298 case base::Value::Type::DICT: {
Fabrice de Gans43eebf702022-04-01 23:43:04299 base::Value::Dict val;
300 if (!ReadDictValue(pickle, iter, recursion, &val))
[email protected]946d1b22009-07-22 23:57:21301 return false;
Fabrice de Gans43eebf702022-04-01 23:43:04302 *value = base::Value(std::move(val));
[email protected]946d1b22009-07-22 23:57:21303 break;
304 }
jdoerriedc72ee942016-12-07 15:43:28305 case base::Value::Type::LIST: {
Fabrice de Gans43eebf702022-04-01 23:43:04306 base::Value::List val;
307 if (!ReadListValue(pickle, iter, recursion, &val))
[email protected]946d1b22009-07-22 23:57:21308 return false;
Fabrice de Gans43eebf702022-04-01 23:43:04309 *value = base::Value(std::move(val));
[email protected]946d1b22009-07-22 23:57:21310 break;
311 }
[email protected]e4dad9fb2009-10-06 18:15:58312 default:
Peter Boströmb7e3e08242024-09-24 22:38:10313 NOTREACHED();
[email protected]946d1b22009-07-22 23:57:21314 }
315
316 return true;
317}
318
[email protected]bf5aedf02012-06-04 21:18:25319} // namespace
320
321// -----------------------------------------------------------------------------
322
323LogData::LogData()
324 : routing_id(0),
325 type(0),
326 sent(0),
327 receive(0),
328 dispatch(0) {
329}
330
vmpstrbf0d713a2016-03-24 20:22:54331LogData::LogData(const LogData& other) = default;
332
Chris Watkins2d879af2017-11-30 02:11:59333LogData::~LogData() = default;
[email protected]bf5aedf02012-06-04 21:18:25334
[email protected]bf5aedf02012-06-04 21:18:25335void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
336 l->append(p ? "true" : "false");
337}
338
rockot502c94f2016-02-03 20:20:16339void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno19ecf1842015-10-30 00:46:20340 m->WriteBytes(&p, sizeof(param_type));
341}
342
rockot502c94f2016-02-03 20:20:16343bool ParamTraits<signed char>::Read(const base::Pickle* m,
344 base::PickleIterator* iter,
345 param_type* r) {
ortuno19ecf1842015-10-30 00:46:20346 const char* data;
347 if (!iter->ReadBytes(&data, sizeof(param_type)))
348 return false;
349 memcpy(r, data, sizeof(param_type));
350 return true;
351}
352
353void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38354 l->append(base::NumberToString(p));
ortuno19ecf1842015-10-30 00:46:20355}
356
rockot502c94f2016-02-03 20:20:16357void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28358 m->WriteBytes(&p, sizeof(param_type));
359}
360
rockot502c94f2016-02-03 20:20:16361bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25362 base::PickleIterator* iter,
363 param_type* r) {
[email protected]c1ee48d2013-07-12 23:12:28364 const char* data;
avi48fc13b2014-12-28 23:31:48365 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28366 return false;
367 memcpy(r, data, sizeof(param_type));
368 return true;
369}
370
371void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
Raul Tambref89a5102019-02-08 23:01:38372 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28373}
374
rockot502c94f2016-02-03 20:20:16375void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28376 m->WriteBytes(&p, sizeof(param_type));
377}
378
rockot502c94f2016-02-03 20:20:16379bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25380 base::PickleIterator* iter,
[email protected]c1ee48d2013-07-12 23:12:28381 param_type* r) {
382 const char* data;
avi48fc13b2014-12-28 23:31:48383 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28384 return false;
385 memcpy(r, data, sizeof(param_type));
386 return true;
387}
388
389void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09390 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28391}
392
[email protected]252cad62010-08-18 18:33:57393void ParamTraits<int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09394 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57395}
396
397void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09398 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57399}
400
Xiaohan Wangab909b32022-01-12 17:57:39401#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
402 BUILDFLAG(IS_FUCHSIA) || \
403 (BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]252cad62010-08-18 18:33:57404void ParamTraits<long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09405 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57406}
407
408void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09409 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57410}
jam03d8a782016-02-10 20:13:39411#endif
[email protected]252cad62010-08-18 18:33:57412
413void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09414 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57415}
416
417void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09418 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57419}
[email protected]7a4de7a62010-08-17 18:38:24420
[email protected]bf5aedf02012-06-04 21:18:25421void ParamTraits<float>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04422 l->append(base::StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24423}
424
rockot502c94f2016-02-03 20:20:16425void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
[email protected]48328ff2013-10-31 09:27:31426 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52427}
428
rockot502c94f2016-02-03 20:20:16429bool ParamTraits<double>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25430 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25431 param_type* r) {
432 const char *data;
avi48fc13b2014-12-28 23:31:48433 if (!iter->ReadBytes(&data, sizeof(*r))) {
Peter Boströmb7e3e08242024-09-24 22:38:10434 NOTREACHED();
[email protected]bf5aedf02012-06-04 21:18:25435 }
436 memcpy(r, data, sizeof(param_type));
437 return true;
[email protected]d84e48b2010-10-21 22:04:52438}
439
[email protected]bf5aedf02012-06-04 21:18:25440void ParamTraits<double>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04441 l->append(base::StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04442}
443
[email protected]bf5aedf02012-06-04 21:18:25444
445void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
446 l->append(p);
[email protected]1d14f582011-09-02 20:42:04447}
448
Jan Wilken Dörrie739ccc212021-03-11 18:13:05449void ParamTraits<std::u16string>::Log(const param_type& p, std::string* l) {
[email protected]ad65a3e2013-12-25 18:18:01450 l->append(base::UTF16ToUTF8(p));
[email protected]bf5aedf02012-06-04 21:18:25451}
[email protected]bf5aedf02012-06-04 21:18:25452
Xiaohan Wangab909b32022-01-12 17:57:39453#if BUILDFLAG(IS_WIN)
Jan Wilken Dörriecf5a66902020-12-07 20:51:31454bool ParamTraits<std::wstring>::Read(const base::Pickle* m,
455 base::PickleIterator* iter,
456 param_type* r) {
Hyowon Kim6f3d96c2023-12-01 08:16:20457 std::u16string_view piece16;
Jan Wilken Dörriecf5a66902020-12-07 20:51:31458 if (!iter->ReadStringPiece16(&piece16))
459 return false;
460
461 *r = base::AsWString(piece16);
462 return true;
463}
464
465void ParamTraits<std::wstring>::Log(const param_type& p, std::string* l) {
466 l->append(base::WideToUTF8(p));
467}
468#endif
469
rockot502c94f2016-02-03 20:20:16470void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
471 const param_type& p) {
Adam Ricec62d8052023-08-03 05:48:44472 WriteCharVector(m, p);
[email protected]bf5aedf02012-06-04 21:18:25473}
474
rockot502c94f2016-02-03 20:20:16475bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25476 base::PickleIterator* iter,
477 param_type* r) {
Adam Ricec62d8052023-08-03 05:48:44478 return ReadCharVector(m, iter, r);
[email protected]bf5aedf02012-06-04 21:18:25479}
480
Peter Kastinga9813a52023-08-03 18:50:43481void ParamTraits<std::vector<char>>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25482 LogBytes(p, l);
483}
484
rockot502c94f2016-02-03 20:20:16485void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
486 const param_type& p) {
Adam Ricec62d8052023-08-03 05:48:44487 WriteCharVector(m, p);
[email protected]bf5aedf02012-06-04 21:18:25488}
489
rockot502c94f2016-02-03 20:20:16490bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25491 base::PickleIterator* iter,
492 param_type* r) {
Adam Ricec62d8052023-08-03 05:48:44493 return ReadCharVector(m, iter, r);
[email protected]bf5aedf02012-06-04 21:18:25494}
495
496void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
497 std::string* l) {
498 LogBytes(p, l);
499}
500
rockot502c94f2016-02-03 20:20:16501void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
502 const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22503 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]d4124852013-03-20 20:25:00504 // Cast to bool below is required because libc++'s
505 // vector<bool>::const_reference is different from bool, and we want to avoid
506 // writing an extra specialization of ParamTraits for it.
[email protected]bf5aedf02012-06-04 21:18:25507 for (size_t i = 0; i < p.size(); i++)
[email protected]d4124852013-03-20 20:25:00508 WriteParam(m, static_cast<bool>(p[i]));
[email protected]bf5aedf02012-06-04 21:18:25509}
510
rockot502c94f2016-02-03 20:20:16511bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25512 base::PickleIterator* iter,
513 param_type* r) {
Peter Kasting28b51cf2022-06-28 15:02:43514 size_t size;
avi48fc13b2014-12-28 23:31:48515 if (!iter->ReadLength(&size))
[email protected]bf5aedf02012-06-04 21:18:25516 return false;
517 r->resize(size);
Peter Kasting28b51cf2022-06-28 15:02:43518 for (size_t i = 0; i < size; i++) {
[email protected]bf5aedf02012-06-04 21:18:25519 bool value;
520 if (!ReadParam(m, iter, &value))
521 return false;
522 (*r)[i] = value;
523 }
524 return true;
525}
526
527void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
528 for (size_t i = 0; i < p.size(); ++i) {
529 if (i != 0)
530 l->push_back(' ');
[email protected]d4124852013-03-20 20:25:00531 LogParam(static_cast<bool>(p[i]), l);
[email protected]bf5aedf02012-06-04 21:18:25532 }
[email protected]d84e48b2010-10-21 22:04:52533}
534
Fabrice de Gans43eebf702022-04-01 23:43:04535void ParamTraits<base::Value::Dict>::Write(base::Pickle* m,
536 const param_type& p) {
537 WriteDictValue(p, 0, m);
538}
539
540bool ParamTraits<base::Value::Dict>::Read(const base::Pickle* m,
541 base::PickleIterator* iter,
542 param_type* r) {
543 return ReadDictValue(m, iter, 0, r);
544}
545
546void ParamTraits<base::Value::Dict>::Log(const param_type& p, std::string* l) {
547 std::string json;
548 base::JSONWriter::Write(p, &json);
549 l->append(json);
550}
551
Xiaohan Wangab909b32022-01-12 17:57:39552#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
rockot502c94f2016-02-03 20:20:16553void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
554 const param_type& p) {
erikchen14525202017-05-06 19:16:51555 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06556 // nacl_message_scanner.cc:WriteHandle().
[email protected]7a4de7a62010-08-17 18:38:24557 const bool valid = p.fd >= 0;
558 WriteParam(m, valid);
559
morrita96693852014-09-24 20:11:45560 if (!valid)
561 return;
562
563 if (p.auto_close) {
morrita1aa788c2015-01-31 05:45:42564 if (!m->WriteAttachment(
565 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
Peter Boströmb7e3e08242024-09-24 22:38:10566 NOTREACHED();
morrita96693852014-09-24 20:11:45567 } else {
morrita1aa788c2015-01-31 05:45:42568 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
Peter Boströmb7e3e08242024-09-24 22:38:10569 NOTREACHED();
[email protected]7a4de7a62010-08-17 18:38:24570 }
571}
572
rockot502c94f2016-02-03 20:20:16573bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25574 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24575 param_type* r) {
morrita96693852014-09-24 20:11:45576 *r = base::FileDescriptor();
577
[email protected]7a4de7a62010-08-17 18:38:24578 bool valid;
579 if (!ReadParam(m, iter, &valid))
580 return false;
581
morrita96693852014-09-24 20:11:45582 if (!valid)
[email protected]7a4de7a62010-08-17 18:38:24583 return true;
[email protected]7a4de7a62010-08-17 18:38:24584
rockot502c94f2016-02-03 20:20:16585 scoped_refptr<base::Pickle::Attachment> attachment;
morrita1aa788c2015-01-31 05:45:42586 if (!m->ReadAttachment(iter, &attachment))
morrita96693852014-09-24 20:11:45587 return false;
588
sammc6ed3efb2016-11-23 03:17:35589 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
590 MessageAttachment::Type::PLATFORM_FILE) {
591 return false;
592 }
593
rockot502c94f2016-02-03 20:20:16594 *r = base::FileDescriptor(
sammc6ed3efb2016-11-23 03:17:35595 static_cast<internal::PlatformFileAttachment*>(attachment.get())
596 ->TakePlatformFile(),
rockot502c94f2016-02-03 20:20:16597 true);
morrita96693852014-09-24 20:11:45598 return true;
[email protected]7a4de7a62010-08-17 18:38:24599}
600
601void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57602 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24603 if (p.auto_close) {
[email protected]7d3cbc92013-03-18 22:33:04604 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24605 } else {
[email protected]7d3cbc92013-03-18 22:33:04606 l->append(base::StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24607 }
608}
Sergey Ulanovac89bb92019-03-22 18:46:49609
610void ParamTraits<base::ScopedFD>::Write(base::Pickle* m, const param_type& p) {
611 // This serialization must be kept in sync with
612 // nacl_message_scanner.cc:WriteHandle().
613 const bool valid = p.is_valid();
614 WriteParam(m, valid);
615
616 if (!valid)
617 return;
618
619 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
620 std::move(const_cast<param_type&>(p))))) {
Peter Boströmb7e3e08242024-09-24 22:38:10621 NOTREACHED();
Sergey Ulanovac89bb92019-03-22 18:46:49622 }
623}
624
625bool ParamTraits<base::ScopedFD>::Read(const base::Pickle* m,
626 base::PickleIterator* iter,
627 param_type* r) {
628 r->reset();
629
630 bool valid;
631 if (!ReadParam(m, iter, &valid))
632 return false;
633
634 if (!valid)
635 return true;
636
637 scoped_refptr<base::Pickle::Attachment> attachment;
638 if (!m->ReadAttachment(iter, &attachment))
639 return false;
640
641 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
642 MessageAttachment::Type::PLATFORM_FILE) {
643 return false;
644 }
645
646 *r = base::ScopedFD(
647 static_cast<internal::PlatformFileAttachment*>(attachment.get())
648 ->TakePlatformFile());
649 return true;
650}
651
652void ParamTraits<base::ScopedFD>::Log(const param_type& p, std::string* l) {
653 l->append(base::StringPrintf("ScopedFD(%d)", p.get()));
654}
Xiaohan Wangab909b32022-01-12 17:57:39655#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
[email protected]7a4de7a62010-08-17 18:38:24656
Xiaohan Wangab909b32022-01-12 17:57:39657#if BUILDFLAG(IS_WIN)
Robert Sesek02910662020-02-28 20:15:51658void ParamTraits<base::win::ScopedHandle>::Write(base::Pickle* m,
659 const param_type& p) {
660 const bool valid = p.IsValid();
661 WriteParam(m, valid);
662 if (!valid)
663 return;
664
665 HandleWin handle(p.Get());
666 WriteParam(m, handle);
667}
668
669bool ParamTraits<base::win::ScopedHandle>::Read(const base::Pickle* m,
670 base::PickleIterator* iter,
671 param_type* r) {
672 r->Close();
673
674 bool valid;
675 if (!ReadParam(m, iter, &valid))
676 return false;
677 if (!valid)
678 return true;
679
680 HandleWin handle;
681 if (!ReadParam(m, iter, &handle))
682 return false;
683
684 r->Set(handle.get_handle());
685 return true;
686}
687
688void ParamTraits<base::win::ScopedHandle>::Log(const param_type& p,
689 std::string* l) {
690 l->append(base::StringPrintf("ScopedHandle(%p)", p.Get()));
691}
Xiaohan Wangab909b32022-01-12 17:57:39692#endif // BUILDFLAG(IS_WIN)
Robert Sesek02910662020-02-28 20:15:51693
Xiaohan Wangab909b32022-01-12 17:57:39694#if BUILDFLAG(IS_FUCHSIA)
Sergey Ulanova97f3282019-04-17 01:27:34695void ParamTraits<zx::vmo>::Write(base::Pickle* m, const param_type& p) {
696 // This serialization must be kept in sync with
697 // nacl_message_scanner.cc:WriteHandle().
698 const bool valid = p.is_valid();
699 WriteParam(m, valid);
700
701 if (!valid)
702 return;
703
704 if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
Sergey Ulanov04367c72019-06-21 15:51:43705 std::move(const_cast<param_type&>(p))))) {
Peter Boströmb7e3e08242024-09-24 22:38:10706 NOTREACHED();
Sergey Ulanova97f3282019-04-17 01:27:34707 }
708}
709
710bool ParamTraits<zx::vmo>::Read(const base::Pickle* m,
711 base::PickleIterator* iter,
712 param_type* r) {
713 r->reset();
714
715 bool valid;
716 if (!ReadParam(m, iter, &valid))
717 return false;
718
719 if (!valid)
720 return true;
721
722 scoped_refptr<base::Pickle::Attachment> attachment;
723 if (!m->ReadAttachment(iter, &attachment))
724 return false;
725
726 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
727 MessageAttachment::Type::FUCHSIA_HANDLE) {
728 return false;
729 }
730
731 *r = zx::vmo(static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
732 ->Take());
733 return true;
734}
735
736void ParamTraits<zx::vmo>::Log(const param_type& p, std::string* l) {
737 l->append("ZirconVMO");
738}
Sergey Ulanov7b343ff2019-08-15 07:52:37739
740void ParamTraits<zx::channel>::Write(base::Pickle* m, const param_type& p) {
741 // This serialization must be kept in sync with
742 // nacl_message_scanner.cc:WriteHandle().
743 const bool valid = p.is_valid();
744 WriteParam(m, valid);
745
746 if (!valid)
747 return;
748
749 if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
750 std::move(const_cast<param_type&>(p))))) {
Peter Boströmb7e3e08242024-09-24 22:38:10751 NOTREACHED();
Sergey Ulanov7b343ff2019-08-15 07:52:37752 }
753}
754
755bool ParamTraits<zx::channel>::Read(const base::Pickle* m,
756 base::PickleIterator* iter,
757 param_type* r) {
758 r->reset();
759
760 bool valid;
761 if (!ReadParam(m, iter, &valid))
762 return false;
763
764 if (!valid)
765 return true;
766
767 scoped_refptr<base::Pickle::Attachment> attachment;
768 if (!m->ReadAttachment(iter, &attachment))
769 return false;
770
771 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
772 MessageAttachment::Type::FUCHSIA_HANDLE) {
773 return false;
774 }
775
776 *r = zx::channel(
777 static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
778 ->Take());
779 return true;
780}
781
782void ParamTraits<zx::channel>::Log(const param_type& p, std::string* l) {
783 l->append("ZirconChannel");
784}
Xiaohan Wangab909b32022-01-12 17:57:39785#endif // BUILDFLAG(IS_FUCHSIA)
Sergey Ulanova97f3282019-04-17 01:27:34786
Xiaohan Wangab909b32022-01-12 17:57:39787#if BUILDFLAG(IS_ANDROID)
Alexandr Ilin0443a8f2018-07-20 20:14:50788void ParamTraits<base::android::ScopedHardwareBufferHandle>::Write(
789 base::Pickle* m,
790 const param_type& p) {
791 const bool is_valid = p.is_valid();
Ken Rockot097248f02018-04-23 16:23:34792 WriteParam(m, is_valid);
793 if (!is_valid)
794 return;
795
Ken Rockot097248f02018-04-23 16:23:34796 // We must keep a ref to the AHardwareBuffer alive until the receiver has
797 // acquired its own reference. We do this by sending a message pipe handle
798 // along with the buffer. When the receiver deserializes (or even if they
799 // die without ever reading the message) their end of the pipe will be
800 // closed. We will eventually detect this and release the AHB reference.
801 mojo::MessagePipe tracking_pipe;
802 m->WriteAttachment(new internal::MojoHandleAttachment(
803 mojo::ScopedHandle::From(std::move(tracking_pipe.handle0))));
Alexandr Ilin0443a8f2018-07-20 20:14:50804 WriteParam(m, base::FileDescriptor(p.SerializeAsFileDescriptor().release(),
805 true /* auto_close */));
Ken Rockot097248f02018-04-23 16:23:34806
807 // Pass ownership of the input handle to our tracking pipe to keep the AHB
808 // alive long enough to be deserialized by the receiver.
Alexandr Ilin0443a8f2018-07-20 20:14:50809 mojo::ScopeToMessagePipe(std::move(const_cast<param_type&>(p)),
810 std::move(tracking_pipe.handle1));
Klaus Weidner3824a8882017-11-03 06:24:57811}
812
Alexandr Ilin0443a8f2018-07-20 20:14:50813bool ParamTraits<base::android::ScopedHardwareBufferHandle>::Read(
814 const base::Pickle* m,
815 base::PickleIterator* iter,
816 param_type* r) {
817 *r = base::android::ScopedHardwareBufferHandle();
Ken Rockot097248f02018-04-23 16:23:34818
819 bool is_valid;
820 if (!ReadParam(m, iter, &is_valid))
Klaus Weidner3824a8882017-11-03 06:24:57821 return false;
Ken Rockot097248f02018-04-23 16:23:34822 if (!is_valid)
823 return true;
824
825 scoped_refptr<base::Pickle::Attachment> tracking_pipe_attachment;
826 if (!m->ReadAttachment(iter, &tracking_pipe_attachment))
Klaus Weidner3824a8882017-11-03 06:24:57827 return false;
Ken Rockot097248f02018-04-23 16:23:34828
829 // We keep this alive until the AHB is safely deserialized below. When this
830 // goes out of scope, the sender holding the other end of this pipe will treat
831 // this handle closure as a signal that it's safe to release their AHB
832 // keepalive ref.
833 mojo::ScopedHandle tracking_pipe =
834 static_cast<MessageAttachment*>(tracking_pipe_attachment.get())
835 ->TakeMojoHandle();
836
837 base::FileDescriptor descriptor;
838 if (!ReadParam(m, iter, &descriptor))
839 return false;
840
841 // NOTE: It is valid to deserialize an invalid FileDescriptor, so the success
842 // of |ReadParam()| above does not imply that |descriptor| is valid.
843 base::ScopedFD scoped_fd(descriptor.fd);
844 if (!scoped_fd.is_valid())
845 return false;
846
847 *r = base::android::ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(
Alexandr Ilin0443a8f2018-07-20 20:14:50848 std::move(scoped_fd));
Klaus Weidner3824a8882017-11-03 06:24:57849 return true;
850}
851
Alexandr Ilin0443a8f2018-07-20 20:14:50852void ParamTraits<base::android::ScopedHardwareBufferHandle>::Log(
853 const param_type& p,
854 std::string* l) {
855 l->append(base::StringPrintf("base::android::ScopedHardwareBufferHandle(%p)",
856 p.get()));
Klaus Weidner3824a8882017-11-03 06:24:57857}
Xiaohan Wangab909b32022-01-12 17:57:39858#endif // BUILDFLAG(IS_ANDROID)
Klaus Weidner3824a8882017-11-03 06:24:57859
Alexandr Ilind497eee2018-04-19 22:50:54860void ParamTraits<base::ReadOnlySharedMemoryRegion>::Write(base::Pickle* m,
861 const param_type& p) {
862 base::subtle::PlatformSharedMemoryRegion handle =
863 base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
864 std::move(const_cast<param_type&>(p)));
865 WriteParam(m, std::move(handle));
866}
867
868bool ParamTraits<base::ReadOnlySharedMemoryRegion>::Read(
869 const base::Pickle* m,
870 base::PickleIterator* iter,
871 param_type* r) {
872 base::subtle::PlatformSharedMemoryRegion handle;
873 if (!ReadParam(m, iter, &handle))
874 return false;
875
876 *r = base::ReadOnlySharedMemoryRegion::Deserialize(std::move(handle));
877 return true;
878}
879
880void ParamTraits<base::ReadOnlySharedMemoryRegion>::Log(const param_type& p,
881 std::string* l) {
882 *l = "<base::ReadOnlySharedMemoryRegion>";
883 // TODO(alexilin): currently there is no way to access underlying handle
884 // without destructing a ReadOnlySharedMemoryRegion instance.
885}
886
887void ParamTraits<base::WritableSharedMemoryRegion>::Write(base::Pickle* m,
888 const param_type& p) {
889 base::subtle::PlatformSharedMemoryRegion handle =
890 base::WritableSharedMemoryRegion::TakeHandleForSerialization(
891 std::move(const_cast<param_type&>(p)));
892 WriteParam(m, std::move(handle));
893}
894
895bool ParamTraits<base::WritableSharedMemoryRegion>::Read(
896 const base::Pickle* m,
897 base::PickleIterator* iter,
898 param_type* r) {
899 base::subtle::PlatformSharedMemoryRegion handle;
900 if (!ReadParam(m, iter, &handle))
901 return false;
902
903 *r = base::WritableSharedMemoryRegion::Deserialize(std::move(handle));
904 return true;
905}
906
907void ParamTraits<base::WritableSharedMemoryRegion>::Log(const param_type& p,
908 std::string* l) {
909 *l = "<base::WritableSharedMemoryRegion>";
910 // TODO(alexilin): currently there is no way to access underlying handle
911 // without destructing a ReadOnlySharedMemoryRegion instance.
912}
913
914void ParamTraits<base::UnsafeSharedMemoryRegion>::Write(base::Pickle* m,
915 const param_type& p) {
916 base::subtle::PlatformSharedMemoryRegion handle =
917 base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
918 std::move(const_cast<param_type&>(p)));
919 WriteParam(m, std::move(handle));
920}
921
922bool ParamTraits<base::UnsafeSharedMemoryRegion>::Read(
923 const base::Pickle* m,
924 base::PickleIterator* iter,
925 param_type* r) {
926 base::subtle::PlatformSharedMemoryRegion handle;
927 if (!ReadParam(m, iter, &handle))
928 return false;
929
930 *r = base::UnsafeSharedMemoryRegion::Deserialize(std::move(handle));
931 return true;
932}
933
934void ParamTraits<base::UnsafeSharedMemoryRegion>::Log(const param_type& p,
935 std::string* l) {
936 *l = "<base::UnsafeSharedMemoryRegion>";
937 // TODO(alexilin): currently there is no way to access underlying handle
938 // without destructing a ReadOnlySharedMemoryRegion instance.
939}
940
941void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Write(
942 base::Pickle* m,
943 const param_type& p) {
Alexandr Ilinebab9da2018-06-01 02:37:47944 // This serialization must be kept in sync with
945 // nacl_message_scanner.cc::WriteHandle().
Alexandr Ilind497eee2018-04-19 22:50:54946 const bool valid = p.IsValid();
947 WriteParam(m, valid);
948
949 if (!valid)
950 return;
951
952 WriteParam(m, p.GetMode());
953 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
954 WriteParam(m, p.GetGUID());
955
Xiaohan Wangab909b32022-01-12 17:57:39956#if BUILDFLAG(IS_WIN)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09957 base::win::ScopedHandle h = const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54958 HandleWin handle_win(h.Get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09959 WriteParam(m, handle_win);
Xiaohan Wangab909b32022-01-12 17:57:39960#elif BUILDFLAG(IS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:43961 zx::vmo vmo = const_cast<param_type&>(p).PassPlatformHandle();
962 WriteParam(m, vmo);
Ali Jumadff201a2022-05-31 23:51:41963#elif BUILDFLAG(IS_APPLE)
Avi Drissmandd92b532023-08-16 22:26:17964 base::apple::ScopedMachSendRight h =
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09965 const_cast<param_type&>(p).PassPlatformHandle();
Alexandr Ilin6544b8a2018-08-15 23:08:54966 MachPortMac mach_port_mac(h.get());
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09967 WriteParam(m, mach_port_mac);
Xiaohan Wangab909b32022-01-12 17:57:39968#elif BUILDFLAG(IS_ANDROID)
Alexandr Ilind497eee2018-04-19 22:50:54969 m->WriteAttachment(new internal::PlatformFileAttachment(
970 base::ScopedFD(const_cast<param_type&>(p).PassPlatformHandle())));
Xiaohan Wangab909b32022-01-12 17:57:39971#elif BUILDFLAG(IS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:54972 base::subtle::ScopedFDPair h =
973 const_cast<param_type&>(p).PassPlatformHandle();
974 m->WriteAttachment(new internal::PlatformFileAttachment(std::move(h.fd)));
975 if (p.GetMode() ==
976 base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
977 m->WriteAttachment(
978 new internal::PlatformFileAttachment(std::move(h.readonly_fd)));
979 }
980#endif
981}
982
983bool ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Read(
984 const base::Pickle* m,
985 base::PickleIterator* iter,
986 param_type* r) {
987 bool valid;
988 if (!ReadParam(m, iter, &valid))
989 return false;
990 if (!valid) {
991 *r = base::subtle::PlatformSharedMemoryRegion();
992 return true;
993 }
994
995 base::subtle::PlatformSharedMemoryRegion::Mode mode;
996 uint64_t shm_size;
997 base::UnguessableToken guid;
998 if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &shm_size) ||
999 !base::IsValueInRangeForNumericType<size_t>(shm_size) ||
1000 !ReadParam(m, iter, &guid)) {
1001 return false;
1002 }
1003 size_t size = static_cast<size_t>(shm_size);
1004
Xiaohan Wangab909b32022-01-12 17:57:391005#if BUILDFLAG(IS_WIN)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091006 HandleWin handle_win;
1007 if (!ReadParam(m, iter, &handle_win))
Alexandr Ilind497eee2018-04-19 22:50:541008 return false;
1009 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091010 base::win::ScopedHandle(handle_win.get_handle()), mode, size, guid);
Xiaohan Wangab909b32022-01-12 17:57:391011#elif BUILDFLAG(IS_FUCHSIA)
Sergey Ulanov04367c72019-06-21 15:51:431012 zx::vmo vmo;
1013 if (!ReadParam(m, iter, &vmo))
Alexandr Ilind497eee2018-04-19 22:50:541014 return false;
Sergey Ulanov04367c72019-06-21 15:51:431015 *r = base::subtle::PlatformSharedMemoryRegion::Take(std::move(vmo), mode,
1016 size, guid);
Ali Jumadff201a2022-05-31 23:51:411017#elif BUILDFLAG(IS_APPLE)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091018 MachPortMac mach_port_mac;
1019 if (!ReadParam(m, iter, &mach_port_mac))
Alexandr Ilind497eee2018-04-19 22:50:541020 return false;
1021 *r = base::subtle::PlatformSharedMemoryRegion::Take(
Avi Drissmandd92b532023-08-16 22:26:171022 base::apple::ScopedMachSendRight(mach_port_mac.get_mach_port()), mode,
1023 size, guid);
Xiaohan Wangab909b32022-01-12 17:57:391024#elif BUILDFLAG(IS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541025 scoped_refptr<base::Pickle::Attachment> attachment;
1026 if (!m->ReadAttachment(iter, &attachment))
1027 return false;
1028 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
1029 MessageAttachment::Type::PLATFORM_FILE) {
1030 return false;
1031 }
1032
Xiaohan Wangab909b32022-01-12 17:57:391033#if BUILDFLAG(IS_ANDROID)
Alexandr Ilind497eee2018-04-19 22:50:541034 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1035 base::ScopedFD(
1036 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1037 ->TakePlatformFile()),
1038 mode, size, guid);
1039#else
1040 scoped_refptr<base::Pickle::Attachment> readonly_attachment;
1041 if (mode == base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
1042 if (!m->ReadAttachment(iter, &readonly_attachment))
1043 return false;
1044
1045 if (static_cast<MessageAttachment*>(readonly_attachment.get())->GetType() !=
1046 MessageAttachment::Type::PLATFORM_FILE) {
1047 return false;
1048 }
1049 }
1050 *r = base::subtle::PlatformSharedMemoryRegion::Take(
1051 base::subtle::ScopedFDPair(
1052 base::ScopedFD(
1053 static_cast<internal::PlatformFileAttachment*>(attachment.get())
1054 ->TakePlatformFile()),
1055 readonly_attachment
1056 ? base::ScopedFD(static_cast<internal::PlatformFileAttachment*>(
1057 readonly_attachment.get())
1058 ->TakePlatformFile())
1059 : base::ScopedFD()),
1060 mode, size, guid);
Xiaohan Wangab909b32022-01-12 17:57:391061#endif // BUILDFLAG(IS_ANDROID)
Alexandr Ilind497eee2018-04-19 22:50:541062
1063#endif
1064
1065 return true;
1066}
1067
1068void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Log(
1069 const param_type& p,
1070 std::string* l) {
Xiaohan Wangab909b32022-01-12 17:57:391071#if BUILDFLAG(IS_FUCHSIA)
Wezb908e432018-09-05 17:35:221072 l->append("Handle: ");
1073 LogParam(p.GetPlatformHandle()->get(), l);
Xiaohan Wangab909b32022-01-12 17:57:391074#elif BUILDFLAG(IS_WIN)
Alexandr Ilind497eee2018-04-19 22:50:541075 l->append("Handle: ");
1076 LogParam(p.GetPlatformHandle(), l);
Ali Jumadff201a2022-05-31 23:51:411077#elif BUILDFLAG(IS_APPLE)
Fabrice de Gans-Ribericbce4342018-05-07 20:02:091078 l->append("Mach port: ");
1079 LogParam(p.GetPlatformHandle(), l);
Xiaohan Wangab909b32022-01-12 17:57:391080#elif BUILDFLAG(IS_ANDROID)
Alexandr Ilind497eee2018-04-19 22:50:541081 l->append("FD: ");
1082 LogParam(p.GetPlatformHandle(), l);
Xiaohan Wangab909b32022-01-12 17:57:391083#elif BUILDFLAG(IS_POSIX)
Alexandr Ilind497eee2018-04-19 22:50:541084 base::subtle::FDPair h = p.GetPlatformHandle();
1085 l->append("FD: ");
1086 LogParam(h.fd, l);
1087 l->append("Read-only FD: ");
1088 LogParam(h.readonly_fd, l);
1089#endif
1090
1091 l->append("Mode: ");
1092 LogParam(p.GetMode(), l);
1093 l->append("size: ");
1094 LogParam(static_cast<uint64_t>(p.GetSize()), l);
1095 l->append("GUID: ");
1096 LogParam(p.GetGUID(), l);
1097}
1098
1099void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Write(
1100 base::Pickle* m,
1101 const param_type& value) {
1102 DCHECK(static_cast<int>(value) >= 0 &&
1103 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue));
1104 m->WriteInt(static_cast<int>(value));
1105}
1106
1107bool ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Read(
1108 const base::Pickle* m,
1109 base::PickleIterator* iter,
1110 param_type* p) {
1111 int value;
1112 if (!iter->ReadInt(&value))
1113 return false;
1114 if (!(static_cast<int>(value) >= 0 &&
1115 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue))) {
1116 return false;
1117 }
1118 *p = static_cast<param_type>(value);
1119 return true;
1120}
1121
1122void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Log(
1123 const param_type& p,
1124 std::string* l) {
1125 LogParam(static_cast<int>(p), l);
1126}
1127
Xiaohan Wangab909b32022-01-12 17:57:391128#if BUILDFLAG(IS_WIN)
erikchend804e1052017-04-29 02:24:361129void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
1130 const param_type& p) {
1131 m->WriteBool(p.IsValid());
1132 if (p.IsValid()) {
Wez51eaaad2017-08-09 05:51:381133 HandleWin handle_win(p.GetHandle());
erikchend804e1052017-04-29 02:24:361134 ParamTraits<HandleWin>::Write(m, handle_win);
1135 ::CloseHandle(p.GetHandle());
1136 }
1137}
1138
1139bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
1140 base::PickleIterator* iter,
1141 param_type* r) {
1142 bool is_valid;
1143 if (!iter->ReadBool(&is_valid))
1144 return false;
1145 if (!is_valid) {
1146 *r = PlatformFileForTransit();
1147 return true;
1148 }
1149
1150 HandleWin handle_win;
1151 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
1152 return false;
1153 *r = PlatformFileForTransit(handle_win.get_handle());
1154 return true;
1155}
1156
1157void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
1158 std::string* l) {
1159 LogParam(p.GetHandle(), l);
1160}
Xiaohan Wangab909b32022-01-12 17:57:391161#endif // BUILDFLAG(IS_WIN)
erikchend804e1052017-04-29 02:24:361162
rockot502c94f2016-02-03 20:20:161163void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:551164 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:251165}
1166
rockot502c94f2016-02-03 20:20:161167bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251168 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:301169 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:551170 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:251171}
1172
[email protected]6d4b67a2013-02-10 04:49:301173void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
1174 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:251175}
1176
Fabrice de Gans43eebf702022-04-01 23:43:041177void ParamTraits<base::Value::List>::Write(base::Pickle* m,
1178 const param_type& p) {
1179 WriteListValue(p, 0, m);
1180}
1181
1182bool ParamTraits<base::Value::List>::Read(const base::Pickle* m,
1183 base::PickleIterator* iter,
1184 param_type* r) {
1185 return ReadListValue(m, iter, 0, r);
1186}
1187
1188void ParamTraits<base::Value::List>::Log(const param_type& p, std::string* l) {
1189 std::string json;
1190 base::JSONWriter::Write(p, &json);
1191 l->append(json);
1192}
1193
Devlin Cronin7178a5bd2021-02-02 02:56:471194void ParamTraits<base::Value>::Write(base::Pickle* m, const param_type& p) {
Fabrice de Gans43eebf702022-04-01 23:43:041195 WriteValue(p, 0, m);
Devlin Cronin7178a5bd2021-02-02 02:56:471196}
1197
1198bool ParamTraits<base::Value>::Read(const base::Pickle* m,
1199 base::PickleIterator* iter,
1200 param_type* r) {
Fabrice de Gans43eebf702022-04-01 23:43:041201 return ReadValue(m, iter, 0, r);
Devlin Cronin7178a5bd2021-02-02 02:56:471202}
1203
1204void ParamTraits<base::Value>::Log(const param_type& p, std::string* l) {
1205 std::string json;
1206 base::JSONWriter::Write(p, &json);
1207 l->append(json);
1208}
1209
rockot502c94f2016-02-03 20:20:161210void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:001211 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251212 WriteParam(m, p.size);
1213 WriteParam(m, p.is_directory);
Peter Kasting08b91b42023-10-21 03:46:091214 WriteParam(m, p.last_modified.InSecondsFSinceUnixEpoch());
1215 WriteParam(m, p.last_accessed.InSecondsFSinceUnixEpoch());
1216 WriteParam(m, p.creation_time.InSecondsFSinceUnixEpoch());
[email protected]bf5aedf02012-06-04 21:18:251217}
1218
rockot502c94f2016-02-03 20:20:161219bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251220 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:001221 param_type* p) {
[email protected]481c3e82014-07-18 01:40:471222 double last_modified, last_accessed, creation_time;
1223 if (!ReadParam(m, iter, &p->size) ||
1224 !ReadParam(m, iter, &p->is_directory) ||
1225 !ReadParam(m, iter, &last_modified) ||
1226 !ReadParam(m, iter, &last_accessed) ||
1227 !ReadParam(m, iter, &creation_time))
1228 return false;
Peter Kasting08b91b42023-10-21 03:46:091229 p->last_modified = base::Time::FromSecondsSinceUnixEpoch(last_modified);
1230 p->last_accessed = base::Time::FromSecondsSinceUnixEpoch(last_accessed);
1231 p->creation_time = base::Time::FromSecondsSinceUnixEpoch(creation_time);
[email protected]481c3e82014-07-18 01:40:471232 return true;
[email protected]bf5aedf02012-06-04 21:18:251233}
1234
[email protected]141bcc52014-01-27 21:36:001235void ParamTraits<base::File::Info>::Log(const param_type& p,
1236 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251237 l->append("(");
1238 LogParam(p.size, l);
1239 l->append(",");
1240 LogParam(p.is_directory, l);
1241 l->append(",");
Peter Kasting08b91b42023-10-21 03:46:091242 LogParam(p.last_modified.InSecondsFSinceUnixEpoch(), l);
[email protected]bf5aedf02012-06-04 21:18:251243 l->append(",");
Peter Kasting08b91b42023-10-21 03:46:091244 LogParam(p.last_accessed.InSecondsFSinceUnixEpoch(), l);
[email protected]bf5aedf02012-06-04 21:18:251245 l->append(",");
Peter Kasting08b91b42023-10-21 03:46:091246 LogParam(p.creation_time.InSecondsFSinceUnixEpoch(), l);
[email protected]bf5aedf02012-06-04 21:18:251247 l->append(")");
1248}
1249
rockot502c94f2016-02-03 20:20:161250void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571251 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251252}
1253
rockot502c94f2016-02-03 20:20:161254bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251255 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251256 param_type* r) {
tfarina10a5c062015-09-04 18:47:571257 int64_t value;
1258 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:251259 return false;
1260 *r = base::Time::FromInternalValue(value);
1261 return true;
1262}
1263
1264void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571265 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251266}
1267
rockot502c94f2016-02-03 20:20:161268void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571269 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251270}
1271
rockot502c94f2016-02-03 20:20:161272bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251273 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251274 param_type* r) {
tfarina10a5c062015-09-04 18:47:571275 int64_t value;
1276 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251277 if (ret)
1278 *r = base::TimeDelta::FromInternalValue(value);
1279
1280 return ret;
1281}
1282
1283void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571284 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251285}
1286
rockot502c94f2016-02-03 20:20:161287void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571288 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251289}
1290
rockot502c94f2016-02-03 20:20:161291bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251292 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251293 param_type* r) {
tfarina10a5c062015-09-04 18:47:571294 int64_t value;
1295 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251296 if (ret)
1297 *r = base::TimeTicks::FromInternalValue(value);
1298
1299 return ret;
1300}
1301
1302void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571303 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251304}
1305
tguilbert4a5ac602016-09-19 21:11:251306// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1307// below should be updated.
1308static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1309 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1310
tguilbert4a5ac602016-09-19 21:11:251311void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1312 const param_type& p) {
1313 DCHECK(!p.is_empty());
1314
1315 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1316 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1317}
1318
1319bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1320 base::PickleIterator* iter,
1321 param_type* r) {
1322 uint64_t high, low;
1323 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1324 !ParamTraits<uint64_t>::Read(m, iter, &low))
1325 return false;
1326
Andrew Williamsc07db022023-01-24 13:38:521327 // This is not mapped as nullable_is_same_type, so any UnguessableToken
1328 // deserialized by the traits should always yield a non-empty token.
1329 // If deserialization results in an empty token, the data is malformed.
Arthur Sonzogni59ac8222023-11-10 09:46:541330 std::optional<base::UnguessableToken> token =
Andrew Williams228be95c2023-01-26 15:13:011331 base::UnguessableToken::Deserialize(high, low);
Andrew Williamsc07db022023-01-24 13:38:521332 if (!token.has_value()) {
tguilbert4a5ac602016-09-19 21:11:251333 return false;
Andrew Williamsc07db022023-01-24 13:38:521334 }
tguilbert4a5ac602016-09-19 21:11:251335
Andrew Williamsc07db022023-01-24 13:38:521336 *r = token.value();
tguilbert4a5ac602016-09-19 21:11:251337 return true;
1338}
1339
1340void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1341 std::string* l) {
1342 l->append(p.ToString());
1343}
1344
rockot502c94f2016-02-03 20:20:161345void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1346 const param_type& p) {
amistry36182522016-06-27 06:34:421347 WriteParam(m, p.mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241348}
1349
rockot502c94f2016-02-03 20:20:161350bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251351 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:241352 param_type* r) {
sammc9bf370c2016-11-14 03:29:081353 return ReadParam(m, iter, &r->mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241354}
1355
1356void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571357 std::string* l) {
sammc9bf370c2016-11-14 03:29:081358 l->append("ChannelHandle(");
amistry36182522016-06-27 06:34:421359 LogParam(p.mojo_handle, l);
[email protected]252cad62010-08-18 18:33:571360 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241361}
1362
rockot502c94f2016-02-03 20:20:161363void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301364 WriteParam(m, p.channel);
1365 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271366 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301367 WriteParam(m, p.flags);
1368 WriteParam(m, p.sent);
1369 WriteParam(m, p.receive);
1370 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451371 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301372 WriteParam(m, p.params);
1373}
1374
rockot502c94f2016-02-03 20:20:161375bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251376 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561377 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271378 return
[email protected]20f0487a2010-09-30 20:06:301379 ReadParam(m, iter, &r->channel) &&
1380 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271381 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301382 ReadParam(m, iter, &r->flags) &&
1383 ReadParam(m, iter, &r->sent) &&
1384 ReadParam(m, iter, &r->receive) &&
1385 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451386 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301387 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301388}
1389
[email protected]bf5aedf02012-06-04 21:18:251390void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1391 // Doesn't make sense to implement this!
1392}
1393
rockot502c94f2016-02-03 20:20:161394void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
Xiaohan Wangab909b32022-01-12 17:57:391395#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
[email protected]34d48612012-06-29 00:05:041396 // We don't serialize the file descriptors in the nested message, so there
1397 // better not be any.
morrita1aa788c2015-01-31 05:45:421398 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041399#endif
1400
Tom Sepez2fc05a72025-06-24 20:02:591401 // Don't just write out the message. This used to send messages between
[email protected]34d48612012-06-29 00:05:041402 // NaCl (Posix environment) and the browser (could be on Windows). The message
1403 // header formats differ between these systems (so does handle sharing, but
1404 // we already asserted we don't have any handles). So just write out the
1405 // parts of the header we use.
1406 //
1407 // Be careful also to use only explicitly-sized types. The NaCl environment
1408 // could be 64-bit and the host browser could be 32-bits. The nested message
1409 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1410 // leave that up to the code sending the message to ensure.
Tom Sepez2fc05a72025-06-24 20:02:591411 // TODO(crbug.com/40511454): remove this code.
tfarina10a5c062015-09-04 18:47:571412 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041413 m->WriteUInt32(p.type());
1414 m->WriteUInt32(p.flags());
Tom Sepez311d8782024-02-14 09:30:521415 m->WriteData(p.payload_bytes());
[email protected]bf5aedf02012-06-04 21:18:251416}
1417
rockot502c94f2016-02-03 20:20:161418bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251419 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251420 Message* r) {
tfarina10a5c062015-09-04 18:47:571421 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481422 if (!iter->ReadUInt32(&routing_id) ||
1423 !iter->ReadUInt32(&type) ||
1424 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251425 return false;
[email protected]34d48612012-06-29 00:05:041426
Peter Kasting28b51cf2022-06-28 15:02:431427 size_t payload_size;
[email protected]34d48612012-06-29 00:05:041428 const char* payload;
avi48fc13b2014-12-28 23:31:481429 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251430 return false;
[email protected]34d48612012-06-29 00:05:041431
tfarina10a5c062015-09-04 18:47:571432 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
Daniel Cheng0d89f9222017-09-22 05:05:071433 r->WriteBytes(payload, payload_size);
1434 return true;
[email protected]bf5aedf02012-06-04 21:18:251435}
1436
1437void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1438 l->append("<IPC::Message>");
1439}
1440
Xiaohan Wangab909b32022-01-12 17:57:391441#if BUILDFLAG(IS_WIN)
[email protected]bf5aedf02012-06-04 21:18:251442// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031443// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161444void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031445 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251446}
1447
rockot502c94f2016-02-03 20:20:161448bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251449 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251450 param_type* r) {
tfarina10a5c062015-09-04 18:47:571451 int32_t temp;
avi48fc13b2014-12-28 23:31:481452 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251453 return false;
[email protected]4a635b72013-03-04 02:29:031454 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251455 return true;
1456}
1457
1458void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001459 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251460}
1461
rockot502c94f2016-02-03 20:20:161462void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251463 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1464}
1465
rockot502c94f2016-02-03 20:20:161466bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251467 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251468 param_type* r) {
1469 const char *data;
Peter Kasting28b51cf2022-06-28 15:02:431470 size_t data_size = 0;
avi48fc13b2014-12-28 23:31:481471 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251472 if (result && data_size == sizeof(MSG)) {
1473 memcpy(r, data, sizeof(MSG));
1474 } else {
Peter Boströmb7e3e08242024-09-24 22:38:101475 NOTREACHED();
[email protected]bf5aedf02012-06-04 21:18:251476 }
1477
1478 return result;
1479}
1480
1481void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1482 l->append("<MSG>");
1483}
1484
Xiaohan Wang53a511632022-01-21 18:14:581485#endif // BUILDFLAG(IS_WIN)
[email protected]bf5aedf02012-06-04 21:18:251486
[email protected]946d1b22009-07-22 23:57:211487} // namespace IPC