Skip to content

Commit c1e9f92

Browse files
committed
Merge branch 'fix_issue_226_author_fixed'
Conflicts: include/msgpack/unpack.hpp
2 parents 582fe38 + 8ad9ce0 commit c1e9f92

22 files changed

+283
-150
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ IF (MSGPACK_ENABLE_CXX)
102102
include/msgpack/adaptor/bool_fwd.hpp
103103
include/msgpack/adaptor/char_ptr.hpp
104104
include/msgpack/adaptor/char_ptr_fwd.hpp
105+
include/msgpack/adaptor/check_container_size.hpp
105106
include/msgpack/adaptor/cpp11/array.hpp
106107
include/msgpack/adaptor/cpp11/array_fwd.hpp
107108
include/msgpack/adaptor/cpp11/array_char.hpp

include/msgpack/adaptor/char_ptr.hpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// MessagePack for C++ static resolution routine
33
//
4-
// Copyright (C) 2014 KONDO Takatoshi
4+
// Copyright (C) 2014-2015 KONDO Takatoshi
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -20,6 +20,8 @@
2020

2121
#include "msgpack/versioning.hpp"
2222
#include "msgpack/object_fwd.hpp"
23+
#include "msgpack/adaptor/check_container_size.hpp"
24+
2325
#include <cstring>
2426

2527
namespace msgpack {
@@ -29,28 +31,28 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
2931
template <typename Stream>
3032
inline packer<Stream>& operator<< (packer<Stream>& o, const char* v)
3133
{
32-
std::size_t size = std::strlen(v);
34+
uint32_t size = checked_get_container_size(std::strlen(v));
3335
o.pack_str(size);
3436
o.pack_str_body(v, size);
3537
return o;
3638
}
3739

3840
inline void operator<< (object::with_zone& o, const char* v)
3941
{
40-
std::size_t size = std::strlen(v);
42+
uint32_t size = checked_get_container_size(std::strlen(v));
4143
o.type = type::STR;
4244
char* ptr = static_cast<char*>(o.zone.allocate_align(size));
4345
o.via.str.ptr = ptr;
44-
o.via.str.size = static_cast<uint32_t>(size);
46+
o.via.str.size = size;
4547
memcpy(ptr, v, size);
4648
}
4749

4850
inline void operator<< (object& o, const char* v)
4951
{
50-
std::size_t size = std::strlen(v);
52+
uint32_t size = checked_get_container_size(std::strlen(v));
5153
o.type = type::STR;
5254
o.via.str.ptr = v;
53-
o.via.str.size = static_cast<uint32_t>(size);
55+
o.via.str.size = size;
5456
}
5557

5658
template <typename Stream>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//
2+
// MessagePack for C++ static resolution routine
3+
//
4+
// Copyright (C) 2015 KONDO Takatoshi
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
#ifndef MSGPACK_CHECK_CONTAINER_SIZE_HPP
19+
#define MSGPACK_CHECK_CONTAINER_SIZE_HPP
20+
21+
#include "msgpack/versioning.hpp"
22+
#include <stdexcept>
23+
24+
namespace msgpack {
25+
26+
MSGPACK_API_VERSION_NAMESPACE(v1) {
27+
28+
struct container_size_overflow : public std::runtime_error {
29+
explicit container_size_overflow(const std::string& msg)
30+
:std::runtime_error(msg) {}
31+
#if !defined(MSGPACK_USE_CPP03)
32+
explicit container_size_overflow(const char* msg):
33+
std::runtime_error(msg) {}
34+
#endif // !defined(MSGPACK_USE_CPP03)
35+
};
36+
37+
namespace detail {
38+
39+
template <std::size_t N>
40+
inline void check_container_size(std::size_t size) {
41+
if (size > 0xffffffff) throw container_size_overflow("container size overflow");
42+
}
43+
44+
template <>
45+
inline void check_container_size<4>(std::size_t size) {
46+
}
47+
48+
} // namespace detail
49+
50+
template <typename T>
51+
inline uint32_t checked_get_container_size(T size) {
52+
detail::check_container_size<sizeof(T)>(size);
53+
return static_cast<uint32_t>(size);
54+
}
55+
56+
57+
} // MSGPACK_API_VERSION_NAMESPACE(v1)
58+
59+
} // namespace msgpack
60+
61+
#endif // MSGPACK_CHECK_CONTAINER_SIZE_HPP

include/msgpack/adaptor/cpp11/array.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// MessagePack for C++ static resolution routine
33
//
4-
// Copyright (C) 2014 KONDO Takatoshi
4+
// Copyright (C) 2014-2015 KONDO Takatoshi
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
2121

2222
#include "msgpack/versioning.hpp"
2323
#include "msgpack/object_fwd.hpp"
24+
#include "msgpack/adaptor/check_container_size.hpp"
2425

2526
#include <array>
2627

@@ -47,7 +48,8 @@ inline object const& operator>> (object const& o, std::array<T, N>& v) {
4748

4849
template <typename Stream, typename T, std::size_t N>
4950
inline packer<Stream>& operator<< (packer<Stream>& o, const std::array<T, N>& v) {
50-
o.pack_array(v.size());
51+
uint32_t size = checked_get_container_size(v.size());
52+
o.pack_array(size);
5153
for(auto const& e : v) o.pack(e);
5254
return o;
5355
}
@@ -59,8 +61,9 @@ inline void operator<< (object::with_zone& o, const std::array<T, N>& v) {
5961
o.via.array.ptr = nullptr;
6062
o.via.array.size = 0;
6163
} else {
62-
object* p = static_cast<object*>(o.zone.allocate_align(sizeof(object)*v.size()));
63-
o.via.array.size = v.size();
64+
uint32_t size = checked_get_container_size(v.size());
65+
object* p = static_cast<object*>(o.zone.allocate_align(sizeof(object)*size));
66+
o.via.array.size = size;
6467
o.via.array.ptr = p;
6568
for (auto const& e : v) *p++ = object(e, o.zone);
6669
}

include/msgpack/adaptor/cpp11/array_char.hpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// MessagePack for C++ static resolution routine
33
//
4-
// Copyright (C) 2014 KONDO Takatoshi
4+
// Copyright (C) 2014-2015 KONDO Takatoshi
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -20,6 +20,8 @@
2020

2121
#include "msgpack/versioning.hpp"
2222
#include "msgpack_fwd.hpp"
23+
#include "msgpack/adaptor/check_container_size.hpp"
24+
2325
#include <array>
2426

2527
namespace msgpack {
@@ -48,28 +50,31 @@ inline object const& operator>> (object const& o, std::array<char, N>& v)
4850
template <typename Stream, std::size_t N>
4951
inline packer<Stream>& operator<< (packer<Stream>& o, const std::array<char, N>& v)
5052
{
51-
o.pack_bin(v.size());
52-
o.pack_bin_body(v.data(), v.size());
53+
uint32_t size = checked_get_container_size(v.size());
54+
o.pack_bin(size);
55+
o.pack_bin_body(v.data(), size);
5356

5457
return o;
5558
}
5659

5760
template <std::size_t N>
5861
inline void operator<< (object& o, const std::array<char, N>& v)
5962
{
63+
uint32_t size = checked_get_container_size(v.size());
6064
o.type = type::BIN;
6165
o.via.bin.ptr = v.data();
62-
o.via.bin.size = static_cast<uint32_t>(v.size());
66+
o.via.bin.size = size;
6367
}
6468

6569
template <std::size_t N>
6670
inline void operator<< (object::with_zone& o, const std::array<char, N>& v)
6771
{
72+
uint32_t size = checked_get_container_size(v.size());
6873
o.type = type::BIN;
69-
char* ptr = static_cast<char*>(o.zone.allocate_align(v.size()));
74+
char* ptr = static_cast<char*>(o.zone.allocate_align(size));
7075
o.via.bin.ptr = ptr;
71-
o.via.bin.size = static_cast<uint32_t>(v.size());
72-
std::memcpy(ptr, v.data(), v.size());
76+
o.via.bin.size = size;
77+
std::memcpy(ptr, v.data(), size);
7378
}
7479

7580
} // MSGPACK_API_VERSION_NAMESPACE(v1)

include/msgpack/adaptor/cpp11/forward_list.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// MessagePack for C++ static resolution routine
33
//
4-
// Copyright (C) 2014 KONDO Takatoshi
4+
// Copyright (C) 2014 KONDO-2015 Takatoshi
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
2121

2222
#include "msgpack/versioning.hpp"
2323
#include "msgpack/object_fwd.hpp"
24+
#include "msgpack/adaptor/check_container_size.hpp"
2425

2526
#include <forward_list>
2627

@@ -44,7 +45,8 @@ inline object const& operator>> (object const& o, std::forward_list<T>& v)
4445
template <typename Stream, typename T>
4546
inline packer<Stream>& operator<< (packer<Stream>& o, const std::forward_list<T>& v)
4647
{
47-
o.pack_array(std::distance(v.begin(), v.end()));
48+
uint32_t size = checked_get_container_size(std::distance(v.begin(), v.end()));
49+
o.pack_array(size);
4850
for(auto const& e : v) o.pack(e);
4951
return o;
5052
}
@@ -57,7 +59,7 @@ inline void operator<< (object::with_zone& o, const std::forward_list<T>& v)
5759
o.via.array.ptr = nullptr;
5860
o.via.array.size = 0;
5961
} else {
60-
std::size_t size = std::distance(v.begin(), v.end());
62+
uint32_t size = checked_get_container_size(std::distance(v.begin(), v.end()));
6163
o.via.array.size = size;
6264
object* p = static_cast<object*>(
6365
o.zone.allocate_align(sizeof(object)*size));

include/msgpack/adaptor/cpp11/tuple.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// MessagePack for C++ static resolution routine
33
//
4-
// Copyright (C) 2008-2014 FURUHASHI Sadayuki and KONDO Takatoshi
4+
// Copyright (C) 2008-2015 FURUHASHI Sadayuki and KONDO Takatoshi
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020

2121
#include "msgpack/versioning.hpp"
2222
#include "msgpack/object_fwd.hpp"
23+
#include "msgpack/adaptor/check_container_size.hpp"
2324

2425
#include <tuple>
2526

@@ -60,7 +61,8 @@ template <typename Stream, typename... Args>
6061
inline const packer<Stream>& operator<< (
6162
packer<Stream>& o,
6263
const std::tuple<Args...>& v) {
63-
o.pack_array(sizeof...(Args));
64+
uint32_t size = checked_get_container_size(sizeof...(Args));
65+
o.pack_array(size);
6466
StdTuplePacker<Stream, decltype(v), sizeof...(Args)>::pack(o, v);
6567
return o;
6668
}
@@ -136,9 +138,10 @@ template <typename... Args>
136138
inline void operator<< (
137139
object::with_zone& o,
138140
std::tuple<Args...> const& v) {
141+
uint32_t size = checked_get_container_size(sizeof...(Args));
139142
o.type = type::ARRAY;
140-
o.via.array.ptr = static_cast<object*>(o.zone.allocate_align(sizeof(object)*sizeof...(Args)));
141-
o.via.array.size = sizeof...(Args);
143+
o.via.array.ptr = static_cast<object*>(o.zone.allocate_align(sizeof(object)*size));
144+
o.via.array.size = size;
142145
StdTupleToObjectWithZone<decltype(v), sizeof...(Args)>::convert(o, v);
143146
}
144147

include/msgpack/adaptor/cpp11/unordered_map.hpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// MessagePack for C++ static resolution routine
33
//
4-
// Copyright (C) 2014 KONDO Takatoshi
4+
// Copyright (C) 2014-2015 KONDO Takatoshi
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020

2121
#include "msgpack/versioning.hpp"
2222
#include "msgpack/object_fwd.hpp"
23+
#include "msgpack/adaptor/check_container_size.hpp"
2324

2425
#include <unordered_map>
2526

@@ -46,9 +47,10 @@ inline object const& operator>> (object const& o, std::unordered_map<K, V>& v)
4647
template <typename Stream, typename K, typename V>
4748
inline packer<Stream>& operator<< (packer<Stream>& o, const std::unordered_map<K,V>& v)
4849
{
49-
o.pack_map(v.size());
50+
uint32_t size = checked_get_container_size(v.size());
51+
o.pack_map(size);
5052
for(typename std::unordered_map<K,V>::const_iterator it(v.begin()), it_end(v.end());
51-
it != it_end; ++it) {
53+
it != it_end; ++it) {
5254
o.pack(it->first);
5355
o.pack(it->second);
5456
}
@@ -63,10 +65,11 @@ inline void operator<< (object::with_zone& o, const std::unordered_map<K,V>& v)
6365
o.via.map.ptr = nullptr;
6466
o.via.map.size = 0;
6567
} else {
66-
object_kv* p = static_cast<object_kv*>(o.zone.allocate_align(sizeof(object_kv)*v.size()));
67-
object_kv* const pend = p + v.size();
68+
uint32_t size = checked_get_container_size(v.size());
69+
object_kv* p = static_cast<object_kv*>(o.zone.allocate_align(sizeof(object_kv)*size));
70+
object_kv* const pend = p + size;
6871
o.via.map.ptr = p;
69-
o.via.map.size = v.size();
72+
o.via.map.size = size;
7073
typename std::unordered_map<K,V>::const_iterator it(v.begin());
7174
do {
7275
p->key = object(it->first, o.zone);
@@ -98,9 +101,10 @@ inline object const& operator>> (object const& o, std::unordered_multimap<K, V>&
98101
template <typename Stream, typename K, typename V>
99102
inline packer<Stream>& operator<< (packer<Stream>& o, const std::unordered_multimap<K,V>& v)
100103
{
101-
o.pack_map(v.size());
104+
uint32_t size = checked_get_container_size(v.size());
105+
o.pack_map(size);
102106
for(typename std::unordered_multimap<K,V>::const_iterator it(v.begin()), it_end(v.end());
103-
it != it_end; ++it) {
107+
it != it_end; ++it) {
104108
o.pack(it->first);
105109
o.pack(it->second);
106110
}
@@ -115,10 +119,11 @@ inline void operator<< (object::with_zone& o, const std::unordered_multimap<K,V>
115119
o.via.map.ptr = nullptr;
116120
o.via.map.size = 0;
117121
} else {
118-
object_kv* p = static_cast<object_kv*>(o.zone.allocate_align(sizeof(object_kv)*v.size()));
119-
object_kv* const pend = p + v.size();
122+
uint32_t size = checked_get_container_size(v.size());
123+
object_kv* p = static_cast<object_kv*>(o.zone.allocate_align(sizeof(object_kv)*size));
124+
object_kv* const pend = p + size;
120125
o.via.map.ptr = p;
121-
o.via.map.size = v.size();
126+
o.via.map.size = size;
122127
typename std::unordered_multimap<K,V>::const_iterator it(v.begin());
123128
do {
124129
p->key = object(it->first, o.zone);

0 commit comments

Comments
 (0)