Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 2026-09-05 version 7.0.3
* Fix ext32 unpacking of the maximum UINT32_MAX-byte payload. (#1185)

# 2026-08-25 version 7.0.2
* Fix integer overflow on msgpack_unpacker_expand_buffer(). (#1182)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
`msgpack` for C
===================

Version 7.0.2 [![Build Status](https://github.com/msgpack/msgpack-c/workflows/CI/badge.svg?branch=c_master)](https://github.com/msgpack/msgpack-c/actions) [![Build status](https://ci.appveyor.com/api/projects/status/8kstcgt79qj123mw/branch/c_master?svg=true)](https://ci.appveyor.com/project/redboltz/msgpack-c/branch/c_master)
Version 7.0.3 [![Build Status](https://github.com/msgpack/msgpack-c/workflows/CI/badge.svg?branch=c_master)](https://github.com/msgpack/msgpack-c/actions) [![Build status](https://ci.appveyor.com/api/projects/status/8kstcgt79qj123mw/branch/c_master?svg=true)](https://ci.appveyor.com/project/redboltz/msgpack-c/branch/c_master)
[![codecov](https://codecov.io/gh/msgpack/msgpack-c/branch/c_master/graph/badge.svg)](https://app.codecov.io/gh/msgpack/msgpack-c/tree/c_master)

It's like JSON but smaller and faster.
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 7.0.2.{build}
version: 7.0.3.{build}

branches:
only:
Expand Down
12 changes: 8 additions & 4 deletions include/msgpack/unpack_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ msgpack_unpack_struct_decl(_stack) {
msgpack_unpack_struct_decl(_context) {
msgpack_unpack_user user;
unsigned int cs;
unsigned int trail;
size_t trail;
unsigned int top;
/*
msgpack_unpack_struct(_stack)* stack;
Expand Down Expand Up @@ -99,7 +99,7 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
const unsigned char* const pe = (unsigned char*)data + len;
const void* n = NULL;

unsigned int trail = ctx->trail;
size_t trail = ctx->trail;
unsigned int cs = ctx->cs;
unsigned int top = ctx->top;
msgpack_unpack_struct(_stack)* stack = ctx->stack;
Expand Down Expand Up @@ -326,7 +326,7 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
case MSGPACK_CS_EXT_16:{
uint16_t tmp;
_msgpack_load16(uint16_t,n,&tmp);
again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, tmp + 1, _ext_zero);
again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, (size_t)tmp + 1, _ext_zero);
}
case MSGPACK_CS_STR_32:{
uint32_t tmp;
Expand All @@ -341,7 +341,11 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
case MSGPACK_CS_EXT_32:{
uint32_t tmp;
_msgpack_load32(uint32_t,n,&tmp);
again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, tmp + 1, _ext_zero);
/* cast before adding: on a 64-bit size_t this lets an ext32 with
* the maximum UINT32_MAX-byte payload carry its trailing type
* byte without wrapping trail back to 0 the way `tmp + 1` would
* when tmp is exactly UINT32_MAX */
again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, (size_t)tmp + 1, _ext_zero);
}
case MSGPACK_ACS_STR_VALUE:
_str_zero:
Expand Down
2 changes: 1 addition & 1 deletion include/msgpack/version_master.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#define MSGPACK_VERSION_MAJOR 7
#define MSGPACK_VERSION_MINOR 0
#define MSGPACK_VERSION_REVISION 2
#define MSGPACK_VERSION_REVISION 3
6 changes: 3 additions & 3 deletions src/unpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ static inline int template_callback_map_item(unpack_user* u, msgpack_object* c,
return 0;
}

static inline int template_callback_str(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
static inline int template_callback_str(unpack_user* u, const char* b, const char* p, size_t l, msgpack_object* o)
{
MSGPACK_UNUSED(b);
if (*u->z == NULL) {
Expand All @@ -291,7 +291,7 @@ static inline int template_callback_str(unpack_user* u, const char* b, const cha
return 0;
}

static inline int template_callback_bin(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
static inline int template_callback_bin(unpack_user* u, const char* b, const char* p, size_t l, msgpack_object* o)
{
MSGPACK_UNUSED(b);
if (*u->z == NULL) {
Expand All @@ -307,7 +307,7 @@ static inline int template_callback_bin(unpack_user* u, const char* b, const cha
return 0;
}

static inline int template_callback_ext(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
static inline int template_callback_ext(unpack_user* u, const char* b, const char* p, size_t l, msgpack_object* o)
{
MSGPACK_UNUSED(b);
if (l == 0) {
Expand Down
39 changes: 39 additions & 0 deletions test/msgpack_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,45 @@ TEST(MSGPACKC, simple_buffer_fixext_4byte_65536)
msgpack_sbuffer_destroy(&sbuf);
}

// ext32's length header covers up to UINT32_MAX bytes of data. The packed
// message (header + body) does not fit in a 32-bit size_t, so this test is
// only built for 64-bit targets. On 32-bit builds gcc also rejects the
// UINT32_MAX-sized calloc()/memcmp() under -Werror.
#if SIZE_MAX > UINT32_MAX
TEST(MSGPACKC, simple_buffer_ext_maxlen)
{
// Needs roughly 8GB of free memory (the source buffer plus the packed
// copy). If the allocation fails, pass vacuously instead of failing.
// (GTEST_SKIP() is not used because it requires googletest >= 1.10.)
const size_t size = static_cast<size_t>(UINT32_MAX);
void* buf = calloc(size, 1);
if (buf == NULL) {
return;
}

msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);

msgpack_pack_ext(&pk, size, 82);
msgpack_pack_ext_body(&pk, buf, size);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_EXT, obj.type);
EXPECT_EQ(82, obj.via.ext.type);
ASSERT_EQ(size, obj.via.ext.size);
EXPECT_EQ(0, memcmp(buf, obj.via.ext.ptr, size));
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
free(buf);
}
#endif // SIZE_MAX > UINT32_MAX

TEST(MSGPACKC, simple_buffer_timestamp_32)
{
msgpack_timestamp ts = {
Expand Down
Loading