1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // 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 7 #include <stddef.h> 8 #include <stdint.h> 9 10 #include "base/files/file_path.h" 11 #include "base/json/json_writer.h" 12 #include "base/strings/nullable_string16.h" 13 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/utf_string_conversions.h" 15 #include "base/time/time.h" 16 #include "base/values.h" 17 #include "build/build_config.h" 18 #include "ipc/ipc_channel_handle.h" 19 #include "ipc/ipc_message_attachment.h" 20 #include "ipc/ipc_message_attachment_set.h" 21 #include "ipc/ipc_mojo_param_traits.h" 22 23 #if defined(OS_POSIX) 24 #include "ipc/ipc_platform_file_attachment_posix.h" 25 #endif 26 27 #if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN) 28 #include "base/memory/shared_memory_handle.h" 29 #endif // (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN) 30 31 #if defined(OS_MACOSX) && !defined(OS_IOS) 32 #include "ipc/mach_port_mac.h" 33 #endif 34 35 #if defined(OS_WIN) 36 #include <tchar.h> 37 #include "ipc/handle_win.h" 38 #endif 39 40 namespace IPC { 41 42 namespace { 43 44 const int kMaxRecursionDepth = 100; 45 46 template<typename CharType> 47 void LogBytes(const std::vector<CharType>& data, std::string* out) { 48 #if defined(OS_WIN) 49 // Windows has a GUI for logging, which can handle arbitrary binary data. 50 for (size_t i = 0; i < data.size(); ++i) 51 out->push_back(data[i]); 52 #else 53 // On POSIX, we log to stdout, which we assume can display ASCII. 54 static const size_t kMaxBytesToLog = 100; 55 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) { 56 if (isprint(data[i])) 57 out->push_back(data[i]); 58 else 59 out->append( 60 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i]))); 61 } 62 if (data.size() > kMaxBytesToLog) { 63 out->append(base::StringPrintf( 64 " and %u more bytes", 65 static_cast<unsigned>(data.size() - kMaxBytesToLog))); 66 } 67 #endif 68 } 69 70 bool ReadValue(const base::Pickle* m, 71 base::PickleIterator* iter, 72 base::Value** value, 73 int recursion); 74 75 void GetValueSize(base::PickleSizer* sizer, 76 const base::Value* value, 77 int recursion) { 78 if (recursion > kMaxRecursionDepth) { 79 LOG(WARNING) << "Max recursion depth hit in GetValueSize."; 80 return; 81 } 82 83 sizer->AddInt(); 84 switch (value->GetType()) { 85 case base::Value::TYPE_NULL: 86 break; 87 case base::Value::TYPE_BOOLEAN: 88 sizer->AddBool(); 89 break; 90 case base::Value::TYPE_INTEGER: 91 sizer->AddInt(); 92 break; 93 case base::Value::TYPE_DOUBLE: 94 sizer->AddDouble(); 95 break; 96 case base::Value::TYPE_STRING: { 97 const base::StringValue* result; 98 value->GetAsString(&result); 99 if (value->GetAsString(&result)) { 100 DCHECK(result); 101 GetParamSize(sizer, result->GetString()); 102 } else { 103 std::string str; 104 bool as_string_result = value->GetAsString(&str); 105 DCHECK(as_string_result); 106 GetParamSize(sizer, str); 107 } 108 break; 109 } 110 case base::Value::TYPE_BINARY: { 111 const base::BinaryValue* binary = 112 static_cast<const base::BinaryValue*>(value); 113 sizer->AddData(static_cast<int>(binary->GetSize())); 114 break; 115 } 116 case base::Value::TYPE_DICTIONARY: { 117 sizer->AddInt(); 118 const base::DictionaryValue* dict = 119 static_cast<const base::DictionaryValue*>(value); 120 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); 121 it.Advance()) { 122 GetParamSize(sizer, it.key()); 123 GetValueSize(sizer, &it.value(), recursion + 1); 124 } 125 break; 126 } 127 case base::Value::TYPE_LIST: { 128 sizer->AddInt(); 129 const base::ListValue* list = static_cast<const base::ListValue*>(value); 130 for (const auto& entry : *list) { 131 GetValueSize(sizer, entry.get(), recursion + 1); 132 } 133 break; 134 } 135 default: 136 NOTREACHED() << "Invalid base::Value type."; 137 } 138 } 139 140 void WriteValue(base::Pickle* m, const base::Value* value, int recursion) { 141 bool result; 142 if (recursion > kMaxRecursionDepth) { 143 LOG(WARNING) << "Max recursion depth hit in WriteValue."; 144 return; 145 } 146 147 m->WriteInt(value->GetType()); 148 149 switch (value->GetType()) { 150 case base::Value::TYPE_NULL: 151 break; 152 case base::Value::TYPE_BOOLEAN: { 153 bool val; 154 result = value->GetAsBoolean(&val); 155 DCHECK(result); 156 WriteParam(m, val); 157 break; 158 } 159 case base::Value::TYPE_INTEGER: { 160 int val; 161 result = value->GetAsInteger(&val); 162 DCHECK(result); 163 WriteParam(m, val); 164 break; 165 } 166 case base::Value::TYPE_DOUBLE: { 167 double val; 168 result = value->GetAsDouble(&val); 169 DCHECK(result); 170 WriteParam(m, val); 171 break; 172 } 173 case base::Value::TYPE_STRING: { 174 std::string val; 175 result = value->GetAsString(&val); 176 DCHECK(result); 177 WriteParam(m, val); 178 break; 179 } 180 case base::Value::TYPE_BINARY: { 181 const base::BinaryValue* binary = 182 static_cast<const base::BinaryValue*>(value); 183 m->WriteData(binary->GetBuffer(), static_cast<int>(binary->GetSize())); 184 break; 185 } 186 case base::Value::TYPE_DICTIONARY: { 187 const base::DictionaryValue* dict = 188 static_cast<const base::DictionaryValue*>(value); 189 190 WriteParam(m, static_cast<int>(dict->size())); 191 192 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); 193 it.Advance()) { 194 WriteParam(m, it.key()); 195 WriteValue(m, &it.value(), recursion + 1); 196 } 197 break; 198 } 199 case base::Value::TYPE_LIST: { 200 const base::ListValue* list = static_cast<const base::ListValue*>(value); 201 WriteParam(m, static_cast<int>(list->GetSize())); 202 for (const auto& entry : *list) { 203 WriteValue(m, entry.get(), recursion + 1); 204 } 205 break; 206 } 207 } 208 } 209 210 // Helper for ReadValue that reads a DictionaryValue into a pre-allocated 211 // object. 212 bool ReadDictionaryValue(const base::Pickle* m, 213 base::PickleIterator* iter, 214 base::DictionaryValue* value, 215 int recursion) { 216 int size; 217 if (!ReadParam(m, iter, &size)) 218 return false; 219 220 for (int i = 0; i < size; ++i) { 221 std::string key; 222 base::Value* subval; 223 if (!ReadParam(m, iter, &key) || 224 !ReadValue(m, iter, &subval, recursion + 1)) 225 return false; 226 value->SetWithoutPathExpansion(key, subval); 227 } 228 229 return true; 230 } 231 232 // Helper for ReadValue that reads a ReadListValue into a pre-allocated 233 // object. 234 bool ReadListValue(const base::Pickle* m, 235 base::PickleIterator* iter, 236 base::ListValue* value, 237 int recursion) { 238 int size; 239 if (!ReadParam(m, iter, &size)) 240 return false; 241 242 for (int i = 0; i < size; ++i) { 243 base::Value* subval; 244 if (!ReadValue(m, iter, &subval, recursion + 1)) 245 return false; 246 value->Set(i, subval); 247 } 248 249 return true; 250 } 251 252 bool ReadValue(const base::Pickle* m, 253 base::PickleIterator* iter, 254 base::Value** value, 255 int recursion) { 256 if (recursion > kMaxRecursionDepth) { 257 LOG(WARNING) << "Max recursion depth hit in ReadValue."; 258 return false; 259 } 260 261 int type; 262 if (!ReadParam(m, iter, &type)) 263 return false; 264 265 switch (type) { 266 case base::Value::TYPE_NULL: 267 *value = base::Value::CreateNullValue().release(); 268 break; 269 case base::Value::TYPE_BOOLEAN: { 270 bool val; 271 if (!ReadParam(m, iter, &val)) 272 return false; 273 *value = new base::FundamentalValue(val); 274 break; 275 } 276 case base::Value::TYPE_INTEGER: { 277 int val; 278 if (!ReadParam(m, iter, &val)) 279 return false; 280 *value = new base::FundamentalValue(val); 281 break; 282 } 283 case base::Value::TYPE_DOUBLE: { 284 double val; 285 if (!ReadParam(m, iter, &val)) 286 return false; 287 *value = new base::FundamentalValue(val); 288 break; 289 } 290 case base::Value::TYPE_STRING: { 291 std::string val; 292 if (!ReadParam(m, iter, &val)) 293 return false; 294 *value = new base::StringValue(val); 295 break; 296 } 297 case base::Value::TYPE_BINARY: { 298 const char* data; 299 int length; 300 if (!iter->ReadData(&data, &length)) 301 return false; 302 std::unique_ptr<base::BinaryValue> val = 303 base::BinaryValue::CreateWithCopiedBuffer(data, length); 304 *value = val.release(); 305 break; 306 } 307 case base::Value::TYPE_DICTIONARY: { 308 std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue()); 309 if (!ReadDictionaryValue(m, iter, val.get(), recursion)) 310 return false; 311 *value = val.release(); 312 break; 313 } 314 case base::Value::TYPE_LIST: { 315 std::unique_ptr<base::ListValue> val(new base::ListValue()); 316 if (!ReadListValue(m, iter, val.get(), recursion)) 317 return false; 318 *value = val.release(); 319 break; 320 } 321 default: 322 return false; 323 } 324 325 return true; 326 } 327 328 } // namespace 329 330 // ----------------------------------------------------------------------------- 331 332 LogData::LogData() 333 : routing_id(0), 334 type(0), 335 sent(0), 336 receive(0), 337 dispatch(0) { 338 } 339 340 LogData::LogData(const LogData& other) = default; 341 342 LogData::~LogData() { 343 } 344 345 void ParamTraits<bool>::Log(const param_type& p, std::string* l) { 346 l->append(p ? "true" : "false"); 347 } 348 349 void ParamTraits<signed char>::GetSize(base::PickleSizer* sizer, 350 const param_type& p) { 351 sizer->AddBytes(sizeof(param_type)); 352 } 353 354 void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) { 355 m->WriteBytes(&p, sizeof(param_type)); 356 } 357 358 bool ParamTraits<signed char>::Read(const base::Pickle* m, 359 base::PickleIterator* iter, 360 param_type* r) { 361 const char* data; 362 if (!iter->ReadBytes(&data, sizeof(param_type))) 363 return false; 364 memcpy(r, data, sizeof(param_type)); 365 return true; 366 } 367 368 void ParamTraits<signed char>::Log(const param_type& p, std::string* l) { 369 l->append(base::IntToString(p)); 370 } 371 372 void ParamTraits<unsigned char>::GetSize(base::PickleSizer* sizer, 373 const param_type& p) { 374 sizer->AddBytes(sizeof(param_type)); 375 } 376 377 void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) { 378 m->WriteBytes(&p, sizeof(param_type)); 379 } 380 381 bool ParamTraits<unsigned char>::Read(const base::Pickle* m, 382 base::PickleIterator* iter, 383 param_type* r) { 384 const char* data; 385 if (!iter->ReadBytes(&data, sizeof(param_type))) 386 return false; 387 memcpy(r, data, sizeof(param_type)); 388 return true; 389 } 390 391 void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) { 392 l->append(base::UintToString(p)); 393 } 394 395 void ParamTraits<unsigned short>::GetSize(base::PickleSizer* sizer, 396 const param_type& p) { 397 sizer->AddBytes(sizeof(param_type)); 398 } 399 400 void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) { 401 m->WriteBytes(&p, sizeof(param_type)); 402 } 403 404 bool ParamTraits<unsigned short>::Read(const base::Pickle* m, 405 base::PickleIterator* iter, 406 param_type* r) { 407 const char* data; 408 if (!iter->ReadBytes(&data, sizeof(param_type))) 409 return false; 410 memcpy(r, data, sizeof(param_type)); 411 return true; 412 } 413 414 void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) { 415 l->append(base::UintToString(p)); 416 } 417 418 void ParamTraits<int>::Log(const param_type& p, std::string* l) { 419 l->append(base::IntToString(p)); 420 } 421 422 void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) { 423 l->append(base::UintToString(p)); 424 } 425 426 #if defined(OS_WIN) || defined(OS_LINUX) || \ 427 (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS)) 428 void ParamTraits<long>::Log(const param_type& p, std::string* l) { 429 l->append(base::Int64ToString(static_cast<int64_t>(p))); 430 } 431 432 void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) { 433 l->append(base::Uint64ToString(static_cast<uint64_t>(p))); 434 } 435 #endif 436 437 void ParamTraits<long long>::Log(const param_type& p, std::string* l) { 438 l->append(base::Int64ToString(static_cast<int64_t>(p))); 439 } 440 441 void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) { 442 l->append(base::Uint64ToString(p)); 443 } 444 445 void ParamTraits<float>::Log(const param_type& p, std::string* l) { 446 l->append(base::StringPrintf("%e", p)); 447 } 448 449 void ParamTraits<double>::GetSize(base::PickleSizer* sizer, 450 const param_type& p) { 451 sizer->AddBytes(sizeof(param_type)); 452 } 453 454 void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) { 455 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type)); 456 } 457 458 bool ParamTraits<double>::Read(const base::Pickle* m, 459 base::PickleIterator* iter, 460 param_type* r) { 461 const char *data; 462 if (!iter->ReadBytes(&data, sizeof(*r))) { 463 NOTREACHED(); 464 return false; 465 } 466 memcpy(r, data, sizeof(param_type)); 467 return true; 468 } 469 470 void ParamTraits<double>::Log(const param_type& p, std::string* l) { 471 l->append(base::StringPrintf("%e", p)); 472 } 473 474 475 void ParamTraits<std::string>::Log(const param_type& p, std::string* l) { 476 l->append(p); 477 } 478 479 void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) { 480 l->append(base::UTF16ToUTF8(p)); 481 } 482 483 void ParamTraits<std::vector<char>>::GetSize(base::PickleSizer* sizer, 484 const param_type& p) { 485 sizer->AddData(static_cast<int>(p.size())); 486 } 487 488 void ParamTraits<std::vector<char>>::Write(base::Pickle* m, 489 const param_type& p) { 490 if (p.empty()) { 491 m->WriteData(NULL, 0); 492 } else { 493 m->WriteData(&p.front(), static_cast<int>(p.size())); 494 } 495 } 496 497 bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m, 498 base::PickleIterator* iter, 499 param_type* r) { 500 const char *data; 501 int data_size = 0; 502 if (!iter->ReadData(&data, &data_size) || data_size < 0) 503 return false; 504 r->resize(data_size); 505 if (data_size) 506 memcpy(&r->front(), data, data_size); 507 return true; 508 } 509 510 void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) { 511 LogBytes(p, l); 512 } 513 514 void ParamTraits<std::vector<unsigned char>>::GetSize(base::PickleSizer* sizer, 515 const param_type& p) { 516 sizer->AddData(static_cast<int>(p.size())); 517 } 518 519 void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m, 520 const param_type& p) { 521 if (p.empty()) { 522 m->WriteData(NULL, 0); 523 } else { 524 m->WriteData(reinterpret_cast<const char*>(&p.front()), 525 static_cast<int>(p.size())); 526 } 527 } 528 529 bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m, 530 base::PickleIterator* iter, 531 param_type* r) { 532 const char *data; 533 int data_size = 0; 534 if (!iter->ReadData(&data, &data_size) || data_size < 0) 535 return false; 536 r->resize(data_size); 537 if (data_size) 538 memcpy(&r->front(), data, data_size); 539 return true; 540 } 541 542 void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p, 543 std::string* l) { 544 LogBytes(p, l); 545 } 546 547 void ParamTraits<std::vector<bool>>::GetSize(base::PickleSizer* sizer, 548 const param_type& p) { 549 GetParamSize(sizer, static_cast<int>(p.size())); 550 for (size_t i = 0; i < p.size(); ++i) 551 GetParamSize(sizer, static_cast<bool>(p[i])); 552 } 553 554 void ParamTraits<std::vector<bool>>::Write(base::Pickle* m, 555 const param_type& p) { 556 WriteParam(m, static_cast<int>(p.size())); 557 // Cast to bool below is required because libc++'s 558 // vector<bool>::const_reference is different from bool, and we want to avoid 559 // writing an extra specialization of ParamTraits for it. 560 for (size_t i = 0; i < p.size(); i++) 561 WriteParam(m, static_cast<bool>(p[i])); 562 } 563 564 bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m, 565 base::PickleIterator* iter, 566 param_type* r) { 567 int size; 568 // ReadLength() checks for < 0 itself. 569 if (!iter->ReadLength(&size)) 570 return false; 571 r->resize(size); 572 for (int i = 0; i < size; i++) { 573 bool value; 574 if (!ReadParam(m, iter, &value)) 575 return false; 576 (*r)[i] = value; 577 } 578 return true; 579 } 580 581 void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) { 582 for (size_t i = 0; i < p.size(); ++i) { 583 if (i != 0) 584 l->push_back(' '); 585 LogParam(static_cast<bool>(p[i]), l); 586 } 587 } 588 589 void ParamTraits<BrokerableAttachment::AttachmentId>::Write( 590 base::Pickle* m, 591 const param_type& p) { 592 m->WriteBytes(p.nonce, BrokerableAttachment::kNonceSize); 593 } 594 595 bool ParamTraits<BrokerableAttachment::AttachmentId>::Read( 596 const base::Pickle* m, 597 base::PickleIterator* iter, 598 param_type* r) { 599 const char* data; 600 if (!iter->ReadBytes(&data, BrokerableAttachment::kNonceSize)) 601 return false; 602 memcpy(r->nonce, data, BrokerableAttachment::kNonceSize); 603 return true; 604 } 605 606 void ParamTraits<BrokerableAttachment::AttachmentId>::Log(const param_type& p, 607 std::string* l) { 608 l->append(base::HexEncode(p.nonce, BrokerableAttachment::kNonceSize)); 609 } 610 611 void ParamTraits<base::DictionaryValue>::GetSize(base::PickleSizer* sizer, 612 const param_type& p) { 613 GetValueSize(sizer, &p, 0); 614 } 615 616 void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m, 617 const param_type& p) { 618 WriteValue(m, &p, 0); 619 } 620 621 bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m, 622 base::PickleIterator* iter, 623 param_type* r) { 624 int type; 625 if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_DICTIONARY) 626 return false; 627 628 return ReadDictionaryValue(m, iter, r, 0); 629 } 630 631 void ParamTraits<base::DictionaryValue>::Log(const param_type& p, 632 std::string* l) { 633 std::string json; 634 base::JSONWriter::Write(p, &json); 635 l->append(json); 636 } 637 638 #if defined(OS_POSIX) 639 void ParamTraits<base::FileDescriptor>::GetSize(base::PickleSizer* sizer, 640 const param_type& p) { 641 GetParamSize(sizer, p.fd >= 0); 642 if (p.fd >= 0) 643 sizer->AddAttachment(); 644 } 645 646 void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m, 647 const param_type& p) { 648 const bool valid = p.fd >= 0; 649 WriteParam(m, valid); 650 651 if (!valid) 652 return; 653 654 if (p.auto_close) { 655 if (!m->WriteAttachment( 656 new internal::PlatformFileAttachment(base::ScopedFD(p.fd)))) 657 NOTREACHED(); 658 } else { 659 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd))) 660 NOTREACHED(); 661 } 662 } 663 664 bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m, 665 base::PickleIterator* iter, 666 param_type* r) { 667 *r = base::FileDescriptor(); 668 669 bool valid; 670 if (!ReadParam(m, iter, &valid)) 671 return false; 672 673 // TODO(morrita): Seems like this should return false. 674 if (!valid) 675 return true; 676 677 scoped_refptr<base::Pickle::Attachment> attachment; 678 if (!m->ReadAttachment(iter, &attachment)) 679 return false; 680 681 *r = base::FileDescriptor( 682 static_cast<MessageAttachment*>(attachment.get())->TakePlatformFile(), 683 true); 684 return true; 685 } 686 687 void ParamTraits<base::FileDescriptor>::Log(const param_type& p, 688 std::string* l) { 689 if (p.auto_close) { 690 l->append(base::StringPrintf("FD(%d auto-close)", p.fd)); 691 } else { 692 l->append(base::StringPrintf("FD(%d)", p.fd)); 693 } 694 } 695 #endif // defined(OS_POSIX) 696 697 #if defined(OS_MACOSX) && !defined(OS_IOS) 698 void ParamTraits<base::SharedMemoryHandle>::GetSize(base::PickleSizer* sizer, 699 const param_type& p) { 700 GetParamSize(sizer, p.GetMemoryObject()); 701 uint32_t dummy = 0; 702 GetParamSize(sizer, dummy); 703 } 704 705 void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m, 706 const param_type& p) { 707 MachPortMac mach_port_mac(p.GetMemoryObject()); 708 ParamTraits<MachPortMac>::Write(m, mach_port_mac); 709 size_t size = 0; 710 bool result = p.GetSize(&size); 711 DCHECK(result); 712 ParamTraits<uint32_t>::Write(m, static_cast<uint32_t>(size)); 713 714 // If the caller intended to pass ownership to the IPC stack, release a 715 // reference. 716 if (p.OwnershipPassesToIPC()) 717 p.Close(); 718 } 719 720 bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m, 721 base::PickleIterator* iter, 722 param_type* r) { 723 MachPortMac mach_port_mac; 724 if (!ParamTraits<MachPortMac>::Read(m, iter, &mach_port_mac)) 725 return false; 726 727 uint32_t size; 728 if (!ParamTraits<uint32_t>::Read(m, iter, &size)) 729 return false; 730 731 *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(), 732 static_cast<size_t>(size), 733 base::GetCurrentProcId()); 734 return true; 735 } 736 737 void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p, 738 std::string* l) { 739 l->append("Mach port: "); 740 LogParam(p.GetMemoryObject(), l); 741 } 742 743 #elif defined(OS_WIN) 744 void ParamTraits<base::SharedMemoryHandle>::GetSize(base::PickleSizer* s, 745 const param_type& p) { 746 GetParamSize(s, p.NeedsBrokering()); 747 if (p.NeedsBrokering()) { 748 GetParamSize(s, p.GetHandle()); 749 } else { 750 GetParamSize(s, HandleToLong(p.GetHandle())); 751 } 752 } 753 754 void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m, 755 const param_type& p) { 756 m->WriteBool(p.NeedsBrokering()); 757 758 if (p.NeedsBrokering()) { 759 HandleWin handle_win(p.GetHandle(), HandleWin::DUPLICATE); 760 ParamTraits<HandleWin>::Write(m, handle_win); 761 762 // If the caller intended to pass ownership to the IPC stack, release a 763 // reference. 764 if (p.OwnershipPassesToIPC() && p.BelongsToCurrentProcess()) 765 p.Close(); 766 } else { 767 m->WriteInt(HandleToLong(p.GetHandle())); 768 } 769 } 770 771 bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m, 772 base::PickleIterator* iter, 773 param_type* r) { 774 bool needs_brokering; 775 if (!iter->ReadBool(&needs_brokering)) 776 return false; 777 778 if (needs_brokering) { 779 HandleWin handle_win; 780 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win)) 781 return false; 782 *r = base::SharedMemoryHandle(handle_win.get_handle(), 783 base::GetCurrentProcId()); 784 return true; 785 } 786 787 int handle_int; 788 if (!iter->ReadInt(&handle_int)) 789 return false; 790 HANDLE handle = LongToHandle(handle_int); 791 *r = base::SharedMemoryHandle(handle, base::GetCurrentProcId()); 792 return true; 793 } 794 795 void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p, 796 std::string* l) { 797 LogParam(p.GetHandle(), l); 798 l->append(" needs brokering: "); 799 LogParam(p.NeedsBrokering(), l); 800 } 801 #endif // defined(OS_MACOSX) && !defined(OS_IOS) 802 803 void ParamTraits<base::FilePath>::GetSize(base::PickleSizer* sizer, 804 const param_type& p) { 805 p.GetSizeForPickle(sizer); 806 } 807 808 void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) { 809 p.WriteToPickle(m); 810 } 811 812 bool ParamTraits<base::FilePath>::Read(const base::Pickle* m, 813 base::PickleIterator* iter, 814 param_type* r) { 815 return r->ReadFromPickle(iter); 816 } 817 818 void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) { 819 ParamTraits<base::FilePath::StringType>::Log(p.value(), l); 820 } 821 822 void ParamTraits<base::ListValue>::GetSize(base::PickleSizer* sizer, 823 const param_type& p) { 824 GetValueSize(sizer, &p, 0); 825 } 826 827 void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) { 828 WriteValue(m, &p, 0); 829 } 830 831 bool ParamTraits<base::ListValue>::Read(const base::Pickle* m, 832 base::PickleIterator* iter, 833 param_type* r) { 834 int type; 835 if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_LIST) 836 return false; 837 838 return ReadListValue(m, iter, r, 0); 839 } 840 841 void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) { 842 std::string json; 843 base::JSONWriter::Write(p, &json); 844 l->append(json); 845 } 846 847 void ParamTraits<base::NullableString16>::GetSize(base::PickleSizer* sizer, 848 const param_type& p) { 849 GetParamSize(sizer, p.string()); 850 GetParamSize(sizer, p.is_null()); 851 } 852 853 void ParamTraits<base::NullableString16>::Write(base::Pickle* m, 854 const param_type& p) { 855 WriteParam(m, p.string()); 856 WriteParam(m, p.is_null()); 857 } 858 859 bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m, 860 base::PickleIterator* iter, 861 param_type* r) { 862 base::string16 string; 863 if (!ReadParam(m, iter, &string)) 864 return false; 865 bool is_null; 866 if (!ReadParam(m, iter, &is_null)) 867 return false; 868 *r = base::NullableString16(string, is_null); 869 return true; 870 } 871 872 void ParamTraits<base::NullableString16>::Log(const param_type& p, 873 std::string* l) { 874 l->append("("); 875 LogParam(p.string(), l); 876 l->append(", "); 877 LogParam(p.is_null(), l); 878 l->append(")"); 879 } 880 881 void ParamTraits<base::File::Info>::GetSize(base::PickleSizer* sizer, 882 const param_type& p) { 883 GetParamSize(sizer, p.size); 884 GetParamSize(sizer, p.is_directory); 885 GetParamSize(sizer, p.last_modified.ToDoubleT()); 886 GetParamSize(sizer, p.last_accessed.ToDoubleT()); 887 GetParamSize(sizer, p.creation_time.ToDoubleT()); 888 } 889 890 void ParamTraits<base::File::Info>::Write(base::Pickle* m, 891 const param_type& p) { 892 WriteParam(m, p.size); 893 WriteParam(m, p.is_directory); 894 WriteParam(m, p.last_modified.ToDoubleT()); 895 WriteParam(m, p.last_accessed.ToDoubleT()); 896 WriteParam(m, p.creation_time.ToDoubleT()); 897 } 898 899 bool ParamTraits<base::File::Info>::Read(const base::Pickle* m, 900 base::PickleIterator* iter, 901 param_type* p) { 902 double last_modified, last_accessed, creation_time; 903 if (!ReadParam(m, iter, &p->size) || 904 !ReadParam(m, iter, &p->is_directory) || 905 !ReadParam(m, iter, &last_modified) || 906 !ReadParam(m, iter, &last_accessed) || 907 !ReadParam(m, iter, &creation_time)) 908 return false; 909 p->last_modified = base::Time::FromDoubleT(last_modified); 910 p->last_accessed = base::Time::FromDoubleT(last_accessed); 911 p->creation_time = base::Time::FromDoubleT(creation_time); 912 return true; 913 } 914 915 void ParamTraits<base::File::Info>::Log(const param_type& p, 916 std::string* l) { 917 l->append("("); 918 LogParam(p.size, l); 919 l->append(","); 920 LogParam(p.is_directory, l); 921 l->append(","); 922 LogParam(p.last_modified.ToDoubleT(), l); 923 l->append(","); 924 LogParam(p.last_accessed.ToDoubleT(), l); 925 l->append(","); 926 LogParam(p.creation_time.ToDoubleT(), l); 927 l->append(")"); 928 } 929 930 void ParamTraits<base::Time>::GetSize(base::PickleSizer* sizer, 931 const param_type& p) { 932 sizer->AddInt64(); 933 } 934 935 void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) { 936 ParamTraits<int64_t>::Write(m, p.ToInternalValue()); 937 } 938 939 bool ParamTraits<base::Time>::Read(const base::Pickle* m, 940 base::PickleIterator* iter, 941 param_type* r) { 942 int64_t value; 943 if (!ParamTraits<int64_t>::Read(m, iter, &value)) 944 return false; 945 *r = base::Time::FromInternalValue(value); 946 return true; 947 } 948 949 void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) { 950 ParamTraits<int64_t>::Log(p.ToInternalValue(), l); 951 } 952 953 void ParamTraits<base::TimeDelta>::GetSize(base::PickleSizer* sizer, 954 const param_type& p) { 955 sizer->AddInt64(); 956 } 957 958 void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) { 959 ParamTraits<int64_t>::Write(m, p.ToInternalValue()); 960 } 961 962 bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m, 963 base::PickleIterator* iter, 964 param_type* r) { 965 int64_t value; 966 bool ret = ParamTraits<int64_t>::Read(m, iter, &value); 967 if (ret) 968 *r = base::TimeDelta::FromInternalValue(value); 969 970 return ret; 971 } 972 973 void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) { 974 ParamTraits<int64_t>::Log(p.ToInternalValue(), l); 975 } 976 977 void ParamTraits<base::TimeTicks>::GetSize(base::PickleSizer* sizer, 978 const param_type& p) { 979 sizer->AddInt64(); 980 } 981 982 void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) { 983 ParamTraits<int64_t>::Write(m, p.ToInternalValue()); 984 } 985 986 bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m, 987 base::PickleIterator* iter, 988 param_type* r) { 989 int64_t value; 990 bool ret = ParamTraits<int64_t>::Read(m, iter, &value); 991 if (ret) 992 *r = base::TimeTicks::FromInternalValue(value); 993 994 return ret; 995 } 996 997 void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) { 998 ParamTraits<int64_t>::Log(p.ToInternalValue(), l); 999 } 1000 1001 void ParamTraits<IPC::ChannelHandle>::GetSize(base::PickleSizer* sizer, 1002 const param_type& p) { 1003 GetParamSize(sizer, p.name); 1004 #if defined(OS_POSIX) 1005 GetParamSize(sizer, p.socket); 1006 #endif 1007 GetParamSize(sizer, p.mojo_handle); 1008 } 1009 1010 void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m, 1011 const param_type& p) { 1012 #if defined(OS_WIN) 1013 // On Windows marshalling pipe handle is not supported. 1014 DCHECK(p.pipe.handle == NULL); 1015 #endif // defined (OS_WIN) 1016 WriteParam(m, p.name); 1017 #if defined(OS_POSIX) 1018 WriteParam(m, p.socket); 1019 #endif 1020 WriteParam(m, p.mojo_handle); 1021 } 1022 1023 bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m, 1024 base::PickleIterator* iter, 1025 param_type* r) { 1026 return ReadParam(m, iter, &r->name) 1027 #if defined(OS_POSIX) 1028 && ReadParam(m, iter, &r->socket) 1029 #endif 1030 && ReadParam(m, iter, &r->mojo_handle); 1031 } 1032 1033 void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p, 1034 std::string* l) { 1035 l->append(base::StringPrintf("ChannelHandle(%s", p.name.c_str())); 1036 #if defined(OS_POSIX) 1037 l->append(", "); 1038 ParamTraits<base::FileDescriptor>::Log(p.socket, l); 1039 #endif 1040 l->append(", "); 1041 LogParam(p.mojo_handle, l); 1042 l->append(")"); 1043 } 1044 1045 void ParamTraits<LogData>::GetSize(base::PickleSizer* sizer, 1046 const param_type& p) { 1047 GetParamSize(sizer, p.channel); 1048 GetParamSize(sizer, p.routing_id); 1049 GetParamSize(sizer, p.type); 1050 GetParamSize(sizer, p.flags); 1051 GetParamSize(sizer, p.sent); 1052 GetParamSize(sizer, p.receive); 1053 GetParamSize(sizer, p.dispatch); 1054 GetParamSize(sizer, p.message_name); 1055 GetParamSize(sizer, p.params); 1056 } 1057 1058 void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) { 1059 WriteParam(m, p.channel); 1060 WriteParam(m, p.routing_id); 1061 WriteParam(m, p.type); 1062 WriteParam(m, p.flags); 1063 WriteParam(m, p.sent); 1064 WriteParam(m, p.receive); 1065 WriteParam(m, p.dispatch); 1066 WriteParam(m, p.message_name); 1067 WriteParam(m, p.params); 1068 } 1069 1070 bool ParamTraits<LogData>::Read(const base::Pickle* m, 1071 base::PickleIterator* iter, 1072 param_type* r) { 1073 return 1074 ReadParam(m, iter, &r->channel) && 1075 ReadParam(m, iter, &r->routing_id) && 1076 ReadParam(m, iter, &r->type) && 1077 ReadParam(m, iter, &r->flags) && 1078 ReadParam(m, iter, &r->sent) && 1079 ReadParam(m, iter, &r->receive) && 1080 ReadParam(m, iter, &r->dispatch) && 1081 ReadParam(m, iter, &r->message_name) && 1082 ReadParam(m, iter, &r->params); 1083 } 1084 1085 void ParamTraits<LogData>::Log(const param_type& p, std::string* l) { 1086 // Doesn't make sense to implement this! 1087 } 1088 1089 void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) { 1090 #if defined(OS_POSIX) 1091 // We don't serialize the file descriptors in the nested message, so there 1092 // better not be any. 1093 DCHECK(!p.HasAttachments()); 1094 #endif 1095 1096 // Don't just write out the message. This is used to send messages between 1097 // NaCl (Posix environment) and the browser (could be on Windows). The message 1098 // header formats differ between these systems (so does handle sharing, but 1099 // we already asserted we don't have any handles). So just write out the 1100 // parts of the header we use. 1101 // 1102 // Be careful also to use only explicitly-sized types. The NaCl environment 1103 // could be 64-bit and the host browser could be 32-bits. The nested message 1104 // may or may not be safe to send between 32-bit and 64-bit systems, but we 1105 // leave that up to the code sending the message to ensure. 1106 m->WriteUInt32(static_cast<uint32_t>(p.routing_id())); 1107 m->WriteUInt32(p.type()); 1108 m->WriteUInt32(p.flags()); 1109 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size())); 1110 } 1111 1112 bool ParamTraits<Message>::Read(const base::Pickle* m, 1113 base::PickleIterator* iter, 1114 Message* r) { 1115 uint32_t routing_id, type, flags; 1116 if (!iter->ReadUInt32(&routing_id) || 1117 !iter->ReadUInt32(&type) || 1118 !iter->ReadUInt32(&flags)) 1119 return false; 1120 1121 int payload_size; 1122 const char* payload; 1123 if (!iter->ReadData(&payload, &payload_size)) 1124 return false; 1125 1126 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags); 1127 return r->WriteBytes(payload, payload_size); 1128 } 1129 1130 void ParamTraits<Message>::Log(const Message& p, std::string* l) { 1131 l->append("<IPC::Message>"); 1132 } 1133 1134 #if defined(OS_WIN) 1135 void ParamTraits<HANDLE>::GetSize(base::PickleSizer* sizer, 1136 const param_type& p) { 1137 sizer->AddInt(); 1138 } 1139 1140 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64 1141 // bit systems. That's why we use the Windows macros to convert to 32 bits. 1142 void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) { 1143 m->WriteInt(HandleToLong(p)); 1144 } 1145 1146 bool ParamTraits<HANDLE>::Read(const base::Pickle* m, 1147 base::PickleIterator* iter, 1148 param_type* r) { 1149 int32_t temp; 1150 if (!iter->ReadInt(&temp)) 1151 return false; 1152 *r = LongToHandle(temp); 1153 return true; 1154 } 1155 1156 void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) { 1157 l->append(base::StringPrintf("0x%p", p)); 1158 } 1159 1160 void ParamTraits<LOGFONT>::GetSize(base::PickleSizer* sizer, 1161 const param_type& p) { 1162 sizer->AddData(sizeof(LOGFONT)); 1163 } 1164 1165 void ParamTraits<LOGFONT>::Write(base::Pickle* m, const param_type& p) { 1166 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT)); 1167 } 1168 1169 bool ParamTraits<LOGFONT>::Read(const base::Pickle* m, 1170 base::PickleIterator* iter, 1171 param_type* r) { 1172 const char *data; 1173 int data_size = 0; 1174 if (iter->ReadData(&data, &data_size) && data_size == sizeof(LOGFONT)) { 1175 const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data)); 1176 if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) { 1177 memcpy(r, data, sizeof(LOGFONT)); 1178 return true; 1179 } 1180 } 1181 1182 NOTREACHED(); 1183 return false; 1184 } 1185 1186 void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) { 1187 l->append(base::StringPrintf("<LOGFONT>")); 1188 } 1189 1190 void ParamTraits<MSG>::GetSize(base::PickleSizer* sizer, const param_type& p) { 1191 sizer->AddData(sizeof(MSG)); 1192 } 1193 1194 void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) { 1195 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG)); 1196 } 1197 1198 bool ParamTraits<MSG>::Read(const base::Pickle* m, 1199 base::PickleIterator* iter, 1200 param_type* r) { 1201 const char *data; 1202 int data_size = 0; 1203 bool result = iter->ReadData(&data, &data_size); 1204 if (result && data_size == sizeof(MSG)) { 1205 memcpy(r, data, sizeof(MSG)); 1206 } else { 1207 result = false; 1208 NOTREACHED(); 1209 } 1210 1211 return result; 1212 } 1213 1214 void ParamTraits<MSG>::Log(const param_type& p, std::string* l) { 1215 l->append("<MSG>"); 1216 } 1217 1218 #endif // OS_WIN 1219 1220 } // namespace IPC 1221