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));
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;
glong utf16_len;
if (buf_len < header->hlen)
- return 0;
+ return -1;
ptr = put_bytes(ptr, &header->id, sizeof(header->id));
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));
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);
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);
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);
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 };
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;
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();
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 };
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);
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();
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);
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 };
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;
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);
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,
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",