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 |