Diff between 2e49852cceb9fa6e1f72f01f488184635a940564 and 714abdfc725dfb94e049e25674437541b9770c98

Changed Files

File Additions Deletions Status
gobex/gobex-header.c +9 -5 modified
gobex/gobex-header.h +2 -2 modified
gobex/gobex-packet.c +8 -1 modified
unit/test-gobex-header.c +24 -1 modified
unit/test-gobex-packet.c +29 -1 modified
unit/test-gobex.c +28 -8 modified

Full Patch

diff --git a/gobex/gobex-header.c b/gobex/gobex-header.c
index 6d0136c..3446bb9 100644
--- a/gobex/gobex-header.c
+++ b/gobex/gobex-header.c
@@ -83,13 +83,17 @@ static const guint8 *get_bytes(void *to, const guint8 *from, gsize count)
 	return (from + count);
 }
 
-static gsize get_data(GObexHeader *header, guint8 *buf, gsize len)
+static gssize get_data(GObexHeader *header, guint8 *buf, gsize len)
 {
 	guint16 u16;
+	gssize ret;
 
-	header->vlen = header->get_data(header, buf + 2, len - 2,
+	ret = header->get_data(header, buf + 2, len - 2,
 						header->get_data_data);
+	if (ret < 0)
+		return ret;
 
+	header->vlen = ret;
 	header->hlen = header->vlen + 3;
 	u16 = g_htons(header->hlen);
 	memcpy(buf, &u16, sizeof(u16));
@@ -97,7 +101,7 @@ static gsize get_data(GObexHeader *header, guint8 *buf, gsize len)
 	return header->hlen;
 }
 
-gsize g_obex_header_encode(GObexHeader *header, void *buf, gsize buf_len)
+gssize g_obex_header_encode(GObexHeader *header, void *buf, gsize buf_len)
 {
 	guint8 *ptr = buf;
 	guint16 u16;
@@ -106,7 +110,7 @@ gsize g_obex_header_encode(GObexHeader *header, void *buf, gsize buf_len)
 	glong utf16_len;
 
 	if (buf_len < header->hlen)
-		return 0;
+		return -1;
 
 	ptr = put_bytes(ptr, &header->id, sizeof(header->id));
 
@@ -114,7 +118,7 @@ gsize g_obex_header_encode(GObexHeader *header, void *buf, gsize buf_len)
 	case G_OBEX_HDR_TYPE_UNICODE:
 		utf16_len = utf8_to_utf16(&utf16, header->v.string);
 		if (utf16_len < 0 || (guint16) utf16_len > buf_len)
-			return 0;
+			return -1;
 		g_assert_cmpuint(utf16_len + 3, ==, header->hlen);
 		u16 = g_htons(utf16_len + 3);
 		ptr = put_bytes(ptr, &u16, sizeof(u16));
diff --git a/gobex/gobex-header.h b/gobex/gobex-header.h
index 7ea3193..b25051f 100644
--- a/gobex/gobex-header.h
+++ b/gobex/gobex-header.h
@@ -55,7 +55,7 @@
 
 typedef struct _GObexHeader GObexHeader;
 
-typedef guint16 (*GObexHeaderDataFunc) (GObexHeader *header, void *buf,
+typedef gssize (*GObexHeaderDataFunc) (GObexHeader *header, void *buf,
 						gsize len, gpointer user_data);
 
 gboolean g_obex_header_get_unicode(GObexHeader *header, const char **str);
@@ -76,7 +76,7 @@ GObexHeader *g_obex_header_new_uint32(guint8 id, guint32 val);
 guint8 g_obex_header_get_id(GObexHeader *header);
 guint16 g_obex_header_get_length(GObexHeader *header);
 
-gsize g_obex_header_encode(GObexHeader *header, void *hdr_ptr, gsize buf_len);
+gssize g_obex_header_encode(GObexHeader *header, void *buf, gsize buf_len);
 GObexHeader *g_obex_header_decode(const void *data, gsize len,
 				GObexDataPolicy data_policy, gsize *parsed,
 				GError **err);
diff --git a/gobex/gobex-packet.c b/gobex/gobex-packet.c
index 29a6aa2..16d4b7a 100644
--- a/gobex/gobex-packet.c
+++ b/gobex/gobex-packet.c
@@ -281,9 +281,16 @@ gssize g_obex_packet_encode(GObexPacket *pkt, guint8 *buf, gsize len)
 
 	for (l = pkt->headers; l != NULL; l = g_slist_next(l)) {
 		GObexHeader *hdr = l->data;
+		gssize ret;
+
 		if (count >= len)
 			return -ENOBUFS;
-		count += g_obex_header_encode(hdr, buf + count, len - count);
+
+		ret = g_obex_header_encode(hdr, buf + count, len - count);
+		if (ret < 0)
+			return ret;
+
+		count += ret;
 	}
 
 	u16 = g_htons(count);
diff --git a/unit/test-gobex-header.c b/unit/test-gobex-header.c
index 61536e2..bf69abb 100644
--- a/unit/test-gobex-header.c
+++ b/unit/test-gobex-header.c
@@ -130,7 +130,7 @@ static void test_header_uint32(void)
 	g_obex_header_free(header);
 }
 
-static guint16 get_body_data(GObexHeader *header, void *buf, gsize len,
+static gssize get_body_data(GObexHeader *header, void *buf, gsize len,
 							gpointer user_data)
 {
 	uint8_t body_data[] = { 1, 2, 3, 4 };
@@ -156,6 +156,27 @@ static void test_header_on_demand(void)
 	g_obex_header_free(header);
 }
 
+static gssize get_body_data_fail(GObexHeader *header, void *buf, gsize len,
+							gpointer user_data)
+{
+	return -1;
+}
+
+static void test_header_on_demand_fail(void)
+{
+	GObexHeader *header;
+	uint8_t buf[1024];
+	gssize len;
+
+	header = g_obex_header_new_on_demand(G_OBEX_HDR_ID_BODY,
+						get_body_data_fail, NULL);
+
+	len = g_obex_header_encode(header, buf, sizeof(buf));
+	g_assert_cmpint(len, ==, -1);
+
+	g_obex_header_free(header);
+}
+
 static GObexHeader *parse_and_encode(uint8_t *buf, size_t buf_len)
 {
 	GObexHeader *header;
@@ -485,6 +506,8 @@ int main(int argc, char *argv[])
 	g_test_add_func("/gobex/test_header_uint32", test_header_uint32);
 
 	g_test_add_func("/gobex/test_header_on_demand", test_header_on_demand);
+	g_test_add_func("/gobex/test_header_on_demand_fail",
+						test_header_on_demand_fail);
 
 	g_test_run();
 
diff --git a/unit/test-gobex-packet.c b/unit/test-gobex-packet.c
index 501d924..33be55d 100644
--- a/unit/test-gobex-packet.c
+++ b/unit/test-gobex-packet.c
@@ -144,7 +144,7 @@ static void test_decode_encode(void)
 	g_obex_packet_free(pkt);
 }
 
-static guint16 get_body_data(GObexHeader *header, void *buf, gsize len,
+static gssize get_body_data(GObexHeader *header, void *buf, gsize len,
 							gpointer user_data)
 {
 	uint8_t data[] = { 1, 2, 3, 4 };
@@ -178,6 +178,32 @@ static void test_encode_on_demand(void)
 	g_obex_packet_free(pkt);
 }
 
+static gssize get_body_data_fail(GObexHeader *header, void *buf, gsize len,
+							gpointer user_data)
+{
+	return -1;
+}
+
+static void test_encode_on_demand_fail(void)
+{
+	GObexPacket *pkt;
+	GObexHeader *hdr;
+	uint8_t buf[255];
+	gssize len;
+
+	pkt = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, NULL);
+
+	hdr = g_obex_header_new_on_demand(G_OBEX_HDR_ID_BODY,
+						get_body_data_fail, NULL);
+	g_obex_packet_add_header(pkt, hdr);
+
+	len = g_obex_packet_encode(pkt, buf, sizeof(buf));
+
+	g_assert_cmpint(len, ==, -1);
+
+	g_obex_packet_free(pkt);
+}
+
 int main(int argc, char *argv[])
 {
 	g_test_init(&argc, &argv, NULL);
@@ -194,6 +220,8 @@ int main(int argc, char *argv[])
 	g_test_add_func("/gobex/test_encode_pkt", test_decode_encode);
 
 	g_test_add_func("/gobex/test_encode_on_demand", test_encode_on_demand);
+	g_test_add_func("/gobex/test_encode_on_demand_fail",
+						test_encode_on_demand_fail);
 
 	g_test_run();
 
diff --git a/unit/test-gobex.c b/unit/test-gobex.c
index 5d65dde..1fb74b5 100644
--- a/unit/test-gobex.c
+++ b/unit/test-gobex.c
@@ -528,7 +528,7 @@ static void test_send_connect(int transport_type)
 
 	create_endpoints(&obex, &io, transport_type);
 
-	r.err = NULL;
+	memset(&r, 0, sizeof(r));
 	r.buf = pkt_connect_req;
 	r.len = sizeof(pkt_connect_req);
 
@@ -570,7 +570,7 @@ static void test_send_connect_pkt(void)
 	test_send_connect(SOCK_SEQPACKET);
 }
 
-static guint16 get_body_data(GObexHeader *header, void *buf, gsize len,
+static gssize get_body_data(GObexHeader *header, void *buf, gsize len,
 							gpointer user_data)
 {
 	uint8_t data[] = { 1, 2, 3, 4 };
@@ -580,7 +580,14 @@ static guint16 get_body_data(GObexHeader *header, void *buf, gsize len,
 	return sizeof(data);
 }
 
-static void test_send_on_demand(int transport_type)
+static gssize get_body_data_fail(GObexHeader *header, void *buf, gsize len,
+							gpointer user_data)
+{
+	g_main_loop_quit(mainloop);
+	return -1;
+}
+
+static void test_send_on_demand(int transport_type, GObexHeaderDataFunc func)
 {
 	struct rcv_buf_info r;
 	GIOChannel *io;
@@ -592,14 +599,13 @@ static void test_send_on_demand(int transport_type)
 
 	create_endpoints(&obex, &io, transport_type);
 
-	r.err = NULL;
+	memset(&r, 0, sizeof(r));
 	r.buf = pkt_put_body;
 	r.len = sizeof(pkt_put_body);
 
 	req = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, NULL);
 
-	hdr = g_obex_header_new_on_demand(G_OBEX_HDR_ID_BODY,
-						get_body_data, NULL);
+	hdr = g_obex_header_new_on_demand(G_OBEX_HDR_ID_BODY, func, &r);
 	g_obex_packet_add_header(req, hdr);
 
 	g_obex_send(obex, req, &r.err);
@@ -627,12 +633,22 @@ static void test_send_on_demand(int transport_type)
 
 static void test_send_on_demand_stream(void)
 {
-	test_send_on_demand(SOCK_STREAM);
+	test_send_on_demand(SOCK_STREAM, get_body_data);
 }
 
 static void test_send_on_demand_pkt(void)
 {
-	test_send_on_demand(SOCK_SEQPACKET);
+	test_send_on_demand(SOCK_SEQPACKET, get_body_data);
+}
+
+static void test_send_on_demand_fail_stream(void)
+{
+	test_send_on_demand(SOCK_STREAM, get_body_data_fail);
+}
+
+static void test_send_on_demand_fail_pkt(void)
+{
+	test_send_on_demand(SOCK_SEQPACKET, get_body_data_fail);
 }
 
 static void handle_connect_req(GObex *obex, GObexPacket *req,
@@ -802,6 +818,10 @@ int main(int argc, char *argv[])
 						test_send_on_demand_stream);
 	g_test_add_func("/gobex/test_send_on_demand_pkt",
 						test_send_on_demand_pkt);
+	g_test_add_func("/gobex/test_send_on_demand_fail_stream",
+					test_send_on_demand_fail_stream);
+	g_test_add_func("/gobex/test_send_on_demand_fail_pkt",
+					test_send_on_demand_fail_pkt);
 	g_test_add_func("/gobex/test_send_connect_req_stream",
 					test_send_connect_req_stream);
 	g_test_add_func("/gobex/test_send_connect_req_pkt",