Skip to content

Commit 1c97e05

Browse files
committed
Fixes #941
Don't abort serialization when running into empty strings in msgpack_object_print_buffer(). Added a couple of unit tests to test empty string cases.
1 parent 4f59b98 commit 1c97e05

File tree

2 files changed

+191
-1
lines changed

2 files changed

+191
-1
lines changed

src/objectc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,9 @@ int msgpack_object_print_buffer(char *buffer, size_t buffer_size, msgpack_object
331331

332332
case MSGPACK_OBJECT_STR:
333333
MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
334-
MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%.*s", (int)o.via.str.size, o.via.str.ptr);
334+
if (o.via.str.size > 0) {
335+
MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "%.*s", (int)o.via.str.size, o.via.str.ptr);
336+
}
335337
MSGPACK_CHECKED_CALL(ret, snprintf, aux_buffer, aux_buffer_size, "\"");
336338
break;
337339

test/msgpack_c.cpp

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,194 @@ TEST(MSGPACKC, simple_buffer_v4raw_32_l)
12031203
msgpack_sbuffer_destroy(&sbuf);
12041204
}
12051205

1206+
TEST(MSGPACKC, simple_object_print_buffer_str_empty)
1207+
{
1208+
unsigned int str_size = 0;
1209+
char buffer[64];
1210+
1211+
msgpack_sbuffer sbuf;
1212+
msgpack_sbuffer_init(&sbuf);
1213+
msgpack_packer pk;
1214+
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
1215+
msgpack_pack_str(&pk, str_size);
1216+
msgpack_pack_str_body(&pk, "", str_size);
1217+
1218+
msgpack_zone z;
1219+
msgpack_zone_init(&z, 2048);
1220+
msgpack_object obj;
1221+
msgpack_unpack_return ret;
1222+
ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
1223+
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
1224+
EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type);
1225+
EXPECT_EQ(str_size, obj.via.str.size);
1226+
1227+
msgpack_object_print_buffer(buffer, sizeof(buffer) - 1, obj);
1228+
EXPECT_STREQ("\"\"", buffer);
1229+
1230+
msgpack_zone_destroy(&z);
1231+
msgpack_sbuffer_destroy(&sbuf);
1232+
}
1233+
1234+
TEST(MSGPACKC, simple_object_print_buffer_array_str)
1235+
{
1236+
const char * str = "hello";
1237+
const size_t str_size = strlen(str);
1238+
const unsigned int array_size = 1;
1239+
char expected[64];
1240+
char buffer[64];
1241+
1242+
msgpack_sbuffer sbuf;
1243+
msgpack_sbuffer_init(&sbuf);
1244+
msgpack_packer pk;
1245+
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
1246+
msgpack_pack_array(&pk, array_size);
1247+
msgpack_pack_str(&pk, str_size);
1248+
msgpack_pack_str_body(&pk, str, str_size);
1249+
1250+
msgpack_zone z;
1251+
msgpack_zone_init(&z, 2048);
1252+
msgpack_object obj;
1253+
msgpack_unpack_return ret;
1254+
ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
1255+
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
1256+
EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type);
1257+
EXPECT_EQ(array_size, obj.via.array.size);
1258+
1259+
msgpack_object o = *obj.via.array.ptr;
1260+
EXPECT_EQ(MSGPACK_OBJECT_STR, o.type);
1261+
EXPECT_EQ(str_size, o.via.str.size);
1262+
EXPECT_EQ(0, memcmp(str, o.via.str.ptr, str_size));
1263+
1264+
sprintf(expected, "[\"%s\"]", str);
1265+
msgpack_object_print_buffer(buffer, sizeof(buffer) - 1, obj);
1266+
EXPECT_STREQ(expected, buffer);
1267+
1268+
msgpack_zone_destroy(&z);
1269+
msgpack_sbuffer_destroy(&sbuf);
1270+
}
1271+
1272+
TEST(MSGPACKC, simple_object_print_buffer_array_str_empty)
1273+
{
1274+
const unsigned int array_size = 1;
1275+
const unsigned int str_size = 0;
1276+
char buffer[64];
1277+
1278+
msgpack_sbuffer sbuf;
1279+
msgpack_sbuffer_init(&sbuf);
1280+
msgpack_packer pk;
1281+
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
1282+
msgpack_pack_array(&pk, array_size);
1283+
msgpack_pack_str(&pk, str_size);
1284+
msgpack_pack_str_body(&pk, "", 0);
1285+
1286+
msgpack_zone z;
1287+
msgpack_zone_init(&z, 2048);
1288+
msgpack_object obj;
1289+
msgpack_unpack_return ret;
1290+
ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
1291+
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
1292+
EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type);
1293+
EXPECT_EQ(array_size, obj.via.array.size);
1294+
1295+
msgpack_object o = *obj.via.array.ptr;
1296+
EXPECT_EQ(MSGPACK_OBJECT_STR, o.type);
1297+
EXPECT_EQ(str_size, o.via.str.size);
1298+
1299+
msgpack_object_print_buffer(buffer, sizeof(buffer) - 1, obj);
1300+
EXPECT_STREQ("[\"\"]", buffer);
1301+
1302+
msgpack_zone_destroy(&z);
1303+
msgpack_sbuffer_destroy(&sbuf);
1304+
}
1305+
1306+
TEST(MSGPACKC, simple_object_print_buffer_map_str)
1307+
{
1308+
const char * mkey = "key";
1309+
const char * mval = "value";
1310+
char expected[64];
1311+
char buffer[64];
1312+
const size_t mkey_size = strlen(mkey);;
1313+
const size_t mval_size = strlen(mval);
1314+
const unsigned int map_size = 1;
1315+
1316+
msgpack_sbuffer sbuf;
1317+
msgpack_sbuffer_init(&sbuf);
1318+
msgpack_packer pk;
1319+
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
1320+
msgpack_pack_map(&pk, map_size);
1321+
msgpack_pack_str(&pk, mkey_size);
1322+
msgpack_pack_str_body(&pk, mkey, mkey_size);
1323+
msgpack_pack_str(&pk, mval_size);
1324+
msgpack_pack_str_body(&pk, mval, mval_size);
1325+
1326+
msgpack_zone z;
1327+
msgpack_zone_init(&z, 2048);
1328+
msgpack_object obj;
1329+
msgpack_unpack_return ret;
1330+
ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
1331+
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
1332+
EXPECT_EQ(MSGPACK_OBJECT_MAP, obj.type);
1333+
EXPECT_EQ(map_size, obj.via.map.size);
1334+
1335+
msgpack_object key = obj.via.map.ptr->key;
1336+
msgpack_object val = obj.via.map.ptr->val;
1337+
EXPECT_EQ(MSGPACK_OBJECT_STR, key.type);
1338+
EXPECT_EQ(mkey_size, key.via.str.size);
1339+
EXPECT_EQ(0, memcmp(mkey, key.via.str.ptr, mkey_size));
1340+
EXPECT_EQ(MSGPACK_OBJECT_STR, val.type);
1341+
EXPECT_EQ(mval_size, val.via.str.size);
1342+
EXPECT_EQ(0, memcmp(mval, val.via.str.ptr, mval_size));
1343+
1344+
sprintf(expected, "{\"%s\"=>\"%s\"}", mkey, mval);
1345+
msgpack_object_print_buffer(buffer, sizeof(buffer) - 1, obj);
1346+
EXPECT_STREQ(expected, buffer);
1347+
1348+
msgpack_zone_destroy(&z);
1349+
msgpack_sbuffer_destroy(&sbuf);
1350+
}
1351+
1352+
TEST(MSGPACKC, simple_object_print_buffer_map_str_empty)
1353+
{
1354+
const char * mkey = "key";
1355+
char expected[64];
1356+
char buffer[64];
1357+
const size_t mkey_size = strlen(mkey);;
1358+
const unsigned int map_size = 1;
1359+
1360+
msgpack_sbuffer sbuf;
1361+
msgpack_sbuffer_init(&sbuf);
1362+
msgpack_packer pk;
1363+
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
1364+
msgpack_pack_map(&pk, map_size);
1365+
msgpack_pack_str(&pk, mkey_size);
1366+
msgpack_pack_str_body(&pk, mkey, mkey_size);
1367+
msgpack_pack_str(&pk, 0);
1368+
msgpack_pack_str_body(&pk, "", 0);
1369+
1370+
msgpack_zone z;
1371+
msgpack_zone_init(&z, 2048);
1372+
msgpack_object obj;
1373+
msgpack_unpack_return ret;
1374+
ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
1375+
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
1376+
EXPECT_EQ(MSGPACK_OBJECT_MAP, obj.type);
1377+
EXPECT_EQ(map_size, obj.via.map.size);
1378+
1379+
msgpack_object key = obj.via.map.ptr->key;
1380+
msgpack_object val = obj.via.map.ptr->val;
1381+
EXPECT_EQ(MSGPACK_OBJECT_STR, key.type);
1382+
EXPECT_EQ(mkey_size, key.via.str.size);
1383+
EXPECT_EQ(0, memcmp(mkey, key.via.str.ptr, mkey_size));
1384+
EXPECT_EQ(MSGPACK_OBJECT_STR, val.type);
1385+
EXPECT_EQ(0UL, val.via.str.size);
1386+
1387+
sprintf(expected, "{\"%s\"=>\"\"}", mkey);
1388+
msgpack_object_print_buffer(buffer, sizeof(buffer) - 1, obj);
1389+
EXPECT_STREQ(expected, buffer);
1390+
1391+
msgpack_zone_destroy(&z);
1392+
msgpack_sbuffer_destroy(&sbuf);
1393+
}
12061394

12071395
TEST(MSGPACKC, unpack_fixstr)
12081396
{

0 commit comments

Comments
 (0)