Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef IPC_IPC_MESSAGE_UTILS_H_ | 5 #ifndef IPC_IPC_MESSAGE_UTILS_H_ |
| 6 #define IPC_IPC_MESSAGE_UTILS_H_ | 6 #define IPC_IPC_MESSAGE_UTILS_H_ |
| 7 | 7 |
| 8 #include <limits.h> | 8 #include <limits.h> |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 #include <stdint.h> | 10 #include <stdint.h> |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 typedef typename SimilarTypeTraits<P>::Type Type; | 113 typedef typename SimilarTypeTraits<P>::Type Type; |
| 114 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p)); | 114 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p)); |
| 115 } | 115 } |
| 116 | 116 |
| 117 template <class P> | 117 template <class P> |
| 118 static inline void LogParam(const P& p, std::string* l) { | 118 static inline void LogParam(const P& p, std::string* l) { |
| 119 typedef typename SimilarTypeTraits<P>::Type Type; | 119 typedef typename SimilarTypeTraits<P>::Type Type; |
| 120 ParamTraits<Type>::Log(static_cast<const Type& >(p), l); | 120 ParamTraits<Type>::Log(static_cast<const Type& >(p), l); |
| 121 } | 121 } |
| 122 | 122 |
| 123 // Checks whether |m| is sufficient to carry |count| elements. This function | |
| 124 // cannot guarantee the |m| contains valid data to be deserialized. |raw_size| | |
| 125 // is the size of bytes needed for one element in the memory. | |
| 126 static inline bool IsPickleSizeSufficient(const base::Pickle* m, | |
|
dcheng
2017/07/12 08:52:14
OK, sorry. I think I probably didn't do a good job
Hzj_jie
2017/07/13 00:01:03
This change has been reverted. Instead a bug http:
| |
| 127 int count, | |
| 128 int raw_size) { | |
| 129 DCHECK(raw_size > 0); | |
| 130 if (count < 0) | |
| 131 return false; | |
| 132 // Rejects if count * raw_size is overflow. See BUG 1006367 for details. | |
|
dcheng
2017/07/12 08:52:14
So we have to spelunk a bit into proto details her
Hzj_jie
2017/07/13 00:01:03
Acknowledged.
| |
| 133 if (INT_MAX / raw_size < count) | |
| 134 return false; | |
| 135 // TODO(zijiehe): Find a better way to analyze the minimum bytes needed for | |
| 136 // each element in the Pickle. Now we assume the size is 1. Note: | |
| 137 // ParamTraits<T> may not implement GetSize() function. | |
| 138 if (static_cast<size_t>(count) > m->payload_size()) | |
|
dcheng
2017/07/12 08:52:15
I think it's OK if we omit this check; the importa
Hzj_jie
2017/07/13 00:01:03
Acknowledged.
| |
| 139 return false; | |
| 140 return true; | |
| 141 } | |
| 142 | |
| 143 // Checks whether |m| is sufficient to carry |count| * P data. | |
| 144 template <class P> | |
| 145 static inline bool IsPickleSizeSufficient(const base::Pickle* m, int count) { | |
| 146 return IsPickleSizeSufficient(m, count, sizeof(P)); | |
| 147 } | |
| 148 | |
| 149 // Checks whether |m| is sufficient to carry |count| * (A + B) data. | |
| 150 template <class A, class B> | |
| 151 static inline bool IsPickleSizeSufficient(const base::Pickle* m, int count) { | |
| 152 return IsPickleSizeSufficient(m, count, sizeof(A) + sizeof(B)); | |
| 153 } | |
| 154 | |
| 123 // Primitive ParamTraits ------------------------------------------------------- | 155 // Primitive ParamTraits ------------------------------------------------------- |
| 124 | 156 |
| 125 template <> | 157 template <> |
| 126 struct ParamTraits<bool> { | 158 struct ParamTraits<bool> { |
| 127 typedef bool param_type; | 159 typedef bool param_type; |
| 128 static void GetSize(base::PickleSizer* sizer, const param_type& p) { | 160 static void GetSize(base::PickleSizer* sizer, const param_type& p) { |
| 129 sizer->AddBool(); | 161 sizer->AddBool(); |
| 130 } | 162 } |
| 131 static void Write(base::Pickle* m, const param_type& p) { m->WriteBool(p); } | 163 static void Write(base::Pickle* m, const param_type& p) { m->WriteBool(p); } |
| 132 static bool Read(const base::Pickle* m, | 164 static bool Read(const base::Pickle* m, |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 420 for (size_t i = 0; i < p.size(); i++) | 452 for (size_t i = 0; i < p.size(); i++) |
| 421 WriteParam(m, p[i]); | 453 WriteParam(m, p[i]); |
| 422 } | 454 } |
| 423 static bool Read(const base::Pickle* m, | 455 static bool Read(const base::Pickle* m, |
| 424 base::PickleIterator* iter, | 456 base::PickleIterator* iter, |
| 425 param_type* r) { | 457 param_type* r) { |
| 426 int size; | 458 int size; |
| 427 // ReadLength() checks for < 0 itself. | 459 // ReadLength() checks for < 0 itself. |
| 428 if (!iter->ReadLength(&size)) | 460 if (!iter->ReadLength(&size)) |
| 429 return false; | 461 return false; |
| 430 // Resizing beforehand is not safe, see BUG 1006367 for details. | 462 if (!IsPickleSizeSufficient<P>(m, size)) |
| 431 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size)) | |
| 432 return false; | 463 return false; |
| 433 r->resize(size); | 464 r->resize(size); |
| 434 for (int i = 0; i < size; i++) { | 465 for (int i = 0; i < size; i++) { |
| 435 if (!ReadParam(m, iter, &(*r)[i])) | 466 if (!ReadParam(m, iter, &(*r)[i])) |
| 436 return false; | 467 return false; |
| 437 } | 468 } |
| 438 return true; | 469 return true; |
| 439 } | 470 } |
| 440 static void Log(const param_type& p, std::string* l) { | 471 static void Log(const param_type& p, std::string* l) { |
| 441 for (size_t i = 0; i < p.size(); ++i) { | 472 for (size_t i = 0; i < p.size(); ++i) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 460 typename param_type::const_iterator iter; | 491 typename param_type::const_iterator iter; |
| 461 for (iter = p.begin(); iter != p.end(); ++iter) | 492 for (iter = p.begin(); iter != p.end(); ++iter) |
| 462 WriteParam(m, *iter); | 493 WriteParam(m, *iter); |
| 463 } | 494 } |
| 464 static bool Read(const base::Pickle* m, | 495 static bool Read(const base::Pickle* m, |
| 465 base::PickleIterator* iter, | 496 base::PickleIterator* iter, |
| 466 param_type* r) { | 497 param_type* r) { |
| 467 int size; | 498 int size; |
| 468 if (!iter->ReadLength(&size)) | 499 if (!iter->ReadLength(&size)) |
| 469 return false; | 500 return false; |
| 501 if (!IsPickleSizeSufficient<P>(m, size)) | |
| 502 return false; | |
| 470 for (int i = 0; i < size; ++i) { | 503 for (int i = 0; i < size; ++i) { |
| 471 P item; | 504 P item; |
| 472 if (!ReadParam(m, iter, &item)) | 505 if (!ReadParam(m, iter, &item)) |
| 473 return false; | 506 return false; |
| 474 r->insert(item); | 507 r->insert(item); |
| 475 } | 508 } |
| 476 return true; | 509 return true; |
| 477 } | 510 } |
| 478 static void Log(const param_type& p, std::string* l) { | 511 static void Log(const param_type& p, std::string* l) { |
| 479 l->append("<std::set>"); | 512 l->append("<std::set>"); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 496 typename param_type::const_iterator iter; | 529 typename param_type::const_iterator iter; |
| 497 for (iter = p.begin(); iter != p.end(); ++iter) { | 530 for (iter = p.begin(); iter != p.end(); ++iter) { |
| 498 WriteParam(m, iter->first); | 531 WriteParam(m, iter->first); |
| 499 WriteParam(m, iter->second); | 532 WriteParam(m, iter->second); |
| 500 } | 533 } |
| 501 } | 534 } |
| 502 static bool Read(const base::Pickle* m, | 535 static bool Read(const base::Pickle* m, |
| 503 base::PickleIterator* iter, | 536 base::PickleIterator* iter, |
| 504 param_type* r) { | 537 param_type* r) { |
| 505 int size; | 538 int size; |
| 506 if (!ReadParam(m, iter, &size) || size < 0) | 539 if (!iter->ReadLength(&size)) |
| 540 return false; | |
| 541 if (!IsPickleSizeSufficient<K, V>(m, size)) | |
| 507 return false; | 542 return false; |
| 508 for (int i = 0; i < size; ++i) { | 543 for (int i = 0; i < size; ++i) { |
| 509 K k; | 544 K k; |
| 510 if (!ReadParam(m, iter, &k)) | 545 if (!ReadParam(m, iter, &k)) |
| 511 return false; | 546 return false; |
| 512 V& value = (*r)[k]; | 547 V& value = (*r)[k]; |
| 513 if (!ReadParam(m, iter, &value)) | 548 if (!ReadParam(m, iter, &value)) |
| 514 return false; | 549 return false; |
| 515 } | 550 } |
| 516 return true; | 551 return true; |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 887 WriteParam(m, iter.second); | 922 WriteParam(m, iter.second); |
| 888 } | 923 } |
| 889 } | 924 } |
| 890 static bool Read(const base::Pickle* m, | 925 static bool Read(const base::Pickle* m, |
| 891 base::PickleIterator* iter, | 926 base::PickleIterator* iter, |
| 892 param_type* r) { | 927 param_type* r) { |
| 893 int size; | 928 int size; |
| 894 if (!iter->ReadLength(&size)) | 929 if (!iter->ReadLength(&size)) |
| 895 return false; | 930 return false; |
| 896 | 931 |
| 932 if (!IsPickleSizeSufficient<Key, Mapped>(m, size)) | |
| 933 return false; | |
| 934 | |
| 897 // Construct by creating in a vector and moving into the flat_map. Properly | 935 // Construct by creating in a vector and moving into the flat_map. Properly |
| 898 // serialized flat_maps will be in-order so this will be O(n). Incorrectly | 936 // serialized flat_maps will be in-order so this will be O(n). Incorrectly |
| 899 // serialized ones will still be handled properly. | 937 // serialized ones will still be handled properly. |
| 900 std::vector<typename param_type::value_type> vect; | 938 std::vector<typename param_type::value_type> vect; |
| 901 vect.resize(size); | 939 vect.resize(size); |
| 902 for (int i = 0; i < size; ++i) { | 940 for (int i = 0; i < size; ++i) { |
| 903 if (!ReadParam(m, iter, &vect[i].first)) | 941 if (!ReadParam(m, iter, &vect[i].first)) |
| 904 return false; | 942 return false; |
| 905 if (!ReadParam(m, iter, &vect[i].second)) | 943 if (!ReadParam(m, iter, &vect[i].second)) |
| 906 return false; | 944 return false; |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1110 template <class ReplyParamType> | 1148 template <class ReplyParamType> |
| 1111 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params, | 1149 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params, |
| 1112 const Message* msg) {} | 1150 const Message* msg) {} |
| 1113 | 1151 |
| 1114 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {} | 1152 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {} |
| 1115 #endif | 1153 #endif |
| 1116 | 1154 |
| 1117 } // namespace IPC | 1155 } // namespace IPC |
| 1118 | 1156 |
| 1119 #endif // IPC_IPC_MESSAGE_UTILS_H_ | 1157 #endif // IPC_IPC_MESSAGE_UTILS_H_ |
| OLD | NEW |