diff --git a/include/msgpack/v1/adaptor/carray.hpp b/include/msgpack/v1/adaptor/carray.hpp index 3d315d7d..44e71f51 100644 --- a/include/msgpack/v1/adaptor/carray.hpp +++ b/include/msgpack/v1/adaptor/carray.hpp @@ -48,9 +48,9 @@ struct convert { std::memcpy(v, o.via.bin.ptr, o.via.bin.size); break; case msgpack::type::STR: - if (o.via.str.size + 1 > N) { throw msgpack::type_error(); } + if (o.via.str.size > N) { throw msgpack::type_error(); } std::memcpy(v, o.via.str.ptr, o.via.str.size); - v[o.via.str.size] = '\0'; + if (o.via.str.size < N) v[o.via.str.size] = '\0'; break; default: throw msgpack::type_error(); @@ -69,9 +69,9 @@ struct convert { std::memcpy(v, o.via.bin.ptr, o.via.bin.size); break; case msgpack::type::STR: - if (o.via.str.size + 1 > N) { throw msgpack::type_error(); } + if (o.via.str.size > N) { throw msgpack::type_error(); } std::memcpy(v, o.via.str.ptr, o.via.str.size); - v[o.via.str.size] = '\0'; + if (o.via.str.size < N) v[o.via.str.size] = '\0'; break; default: throw msgpack::type_error(); @@ -86,7 +86,8 @@ template struct pack { template msgpack::packer& operator()(msgpack::packer& o, const T(&v)[N]) const { - o.pack_array(N); + uint32_t size = checked_get_container_size(N); + o.pack_array(size); const T* ptr = v; for (; ptr != &v[N]; ++ptr) o.pack(*ptr); return o; @@ -98,9 +99,11 @@ struct pack { template msgpack::packer& operator()(msgpack::packer& o, const char(&v)[N]) const { char const* p = v; - uint32_t size = checked_get_container_size(std::strlen(p)); - o.pack_str(size); - o.pack_str_body(p, size); + uint32_t size = checked_get_container_size(N); + char const* p2 = static_cast(std::memchr(p, '\0', size)); + uint32_t adjusted_size = p2 ? p2 - p : size; + o.pack_str(adjusted_size); + o.pack_str_body(p, adjusted_size); return o; } }; @@ -109,9 +112,12 @@ template struct pack { template msgpack::packer& operator()(msgpack::packer& o, const char(&v)[N]) const { - uint32_t size = checked_get_container_size(std::strlen(v)); - o.pack_str(size); - o.pack_str_body(v, size); + uint32_t size = checked_get_container_size(N); + char const* p = v; + char const* p2 = static_cast(std::memchr(p, '\0', size)); + uint32_t adjusted_size = p2 ? p2 - p : size; + o.pack_str(adjusted_size); + o.pack_str_body(p, adjusted_size); return o; } }; @@ -143,12 +149,13 @@ struct pack { template struct object_with_zone { void operator()(msgpack::object::with_zone& o, const T(&v)[N]) const { + uint32_t size = checked_get_container_size(N); o.type = msgpack::type::ARRAY; - msgpack::object* ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * N)); + msgpack::object* ptr = static_cast(o.zone.allocate_align(sizeof(msgpack::object) * size)); o.via.array.ptr = ptr; - o.via.array.size = N; + o.via.array.size = size; const T* pv = v; - for (; pv != &v[N]; ++pv) { + for (; pv != &v[size]; ++pv) { *ptr++ = msgpack::object(*pv, o.zone); } } @@ -157,24 +164,30 @@ struct object_with_zone { template struct object_with_zone { void operator()(msgpack::object::with_zone& o, const char(&v)[N]) const { - uint32_t size = checked_get_container_size(std::strlen(v)); + char const* p = v; + uint32_t size = checked_get_container_size(N); + char const* p2 = static_cast(std::memchr(p, '\0', size)); + uint32_t adjusted_size = p2 ? p2 - p : size; o.type = msgpack::type::STR; - char* ptr = static_cast(o.zone.allocate_align(size)); + char* ptr = static_cast(o.zone.allocate_align(adjusted_size)); o.via.str.ptr = ptr; - o.via.str.size = size; - std::memcpy(ptr, v, size); + o.via.str.size = adjusted_size; + std::memcpy(ptr, p, adjusted_size); } }; template struct object_with_zone { void operator()(msgpack::object::with_zone& o, const char(&v)[N]) const { - uint32_t size = checked_get_container_size(std::strlen(v)); + char const* p = v; + uint32_t size = checked_get_container_size(N); + char const* p2 = static_cast(std::memchr(p, '\0', size)); + uint32_t adjusted_size = p2 ? p2 - p : size; o.type = msgpack::type::STR; - char* ptr = static_cast(o.zone.allocate_align(size)); + char* ptr = static_cast(o.zone.allocate_align(adjusted_size)); o.via.str.ptr = ptr; - o.via.str.size = size; - std::memcpy(ptr, v, size); + o.via.str.size = adjusted_size; + std::memcpy(ptr, p, adjusted_size); } }; @@ -205,20 +218,26 @@ struct object_with_zone { template struct object { void operator()(msgpack::object& o, const char(&v)[N]) const { - uint32_t size = checked_get_container_size(std::strlen(v)); + char const* p = v; + uint32_t size = checked_get_container_size(N); + char const* p2 = static_cast(std::memchr(p, '\0', size)); + uint32_t adjusted_size = p2 ? p2 - p : size; o.type = msgpack::type::STR; - o.via.str.ptr = v; - o.via.str.size = size; + o.via.str.ptr = p; + o.via.str.size = adjusted_size; } }; template struct object { void operator()(msgpack::object& o, const char(&v)[N]) const { - uint32_t size = checked_get_container_size(std::strlen(v)); + char const* p = v; + uint32_t size = checked_get_container_size(N); + char const* p2 = static_cast(std::memchr(p, '\0', size)); + uint32_t adjusted_size = p2 ? p2 - p : size; o.type = msgpack::type::STR; - o.via.str.ptr = v; - o.via.str.size = size; + o.via.str.ptr = p; + o.via.str.size = adjusted_size; } };