blob: ebadd934f9250574533763c8a7bfc84e4c44308a [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"
jdoerrief1e72e32017-04-26 16:23:5512#include "base/memory/ptr_util.h"
[email protected]0238a162013-06-13 13:47:4613#include "base/strings/nullable_string16.h"
[email protected]4aa794a12013-06-11 06:32:1814#include "base/strings/string_number_conversions.h"
[email protected]906265872013-06-07 22:40:4515#include "base/strings/utf_string_conversions.h"
[email protected]b43e5562013-06-28 15:20:0216#include "base/time/time.h"
tguilbert4a5ac602016-09-19 21:11:2517#include "base/unguessable_token.h"
[email protected]946d1b22009-07-22 23:57:2118#include "base/values.h"
avi246998d82015-12-22 02:39:0419#include "build/build_config.h"
[email protected]bf5aedf02012-06-04 21:18:2520#include "ipc/ipc_channel_handle.h"
morrita1aa788c2015-01-31 05:45:4221#include "ipc/ipc_message_attachment.h"
morrita4b5c28e22015-01-14 21:17:0622#include "ipc/ipc_message_attachment_set.h"
amistry36182522016-06-27 06:34:4223#include "ipc/ipc_mojo_param_traits.h"
[email protected]bf5aedf02012-06-04 21:18:2524
morrita1aa788c2015-01-31 05:45:4225#if defined(OS_POSIX)
sammc9bf370c2016-11-14 03:29:0826#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4227#include "ipc/ipc_platform_file_attachment_posix.h"
28#endif
29
erikchenaf8299d2015-10-09 19:12:0630#if defined(OS_MACOSX) && !defined(OS_IOS)
31#include "ipc/mach_port_mac.h"
32#endif
33
morrita4b5c28e22015-01-14 21:17:0634#if defined(OS_WIN)
[email protected]2e02cfe82012-11-21 00:58:0035#include <tchar.h>
erikchen5ea2ab72015-09-25 22:34:3136#include "ipc/handle_win.h"
erikchend804e1052017-04-29 02:24:3637#include "ipc/ipc_platform_file.h"
[email protected]7a4de7a62010-08-17 18:38:2438#endif
[email protected]946d1b22009-07-22 23:57:2139
Scott Graham3eebff02017-06-30 01:07:1040#if defined(OS_FUCHSIA)
41#include "ipc/handle_fuchsia.h"
42#endif
43
[email protected]946d1b22009-07-22 23:57:2144namespace IPC {
45
[email protected]bf5aedf02012-06-04 21:18:2546namespace {
47
joaodasilva383b174a2017-01-10 09:55:3648const int kMaxRecursionDepth = 200;
[email protected]946d1b22009-07-22 23:57:2149
[email protected]bf5aedf02012-06-04 21:18:2550template<typename CharType>
51void LogBytes(const std::vector<CharType>& data, std::string* out) {
52#if defined(OS_WIN)
53 // Windows has a GUI for logging, which can handle arbitrary binary data.
54 for (size_t i = 0; i < data.size(); ++i)
55 out->push_back(data[i]);
56#else
57 // On POSIX, we log to stdout, which we assume can display ASCII.
58 static const size_t kMaxBytesToLog = 100;
59 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
60 if (isprint(data[i]))
61 out->push_back(data[i]);
62 else
[email protected]7d3cbc92013-03-18 22:33:0463 out->append(
64 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]bf5aedf02012-06-04 21:18:2565 }
66 if (data.size() > kMaxBytesToLog) {
[email protected]f8660f82013-03-30 17:29:2867 out->append(base::StringPrintf(
68 " and %u more bytes",
69 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
[email protected]bf5aedf02012-06-04 21:18:2570 }
71#endif
72}
[email protected]946d1b22009-07-22 23:57:2173
rockot502c94f2016-02-03 20:20:1674bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:2575 base::PickleIterator* iter,
jdoerrief1e72e32017-04-26 16:23:5576 std::unique_ptr<base::Value>* value,
[email protected]bf5aedf02012-06-04 21:18:2577 int recursion);
[email protected]946d1b22009-07-22 23:57:2178
rockot502c94f2016-02-03 20:20:1679void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
[email protected]dbc761a2012-07-26 01:29:2180 bool result;
[email protected]946d1b22009-07-22 23:57:2181 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:3682 LOG(ERROR) << "Max recursion depth hit in WriteValue.";
[email protected]946d1b22009-07-22 23:57:2183 return;
84 }
85
jdoerrie76cee9c2017-10-06 22:42:4286 m->WriteInt(static_cast<int>(value->type()));
[email protected]946d1b22009-07-22 23:57:2187
jdoerrie76cee9c2017-10-06 22:42:4288 switch (value->type()) {
jdoerriedc72ee942016-12-07 15:43:2889 case base::Value::Type::NONE:
[email protected]946d1b22009-07-22 23:57:2190 break;
jdoerriedc72ee942016-12-07 15:43:2891 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:2192 bool val;
[email protected]dbc761a2012-07-26 01:29:2193 result = value->GetAsBoolean(&val);
94 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:2195 WriteParam(m, val);
96 break;
97 }
jdoerriedc72ee942016-12-07 15:43:2898 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:2199 int val;
[email protected]dbc761a2012-07-26 01:29:21100 result = value->GetAsInteger(&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::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21106 double val;
[email protected]dbc761a2012-07-26 01:29:21107 result = value->GetAsDouble(&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::STRING: {
[email protected]946d1b22009-07-22 23:57:21113 std::string val;
[email protected]dbc761a2012-07-26 01:29:21114 result = value->GetAsString(&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::BINARY: {
jdoerrie5328aff2017-04-25 20:08:15120 m->WriteData(value->GetBlob().data(),
Chris Palmerc5ea9b92017-09-25 22:53:22121 base::checked_cast<int>(value->GetBlob().size()));
[email protected]e4dad9fb2009-10-06 18:15:58122 break;
[email protected]946d1b22009-07-22 23:57:21123 }
jdoerriedc72ee942016-12-07 15:43:28124 case base::Value::Type::DICTIONARY: {
[email protected]ea5ef4c2013-06-13 22:50:27125 const base::DictionaryValue* dict =
126 static_cast<const base::DictionaryValue*>(value);
[email protected]946d1b22009-07-22 23:57:21127
Chris Palmerc5ea9b92017-09-25 22:53:22128 WriteParam(m, base::checked_cast<int>(dict->size()));
[email protected]946d1b22009-07-22 23:57:21129
[email protected]ea5ef4c2013-06-13 22:50:27130 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
131 it.Advance()) {
[email protected]a899c0b02013-01-18 14:43:27132 WriteParam(m, it.key());
133 WriteValue(m, &it.value(), recursion + 1);
[email protected]946d1b22009-07-22 23:57:21134 }
135 break;
136 }
jdoerriedc72ee942016-12-07 15:43:28137 case base::Value::Type::LIST: {
[email protected]ea5ef4c2013-06-13 22:50:27138 const base::ListValue* list = static_cast<const base::ListValue*>(value);
Chris Palmerc5ea9b92017-09-25 22:53:22139 WriteParam(m, base::checked_cast<int>(list->GetSize()));
dchengcb60e702016-05-25 18:30:47140 for (const auto& entry : *list) {
jdoerriea5676c62017-04-11 18:09:14141 WriteValue(m, &entry, recursion + 1);
[email protected]946d1b22009-07-22 23:57:21142 }
143 break;
144 }
145 }
146}
147
148// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
149// object.
rockot502c94f2016-02-03 20:20:16150bool ReadDictionaryValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25151 base::PickleIterator* iter,
152 base::DictionaryValue* value,
153 int recursion) {
[email protected]946d1b22009-07-22 23:57:21154 int size;
155 if (!ReadParam(m, iter, &size))
156 return false;
157
158 for (int i = 0; i < size; ++i) {
[email protected]e7b418b2010-07-30 19:47:47159 std::string key;
jdoerrief1e72e32017-04-26 16:23:55160 std::unique_ptr<base::Value> subval;
[email protected]946d1b22009-07-22 23:57:21161 if (!ReadParam(m, iter, &key) ||
162 !ReadValue(m, iter, &subval, recursion + 1))
163 return false;
jdoerrief1e72e32017-04-26 16:23:55164 value->SetWithoutPathExpansion(key, std::move(subval));
[email protected]946d1b22009-07-22 23:57:21165 }
166
167 return true;
168}
169
170// Helper for ReadValue that reads a ReadListValue into a pre-allocated
171// object.
rockot502c94f2016-02-03 20:20:16172bool ReadListValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25173 base::PickleIterator* iter,
174 base::ListValue* value,
175 int recursion) {
[email protected]946d1b22009-07-22 23:57:21176 int size;
177 if (!ReadParam(m, iter, &size))
178 return false;
179
180 for (int i = 0; i < size; ++i) {
jdoerrief1e72e32017-04-26 16:23:55181 std::unique_ptr<base::Value> subval;
[email protected]946d1b22009-07-22 23:57:21182 if (!ReadValue(m, iter, &subval, recursion + 1))
183 return false;
jdoerrief1e72e32017-04-26 16:23:55184 value->Set(i, std::move(subval));
[email protected]946d1b22009-07-22 23:57:21185 }
186
187 return true;
188}
189
rockot502c94f2016-02-03 20:20:16190bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25191 base::PickleIterator* iter,
jdoerrief1e72e32017-04-26 16:23:55192 std::unique_ptr<base::Value>* value,
[email protected]bf5aedf02012-06-04 21:18:25193 int recursion) {
[email protected]946d1b22009-07-22 23:57:21194 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:36195 LOG(ERROR) << "Max recursion depth hit in ReadValue.";
[email protected]946d1b22009-07-22 23:57:21196 return false;
197 }
198
199 int type;
200 if (!ReadParam(m, iter, &type))
201 return false;
202
jdoerriedc72ee942016-12-07 15:43:28203 switch (static_cast<base::Value::Type>(type)) {
204 case base::Value::Type::NONE:
Jeremy Roman160eb922017-08-29 17:43:43205 *value = std::make_unique<base::Value>();
jdoerriee067999a2017-04-07 06:39:00206 break;
jdoerriedc72ee942016-12-07 15:43:28207 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21208 bool val;
209 if (!ReadParam(m, iter, &val))
210 return false;
Jeremy Roman160eb922017-08-29 17:43:43211 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21212 break;
213 }
jdoerriedc72ee942016-12-07 15:43:28214 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21215 int val;
216 if (!ReadParam(m, iter, &val))
217 return false;
Jeremy Roman160eb922017-08-29 17:43:43218 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21219 break;
220 }
jdoerriedc72ee942016-12-07 15:43:28221 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21222 double val;
223 if (!ReadParam(m, iter, &val))
224 return false;
Jeremy Roman160eb922017-08-29 17:43:43225 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21226 break;
227 }
jdoerriedc72ee942016-12-07 15:43:28228 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21229 std::string val;
230 if (!ReadParam(m, iter, &val))
231 return false;
Jeremy Roman160eb922017-08-29 17:43:43232 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21233 break;
234 }
jdoerriedc72ee942016-12-07 15:43:28235 case base::Value::Type::BINARY: {
[email protected]e4dad9fb2009-10-06 18:15:58236 const char* data;
237 int length;
avi48fc13b2014-12-28 23:31:48238 if (!iter->ReadData(&data, &length))
[email protected]e4dad9fb2009-10-06 18:15:58239 return false;
jdoerrief1e72e32017-04-26 16:23:55240 *value = base::Value::CreateWithCopiedBuffer(data, length);
[email protected]946d1b22009-07-22 23:57:21241 break;
242 }
jdoerriedc72ee942016-12-07 15:43:28243 case base::Value::Type::DICTIONARY: {
jdoerrief1e72e32017-04-26 16:23:55244 base::DictionaryValue val;
245 if (!ReadDictionaryValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21246 return false;
Jeremy Roman160eb922017-08-29 17:43:43247 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21248 break;
249 }
jdoerriedc72ee942016-12-07 15:43:28250 case base::Value::Type::LIST: {
jdoerrief1e72e32017-04-26 16:23:55251 base::ListValue val;
252 if (!ReadListValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21253 return false;
Jeremy Roman160eb922017-08-29 17:43:43254 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21255 break;
256 }
[email protected]e4dad9fb2009-10-06 18:15:58257 default:
[email protected]946d1b22009-07-22 23:57:21258 return false;
259 }
260
261 return true;
262}
263
[email protected]bf5aedf02012-06-04 21:18:25264} // namespace
265
266// -----------------------------------------------------------------------------
267
268LogData::LogData()
269 : routing_id(0),
270 type(0),
271 sent(0),
272 receive(0),
273 dispatch(0) {
274}
275
vmpstrbf0d713a2016-03-24 20:22:54276LogData::LogData(const LogData& other) = default;
277
Chris Watkins2d879af2017-11-30 02:11:59278LogData::~LogData() = default;
[email protected]bf5aedf02012-06-04 21:18:25279
[email protected]bf5aedf02012-06-04 21:18:25280void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
281 l->append(p ? "true" : "false");
282}
283
rockot502c94f2016-02-03 20:20:16284void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno19ecf1842015-10-30 00:46:20285 m->WriteBytes(&p, sizeof(param_type));
286}
287
rockot502c94f2016-02-03 20:20:16288bool ParamTraits<signed char>::Read(const base::Pickle* m,
289 base::PickleIterator* iter,
290 param_type* r) {
ortuno19ecf1842015-10-30 00:46:20291 const char* data;
292 if (!iter->ReadBytes(&data, sizeof(param_type)))
293 return false;
294 memcpy(r, data, sizeof(param_type));
295 return true;
296}
297
298void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
299 l->append(base::IntToString(p));
300}
301
rockot502c94f2016-02-03 20:20:16302void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28303 m->WriteBytes(&p, sizeof(param_type));
304}
305
rockot502c94f2016-02-03 20:20:16306bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25307 base::PickleIterator* iter,
308 param_type* r) {
[email protected]c1ee48d2013-07-12 23:12:28309 const char* data;
avi48fc13b2014-12-28 23:31:48310 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28311 return false;
312 memcpy(r, data, sizeof(param_type));
313 return true;
314}
315
316void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
317 l->append(base::UintToString(p));
318}
319
rockot502c94f2016-02-03 20:20:16320void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28321 m->WriteBytes(&p, sizeof(param_type));
322}
323
rockot502c94f2016-02-03 20:20:16324bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25325 base::PickleIterator* iter,
[email protected]c1ee48d2013-07-12 23:12:28326 param_type* r) {
327 const char* data;
avi48fc13b2014-12-28 23:31:48328 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28329 return false;
330 memcpy(r, data, sizeof(param_type));
331 return true;
332}
333
334void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09335 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28336}
337
[email protected]252cad62010-08-18 18:33:57338void ParamTraits<int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09339 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57340}
341
342void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09343 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57344}
345
Sergey Ulanova98ff6b52017-07-13 01:54:20346#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_FUCHSIA) || \
jamac78d7d82016-02-11 00:50:28347 (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]252cad62010-08-18 18:33:57348void ParamTraits<long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09349 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57350}
351
352void ParamTraits<unsigned long>::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}
jam03d8a782016-02-10 20:13:39355#endif
[email protected]252cad62010-08-18 18:33:57356
357void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09358 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57359}
360
361void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09362 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57363}
[email protected]7a4de7a62010-08-17 18:38:24364
[email protected]bf5aedf02012-06-04 21:18:25365void ParamTraits<float>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04366 l->append(base::StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24367}
368
rockot502c94f2016-02-03 20:20:16369void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
[email protected]48328ff2013-10-31 09:27:31370 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52371}
372
rockot502c94f2016-02-03 20:20:16373bool ParamTraits<double>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25374 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25375 param_type* r) {
376 const char *data;
avi48fc13b2014-12-28 23:31:48377 if (!iter->ReadBytes(&data, sizeof(*r))) {
[email protected]bf5aedf02012-06-04 21:18:25378 NOTREACHED();
379 return false;
380 }
381 memcpy(r, data, sizeof(param_type));
382 return true;
[email protected]d84e48b2010-10-21 22:04:52383}
384
[email protected]bf5aedf02012-06-04 21:18:25385void ParamTraits<double>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04386 l->append(base::StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04387}
388
[email protected]bf5aedf02012-06-04 21:18:25389
390void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
391 l->append(p);
[email protected]1d14f582011-09-02 20:42:04392}
393
[email protected]476dafb2013-12-03 00:39:26394void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
[email protected]ad65a3e2013-12-25 18:18:01395 l->append(base::UTF16ToUTF8(p));
[email protected]bf5aedf02012-06-04 21:18:25396}
[email protected]bf5aedf02012-06-04 21:18:25397
rockot502c94f2016-02-03 20:20:16398void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
399 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25400 if (p.empty()) {
401 m->WriteData(NULL, 0);
402 } else {
Chris Palmerc5ea9b92017-09-25 22:53:22403 m->WriteData(&p.front(), base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25404 }
405}
406
rockot502c94f2016-02-03 20:20:16407bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25408 base::PickleIterator* iter,
409 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25410 const char *data;
411 int data_size = 0;
avi48fc13b2014-12-28 23:31:48412 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25413 return false;
414 r->resize(data_size);
415 if (data_size)
416 memcpy(&r->front(), data, data_size);
417 return true;
418}
419
420void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
421 LogBytes(p, l);
422}
423
rockot502c94f2016-02-03 20:20:16424void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
425 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25426 if (p.empty()) {
427 m->WriteData(NULL, 0);
428 } else {
429 m->WriteData(reinterpret_cast<const char*>(&p.front()),
Chris Palmerc5ea9b92017-09-25 22:53:22430 base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25431 }
432}
433
rockot502c94f2016-02-03 20:20:16434bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25435 base::PickleIterator* iter,
436 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25437 const char *data;
438 int data_size = 0;
avi48fc13b2014-12-28 23:31:48439 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25440 return false;
441 r->resize(data_size);
442 if (data_size)
443 memcpy(&r->front(), data, data_size);
444 return true;
445}
446
447void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
448 std::string* l) {
449 LogBytes(p, l);
450}
451
rockot502c94f2016-02-03 20:20:16452void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
453 const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22454 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]d4124852013-03-20 20:25:00455 // Cast to bool below is required because libc++'s
456 // vector<bool>::const_reference is different from bool, and we want to avoid
457 // writing an extra specialization of ParamTraits for it.
[email protected]bf5aedf02012-06-04 21:18:25458 for (size_t i = 0; i < p.size(); i++)
[email protected]d4124852013-03-20 20:25:00459 WriteParam(m, static_cast<bool>(p[i]));
[email protected]bf5aedf02012-06-04 21:18:25460}
461
rockot502c94f2016-02-03 20:20:16462bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25463 base::PickleIterator* iter,
464 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25465 int size;
466 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48467 if (!iter->ReadLength(&size))
[email protected]bf5aedf02012-06-04 21:18:25468 return false;
469 r->resize(size);
470 for (int i = 0; i < size; i++) {
471 bool value;
472 if (!ReadParam(m, iter, &value))
473 return false;
474 (*r)[i] = value;
475 }
476 return true;
477}
478
479void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
480 for (size_t i = 0; i < p.size(); ++i) {
481 if (i != 0)
482 l->push_back(' ');
[email protected]d4124852013-03-20 20:25:00483 LogParam(static_cast<bool>(p[i]), l);
[email protected]bf5aedf02012-06-04 21:18:25484 }
[email protected]d84e48b2010-10-21 22:04:52485}
486
rockot502c94f2016-02-03 20:20:16487void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
[email protected]ea5ef4c2013-06-13 22:50:27488 const param_type& p) {
[email protected]946d1b22009-07-22 23:57:21489 WriteValue(m, &p, 0);
490}
491
rockot502c94f2016-02-03 20:20:16492bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25493 base::PickleIterator* iter,
494 param_type* r) {
[email protected]946d1b22009-07-22 23:57:21495 int type;
jdoerriedc72ee942016-12-07 15:43:28496 if (!ReadParam(m, iter, &type) ||
497 type != static_cast<int>(base::Value::Type::DICTIONARY))
[email protected]946d1b22009-07-22 23:57:21498 return false;
499
500 return ReadDictionaryValue(m, iter, r, 0);
501}
502
[email protected]ea5ef4c2013-06-13 22:50:27503void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
504 std::string* l) {
[email protected]946d1b22009-07-22 23:57:21505 std::string json;
estade8d046462015-05-16 01:02:34506 base::JSONWriter::Write(p, &json);
[email protected]252cad62010-08-18 18:33:57507 l->append(json);
[email protected]946d1b22009-07-22 23:57:21508}
509
[email protected]7a4de7a62010-08-17 18:38:24510#if defined(OS_POSIX)
rockot502c94f2016-02-03 20:20:16511void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
512 const param_type& p) {
erikchen14525202017-05-06 19:16:51513 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06514 // nacl_message_scanner.cc:WriteHandle().
[email protected]7a4de7a62010-08-17 18:38:24515 const bool valid = p.fd >= 0;
516 WriteParam(m, valid);
517
morrita96693852014-09-24 20:11:45518 if (!valid)
519 return;
520
521 if (p.auto_close) {
morrita1aa788c2015-01-31 05:45:42522 if (!m->WriteAttachment(
523 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
morrita96693852014-09-24 20:11:45524 NOTREACHED();
525 } else {
morrita1aa788c2015-01-31 05:45:42526 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
[email protected]7a4de7a62010-08-17 18:38:24527 NOTREACHED();
528 }
529}
530
rockot502c94f2016-02-03 20:20:16531bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25532 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24533 param_type* r) {
morrita96693852014-09-24 20:11:45534 *r = base::FileDescriptor();
535
[email protected]7a4de7a62010-08-17 18:38:24536 bool valid;
537 if (!ReadParam(m, iter, &valid))
538 return false;
539
morrita96693852014-09-24 20:11:45540 if (!valid)
[email protected]7a4de7a62010-08-17 18:38:24541 return true;
[email protected]7a4de7a62010-08-17 18:38:24542
rockot502c94f2016-02-03 20:20:16543 scoped_refptr<base::Pickle::Attachment> attachment;
morrita1aa788c2015-01-31 05:45:42544 if (!m->ReadAttachment(iter, &attachment))
morrita96693852014-09-24 20:11:45545 return false;
546
sammc6ed3efb2016-11-23 03:17:35547 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
548 MessageAttachment::Type::PLATFORM_FILE) {
549 return false;
550 }
551
rockot502c94f2016-02-03 20:20:16552 *r = base::FileDescriptor(
sammc6ed3efb2016-11-23 03:17:35553 static_cast<internal::PlatformFileAttachment*>(attachment.get())
554 ->TakePlatformFile(),
rockot502c94f2016-02-03 20:20:16555 true);
morrita96693852014-09-24 20:11:45556 return true;
[email protected]7a4de7a62010-08-17 18:38:24557}
558
559void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57560 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24561 if (p.auto_close) {
[email protected]7d3cbc92013-03-18 22:33:04562 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24563 } else {
[email protected]7d3cbc92013-03-18 22:33:04564 l->append(base::StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24565 }
566}
567#endif // defined(OS_POSIX)
568
Klaus Weidner3824a8882017-11-03 06:24:57569#if defined(OS_ANDROID)
570void ParamTraits<base::SharedMemoryHandle::Type>::Write(base::Pickle* m,
571 const param_type& p) {
572 DCHECK(static_cast<int>(p) >= 0 && p <= base::SharedMemoryHandle::Type::LAST);
573 m->WriteInt(static_cast<int>(p));
574}
575
576bool ParamTraits<base::SharedMemoryHandle::Type>::Read(
577 const base::Pickle* m,
578 base::PickleIterator* iter,
579 param_type* r) {
580 int value;
581 if (!iter->ReadInt(&value))
582 return false;
583 if (value < 0 ||
584 value > static_cast<int>(base::SharedMemoryHandle::Type::LAST))
585 return false;
586 *r = static_cast<param_type>(value);
587 return true;
588}
589
590void ParamTraits<base::SharedMemoryHandle::Type>::Log(const param_type& p,
591 std::string* l) {
592 l->append(base::IntToString(static_cast<int>(p)));
593}
594#endif
595
erikchen22a813b2017-04-28 17:10:50596void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
597 const param_type& p) {
erikchen14525202017-05-06 19:16:51598 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06599 // nacl_message_scanner.cc:WriteHandle().
erikchen22a813b2017-04-28 17:10:50600 const bool valid = p.IsValid();
601 WriteParam(m, valid);
602
603 if (!valid)
604 return;
605
erikchen9d6afd712017-05-18 17:49:06606#if defined(OS_MACOSX) && !defined(OS_IOS)
607 MachPortMac mach_port_mac(p.GetMemoryObject());
608 WriteParam(m, mach_port_mac);
609#elif defined(OS_WIN)
Wez51eaaad2017-08-09 05:51:38610 HandleWin handle_win(p.GetHandle());
erikchen9d6afd712017-05-18 17:49:06611 WriteParam(m, handle_win);
Wez8c49ebc92017-08-10 17:11:13612#elif defined(OS_FUCHSIA)
613 HandleFuchsia handle_fuchsia(p.GetHandle());
614 WriteParam(m, handle_fuchsia);
erikchen9d6afd712017-05-18 17:49:06615#else
Klaus Weidner3824a8882017-11-03 06:24:57616#if defined(OS_ANDROID)
617 // Android transfers both ashmem and AHardwareBuffer SharedMemoryHandle
618 // subtypes, both are transferred via file descriptor but need to be handled
619 // differently by the receiver. Write the type to distinguish.
620 WriteParam(m, p.GetType());
David 'Digit' Turnere2a65762018-01-19 17:51:51621 WriteParam(m, p.IsReadOnly());
622
623 // Ensure the region is read-only before sending it through IPC.
624 if (p.IsReadOnly()) {
625 if (!p.IsRegionReadOnly()) {
626 LOG(ERROR) << "Sending unsealed read-only region through IPC";
627 p.SetRegionReadOnly();
628 }
629 }
Klaus Weidner3824a8882017-11-03 06:24:57630#endif
erikchen22a813b2017-04-28 17:10:50631 if (p.OwnershipPassesToIPC()) {
632 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
633 base::ScopedFD(p.GetHandle()))))
634 NOTREACHED();
635 } else {
636 if (!m->WriteAttachment(
637 new internal::PlatformFileAttachment(p.GetHandle())))
638 NOTREACHED();
639 }
erikchen9d6afd712017-05-18 17:49:06640#endif
641
642#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
643 // If the caller intended to pass ownership to the IPC stack, release a
644 // reference.
645 if (p.OwnershipPassesToIPC())
646 p.Close();
647#endif
648
erikchen14525202017-05-06 19:16:51649 DCHECK(!p.GetGUID().is_empty());
650 WriteParam(m, p.GetGUID());
erikchen9d6afd712017-05-18 17:49:06651 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
erikchen22a813b2017-04-28 17:10:50652}
653
654bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
655 base::PickleIterator* iter,
656 param_type* r) {
657 *r = base::SharedMemoryHandle();
658
659 bool valid;
660 if (!ReadParam(m, iter, &valid))
661 return false;
erikchen22a813b2017-04-28 17:10:50662 if (!valid)
663 return true;
664
erikchen9d6afd712017-05-18 17:49:06665#if defined(OS_MACOSX) && !defined(OS_IOS)
666 MachPortMac mach_port_mac;
667 if (!ReadParam(m, iter, &mach_port_mac))
668 return false;
669#elif defined(OS_WIN)
670 HandleWin handle_win;
671 if (!ReadParam(m, iter, &handle_win))
672 return false;
Scott Graham3eebff02017-06-30 01:07:10673#elif defined(OS_FUCHSIA)
674 HandleFuchsia handle_fuchsia;
675 if (!ReadParam(m, iter, &handle_fuchsia))
676 return false;
erikchen9d6afd712017-05-18 17:49:06677#else
Klaus Weidner3824a8882017-11-03 06:24:57678#if defined(OS_ANDROID)
679 // Android uses both ashmen and AHardwareBuffer subtypes, get the actual type
680 // for use as a constructor argument alongside the file descriptor.
681 base::SharedMemoryHandle::Type android_subtype;
David 'Digit' Turnere2a65762018-01-19 17:51:51682 bool is_read_only = false;
683 if (!ReadParam(m, iter, &android_subtype) ||
684 !ReadParam(m, iter, &is_read_only)) {
Klaus Weidner3824a8882017-11-03 06:24:57685 return false;
David 'Digit' Turnere2a65762018-01-19 17:51:51686 }
Klaus Weidner3824a8882017-11-03 06:24:57687#endif
erikchen22a813b2017-04-28 17:10:50688 scoped_refptr<base::Pickle::Attachment> attachment;
689 if (!m->ReadAttachment(iter, &attachment))
690 return false;
691
692 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
693 MessageAttachment::Type::PLATFORM_FILE) {
694 return false;
695 }
erikchen9d6afd712017-05-18 17:49:06696#endif
erikchen22a813b2017-04-28 17:10:50697
erikchen14525202017-05-06 19:16:51698 base::UnguessableToken guid;
erikchen9d6afd712017-05-18 17:49:06699 uint64_t size;
700 if (!ReadParam(m, iter, &guid) || !ReadParam(m, iter, &size)) {
erikchen14525202017-05-06 19:16:51701 return false;
erikchen9d6afd712017-05-18 17:49:06702 }
erikchen14525202017-05-06 19:16:51703
erikchen9d6afd712017-05-18 17:49:06704#if defined(OS_MACOSX) && !defined(OS_IOS)
705 *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
706 static_cast<size_t>(size), guid);
707#elif defined(OS_WIN)
708 *r = base::SharedMemoryHandle(handle_win.get_handle(),
709 static_cast<size_t>(size), guid);
Scott Graham3eebff02017-06-30 01:07:10710#elif defined(OS_FUCHSIA)
711 *r = base::SharedMemoryHandle(handle_fuchsia.get_handle(),
712 static_cast<size_t>(size), guid);
Klaus Weidner3824a8882017-11-03 06:24:57713#elif defined(OS_ANDROID)
714 *r = base::SharedMemoryHandle(
715 android_subtype,
716 base::FileDescriptor(
717 static_cast<internal::PlatformFileAttachment*>(attachment.get())
718 ->TakePlatformFile(),
719 true),
720 static_cast<size_t>(size), guid);
David 'Digit' Turnere2a65762018-01-19 17:51:51721 if (is_read_only)
722 r->SetReadOnly();
erikchen9d6afd712017-05-18 17:49:06723#else
erikchen14525202017-05-06 19:16:51724 *r = base::SharedMemoryHandle(
725 base::FileDescriptor(
726 static_cast<internal::PlatformFileAttachment*>(attachment.get())
727 ->TakePlatformFile(),
728 true),
erikchen9d6afd712017-05-18 17:49:06729 static_cast<size_t>(size), guid);
730#endif
731
erikchen22a813b2017-04-28 17:10:50732 return true;
733}
734
735void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
736 std::string* l) {
erikchen9d6afd712017-05-18 17:49:06737#if defined(OS_MACOSX) && !defined(OS_IOS)
738 l->append("Mach port: ");
739 LogParam(p.GetMemoryObject(), l);
740#elif defined(OS_WIN)
741 l->append("HANDLE: ");
742 LogParam(p.GetHandle(), l);
743#else
744 l->append("FD: ");
745 LogParam(p.GetHandle(), l);
746#endif
747
erikchen14525202017-05-06 19:16:51748 l->append("GUID: ");
erikchen9d6afd712017-05-18 17:49:06749 LogParam(p.GetGUID(), l);
750 l->append("size: ");
751 LogParam(static_cast<uint64_t>(p.GetSize()), l);
David 'Digit' Turnere2a65762018-01-19 17:51:51752#if defined(OS_ANDROID)
753 l->append("read-only: ");
754 LogParam(p.IsReadOnly(), l);
755#endif
erikchen22a813b2017-04-28 17:10:50756}
scottmgd19b4f72015-06-19 22:51:00757
erikchend804e1052017-04-29 02:24:36758#if defined(OS_WIN)
erikchend804e1052017-04-29 02:24:36759void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
760 const param_type& p) {
761 m->WriteBool(p.IsValid());
762 if (p.IsValid()) {
Wez51eaaad2017-08-09 05:51:38763 HandleWin handle_win(p.GetHandle());
erikchend804e1052017-04-29 02:24:36764 ParamTraits<HandleWin>::Write(m, handle_win);
765 ::CloseHandle(p.GetHandle());
766 }
767}
768
769bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
770 base::PickleIterator* iter,
771 param_type* r) {
772 bool is_valid;
773 if (!iter->ReadBool(&is_valid))
774 return false;
775 if (!is_valid) {
776 *r = PlatformFileForTransit();
777 return true;
778 }
779
780 HandleWin handle_win;
781 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
782 return false;
783 *r = PlatformFileForTransit(handle_win.get_handle());
784 return true;
785}
786
787void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
788 std::string* l) {
789 LogParam(p.GetHandle(), l);
790}
791#endif // defined(OS_WIN)
792
rockot502c94f2016-02-03 20:20:16793void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:55794 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:25795}
796
rockot502c94f2016-02-03 20:20:16797bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25798 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:30799 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:55800 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:25801}
802
[email protected]6d4b67a2013-02-10 04:49:30803void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
804 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:25805}
806
rockot502c94f2016-02-03 20:20:16807void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25808 WriteValue(m, &p, 0);
809}
810
rockot502c94f2016-02-03 20:20:16811bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25812 base::PickleIterator* iter,
813 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25814 int type;
jdoerriedc72ee942016-12-07 15:43:28815 if (!ReadParam(m, iter, &type) ||
816 type != static_cast<int>(base::Value::Type::LIST))
[email protected]bf5aedf02012-06-04 21:18:25817 return false;
818
819 return ReadListValue(m, iter, r, 0);
820}
821
[email protected]ea5ef4c2013-06-13 22:50:27822void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25823 std::string json;
estade8d046462015-05-16 01:02:34824 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:25825 l->append(json);
826}
827
rockot502c94f2016-02-03 20:20:16828void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
[email protected]0238a162013-06-13 13:47:46829 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25830 WriteParam(m, p.string());
831 WriteParam(m, p.is_null());
832}
833
rockot502c94f2016-02-03 20:20:16834bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25835 base::PickleIterator* iter,
[email protected]0238a162013-06-13 13:47:46836 param_type* r) {
[email protected]476dafb2013-12-03 00:39:26837 base::string16 string;
[email protected]bf5aedf02012-06-04 21:18:25838 if (!ReadParam(m, iter, &string))
839 return false;
840 bool is_null;
841 if (!ReadParam(m, iter, &is_null))
842 return false;
[email protected]0238a162013-06-13 13:47:46843 *r = base::NullableString16(string, is_null);
[email protected]bf5aedf02012-06-04 21:18:25844 return true;
845}
846
[email protected]0238a162013-06-13 13:47:46847void ParamTraits<base::NullableString16>::Log(const param_type& p,
848 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25849 l->append("(");
850 LogParam(p.string(), l);
851 l->append(", ");
852 LogParam(p.is_null(), l);
853 l->append(")");
854}
855
rockot502c94f2016-02-03 20:20:16856void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:00857 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25858 WriteParam(m, p.size);
859 WriteParam(m, p.is_directory);
860 WriteParam(m, p.last_modified.ToDoubleT());
861 WriteParam(m, p.last_accessed.ToDoubleT());
862 WriteParam(m, p.creation_time.ToDoubleT());
863}
864
rockot502c94f2016-02-03 20:20:16865bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25866 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:00867 param_type* p) {
[email protected]481c3e82014-07-18 01:40:47868 double last_modified, last_accessed, creation_time;
869 if (!ReadParam(m, iter, &p->size) ||
870 !ReadParam(m, iter, &p->is_directory) ||
871 !ReadParam(m, iter, &last_modified) ||
872 !ReadParam(m, iter, &last_accessed) ||
873 !ReadParam(m, iter, &creation_time))
874 return false;
875 p->last_modified = base::Time::FromDoubleT(last_modified);
876 p->last_accessed = base::Time::FromDoubleT(last_accessed);
877 p->creation_time = base::Time::FromDoubleT(creation_time);
878 return true;
[email protected]bf5aedf02012-06-04 21:18:25879}
880
[email protected]141bcc52014-01-27 21:36:00881void ParamTraits<base::File::Info>::Log(const param_type& p,
882 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25883 l->append("(");
884 LogParam(p.size, l);
885 l->append(",");
886 LogParam(p.is_directory, l);
887 l->append(",");
888 LogParam(p.last_modified.ToDoubleT(), l);
889 l->append(",");
890 LogParam(p.last_accessed.ToDoubleT(), l);
891 l->append(",");
892 LogParam(p.creation_time.ToDoubleT(), l);
893 l->append(")");
894}
895
rockot502c94f2016-02-03 20:20:16896void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57897 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:25898}
899
rockot502c94f2016-02-03 20:20:16900bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25901 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25902 param_type* r) {
tfarina10a5c062015-09-04 18:47:57903 int64_t value;
904 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:25905 return false;
906 *r = base::Time::FromInternalValue(value);
907 return true;
908}
909
910void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57911 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:25912}
913
rockot502c94f2016-02-03 20:20:16914void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57915 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:25916}
917
rockot502c94f2016-02-03 20:20:16918bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25919 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25920 param_type* r) {
tfarina10a5c062015-09-04 18:47:57921 int64_t value;
922 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:25923 if (ret)
924 *r = base::TimeDelta::FromInternalValue(value);
925
926 return ret;
927}
928
929void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57930 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:25931}
932
rockot502c94f2016-02-03 20:20:16933void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57934 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:25935}
936
rockot502c94f2016-02-03 20:20:16937bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25938 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25939 param_type* r) {
tfarina10a5c062015-09-04 18:47:57940 int64_t value;
941 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:25942 if (ret)
943 *r = base::TimeTicks::FromInternalValue(value);
944
945 return ret;
946}
947
948void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57949 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:25950}
951
tguilbert4a5ac602016-09-19 21:11:25952// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
953// below should be updated.
954static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
955 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
956
tguilbert4a5ac602016-09-19 21:11:25957void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
958 const param_type& p) {
959 DCHECK(!p.is_empty());
960
erikchen14525202017-05-06 19:16:51961 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06962 // nacl_message_scanner.cc:WriteHandle().
tguilbert4a5ac602016-09-19 21:11:25963 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
964 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
965}
966
967bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
968 base::PickleIterator* iter,
969 param_type* r) {
970 uint64_t high, low;
971 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
972 !ParamTraits<uint64_t>::Read(m, iter, &low))
973 return false;
974
975 // Receiving a zeroed UnguessableToken is a security issue.
976 if (high == 0 && low == 0)
977 return false;
978
979 *r = base::UnguessableToken::Deserialize(high, low);
980 return true;
981}
982
983void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
984 std::string* l) {
985 l->append(p.ToString());
986}
987
rockot502c94f2016-02-03 20:20:16988void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
989 const param_type& p) {
sammc9bf370c2016-11-14 03:29:08990#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:24991 WriteParam(m, p.socket);
sammc9bf370c2016-11-14 03:29:08992#else
amistry36182522016-06-27 06:34:42993 WriteParam(m, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:08994#endif
[email protected]7a4de7a62010-08-17 18:38:24995}
996
rockot502c94f2016-02-03 20:20:16997bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25998 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24999 param_type* r) {
sammc9bf370c2016-11-14 03:29:081000#if defined(OS_NACL_SFI)
1001 return ReadParam(m, iter, &r->socket);
1002#else
1003 return ReadParam(m, iter, &r->mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241004#endif
[email protected]7a4de7a62010-08-17 18:38:241005}
1006
1007void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571008 std::string* l) {
sammc9bf370c2016-11-14 03:29:081009 l->append("ChannelHandle(");
1010#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241011 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
sammc9bf370c2016-11-14 03:29:081012#else
amistry36182522016-06-27 06:34:421013 LogParam(p.mojo_handle, l);
sammc9bf370c2016-11-14 03:29:081014#endif
[email protected]252cad62010-08-18 18:33:571015 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241016}
1017
rockot502c94f2016-02-03 20:20:161018void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301019 WriteParam(m, p.channel);
1020 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271021 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301022 WriteParam(m, p.flags);
1023 WriteParam(m, p.sent);
1024 WriteParam(m, p.receive);
1025 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451026 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301027 WriteParam(m, p.params);
1028}
1029
rockot502c94f2016-02-03 20:20:161030bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251031 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561032 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271033 return
[email protected]20f0487a2010-09-30 20:06:301034 ReadParam(m, iter, &r->channel) &&
1035 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271036 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301037 ReadParam(m, iter, &r->flags) &&
1038 ReadParam(m, iter, &r->sent) &&
1039 ReadParam(m, iter, &r->receive) &&
1040 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451041 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301042 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301043}
1044
[email protected]bf5aedf02012-06-04 21:18:251045void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1046 // Doesn't make sense to implement this!
1047}
1048
rockot502c94f2016-02-03 20:20:161049void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
[email protected]34d48612012-06-29 00:05:041050#if defined(OS_POSIX)
1051 // We don't serialize the file descriptors in the nested message, so there
1052 // better not be any.
morrita1aa788c2015-01-31 05:45:421053 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041054#endif
1055
1056 // Don't just write out the message. This is used to send messages between
1057 // NaCl (Posix environment) and the browser (could be on Windows). The message
1058 // header formats differ between these systems (so does handle sharing, but
1059 // we already asserted we don't have any handles). So just write out the
1060 // parts of the header we use.
1061 //
1062 // Be careful also to use only explicitly-sized types. The NaCl environment
1063 // could be 64-bit and the host browser could be 32-bits. The nested message
1064 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1065 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:571066 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041067 m->WriteUInt32(p.type());
1068 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:571069 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:251070}
1071
rockot502c94f2016-02-03 20:20:161072bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251073 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251074 Message* r) {
tfarina10a5c062015-09-04 18:47:571075 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481076 if (!iter->ReadUInt32(&routing_id) ||
1077 !iter->ReadUInt32(&type) ||
1078 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251079 return false;
[email protected]34d48612012-06-29 00:05:041080
1081 int payload_size;
1082 const char* payload;
avi48fc13b2014-12-28 23:31:481083 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251084 return false;
[email protected]34d48612012-06-29 00:05:041085
tfarina10a5c062015-09-04 18:47:571086 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
Daniel Cheng0d89f9222017-09-22 05:05:071087 r->WriteBytes(payload, payload_size);
1088 return true;
[email protected]bf5aedf02012-06-04 21:18:251089}
1090
1091void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1092 l->append("<IPC::Message>");
1093}
1094
1095#if defined(OS_WIN)
1096// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031097// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161098void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031099 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251100}
1101
rockot502c94f2016-02-03 20:20:161102bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251103 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251104 param_type* r) {
tfarina10a5c062015-09-04 18:47:571105 int32_t temp;
avi48fc13b2014-12-28 23:31:481106 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251107 return false;
[email protected]4a635b72013-03-04 02:29:031108 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251109 return true;
1110}
1111
1112void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001113 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251114}
1115
rockot502c94f2016-02-03 20:20:161116void ParamTraits<LOGFONT>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251117 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
1118}
1119
rockot502c94f2016-02-03 20:20:161120bool ParamTraits<LOGFONT>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251121 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251122 param_type* r) {
1123 const char *data;
1124 int data_size = 0;
avi48fc13b2014-12-28 23:31:481125 if (iter->ReadData(&data, &data_size) && data_size == sizeof(LOGFONT)) {
[email protected]2e02cfe82012-11-21 00:58:001126 const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data));
1127 if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) {
1128 memcpy(r, data, sizeof(LOGFONT));
1129 return true;
1130 }
[email protected]bf5aedf02012-06-04 21:18:251131 }
1132
[email protected]2e02cfe82012-11-21 00:58:001133 NOTREACHED();
1134 return false;
[email protected]bf5aedf02012-06-04 21:18:251135}
1136
1137void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:041138 l->append(base::StringPrintf("<LOGFONT>"));
[email protected]bf5aedf02012-06-04 21:18:251139}
1140
rockot502c94f2016-02-03 20:20:161141void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251142 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1143}
1144
rockot502c94f2016-02-03 20:20:161145bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251146 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251147 param_type* r) {
1148 const char *data;
1149 int data_size = 0;
avi48fc13b2014-12-28 23:31:481150 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251151 if (result && data_size == sizeof(MSG)) {
1152 memcpy(r, data, sizeof(MSG));
1153 } else {
1154 result = false;
1155 NOTREACHED();
1156 }
1157
1158 return result;
1159}
1160
1161void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1162 l->append("<MSG>");
1163}
1164
1165#endif // OS_WIN
1166
[email protected]946d1b22009-07-22 23:57:211167} // namespace IPC