pidgin: 1a9df376: This should fix TLV in from and out of t...
qulogic at pidgin.im
qulogic at pidgin.im
Fri May 6 02:36:31 EDT 2011
----------------------------------------------------------------------
Revision: 1a9df376c3e5a53f210cec632c3471d97d588420
Parent: a811db8a9e8edb09216f22dfae23e330fbac64a2
Author: qulogic at pidgin.im
Date: 05/05/11 17:49:21
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/1a9df376c3e5a53f210cec632c3471d97d588420
Changelog:
This should fix TLV in from and out of the wire.
Changes against parent a811db8a9e8edb09216f22dfae23e330fbac64a2
patched libpurple/protocols/msn/p2p.c
patched libpurple/protocols/msn/tlv.c
patched libpurple/protocols/msn/tlv.h
-------------- next part --------------
============================================================
--- libpurple/protocols/msn/p2p.c 4191219d7c75b7feca61b944dc83227741be685a
+++ libpurple/protocols/msn/p2p.c 812b1e0a91a7d81abf1d375cf368e337a1b75a69
@@ -204,41 +204,43 @@ msn_p2p_header_to_wire(MsnP2PInfo *info,
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);
else
- 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);
else
- 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;
}
if (len)
- *len = header->header_len + header->data_header_len;
+ *len = header->header_len + header->data_header_len + 16;
break;
}
@@ -248,7 +250,6 @@ msn_p2p_header_to_wire(MsnP2PInfo *info,
}
return wire;
-
}
size_t
============================================================
--- libpurple/protocols/msn/tlv.c d82a1c8eab5c36339c61ac5a6537e4a9dd298f2e
+++ libpurple/protocols/msn/tlv.c e704d17a9c254d2bf125c3b8dd7bf4d75a196ead
@@ -45,51 +45,50 @@ freetlv(msn_tlv_t *oldtlv)
g_free(oldtlv);
}
-static GSList *
-msn_tlv_read(GSList *list, const char *bs, size_t *bs_len)
+GSList *
+msn_tlvlist_read(const char *bs, size_t bs_len)
{
- guint8 type, length;
- msn_tlv_t *tlv;
+ GSList *list = NULL;
- type = msn_read8(bs);
- length = msn_read8(bs);
- *bs_len -= 2;
+ while (bs_len > 0) {
+ guint8 type, length;
+ msn_tlv_t *tlv;
- if (length > *bs_len) {
- msn_tlvlist_free(list);
- return NULL;
- }
+ if (bs_len < 2) {
+ msn_tlvlist_free(list);
+ return NULL;
+ }
- tlv = createtlv(type, length, NULL);
- if (length > 0) {
- tlv->value = g_memdup(bs, length);
- if (!tlv->value) {
- freetlv(tlv);
+ type = msn_pop8(bs);
+ length = msn_pop8(bs);
+ bs_len -= 2;
+
+ if (length > bs_len) {
msn_tlvlist_free(list);
return NULL;
}
- }
- *bs_len -= length;
+ tlv = createtlv(type, length, NULL);
+ if (length > 0) {
+ tlv->value = g_memdup(bs, length);
+ if (!tlv->value) {
+ freetlv(tlv);
+ msn_tlvlist_free(list);
+ return NULL;
+ }
+ }
- return g_slist_prepend(list, tlv);
-}
+ bs_len -= length;
+ bs += length;
-GSList *
-msn_tlvlist_read(const char *bs, size_t bs_len)
-{
- GSList *list = NULL;
-
- while (bs_len > 0) {
- list = msn_tlv_read(list, bs, &bs_len);
- if (list == NULL)
- return NULL;
+ list = g_slist_prepend(list, tlv);
}
return g_slist_reverse(list);
}
-GSList *msn_tlvlist_copy(GSList *orig)
+GSList *
+msn_tlvlist_copy(GSList *orig)
{
GSList *new = NULL;
msn_tlv_t *tlv;
@@ -302,31 +301,38 @@ msn_tlvlist_remove(GSList **list, const
}
}
-int
-msn_tlvlist_write(char *bs, size_t bs_len, GSList *list)
+char *
+msn_tlvlist_write(GSList *list, size_t *out_len)
{
-#if 0
- int goodbuflen;
- GSList *cur;
- msn_tlv_t *tlv;
+ char *buf;
+ char *tmp;
+ size_t bytes_left;
+ size_t total_len;
- /* do an initial run to test total length */
- goodbuflen = msn_tlvlist_size(*list);
+ tmp = buf = g_malloc(256);
+ bytes_left = total_len = 256;
- if (goodbuflen > byte_stream_bytes_left(bs))
- return 0; /* not enough buffer */
+ for (; list; list = g_slist_next(list)) {
+ msn_tlv_t *tlv = (msn_tlv_t *)list->data;
- /* do the real write-out */
- for (cur = *list; cur; cur = cur->next) {
- tlv = cur->data;
- byte_stream_put16(bs, tlv->type);
- byte_stream_put16(bs, tlv->length);
- if (tlv->length > 0)
- byte_stream_putraw(bs, tlv->value, tlv->length);
+ if (G_UNLIKELY(tlv->length + 2 > bytes_left)) {
+ buf = g_realloc(buf, total_len + 256);
+ bytes_left += 256;
+ total_len += 256;
+ tmp = buf + (total_len - bytes_left);
+ }
+
+ msn_push8(tmp, tlv->type);
+ msn_push8(tmp, tlv->length);
+ memcpy(tmp, tlv->value, tlv->length);
+ tmp += tlv->length;
+
+ bytes_left -= (tlv->length + 2);
}
-#endif
- return 0; /* TODO: This is a nonsensical return */
+ *out_len = total_len - bytes_left;
+
+ return buf;
}
msn_tlv_t *
============================================================
--- libpurple/protocols/msn/tlv.h ae315629b373f87b18d8acc905411279fe736b29
+++ libpurple/protocols/msn/tlv.h 04f95750057199c9288aa7b52e3923c054b8f75b
@@ -52,7 +52,7 @@ gboolean msn_tlvlist_equal(GSList *one,
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);
More information about the Commits
mailing list