--- a/libpurple/protocols/msn/p2p.c Thu May 05 07:21:14 2011 +0000
+++ b/libpurple/protocols/msn/p2p.c Thu May 05 21:49:21 2011 +0000
@@ -204,41 +204,43 @@
case MSN_P2P_VERSION_TWO: {
MsnP2Pv2Header *header = &info->header.v2;
+ char *header_wire = NULL; + char *data_header_wire = NULL; if (header->header_tlv != NULL)
- header->header_len = msn_tlvlist_size(header->header_tlv) + 8;
+ header_wire = msn_tlvlist_write(header->header_tlv, (size_t *)&header->header_len); - header->header_len = 8;
+ header->header_len = 0; if (header->data_tlv != NULL)
- header->data_header_len = msn_tlvlist_size(header->data_tlv) + 8;
+ data_header_wire = msn_tlvlist_write(header->data_tlv, (size_t *)&header->data_header_len); - header->data_header_len = 8;
+ header->data_header_len = 0; - tmp = wire = g_new(char, header->header_len + header->data_header_len);
+ tmp = wire = g_new(char, 16 + header->header_len + header->data_header_len); - msn_push8(tmp, header->header_len);
+ msn_push8(tmp, header->header_len + 8); msn_push8(tmp, header->opcode);
- msn_push16be(tmp, header->data_header_len + header->message_len);
+ msn_push16be(tmp, header->data_header_len + 8 + header->message_len); msn_push32be(tmp, header->base_id);
- if (header->header_tlv != NULL) {
- msn_tlvlist_write(tmp, header->header_len - 8, header->header_tlv);
- tmp += header->header_len - 8;
+ if (header_wire != NULL) { + memcpy(tmp, header_wire, header->header_len); + tmp += header->header_len; - msn_push8(tmp, header->data_header_len);
+ msn_push8(tmp, header->data_header_len + 8); msn_push8(tmp, header->data_tf);
msn_push16be(tmp, header->package_number);
msn_push32be(tmp, header->session_id);
- if (header->data_tlv != NULL) {
- msn_tlvlist_write(tmp, header->data_header_len - 8, header->data_tlv);
- tmp += header->data_header_len - 8;
+ if (data_header_wire != NULL) { + memcpy(tmp, data_header_wire, header->data_header_len); + tmp += header->data_header_len; - *len = header->header_len + header->data_header_len;
+ *len = header->header_len + header->data_header_len + 16; @@ -248,7 +250,6 @@
--- a/libpurple/protocols/msn/tlv.c Thu May 05 07:21:14 2011 +0000
+++ b/libpurple/protocols/msn/tlv.c Thu May 05 21:49:21 2011 +0000
@@ -45,51 +45,50 @@
-msn_tlv_read(GSList *list, const char *bs, size_t *bs_len)
- length = msn_read8(bs);
- if (length > *bs_len) {
- msn_tlvlist_free(list);
- tlv = createtlv(type, length, NULL);
- tlv->value = g_memdup(bs, length);
- msn_tlvlist_free(list);
- return g_slist_prepend(list, tlv);
msn_tlvlist_read(const char *bs, size_t bs_len)
- list = msn_tlv_read(list, bs, &bs_len);
+ msn_tlvlist_free(list); + msn_tlvlist_free(list); + tlv = createtlv(type, length, NULL); + tlv->value = g_memdup(bs, length); + msn_tlvlist_free(list); + list = g_slist_prepend(list, tlv); return g_slist_reverse(list);
-GSList *msn_tlvlist_copy(GSList *orig)
+msn_tlvlist_copy(GSList *orig) @@ -302,31 +301,38 @@
-msn_tlvlist_write(char *bs, size_t bs_len, GSList *list)
+msn_tlvlist_write(GSList *list, size_t *out_len)
- /* do an initial run to test total length */
- goodbuflen = msn_tlvlist_size(*list);
+ tmp = buf = g_malloc(256); + bytes_left = total_len = 256; + for (; list; list = g_slist_next(list)) { + msn_tlv_t *tlv = (msn_tlv_t *)list->data; - if (goodbuflen > byte_stream_bytes_left(bs))
- return 0; /* not enough buffer */
+ if (G_UNLIKELY(tlv->length + 2 > bytes_left)) { + buf = g_realloc(buf, total_len + 256); + tmp = buf + (total_len - bytes_left); - /* do the real write-out */
- for (cur = *list; cur; cur = cur->next) {
- byte_stream_put16(bs, tlv->type);
- byte_stream_put16(bs, tlv->length);
- byte_stream_putraw(bs, tlv->value, tlv->length);
+ msn_push8(tmp, tlv->type); + msn_push8(tmp, tlv->length); + memcpy(tmp, tlv->value, tlv->length); + bytes_left -= (tlv->length + 2);
- return 0; /* TODO: This is a nonsensical return */
+ *out_len = total_len - bytes_left; --- a/libpurple/protocols/msn/tlv.h Thu May 05 07:21:14 2011 +0000
+++ b/libpurple/protocols/msn/tlv.h Thu May 05 21:49:21 2011 +0000
@@ -52,7 +52,7 @@
int msn_tlvlist_count(GSList *list);
size_t msn_tlvlist_size(GSList *list);
gboolean msn_tlvlist_equal(GSList *one, GSList *two);
-int msn_tlvlist_write(char *bs, size_t bs_len, GSList *list);
+char *msn_tlvlist_write(GSList *list, size_t *out_len); void msn_tlvlist_free(GSList *list);
int msn_tlvlist_add_raw(GSList **list, const guint16 type, const guint16 length, const char *value);