THRIFT-3968: Deserializing empty string/binary fields
Client: C (GLib)
Patch: Simon South <simonsouth@apache.org>
Deserialize empty strings as they are instead of returning NULL.
Expand test cases to clarify existing behavior when deserializing empty
binary fields.
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c
index 48a2c5c..7c2d017 100644
--- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c
@@ -784,11 +784,18 @@
}
xfer += ret;
- if (read_len > 0)
- {
- /* allocate the memory for the string */
- len = (guint32) read_len + 1; /* space for null terminator */
- *str = g_new0 (gchar, len);
+ if (read_len < 0) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
+ "got negative size of %d", read_len);
+ *str = NULL;
+ return -1;
+ }
+
+ /* allocate the memory for the string */
+ len = (guint32) read_len + 1; /* space for null terminator */
+ *str = g_new0 (gchar, len);
+ if (read_len > 0) {
if ((ret =
thrift_transport_read_all (protocol->transport,
*str, read_len, error)) < 0)
@@ -800,7 +807,7 @@
}
xfer += ret;
} else {
- *str = NULL;
+ **str = 0;
}
return xfer;
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c
index 87b6b30..a0dd3cc 100644
--- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c
@@ -1388,9 +1388,17 @@
return -1;
}
+ if (read_len < 0) {
+ g_set_error (error, THRIFT_PROTOCOL_ERROR,
+ THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
+ "got negative size of %d", read_len);
+ *str = NULL;
+ return -1;
+ }
+
+ /* allocate the memory as an array of unsigned char for binary data */
+ *str = g_new0 (gchar, read_len + 1);
if (read_len > 0) {
- /* allocate the memory as an array of unsigned char for binary data */
- *str = g_new0 (gchar, read_len + 1);
if ((ret =
thrift_transport_read_all (protocol->transport,
*str, read_len, error)) < 0) {
@@ -1399,16 +1407,8 @@
return -1;
}
xfer += ret;
-
- } else if (read_len == 0) {
- *str = NULL;
-
} else {
- g_set_error (error, THRIFT_PROTOCOL_ERROR,
- THRIFT_PROTOCOL_ERROR_NEGATIVE_SIZE,
- "got negative size of %d", read_len);
- *str = NULL;
- return -1;
+ **str = 0;
}
return xfer;
diff --git a/lib/c_glib/test/testbinaryprotocol.c b/lib/c_glib/test/testbinaryprotocol.c
index 7ca5150..58f4df8 100755
--- a/lib/c_glib/test/testbinaryprotocol.c
+++ b/lib/c_glib/test/testbinaryprotocol.c
@@ -173,6 +173,7 @@
TEST_DOUBLE, NULL) > 0);
assert (thrift_binary_protocol_write_string (protocol,
TEST_STRING, NULL) > 0);
+ assert (thrift_binary_protocol_write_string (protocol, "", NULL) > 0);
assert (thrift_binary_protocol_write_binary (protocol, binary,
len, NULL) > 0);
assert (thrift_binary_protocol_write_binary (protocol, NULL, 0, NULL) > 0);
@@ -456,6 +457,8 @@
assert (thrift_binary_protocol_write_string (protocol,
TEST_STRING, NULL) > 0);
thrift_transport_flush (transport, NULL);
+ assert (thrift_binary_protocol_write_string (protocol, "", NULL) > 0);
+ thrift_transport_flush (transport, NULL);
assert (thrift_binary_protocol_write_binary (protocol, binary,
len, NULL) > 0);
thrift_transport_flush (transport, NULL);
@@ -491,6 +494,7 @@
gint64 value_64 = 0;
gdouble value_double = 0;
gchar *string = NULL;
+ gchar *empty_string = NULL;
gpointer binary = NULL;
guint32 len = 0;
void *comparator = (void *) TEST_STRING;
@@ -515,6 +519,8 @@
assert (thrift_binary_protocol_read_double (protocol,
&value_double, NULL) > 0);
assert (thrift_binary_protocol_read_string (protocol, &string, NULL) > 0);
+ assert (thrift_binary_protocol_read_string (protocol, &empty_string,
+ NULL) > 0);
assert (thrift_binary_protocol_read_binary (protocol, &binary,
&len, NULL) > 0);
@@ -525,12 +531,17 @@
assert (value_64 == TEST_I64);
assert (value_double == TEST_DOUBLE);
assert (strcmp (TEST_STRING, string) == 0);
+ assert (strcmp ("", empty_string) == 0);
assert (memcmp (comparator, binary, len) == 0);
g_free (string);
+ g_free (empty_string);
g_free (binary);
- thrift_binary_protocol_read_binary (protocol, &binary, &len, NULL);
+ assert (thrift_binary_protocol_read_binary (protocol, &binary,
+ &len, NULL) > 0);
+ assert (binary == NULL);
+ assert (len == 0);
g_free (binary);
transport_read_count = 0;
@@ -768,6 +779,7 @@
gint64 value_64 = 0;
gdouble value_double = 0;
gchar *string = NULL;
+ gchar *empty_string = NULL;
gpointer binary = NULL;
guint32 len = 0;
void *comparator = (void *) TEST_STRING;
@@ -795,6 +807,8 @@
assert (thrift_binary_protocol_read_double (protocol,
&value_double, NULL) > 0);
assert (thrift_binary_protocol_read_string (protocol, &string, NULL) > 0);
+ assert (thrift_binary_protocol_read_string (protocol, &empty_string,
+ NULL) > 0);
assert (thrift_binary_protocol_read_binary (protocol, &binary,
&len, NULL) > 0);
@@ -805,9 +819,17 @@
assert (value_64 == TEST_I64);
assert (value_double == TEST_DOUBLE);
assert (strcmp (TEST_STRING, string) == 0);
+ assert (strcmp ("", empty_string) == 0);
assert (memcmp (comparator, binary, len) == 0);
g_free (string);
+ g_free (empty_string);
+ g_free (binary);
+
+ assert (thrift_binary_protocol_read_binary (protocol, &binary,
+ &len, NULL) > 0);
+ assert (binary == NULL);
+ assert (len == 0);
g_free (binary);
thrift_transport_read_end (client, NULL);
diff --git a/lib/c_glib/test/testcompactprotocol.c b/lib/c_glib/test/testcompactprotocol.c
index 9b57a8c..03bc226 100755
--- a/lib/c_glib/test/testcompactprotocol.c
+++ b/lib/c_glib/test/testcompactprotocol.c
@@ -189,6 +189,7 @@
TEST_DOUBLE, NULL) > 0);
assert (thrift_compact_protocol_write_string (protocol,
TEST_STRING, NULL) > 0);
+ assert (thrift_compact_protocol_write_string (protocol, "", NULL) > 0);
assert (thrift_compact_protocol_write_binary (protocol, binary,
len, NULL) > 0);
assert (thrift_compact_protocol_write_binary (protocol, NULL, 0, NULL) > 0);
@@ -636,6 +637,8 @@
assert (thrift_compact_protocol_write_string (protocol,
TEST_STRING, NULL) > 0);
thrift_transport_flush (transport, NULL);
+ assert (thrift_compact_protocol_write_string (protocol, "", NULL) > 0);
+ thrift_transport_flush (transport, NULL);
assert (thrift_compact_protocol_write_binary (protocol, binary,
len, NULL) > 0);
thrift_transport_flush (transport, NULL);
@@ -677,6 +680,7 @@
gint64 value_n64 = 0;
gdouble value_double = 0;
gchar *string = NULL;
+ gchar *empty_string = NULL;
gpointer binary = NULL;
guint32 len = 0;
void *comparator = (void *) TEST_STRING;
@@ -710,6 +714,8 @@
assert (thrift_compact_protocol_read_double (protocol,
&value_double, NULL) > 0);
assert (thrift_compact_protocol_read_string (protocol, &string, NULL) > 0);
+ assert (thrift_compact_protocol_read_string (protocol, &empty_string,
+ NULL) > 0);
assert (thrift_compact_protocol_read_binary (protocol, &binary,
&len, NULL) > 0);
@@ -729,12 +735,17 @@
assert (zigzag_n64 == 3);
assert (value_double == TEST_DOUBLE);
assert (strcmp (TEST_STRING, string) == 0);
+ assert (strcmp ("", empty_string) == 0);
assert (memcmp (comparator, binary, len) == 0);
g_free (string);
+ g_free (empty_string);
g_free (binary);
- thrift_compact_protocol_read_binary (protocol, &binary, &len, NULL);
+ assert (thrift_compact_protocol_read_binary (protocol, &binary,
+ &len, NULL) > 0);
+ assert (binary == NULL);
+ assert (len == 0);
g_free (binary);
transport_read_count = 0;
@@ -1181,6 +1192,7 @@
gint64 value_n64 = 0;
gdouble value_double = 0;
gchar *string = NULL;
+ gchar *empty_string = NULL;
gpointer binary = NULL;
guint32 len = 0;
void *comparator = (void *) TEST_STRING;
@@ -1217,6 +1229,8 @@
assert (thrift_compact_protocol_read_double (protocol,
&value_double, NULL) > 0);
assert (thrift_compact_protocol_read_string (protocol, &string, NULL) > 0);
+ assert (thrift_compact_protocol_read_string (protocol, &empty_string,
+ NULL) > 0);
assert (thrift_compact_protocol_read_binary (protocol, &binary,
&len, NULL) > 0);
@@ -1236,9 +1250,17 @@
assert (zigzag_n64 == 3);
assert (value_double == TEST_DOUBLE);
assert (strcmp (TEST_STRING, string) == 0);
+ assert (strcmp ("", empty_string) == 0);
assert (memcmp (comparator, binary, len) == 0);
g_free (string);
+ g_free (empty_string);
+ g_free (binary);
+
+ assert (thrift_compact_protocol_read_binary (protocol, &binary,
+ &len, NULL) > 0);
+ assert (binary == NULL);
+ assert (len == 0);
g_free (binary);
thrift_transport_read_end (client, NULL);