Skip to content

Commit 734e47c

Browse files
authored
Merge pull request #942 from vmallet/fix_print_buffer_empty_str
Fix #941: empty strings break msgpack_object_print_buffer() (C)
2 parents 4f59b98 + f06b46d commit 734e47c

File tree

2 files changed

+200
-1
lines changed

2 files changed

+200
-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: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
#define msgpack_rand() drand48()
2222
#endif // _MSC_VER || __MINGW32__
2323

24+
#if defined(_MSC_VER)
25+
#define msgpack_snprintf sprintf_s
26+
#else // _MSC_VER
27+
#define msgpack_snprintf snprintf
28+
#endif // _MSC_VER
29+
2430
using namespace std;
2531

2632
const unsigned int kLoop = 10000;
@@ -1203,6 +1209,197 @@ TEST(MSGPACKC, simple_buffer_v4raw_32_l)
12031209
msgpack_sbuffer_destroy(&sbuf);
12041210
}
12051211

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

12071404
TEST(MSGPACKC, unpack_fixstr)
12081405
{

0 commit comments

Comments
 (0)