pidgin: 737941c5: Move the status note parsing into a sepa...
markdoliner at pidgin.im
markdoliner at pidgin.im
Tue Mar 4 04:45:48 EST 2008
-----------------------------------------------------------------
Revision: 737941c554250344668ddf2ad67d340390521557
Ancestor: 541f6529c3dbec16782707ce37eb8206f95fc92e
Author: markdoliner at pidgin.im
Date: 2008-03-04T09:41:44
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/737941c554250344668ddf2ad67d340390521557
Modified files:
libpurple/protocols/oscar/family_icbm.c
ChangeLog:
Move the status note parsing into a separate function, which I think
is much cleaner. Also fix a crash when dereferencing a null pointer.
Fixes #5023.
-------------- next part --------------
============================================================
--- libpurple/protocols/oscar/family_icbm.c 28f68371090128f88aa0851dd5e57bf91ce5ea09
+++ libpurple/protocols/oscar/family_icbm.c 8fdd7bd0305cdda828beb1281eab65a19d22acf1
@@ -2332,181 +2332,207 @@ int aim_im_denytransfer(OscarData *od, c
return 0;
}
-/*
- * Subtype 0x000b - Receive the response from an ICQ status message
- * request (in which case this contains the ICQ status message) or
- * a file transfer or direct IM request was declined.
- */
-static int clientautoresp(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
+static void parse_status_note_text(OscarData *od, guchar *cookie, char *sn, ByteStream *bs)
{
- int ret = 0;
- aim_rxcallback_t userfunc;
- guint16 channel, reason;
- char *sn;
- guchar *cookie;
- guint8 snlen;
+ struct aim_icq_info *info;
+ struct aim_icq_info *prev_info;
+ char *response;
+ char *encoding;
+ char *stripped_encoding;
+ char *status_note_title;
+ char *status_note_text;
+ char *stripped_status_note_text;
+ char *status_note;
+ guint32 length;
+ guint16 version;
+ guint32 capability;
+ guint8 message_type;
+ guint16 status_code;
+ guint16 text_length;
+ guint32 request_length;
+ guint32 response_length;
+ guint32 encoding_length;
+ PurpleAccount *account;
+ PurpleBuddy *buddy;
+ PurplePresence *presence;
+ PurpleStatus *status;
- cookie = byte_stream_getraw(bs, 8);
- channel = byte_stream_get16(bs);
- snlen = byte_stream_get8(bs);
- sn = byte_stream_getstr(bs, snlen);
- reason = byte_stream_get16(bs);
-
- if (channel == 0x0002)
+ for (prev_info = NULL, info = od->icq_info; info != NULL; prev_info = info, info = info->next)
{
- /* parse status note text */
+ if (memcmp(&info->icbm_cookie, cookie, 8) == 0)
+ {
+ if (prev_info == NULL)
+ od->icq_info = info->next;
+ else
+ prev_info->next = info->next;
- struct aim_icq_info *info = NULL;
- struct aim_icq_info *prev_info = NULL;
- char *response = NULL;
- char *encoding = NULL;
- char *stripped_encoding = NULL;
- char *status_note_text = NULL;
- char *stripped_status_note_text = NULL;
- char *status_note = NULL;
+ break;
+ }
+ }
- /*
- * TODO: Using a while statement here is kind of an ugly hack
- * to be able to use 'break'. We might as well be using
- * 'goto'. Should probably get rid of this.
- */
- while (reason == 0x0003) /* channel-specific */
- {
- guint32 length;
- guint16 version;
- guint32 capability;
- guint8 message_type;
- guint16 status_code;
- guint16 text_length;
- guint32 request_length;
- guint32 response_length;
- guint32 encoding_length;
- PurpleAccount *account;
- PurpleBuddy *buddy;
- PurplePresence *presence;
- PurpleStatus *status;
+ if (info == NULL)
+ return;
- for (info = od->icq_info; info != NULL; info = info->next)
- {
- if (memcmp(&info->icbm_cookie, cookie, 8) == 0)
- {
- if (prev_info == NULL)
- od->icq_info = info->next;
- else
- prev_info->next = info->next;
+ status_note_title = info->status_note_title;
+ g_free(info);
- break;
- }
+ length = byte_stream_getle16(bs);
+ if (length != 27) {
+ purple_debug_misc("oscar", "clientautoresp: incorrect header "
+ "size; expected 27, received %u.\n", length);
+ g_free(status_note_title);
+ return;
+ }
- prev_info = info;
- }
+ version = byte_stream_getle16(bs);
+ if (version != 9) {
+ purple_debug_misc("oscar", "clientautoresp: incorrect version; "
+ "expected 9, received %u.\n", version);
+ g_free(status_note_title);
+ return;
+ }
- if (info == NULL)
- break;
+ capability = aim_locate_getcaps(od, bs, 0x10);
+ if (capability != OSCAR_CAPABILITY_EMPTY) {
+ purple_debug_misc("oscar", "clientautoresp: plugin ID is not null.\n");
+ g_free(status_note_title);
+ return;
+ }
- if ((length = byte_stream_getle16(bs)) != 27)
- {
- purple_debug_misc("oscar", "clientautoresp: incorrect header size; expected 27, received %u.\n", length);
- break;
- }
- if ((version = byte_stream_getle16(bs)) != 9)
- {
- purple_debug_misc("oscar", "clientautoresp: incorrect version; expected 9, received %u.\n", version);
- break;
- }
- capability = aim_locate_getcaps(od, bs, 0x10);
- if (capability != OSCAR_CAPABILITY_EMPTY)
- {
- purple_debug_misc("oscar", "clientautoresp: plugin ID is not null.\n");
- break;
- }
- byte_stream_advance(bs, 2); /* unknown */
- byte_stream_advance(bs, 4); /* client capabilities flags */
- byte_stream_advance(bs, 1); /* unknown */
- byte_stream_advance(bs, 2); /* downcouner? */
+ byte_stream_advance(bs, 2); /* unknown */
+ byte_stream_advance(bs, 4); /* client capabilities flags */
+ byte_stream_advance(bs, 1); /* unknown */
+ byte_stream_advance(bs, 2); /* downcouner? */
- if ((length = byte_stream_getle16(bs)) != 14)
- {
- purple_debug_misc("oscar", "clientautoresp: incorrect header size; expected 14, received %u.\n", length);
- break;
- }
- byte_stream_advance(bs, 2); /* downcounter? */
- byte_stream_advance(bs, 12); /* unknown */
+ length = byte_stream_getle16(bs);
+ if (length != 14) {
+ purple_debug_misc("oscar", "clientautoresp: incorrect header "
+ "size; expected 14, received %u.\n", length);
+ g_free(status_note_title);
+ return;
+ }
- if ((message_type = byte_stream_get8(bs)) != 0x1a)
- {
- purple_debug_misc("oscar", "clientautoresp: incorrect message type; expected 0x1a, received 0x%x.\n", message_type);
- break;
- }
- byte_stream_advance(bs, 1); /* message flags */
- if ((status_code = byte_stream_getle16(bs)) != 0)
- {
- purple_debug_misc("oscar", "clientautoresp: incorrect status code; expected 0, received %u.\n", status_code);
- break;
- }
- byte_stream_advance(bs, 2); /* priority code */
+ byte_stream_advance(bs, 2); /* downcounter? */
+ byte_stream_advance(bs, 12); /* unknown */
- text_length = byte_stream_getle16(bs);
- byte_stream_advance(bs, text_length); /* text */
+ message_type = byte_stream_get8(bs);
+ if (message_type != 0x1a) {
+ purple_debug_misc("oscar", "clientautoresp: incorrect message "
+ "type; expected 0x1a, received 0x%x.\n", message_type);
+ g_free(status_note_title);
+ return;
+ }
- length = byte_stream_getle16(bs);
- byte_stream_advance(bs, 18); /* unknown */
- if (length != 18 + 4 + (request_length = byte_stream_getle32(bs)) + 17)
- {
- purple_debug_misc("oscar", "clientautoresp: incorrect block; expected length is %u, got %u.\n", 18 + 4 + request_length + 17, length);
- break;
- }
- byte_stream_advance(bs, request_length); /* x request */
- byte_stream_advance(bs, 17); /* unknown */
+ byte_stream_advance(bs, 1); /* message flags */
- length = byte_stream_getle32(bs);
- response_length = byte_stream_getle32(bs);
- response = byte_stream_getstr(bs, response_length);
- if (length != 4 + response_length + 4 + (encoding_length = byte_stream_getle32(bs)))
- {
- purple_debug_misc("oscar", "clientautoresp: incorrect block; expected length is %u, got %u.\n", 4 + response_length + 4 + encoding_length, length);
- break;
- }
- encoding = byte_stream_getstr(bs, encoding_length);
+ status_code = byte_stream_getle16(bs);
+ if (status_code != 0) {
+ purple_debug_misc("oscar", "clientautoresp: incorrect status "
+ "code; expected 0, received %u.\n", status_code);
+ g_free(status_note_title);
+ return;
+ }
- account = purple_connection_get_account(od->gc);
- stripped_encoding = oscar_encoding_extract(encoding);
- status_note_text = oscar_encoding_to_utf8(account, stripped_encoding, response, response_length);
- stripped_status_note_text = purple_markup_strip_html(status_note_text);
+ byte_stream_advance(bs, 2); /* priority code */
- if (stripped_status_note_text != NULL && stripped_status_note_text[0] != 0)
- status_note = g_strdup_printf("%s: %s", info->status_note_title, stripped_status_note_text);
- else
- status_note = g_strdup(info->status_note_title);
+ text_length = byte_stream_getle16(bs);
+ byte_stream_advance(bs, text_length); /* text */
- buddy = purple_find_buddy(account, sn);
- if (buddy == NULL)
- {
- purple_debug_misc("oscar", "clientautoresp: buddy %s was not found.\n", sn);
- break;
- }
+ length = byte_stream_getle16(bs);
+ byte_stream_advance(bs, 18); /* unknown */
- purple_debug_misc("oscar", "clientautoresp: setting status message to \"%s\".\n", status_note);
+ request_length = byte_stream_getle32(bs);
+ if (length != 18 + 4 + request_length + 17) {
+ purple_debug_misc("oscar", "clientautoresp: incorrect block; "
+ "expected length is %u, got %u.\n",
+ 18 + 4 + request_length + 17, length);
+ g_free(status_note_title);
+ return;
+ }
- presence = purple_buddy_get_presence(buddy);
- status = purple_presence_get_active_status(presence);
+ byte_stream_advance(bs, request_length); /* x request */
+ byte_stream_advance(bs, 17); /* unknown */
- purple_prpl_got_user_status(account, sn,
- purple_status_get_id(status),
- "message", status_note, NULL);
+ length = byte_stream_getle32(bs);
+ response_length = byte_stream_getle32(bs);
+ response = byte_stream_getstr(bs, response_length);
+ encoding_length = byte_stream_getle32(bs);
+ if (length != 4 + response_length + 4 + encoding_length) {
+ purple_debug_misc("oscar", "clientautoresp: incorrect block; "
+ "expected length is %u, got %u.\n",
+ 4 + response_length + 4 + encoding_length, length);
+ g_free(status_note_title);
+ g_free(response);
+ return;
+ }
- break;
- }
+ encoding = byte_stream_getstr(bs, encoding_length);
+ account = purple_connection_get_account(od->gc);
+
+ stripped_encoding = oscar_encoding_extract(encoding);
+ status_note_text = oscar_encoding_to_utf8(account, stripped_encoding, response, response_length);
+ stripped_status_note_text = purple_markup_strip_html(status_note_text);
+
+ if (stripped_status_note_text != NULL && stripped_status_note_text[0] != 0)
+ status_note = g_strdup_printf("%s: %s", status_note_title, stripped_status_note_text);
+ else
+ status_note = g_strdup(status_note_title);
+
+ g_free(status_note_title);
+ g_free(response);
+ g_free(encoding);
+ g_free(stripped_encoding);
+ g_free(status_note_text);
+ g_free(stripped_status_note_text);
+
+ buddy = purple_find_buddy(account, sn);
+ if (buddy == NULL)
+ {
+ purple_debug_misc("oscar", "clientautoresp: buddy %s was not found.\n", sn);
g_free(status_note);
- g_free(stripped_status_note_text);
- g_free(status_note_text);
- g_free(stripped_encoding);
- g_free(encoding);
- g_free(response);
- g_free(info->status_note_title);
- g_free(info);
+ return;
+ }
+ purple_debug_misc("oscar", "clientautoresp: setting status "
+ "message to \"%s\".\n", status_note);
+
+ presence = purple_buddy_get_presence(buddy);
+ status = purple_presence_get_active_status(presence);
+
+ purple_prpl_got_user_status(account, sn,
+ purple_status_get_id(status),
+ "message", status_note, NULL);
+
+ g_free(status_note);
+}
+
+/*
+ * Subtype 0x000b - Receive the response from an ICQ status message
+ * request (in which case this contains the ICQ status message) or
+ * a file transfer or direct IM request was declined.
+ */
+static int clientautoresp(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
+{
+ int ret = 0;
+ aim_rxcallback_t userfunc;
+ guint16 channel, reason;
+ char *sn;
+ guchar *cookie;
+ guint8 snlen;
+
+ cookie = byte_stream_getraw(bs, 8);
+ channel = byte_stream_get16(bs);
+ snlen = byte_stream_get8(bs);
+ sn = byte_stream_getstr(bs, snlen);
+ reason = byte_stream_get16(bs);
+
+ if (channel == 0x0002)
+ {
+ if (reason == 0x0003) /* channel-specific */
+ /* parse status note text */
+ parse_status_note_text(od, cookie, sn, bs);
+
byte_stream_get16(bs); /* Unknown */
byte_stream_get16(bs); /* Unknown */
if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
More information about the Commits
mailing list