diff --git a/CMakeLists.txt b/CMakeLists.txt index ef055888..c064fbad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,7 @@ IF (MSGPACK_ENABLE_CXX) include/msgpack/adaptor/bool_fwd.hpp include/msgpack/adaptor/char_ptr.hpp include/msgpack/adaptor/char_ptr_fwd.hpp + include/msgpack/adaptor/check_container_size.hpp include/msgpack/adaptor/cpp11/array.hpp include/msgpack/adaptor/cpp11/array_fwd.hpp include/msgpack/adaptor/cpp11/array_char.hpp diff --git a/include/msgpack/adaptor/char_ptr.hpp b/include/msgpack/adaptor/char_ptr.hpp index 7a8c5cd2..4c3e1a99 100644 --- a/include/msgpack/adaptor/char_ptr.hpp +++ b/include/msgpack/adaptor/char_ptr.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2014 KONDO Takatoshi +// Copyright (C) 2014-2015 KONDO Takatoshi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" + #include namespace msgpack { @@ -29,7 +31,7 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { template inline packer& operator<< (packer& o, const char* v) { - std::size_t size = std::strlen(v); + uint32_t size = checked_get_container_size(std::strlen(v)); o.pack_str(size); o.pack_str_body(v, size); return o; @@ -37,20 +39,20 @@ inline packer& operator<< (packer& o, const char* v) inline void operator<< (object::with_zone& o, const char* v) { - std::size_t size = std::strlen(v); + uint32_t size = checked_get_container_size(std::strlen(v)); o.type = type::STR; char* ptr = static_cast(o.zone.allocate_align(size)); o.via.str.ptr = ptr; - o.via.str.size = static_cast(size); + o.via.str.size = size; memcpy(ptr, v, size); } inline void operator<< (object& o, const char* v) { - std::size_t size = std::strlen(v); + uint32_t size = checked_get_container_size(std::strlen(v)); o.type = type::STR; o.via.str.ptr = v; - o.via.str.size = static_cast(size); + o.via.str.size = size; } template diff --git a/include/msgpack/adaptor/check_container_size.hpp b/include/msgpack/adaptor/check_container_size.hpp new file mode 100644 index 00000000..41fc898f --- /dev/null +++ b/include/msgpack/adaptor/check_container_size.hpp @@ -0,0 +1,61 @@ +// +// MessagePack for C++ static resolution routine +// +// Copyright (C) 2015 KONDO Takatoshi +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef MSGPACK_CHECK_CONTAINER_SIZE_HPP +#define MSGPACK_CHECK_CONTAINER_SIZE_HPP + +#include "msgpack/versioning.hpp" +#include + +namespace msgpack { + +MSGPACK_API_VERSION_NAMESPACE(v1) { + +struct container_size_overflow : public std::runtime_error { + explicit container_size_overflow(const std::string& msg) + :std::runtime_error(msg) {} +#if !defined(MSGPACK_USE_CPP03) + explicit container_size_overflow(const char* msg): + std::runtime_error(msg) {} +#endif // !defined(MSGPACK_USE_CPP03) +}; + +namespace detail { + +template +inline void check_container_size(std::size_t size) { + if (size > 0xffffffff) throw container_size_overflow("container size overflow"); +} + +template <> +inline void check_container_size<4>(std::size_t size) { +} + +} // namespace detail + +template +inline uint32_t checked_get_container_size(T size) { + detail::check_container_size(size); + return static_cast(size); +} + + +} // MSGPACK_API_VERSION_NAMESPACE(v1) + +} // namespace msgpack + +#endif // MSGPACK_CHECK_CONTAINER_SIZE_HPP diff --git a/include/msgpack/adaptor/cpp11/array.hpp b/include/msgpack/adaptor/cpp11/array.hpp index 6c932adf..8affe932 100644 --- a/include/msgpack/adaptor/cpp11/array.hpp +++ b/include/msgpack/adaptor/cpp11/array.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2014 KONDO Takatoshi +// Copyright (C) 2014-2015 KONDO Takatoshi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" #include @@ -47,7 +48,8 @@ inline object const& operator>> (object const& o, std::array& v) { template inline packer& operator<< (packer& o, const std::array& v) { - o.pack_array(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_array(size); for(auto const& e : v) o.pack(e); return o; } @@ -59,8 +61,9 @@ inline void operator<< (object::with_zone& o, const std::array& v) { o.via.array.ptr = nullptr; o.via.array.size = 0; } else { - object* p = static_cast(o.zone.allocate_align(sizeof(object)*v.size())); - o.via.array.size = v.size(); + uint32_t size = checked_get_container_size(v.size()); + object* p = static_cast(o.zone.allocate_align(sizeof(object)*size)); + o.via.array.size = size; o.via.array.ptr = p; for (auto const& e : v) *p++ = object(e, o.zone); } diff --git a/include/msgpack/adaptor/cpp11/array_char.hpp b/include/msgpack/adaptor/cpp11/array_char.hpp index 9df71bb1..ab26f2e6 100644 --- a/include/msgpack/adaptor/cpp11/array_char.hpp +++ b/include/msgpack/adaptor/cpp11/array_char.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2014 KONDO Takatoshi +// Copyright (C) 2014-2015 KONDO Takatoshi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ #include "msgpack/versioning.hpp" #include "msgpack_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" + #include namespace msgpack { @@ -48,8 +50,9 @@ inline object const& operator>> (object const& o, std::array& v) template inline packer& operator<< (packer& o, const std::array& v) { - o.pack_bin(v.size()); - o.pack_bin_body(v.data(), v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_bin(size); + o.pack_bin_body(v.data(), size); return o; } @@ -57,19 +60,21 @@ inline packer& operator<< (packer& o, const std::array& template inline void operator<< (object& o, const std::array& v) { + uint32_t size = checked_get_container_size(v.size()); o.type = type::BIN; o.via.bin.ptr = v.data(); - o.via.bin.size = static_cast(v.size()); + o.via.bin.size = size; } template inline void operator<< (object::with_zone& o, const std::array& v) { + uint32_t size = checked_get_container_size(v.size()); o.type = type::BIN; - char* ptr = static_cast(o.zone.allocate_align(v.size())); + char* ptr = static_cast(o.zone.allocate_align(size)); o.via.bin.ptr = ptr; - o.via.bin.size = static_cast(v.size()); - std::memcpy(ptr, v.data(), v.size()); + o.via.bin.size = size; + std::memcpy(ptr, v.data(), size); } } // MSGPACK_API_VERSION_NAMESPACE(v1) diff --git a/include/msgpack/adaptor/cpp11/forward_list.hpp b/include/msgpack/adaptor/cpp11/forward_list.hpp index dd78afd6..974ba1ce 100644 --- a/include/msgpack/adaptor/cpp11/forward_list.hpp +++ b/include/msgpack/adaptor/cpp11/forward_list.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2014 KONDO Takatoshi +// Copyright (C) 2014 KONDO-2015 Takatoshi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" #include @@ -44,7 +45,8 @@ inline object const& operator>> (object const& o, std::forward_list& v) template inline packer& operator<< (packer& o, const std::forward_list& v) { - o.pack_array(std::distance(v.begin(), v.end())); + uint32_t size = checked_get_container_size(std::distance(v.begin(), v.end())); + o.pack_array(size); for(auto const& e : v) o.pack(e); return o; } @@ -57,7 +59,7 @@ inline void operator<< (object::with_zone& o, const std::forward_list& v) o.via.array.ptr = nullptr; o.via.array.size = 0; } else { - std::size_t size = std::distance(v.begin(), v.end()); + uint32_t size = checked_get_container_size(std::distance(v.begin(), v.end())); o.via.array.size = size; object* p = static_cast( o.zone.allocate_align(sizeof(object)*size)); diff --git a/include/msgpack/adaptor/cpp11/tuple.hpp b/include/msgpack/adaptor/cpp11/tuple.hpp index b917360a..5ca0c402 100644 --- a/include/msgpack/adaptor/cpp11/tuple.hpp +++ b/include/msgpack/adaptor/cpp11/tuple.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2008-2014 FURUHASHI Sadayuki and KONDO Takatoshi +// Copyright (C) 2008-2015 FURUHASHI Sadayuki and KONDO Takatoshi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" #include @@ -60,7 +61,8 @@ template inline const packer& operator<< ( packer& o, const std::tuple& v) { - o.pack_array(sizeof...(Args)); + uint32_t size = checked_get_container_size(sizeof...(Args)); + o.pack_array(size); StdTuplePacker::pack(o, v); return o; } @@ -136,9 +138,10 @@ template inline void operator<< ( object::with_zone& o, std::tuple const& v) { + uint32_t size = checked_get_container_size(sizeof...(Args)); o.type = type::ARRAY; - o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(object)*sizeof...(Args))); - o.via.array.size = sizeof...(Args); + o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(object)*size)); + o.via.array.size = size; StdTupleToObjectWithZone::convert(o, v); } diff --git a/include/msgpack/adaptor/cpp11/unordered_map.hpp b/include/msgpack/adaptor/cpp11/unordered_map.hpp index 6d31cf86..513e19a7 100644 --- a/include/msgpack/adaptor/cpp11/unordered_map.hpp +++ b/include/msgpack/adaptor/cpp11/unordered_map.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2014 KONDO Takatoshi +// Copyright (C) 2014-2015 KONDO Takatoshi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" #include @@ -46,9 +47,10 @@ inline object const& operator>> (object const& o, std::unordered_map& v) template inline packer& operator<< (packer& o, const std::unordered_map& v) { - o.pack_map(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_map(size); for(typename std::unordered_map::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { + it != it_end; ++it) { o.pack(it->first); o.pack(it->second); } @@ -63,10 +65,11 @@ inline void operator<< (object::with_zone& o, const std::unordered_map& v) o.via.map.ptr = nullptr; o.via.map.size = 0; } else { - object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*v.size())); - object_kv* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*size)); + object_kv* const pend = p + size; o.via.map.ptr = p; - o.via.map.size = v.size(); + o.via.map.size = size; typename std::unordered_map::const_iterator it(v.begin()); do { p->key = object(it->first, o.zone); @@ -98,9 +101,10 @@ inline object const& operator>> (object const& o, std::unordered_multimap& template inline packer& operator<< (packer& o, const std::unordered_multimap& v) { - o.pack_map(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_map(size); for(typename std::unordered_multimap::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { + it != it_end; ++it) { o.pack(it->first); o.pack(it->second); } @@ -115,10 +119,11 @@ inline void operator<< (object::with_zone& o, const std::unordered_multimap o.via.map.ptr = nullptr; o.via.map.size = 0; } else { - object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*v.size())); - object_kv* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*size)); + object_kv* const pend = p + size; o.via.map.ptr = p; - o.via.map.size = v.size(); + o.via.map.size = size; typename std::unordered_multimap::const_iterator it(v.begin()); do { p->key = object(it->first, o.zone); diff --git a/include/msgpack/adaptor/cpp11/unordered_set.hpp b/include/msgpack/adaptor/cpp11/unordered_set.hpp index fe8eb3b1..8ac20d58 100644 --- a/include/msgpack/adaptor/cpp11/unordered_set.hpp +++ b/include/msgpack/adaptor/cpp11/unordered_set.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2014 KONDO Takatoshi +// Copyright (C) 2014-2015 KONDO Takatoshi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" #include @@ -45,9 +46,10 @@ inline object const& operator>> (object const& o, std::unordered_set& v) template inline packer& operator<< (packer& o, const std::unordered_set& v) { - o.pack_array(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_array(size); for(typename std::unordered_set::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { + it != it_end; ++it) { o.pack(*it); } return o; @@ -61,10 +63,11 @@ inline void operator<< (object::with_zone& o, const std::unordered_set& v) o.via.array.ptr = nullptr; o.via.array.size = 0; } else { - object* p = static_cast(o.zone.allocate_align(sizeof(object)*v.size())); - object* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object* p = static_cast(o.zone.allocate_align(sizeof(object)*size)); + object* const pend = p + size; o.via.array.ptr = p; - o.via.array.size = v.size(); + o.via.array.size = size; typename std::unordered_set::const_iterator it(v.begin()); do { *p = object(*it, o.zone); @@ -93,7 +96,8 @@ inline object const& operator>> (object const& o, std::unordered_multiset& v) template inline packer& operator<< (packer& o, const std::unordered_multiset& v) { - o.pack_array(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_array(size); for(typename std::unordered_multiset::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(*it); @@ -109,10 +113,11 @@ inline void operator<< (object::with_zone& o, const std::unordered_multiset& o.via.array.ptr = nullptr; o.via.array.size = 0; } else { - object* p = static_cast(o.zone.allocate_align(sizeof(object)*v.size())); - object* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object* p = static_cast(o.zone.allocate_align(sizeof(object)*size)); + object* const pend = p + size; o.via.array.ptr = p; - o.via.array.size = v.size(); + o.via.array.size = size; typename std::unordered_multiset::const_iterator it(v.begin()); do { *p = object(*it, o.zone); diff --git a/include/msgpack/adaptor/deque.hpp b/include/msgpack/adaptor/deque.hpp index 94bac923..b460963b 100644 --- a/include/msgpack/adaptor/deque.hpp +++ b/include/msgpack/adaptor/deque.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2008-2009 FURUHASHI Sadayuki +// Copyright (C) 2008-2015 FURUHASHI Sadayuki // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" + #include namespace msgpack { @@ -43,7 +45,8 @@ inline object const& operator>> (object const& o, std::deque& v) template inline packer& operator<< (packer& o, const std::deque& v) { - o.pack_array(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_array(size); for(typename std::deque::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(*it); @@ -59,10 +62,11 @@ inline void operator<< (object::with_zone& o, const std::deque& v) o.via.array.ptr = nullptr; o.via.array.size = 0; } else { - object* p = static_cast(o.zone.allocate_align(sizeof(object)*v.size())); - object* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object* p = static_cast(o.zone.allocate_align(sizeof(object)*size)); + object* const pend = p + size; o.via.array.ptr = p; - o.via.array.size = v.size(); + o.via.array.size = size; typename std::deque::const_iterator it(v.begin()); do { *p = object(*it, o.zone); diff --git a/include/msgpack/adaptor/list.hpp b/include/msgpack/adaptor/list.hpp index 321f531b..6d97b100 100644 --- a/include/msgpack/adaptor/list.hpp +++ b/include/msgpack/adaptor/list.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2008-2009 FURUHASHI Sadayuki +// Copyright (C) 2008-2015 FURUHASHI Sadayuki // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" + #include namespace msgpack { @@ -43,9 +45,10 @@ inline object const& operator>> (object const& o, std::list& v) template inline packer& operator<< (packer& o, const std::list& v) { - o.pack_array(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_array(size); for(typename std::list::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { + it != it_end; ++it) { o.pack(*it); } return o; @@ -59,10 +62,11 @@ inline void operator<< (object::with_zone& o, const std::list& v) o.via.array.ptr = nullptr; o.via.array.size = 0; } else { - object* p = static_cast(o.zone.allocate_align(sizeof(object)*v.size())); - object* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object* p = static_cast(o.zone.allocate_align(sizeof(object)*size)); + object* const pend = p + size; o.via.array.ptr = p; - o.via.array.size = v.size(); + o.via.array.size = size; typename std::list::const_iterator it(v.begin()); do { *p = object(*it, o.zone); diff --git a/include/msgpack/adaptor/map.hpp b/include/msgpack/adaptor/map.hpp index c8e5c22f..211757e7 100644 --- a/include/msgpack/adaptor/map.hpp +++ b/include/msgpack/adaptor/map.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2008-2009 FURUHASHI Sadayuki +// Copyright (C) 2008-2015 FURUHASHI Sadayuki // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" + #include #include #include @@ -63,9 +65,10 @@ inline object const& operator>> (object const& o, type::assoc_vector& v) template inline packer& operator<< (packer& o, const type::assoc_vector& v) { - o.pack_map(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_map(size); for(typename type::assoc_vector::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { + it != it_end; ++it) { o.pack(it->first); o.pack(it->second); } @@ -80,10 +83,11 @@ inline void operator<< (object::with_zone& o, const type::assoc_vector& v) o.via.map.ptr = nullptr; o.via.map.size = 0; } else { - object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*v.size())); - object_kv* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*size)); + object_kv* const pend = p + size; o.via.map.ptr = p; - o.via.map.size = v.size(); + o.via.map.size = size; typename type::assoc_vector::const_iterator it(v.begin()); do { p->key = object(it->first, o.zone); @@ -121,9 +125,10 @@ inline object const& operator>> (object const& o, std::map& v) template inline packer& operator<< (packer& o, const std::map& v) { - o.pack_map(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_map(size); for(typename std::map::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { + it != it_end; ++it) { o.pack(it->first); o.pack(it->second); } @@ -138,10 +143,11 @@ inline void operator<< (object::with_zone& o, const std::map& v) o.via.map.ptr = nullptr; o.via.map.size = 0; } else { - object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*v.size())); - object_kv* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*size)); + object_kv* const pend = p + size; o.via.map.ptr = p; - o.via.map.size = v.size(); + o.via.map.size = size; typename std::map::const_iterator it(v.begin()); do { p->key = object(it->first, o.zone); @@ -173,9 +179,10 @@ inline object const& operator>> (object const& o, std::multimap& v) template inline packer& operator<< (packer& o, const std::multimap& v) { - o.pack_map(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_map(size); for(typename std::multimap::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { + it != it_end; ++it) { o.pack(it->first); o.pack(it->second); } @@ -190,10 +197,11 @@ inline void operator<< (object::with_zone& o, const std::multimap& v) o.via.map.ptr = nullptr; o.via.map.size = 0; } else { - object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*v.size())); - object_kv* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*size)); + object_kv* const pend = p + size; o.via.map.ptr = p; - o.via.map.size = v.size(); + o.via.map.size = size; typename std::multimap::const_iterator it(v.begin()); do { p->key = object(it->first, o.zone); diff --git a/include/msgpack/adaptor/set.hpp b/include/msgpack/adaptor/set.hpp index 427b52fc..e741241f 100644 --- a/include/msgpack/adaptor/set.hpp +++ b/include/msgpack/adaptor/set.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2008-2009 FURUHASHI Sadayuki +// Copyright (C) 2008-2015 FURUHASHI Sadayuki // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" #include @@ -45,9 +46,10 @@ inline object const& operator>> (object const& o, std::set& v) template inline packer& operator<< (packer& o, const std::set& v) { - o.pack_array(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_array(size); for(typename std::set::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { + it != it_end; ++it) { o.pack(*it); } return o; @@ -61,10 +63,11 @@ inline void operator<< (object::with_zone& o, const std::set& v) o.via.array.ptr = nullptr; o.via.array.size = 0; } else { - object* p = static_cast(o.zone.allocate_align(sizeof(object)*v.size())); - object* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object* p = static_cast(o.zone.allocate_align(sizeof(object)*size)); + object* const pend = p + size; o.via.array.ptr = p; - o.via.array.size = v.size(); + o.via.array.size = size; typename std::set::const_iterator it(v.begin()); do { *p = object(*it, o.zone); @@ -93,9 +96,10 @@ inline object const& operator>> (object const& o, std::multiset& v) template inline packer& operator<< (packer& o, const std::multiset& v) { - o.pack_array(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_array(size); for(typename std::multiset::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { + it != it_end; ++it) { o.pack(*it); } return o; @@ -109,10 +113,11 @@ inline void operator<< (object::with_zone& o, const std::multiset& v) o.via.array.ptr = nullptr; o.via.array.size = 0; } else { - object* p = static_cast(o.zone.allocate_align(sizeof(object)*v.size())); - object* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object* p = static_cast(o.zone.allocate_align(sizeof(object)*size)); + object* const pend = p + size; o.via.array.ptr = p; - o.via.array.size = v.size(); + o.via.array.size = size; typename std::multiset::const_iterator it(v.begin()); do { *p = object(*it, o.zone); diff --git a/include/msgpack/adaptor/string.hpp b/include/msgpack/adaptor/string.hpp index 05c2867f..26a4dd79 100644 --- a/include/msgpack/adaptor/string.hpp +++ b/include/msgpack/adaptor/string.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2008-2009 FURUHASHI Sadayuki +// Copyright (C) 2008-2015 FURUHASHI Sadayuki // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" + #include namespace msgpack { @@ -45,25 +47,28 @@ inline object const& operator>> (object const& o, std::string& v) template inline packer& operator<< (packer& o, const std::string& v) { - o.pack_str(v.size()); - o.pack_str_body(v.data(), v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_str(size); + o.pack_str_body(v.data(), size); return o; } inline void operator<< (object::with_zone& o, const std::string& v) { + uint32_t size = checked_get_container_size(v.size()); o.type = type::STR; - char* ptr = static_cast(o.zone.allocate_align(v.size())); + char* ptr = static_cast(o.zone.allocate_align(size)); o.via.str.ptr = ptr; - o.via.str.size = static_cast(v.size()); - memcpy(ptr, v.data(), v.size()); + o.via.str.size = size; + memcpy(ptr, v.data(), size); } inline void operator<< (object& o, const std::string& v) { + uint32_t size = checked_get_container_size(v.size()); o.type = type::STR; o.via.str.ptr = v.data(); - o.via.str.size = static_cast(v.size()); + o.via.str.size = size; } } // MSGPACK_API_VERSION_NAMESPACE(v1) diff --git a/include/msgpack/adaptor/tr1/unordered_map.hpp b/include/msgpack/adaptor/tr1/unordered_map.hpp index 763d7427..7ed07dae 100644 --- a/include/msgpack/adaptor/tr1/unordered_map.hpp +++ b/include/msgpack/adaptor/tr1/unordered_map.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2008-2009 FURUHASHI Sadayuki +// Copyright (C) 2008-2015 FURUHASHI Sadayuki // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" #if defined(_LIBCPP_VERSION) || (_MSC_VER >= 1700) @@ -65,9 +66,10 @@ inline object const& operator>> (object const& o, MSGPACK_STD_TR1::unordered_map template inline packer& operator<< (packer& o, const MSGPACK_STD_TR1::unordered_map& v) { - o.pack_map(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_map(size); for(typename MSGPACK_STD_TR1::unordered_map::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { + it != it_end; ++it) { o.pack(it->first); o.pack(it->second); } @@ -82,10 +84,11 @@ inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_m o.via.map.ptr = nullptr; o.via.map.size = 0; } else { - object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*v.size())); - object_kv* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*size)); + object_kv* const pend = p + size; o.via.map.ptr = p; - o.via.map.size = v.size(); + o.via.map.size = size; typename MSGPACK_STD_TR1::unordered_map::const_iterator it(v.begin()); do { p->key = object(it->first, o.zone); @@ -117,9 +120,10 @@ inline object const& operator>> (object const& o, MSGPACK_STD_TR1::unordered_mul template inline packer& operator<< (packer& o, const MSGPACK_STD_TR1::unordered_multimap& v) { - o.pack_map(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_map(size); for(typename MSGPACK_STD_TR1::unordered_multimap::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { + it != it_end; ++it) { o.pack(it->first); o.pack(it->second); } @@ -134,10 +138,11 @@ inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_m o.via.map.ptr = nullptr; o.via.map.size = 0; } else { - object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*v.size())); - object_kv* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object_kv* p = static_cast(o.zone.allocate_align(sizeof(object_kv)*size)); + object_kv* const pend = p + size; o.via.map.ptr = p; - o.via.map.size = v.size(); + o.via.map.size = size; typename MSGPACK_STD_TR1::unordered_multimap::const_iterator it(v.begin()); do { p->key = object(it->first, o.zone); diff --git a/include/msgpack/adaptor/tr1/unordered_set.hpp b/include/msgpack/adaptor/tr1/unordered_set.hpp index 4542dda1..28e1b993 100644 --- a/include/msgpack/adaptor/tr1/unordered_set.hpp +++ b/include/msgpack/adaptor/tr1/unordered_set.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2008-2009 FURUHASHI Sadayuki +// Copyright (C) 2008-2015 FURUHASHI Sadayuki // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" #if defined(_LIBCPP_VERSION) || (_MSC_VER >= 1700) @@ -64,9 +65,10 @@ inline object const& operator>> (object const& o, MSGPACK_STD_TR1::unordered_set template inline packer& operator<< (packer& o, const MSGPACK_STD_TR1::unordered_set& v) { - o.pack_array(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_array(size); for(typename MSGPACK_STD_TR1::unordered_set::const_iterator it(v.begin()), it_end(v.end()); - it != it_end; ++it) { + it != it_end; ++it) { o.pack(*it); } return o; @@ -80,10 +82,11 @@ inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_s o.via.array.ptr = nullptr; o.via.array.size = 0; } else { - object* p = static_cast(o.zone.allocate_align(sizeof(object)*v.size())); - object* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object* p = static_cast(o.zone.allocate_align(sizeof(object)*size)); + object* const pend = p + size; o.via.array.ptr = p; - o.via.array.size = v.size(); + o.via.array.size = size; typename MSGPACK_STD_TR1::unordered_set::const_iterator it(v.begin()); do { *p = object(*it, o.zone); @@ -112,7 +115,8 @@ inline object const& operator>> (object const& o, MSGPACK_STD_TR1::unordered_mul template inline packer& operator<< (packer& o, const MSGPACK_STD_TR1::unordered_multiset& v) { - o.pack_array(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_array(size); for(typename MSGPACK_STD_TR1::unordered_multiset::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(*it); @@ -128,10 +132,11 @@ inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_m o.via.array.ptr = nullptr; o.via.array.size = 0; } else { - object* p = static_cast(o.zone.allocate_align(sizeof(object)*v.size())); - object* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object* p = static_cast(o.zone.allocate_align(sizeof(object)*size)); + object* const pend = p + size; o.via.array.ptr = p; - o.via.array.size = v.size(); + o.via.array.size = size; typename MSGPACK_STD_TR1::unordered_multiset::const_iterator it(v.begin()); do { *p = object(*it, o.zone); diff --git a/include/msgpack/adaptor/vector.hpp b/include/msgpack/adaptor/vector.hpp index fe643117..2e5175c7 100644 --- a/include/msgpack/adaptor/vector.hpp +++ b/include/msgpack/adaptor/vector.hpp @@ -20,6 +20,8 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" + #include namespace msgpack { @@ -47,7 +49,8 @@ inline object const& operator>> (object const& o, std::vector& v) template inline packer& operator<< (packer& o, const std::vector& v) { - o.pack_array(v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_array(size); for(typename std::vector::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(*it); @@ -63,10 +66,11 @@ inline void operator<< (object::with_zone& o, const std::vector& v) o.via.array.ptr = nullptr; o.via.array.size = 0; } else { - object* p = static_cast(o.zone.allocate_align(sizeof(object)*v.size())); - object* const pend = p + v.size(); + uint32_t size = checked_get_container_size(v.size()); + object* p = static_cast(o.zone.allocate_align(sizeof(object)*size)); + object* const pend = p + size; o.via.array.ptr = p; - o.via.array.size = v.size(); + o.via.array.size = size; typename std::vector::const_iterator it(v.begin()); do { *p = object(*it, o.zone); diff --git a/include/msgpack/adaptor/vector_char.hpp b/include/msgpack/adaptor/vector_char.hpp index 4db6e94c..73b26a96 100644 --- a/include/msgpack/adaptor/vector_char.hpp +++ b/include/msgpack/adaptor/vector_char.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2014 KONDO Takatoshi +// Copyright (C) 2014-2015 KONDO Takatoshi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ #include "msgpack/versioning.hpp" #include "msgpack/object_fwd.hpp" +#include "msgpack/adaptor/check_container_size.hpp" + #include namespace msgpack { @@ -47,26 +49,29 @@ inline object const& operator>> (object const& o, std::vector& v) template inline packer& operator<< (packer& o, const std::vector& v) { - o.pack_bin(v.size()); - o.pack_bin_body(&v.front(), v.size()); + uint32_t size = checked_get_container_size(v.size()); + o.pack_bin(size); + o.pack_bin_body(&v.front(), size); return o; } inline void operator<< (object& o, const std::vector& v) { + uint32_t size = checked_get_container_size(v.size()); o.type = type::BIN; o.via.bin.ptr = &v.front(); - o.via.bin.size = static_cast(v.size()); + o.via.bin.size = size; } inline void operator<< (object::with_zone& o, const std::vector& v) { + uint32_t size = checked_get_container_size(v.size()); o.type = type::BIN; - char* ptr = static_cast(o.zone.allocate_align(v.size())); + char* ptr = static_cast(o.zone.allocate_align(size)); o.via.bin.ptr = ptr; - o.via.bin.size = static_cast(v.size()); - std::memcpy(ptr, &v.front(), v.size()); + o.via.bin.size = size; + std::memcpy(ptr, &v.front(), size); } } // MSGPACK_API_VERSION_NAMESPACE(v1) diff --git a/include/msgpack/pack.hpp b/include/msgpack/pack.hpp index 9360d229..eea8a51c 100644 --- a/include/msgpack/pack.hpp +++ b/include/msgpack/pack.hpp @@ -78,18 +78,18 @@ public: packer& pack_true(); packer& pack_false(); - packer& pack_array(size_t n); + packer& pack_array(uint32_t n); - packer& pack_map(size_t n); + packer& pack_map(uint32_t n); - packer& pack_str(size_t l); - packer& pack_str_body(const char* b, size_t l); + packer& pack_str(uint32_t l); + packer& pack_str_body(const char* b, uint32_t l); - packer& pack_bin(size_t l); - packer& pack_bin_body(const char* b, size_t l); + packer& pack_bin(uint32_t l); + packer& pack_bin_body(const char* b, uint32_t l); packer& pack_ext(size_t l, int8_t type); - packer& pack_ext_body(const char* b, size_t l); + packer& pack_ext_body(const char* b, uint32_t l); private: template @@ -638,7 +638,7 @@ inline packer& packer::pack_false() template -inline packer& packer::pack_array(size_t n) +inline packer& packer::pack_array(uint32_t n) { if(n < 16) { char d = static_cast(0x90u | n); @@ -656,10 +656,10 @@ inline packer& packer::pack_array(size_t n) } template -inline packer& packer::pack_map(size_t n) +inline packer& packer::pack_map(uint32_t n) { if(n < 16) { - unsigned char d = 0x80u | n; + unsigned char d = static_cast(0x80u | n); char buf = take8_8(d); append_buffer(&buf, 1); } else if(n < 65536) { @@ -675,7 +675,7 @@ inline packer& packer::pack_map(size_t n) } template -inline packer& packer::pack_str(size_t l) +inline packer& packer::pack_str(uint32_t l) { if(l < 32) { unsigned char d = 0xa0u | static_cast(l); @@ -698,14 +698,14 @@ inline packer& packer::pack_str(size_t l) } template -inline packer& packer::pack_str_body(const char* b, size_t l) +inline packer& packer::pack_str_body(const char* b, uint32_t l) { append_buffer(b, l); return *this; } template -inline packer& packer::pack_bin(size_t l) +inline packer& packer::pack_bin(uint32_t l) { if(l < 256) { char buf[2]; @@ -724,7 +724,7 @@ inline packer& packer::pack_bin(size_t l) } template -inline packer& packer::pack_bin_body(const char* b, size_t l) +inline packer& packer::pack_bin_body(const char* b, uint32_t l) { append_buffer(b, l); return *this; @@ -790,7 +790,7 @@ inline packer& packer::pack_ext(size_t l, int8_t type) } template -inline packer& packer::pack_ext_body(const char* b, size_t l) +inline packer& packer::pack_ext_body(const char* b, uint32_t l) { append_buffer(b, l); return *this; diff --git a/include/msgpack/unpack.hpp b/include/msgpack/unpack.hpp index 3a670736..c091463f 100644 --- a/include/msgpack/unpack.hpp +++ b/include/msgpack/unpack.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ deserializing routine // -// Copyright (C) 2008-2013 FURUHASHI Sadayuki and KONDO Takatoshi +// Copyright (C) 2008-2015 FURUHASHI Sadayuki and KONDO Takatoshi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -324,7 +324,7 @@ inline void unpack_ext(unpack_user& u, const char* p, std::size_t l, object& o) std::memcpy(tmp, p, l); o.via.ext.ptr = tmp; } - o.via.ext.size = l - 1; + o.via.ext.size = static_cast(l - 1); } @@ -616,7 +616,7 @@ inline int context::execute(const char* data, std::size_t len, std::size_t& off) } else if(0xa0 <= selector && selector <= 0xbf) { // FixStr m_trail = static_cast(*m_current) & 0x1f; if(m_trail == 0) { - unpack_str(m_user, n, m_trail, obj); + unpack_str(m_user, n, static_cast(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret; } @@ -769,7 +769,7 @@ inline int context::execute(const char* data, std::size_t len, std::size_t& off) load(tmp, n); m_trail = tmp; if(m_trail == 0) { - unpack_str(m_user, n, m_trail, obj); + unpack_str(m_user, n, static_cast(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret; } @@ -783,7 +783,7 @@ inline int context::execute(const char* data, std::size_t len, std::size_t& off) load(tmp, n); m_trail = tmp; if(m_trail == 0) { - unpack_bin(m_user, n, m_trail, obj); + unpack_bin(m_user, n, static_cast(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret; } @@ -811,7 +811,7 @@ inline int context::execute(const char* data, std::size_t len, std::size_t& off) load(tmp, n); m_trail = tmp; if(m_trail == 0) { - unpack_str(m_user, n, m_trail, obj); + unpack_str(m_user, n, static_cast(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret; } @@ -825,7 +825,7 @@ inline int context::execute(const char* data, std::size_t len, std::size_t& off) load(tmp, n); m_trail = tmp; if(m_trail == 0) { - unpack_bin(m_user, n, m_trail, obj); + unpack_bin(m_user, n, static_cast(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret; } @@ -853,7 +853,7 @@ inline int context::execute(const char* data, std::size_t len, std::size_t& off) load(tmp, n); m_trail = tmp; if(m_trail == 0) { - unpack_str(m_user, n, m_trail, obj); + unpack_str(m_user, n, static_cast(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret; } @@ -867,7 +867,7 @@ inline int context::execute(const char* data, std::size_t len, std::size_t& off) load(tmp, n); m_trail = tmp; if(m_trail == 0) { - unpack_bin(m_user, n, m_trail, obj); + unpack_bin(m_user, n, static_cast(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret; } @@ -893,12 +893,12 @@ inline int context::execute(const char* data, std::size_t len, std::size_t& off) } } break; case MSGPACK_ACS_STR_VALUE: { - unpack_str(m_user, n, m_trail, obj); + unpack_str(m_user, n, static_cast(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret; } break; case MSGPACK_ACS_BIN_VALUE: { - unpack_bin(m_user, n, m_trail, obj); + unpack_bin(m_user, n, static_cast(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret; } break; diff --git a/src/Makefile.am b/src/Makefile.am index b39f256c..9e87e0d1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -58,6 +58,7 @@ nobase_include_HEADERS += \ ../include/msgpack/adaptor/bool_fwd.hpp \ ../include/msgpack/adaptor/char_ptr.hpp \ ../include/msgpack/adaptor/char_ptr_fwd.hpp \ + ../include/msgpack/adaptor/check_container_size.hpp \ ../include/msgpack/adaptor/cpp11/array.hpp \ ../include/msgpack/adaptor/cpp11/array_fwd.hpp \ ../include/msgpack/adaptor/cpp11/array_char.hpp \ diff --git a/test/object_with_zone.cpp b/test/object_with_zone.cpp index af817ec3..e543e890 100644 --- a/test/object_with_zone.cpp +++ b/test/object_with_zone.cpp @@ -322,7 +322,7 @@ TEST(object_without_zone, char_ptr) TEST(object_with_zone, raw_ref) { string s = "abc"; - msgpack::type::raw_ref v(s.data(), s.size()); + msgpack::type::raw_ref v(s.data(), static_cast(s.size())); msgpack::zone z; msgpack::object obj(v, z); EXPECT_EQ(obj.as(), v); @@ -336,7 +336,7 @@ TEST(object_with_zone, raw_ref) TEST(object_without_zone, raw_ref) { string s = "abc"; - msgpack::type::raw_ref v(s.data(), s.size()); + msgpack::type::raw_ref v(s.data(), static_cast(s.size())); msgpack::zone z; msgpack::object obj(v); EXPECT_EQ(obj.as(), v);