soc.2010.icq-tlc: d1c89d7b: Stop using custom encodings (and LATIN-1...
ivan.komarov at soc.pidgin.im
ivan.komarov at soc.pidgin.im
Tue Jul 27 17:21:48 EDT 2010
----------------------------------------------------------------------
Revision: d1c89d7bc669f5fa5636b54af6a36e6640d021e1
Parent: 0f6b638a4703cdf41c980ba852428061efee8416
Author: ivan.komarov at soc.pidgin.im
Date: 07/27/10 17:17:01
Branch: im.pidgin.soc.2010.icq-tlc
URL: http://d.pidgin.im/viewmtn/revision/info/d1c89d7bc669f5fa5636b54af6a36e6640d021e1
Changelog:
Stop using custom encodings (and LATIN-1, for that matter) for sending
OSCAR messages (ICBM, chat, Direct IM). Now, we use ASCII if a message
contains ASCII characters only, and UTF-16 in all other cases.
That fixes #10833 (offline messages now will be sent as UTF-16)
and also a whole bunch of potential problems we can get
with charset 0x3. Different clients tend to interpret this
charset differently; for instance, the official client
always interprets it as LATIN-1, while alternative
clients may decode it as some other user-specified
8-bit encoding. On the other hand, ASCII messages
(charset 0x0) and UTF-16 messages (charset 0x2) are understood
uniformly by all clients.
I also cleaned-up the code a little (got rid of code paths that were
never executed, flags that were always set, unused struct members, etc.)
Changes against parent 0f6b638a4703cdf41c980ba852428061efee8416
patched libpurple/protocols/oscar/encoding.c
patched libpurple/protocols/oscar/encoding.h
patched libpurple/protocols/oscar/family_icbm.c
patched libpurple/protocols/oscar/oscar.c
patched libpurple/protocols/oscar/oscar.h
-------------- next part --------------
============================================================
--- libpurple/protocols/oscar/oscar.c d247a5a892353b94a722ab99f5975937e68e3644
+++ libpurple/protocols/oscar/oscar.c 1e16aecb59bb00869f286455abf9226d635924c8
@@ -108,7 +108,6 @@ static int purple_icon_parseicon (Osca
static int purple_conv_chat_incoming_msg(OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_email_parseupdate(OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_icon_parseicon (OscarData *, FlapConnection *, FlapFrame *, ...);
-static int purple_parse_msgack (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_evilnotify (OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_searcherror(OscarData *, FlapConnection *, FlapFrame *, ...);
static int purple_parse_searchreply(OscarData *, FlapConnection *, FlapFrame *, ...);
@@ -666,7 +665,6 @@ oscar_login(PurpleAccount *account)
oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_MISSEDCALL, purple_parse_misses, 0);
oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_CLIENTAUTORESP, purple_parse_clientauto, 0);
oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_MTN, purple_parse_mtn, 0);
- oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_ACK, purple_parse_msgack, 0);
oscar_data_addhandler(od, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_RIGHTSINFO, purple_parse_locaterights, 0);
oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x0001, purple_parse_genericerr, 0);
oscar_data_addhandler(od, SNAC_FAMILY_OSERVICE, 0x000f, purple_selfinfo, 0);
@@ -2724,24 +2722,6 @@ purple_icons_fetch(PurpleConnection *gc)
purple_debug_misc("oscar", "no more icons to request\n");
}
-/*
- * Received in response to an IM sent with the AIM_IMFLAGS_ACK option.
- */
-static int purple_parse_msgack(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
- va_list ap;
- guint16 type;
- char *bn;
-
- va_start(ap, fr);
- type = (guint16) va_arg(ap, unsigned int);
- bn = va_arg(ap, char *);
- va_end(ap);
-
- purple_debug_info("oscar", "Sent message to %s.\n", bn);
-
- return 1;
-}
-
static int purple_parse_evilnotify(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
#ifdef CRAZY_WARNING
va_list ap;
@@ -3183,8 +3163,8 @@ purple_odc_send_im(PeerConnection *conn,
GString *msg;
GString *data;
gchar *tmp;
- int tmplen;
- guint16 charset, charsubset;
+ gsize tmplen;
+ guint16 charset;
GData *attribs;
const char *start, *end, *last;
int oscar_id = 0;
@@ -3245,8 +3225,7 @@ purple_odc_send_im(PeerConnection *conn,
g_string_append(msg, "</BODY></HTML>");
/* Convert the message to a good encoding */
- oscar_convert_to_best_encoding(conn->od->gc,
- conn->bn, msg->str, &tmp, &tmplen, &charset, &charsubset);
+ tmp = oscar_convert_to_best_encoding(msg->str, &tmplen, &charset, NULL);
g_string_free(msg, TRUE);
msg = g_string_new_len(tmp, tmplen);
g_free(tmp);
@@ -3326,7 +3305,7 @@ oscar_send_im(PurpleConnection *gc, cons
g_hash_table_insert(od->buddyinfo, g_strdup(purple_normalize(account, name)), bi);
}
- args.flags = AIM_IMFLAGS_ACK | AIM_IMFLAGS_CUSTOMFEATURES;
+ args.flags = 0;
if (!is_sms && (!buddy || !PURPLE_BUDDY_IS_ONLINE(buddy)))
args.flags |= AIM_IMFLAGS_OFFLINE;
@@ -3395,7 +3374,7 @@ oscar_send_im(PurpleConnection *gc, cons
g_free(tmp1);
tmp1 = tmp2;
- oscar_convert_to_best_encoding(gc, name, tmp1, (char **)&args.msg, &args.msglen, &args.charset, &args.charsubset);
+ args.msg = oscar_convert_to_best_encoding(tmp1, &args.msglen, &args.charset, NULL);
if (is_html && (args.msglen > MAXMSGLEN)) {
/* If the length was too long, try stripping the HTML and then running it back through
* purple_strdup_withhtml() and the encoding process. The result may be shorter. */
@@ -3412,14 +3391,12 @@ oscar_send_im(PurpleConnection *gc, cons
g_free(tmp1);
tmp1 = tmp2;
- oscar_convert_to_best_encoding(gc, name, tmp1, (char **)&args.msg, &args.msglen, &args.charset, &args.charsubset);
-
+ args.msg = oscar_convert_to_best_encoding(tmp1, &args.msglen, &args.charset, NULL);
purple_debug_info("oscar", "Sending %s as %s because the original was too long.\n",
message, (char *)args.msg);
}
- purple_debug_info("oscar", "Sending IM, charset=0x%04hx, charsubset=0x%04hx, length=%d\n",
- args.charset, args.charsubset, args.msglen);
+ purple_debug_info("oscar", "Sending IM, charset=0x%04hx, length=%" G_GSIZE_FORMAT "\n", args.charset, args.msglen);
ret = aim_im_sendch1_ext(od, &args);
g_free((char *)args.msg);
}
@@ -3461,28 +3438,6 @@ void oscar_set_idle(PurpleConnection *gc
aim_srv_setidle(od, time);
}
-static
-gchar *purple_prpl_oscar_convert_to_infotext(const gchar *str, gsize *ret_len, char **encoding)
-{
- int charset = 0;
- char *encoded = NULL;
-
- charset = oscar_charset_check(str);
- if (charset == AIM_CHARSET_UNICODE) {
- encoded = g_convert(str, -1, "UTF-16BE", "UTF-8", NULL, ret_len, NULL);
- *encoding = "unicode-2-0";
- } else if (charset == AIM_CHARSET_LATIN_1) {
- encoded = g_convert(str, -1, "ISO-8859-1", "UTF-8", NULL, ret_len, NULL);
- *encoding = "iso-8859-1";
- } else {
- encoded = g_strdup(str);
- *ret_len = strlen(str);
- *encoding = "us-ascii";
- }
-
- return encoded;
-}
-
void
oscar_set_info(PurpleConnection *gc, const char *rawinfo)
{
@@ -3586,7 +3541,7 @@ oscar_set_info_and_status(PurpleAccount
else if (rawinfo != NULL)
{
char *htmlinfo = purple_strdup_withhtml(rawinfo);
- info = purple_prpl_oscar_convert_to_infotext(htmlinfo, &infolen, &info_encoding);
+ info = oscar_convert_to_best_encoding(htmlinfo, &infolen, NULL, &info_encoding);
g_free(htmlinfo);
if (infolen > od->rights.maxsiglen)
@@ -3619,7 +3574,7 @@ oscar_set_info_and_status(PurpleAccount
/* We do this for icq too so that they work for old third party clients */
linkified = purple_markup_linkify(status_html);
- away = purple_prpl_oscar_convert_to_infotext(linkified, &awaylen, &away_encoding);
+ away = oscar_convert_to_best_encoding(linkified, &awaylen, NULL, &away_encoding);
g_free(linkified);
if (awaylen > od->rights.maxawaymsglen)
@@ -4592,9 +4547,9 @@ int oscar_send_chat(PurpleConnection *gc
PurpleConversation *conv = NULL;
struct chat_connection *c = NULL;
char *buf, *buf2, *buf3;
- guint16 charset, charsubset;
- char *charsetstr = NULL;
- int len;
+ guint16 charset;
+ char *charsetstr;
+ gsize len;
if (!(conv = purple_find_chat(gc, id)))
return -EINVAL;
@@ -4610,7 +4565,7 @@ int oscar_send_chat(PurpleConnection *gc
"You cannot send IM Images in AIM chats."),
PURPLE_MESSAGE_ERROR, time(NULL));
- oscar_convert_to_best_encoding(gc, NULL, buf, &buf2, &len, &charset, &charsubset);
+ buf2 = oscar_convert_to_best_encoding(buf, &len, &charset, &charsetstr);
/*
* Evan S. suggested that maxvis really does mean "number of
* visible characters" and not "number of bytes"
@@ -4626,10 +4581,11 @@ int oscar_send_chat(PurpleConnection *gc
buf = purple_strdup_withhtml(buf3);
g_free(buf3);
- oscar_convert_to_best_encoding(gc, NULL, buf, &buf2, &len, &charset, &charsubset);
+ buf2 = oscar_convert_to_best_encoding(buf, &len, &charset, &charsetstr);
if ((len > c->maxlen) || (len > c->maxvis)) {
- purple_debug_warning("oscar", "Could not send %s because (%i > maxlen %i) or (%i > maxvis %i)\n",
+ purple_debug_warning("oscar",
+ "Could not send %s because (%" G_GSIZE_FORMAT " > maxlen %i) or (%" G_GSIZE_FORMAT " > maxvis %i)\n",
buf2, len, c->maxlen, len, c->maxvis);
g_free(buf);
g_free(buf2);
@@ -4640,12 +4596,6 @@ int oscar_send_chat(PurpleConnection *gc
message, buf2);
}
- if (charset == AIM_CHARSET_ASCII)
- charsetstr = "us-ascii";
- else if (charset == AIM_CHARSET_UNICODE)
- charsetstr = "unicode-2-0";
- else if (charset == AIM_CHARSET_LATIN_1)
- charsetstr = "iso-8859-1";
aim_chat_send_im(od, c->conn, 0, buf2, len, charsetstr, "en");
g_free(buf2);
g_free(buf);
============================================================
--- libpurple/protocols/oscar/family_icbm.c ecb6550278f98afc4c6046ba4c140b78fdf732cc
+++ libpurple/protocols/oscar/family_icbm.c 91154315d63e25cbc008736855ff763fc8735880
@@ -348,31 +348,9 @@ static int aim_im_paraminfo(OscarData *o
*
* Possible flags:
* AIM_IMFLAGS_AWAY -- Marks the message as an autoresponse
- * AIM_IMFLAGS_ACK -- Requests that the server send an ack
- * when the message is received (of type SNAC_FAMILY_ICBM/0x000c)
* AIM_IMFLAGS_OFFLINE--If destination is offline, store it until they are
* online (probably ICQ only).
*
- * Generally, you should use the lowest encoding possible to send
- * your message. If you only use basic punctuation and the generic
- * Latin alphabet, use ASCII7 (no flags). If you happen to use non-ASCII7
- * characters, but they are all clearly defined in ISO-8859-1, then
- * use that. Keep in mind that not all characters in the PC ASCII8
- * character set are defined in the ISO standard. For those cases (most
- * notably when the (r) symbol is used), you must use the full UNICODE
- * encoding for your message. In UNICODE mode, _all_ characters must
- * occupy 16bits, including ones that are not special. (Remember that
- * the first 128 UNICODE symbols are equivalent to ASCII7, however they
- * must be prefixed with a zero high order byte.)
- *
- * I strongly discourage the use of UNICODE mode, mainly because none
- * of the clients I use can parse those messages (and besides that,
- * wchars are difficult and non-portable to handle in most UNIX environments).
- * If you really need to include special characters, use the HTML UNICODE
- * entities. These are of the form ߪ where 2026 is the hex
- * representation of the UNICODE index (in this case, UNICODE
- * "Horizontal Ellipsis", or 133 in in ASCII8).
- *
* Implementation note: Since this is one of the most-used functions
* in all of libfaim, it is written with performance in mind. As such,
* it is not as clear as it could be in respect to how this message is
@@ -390,7 +368,6 @@ int aim_im_sendch1_ext(OscarData *od, st
ByteStream data;
guchar cookie[8];
int msgtlvlen;
- static const guint8 deffeatures[] = { 0x01, 0x01, 0x01, 0x02 };
if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)))
return -EINVAL;
@@ -398,38 +375,18 @@ int aim_im_sendch1_ext(OscarData *od, st
if (!args)
return -EINVAL;
- if (args->flags & AIM_IMFLAGS_MULTIPART) {
- if (args->mpmsg->numparts == 0)
- return -EINVAL;
- } else {
- if (!args->msg || (args->msglen <= 0))
- return -EINVAL;
+ if (!args->msg || (args->msglen <= 0))
+ return -EINVAL;
- if (args->msglen > MAXMSGLEN)
- return -E2BIG;
- }
+ if (args->msglen > MAXMSGLEN)
+ return -E2BIG;
/* Painfully calculate the size of the message TLV */
msgtlvlen = 1 + 1; /* 0501 */
+ msgtlvlen += 2 + args->featureslen;
+ msgtlvlen += 2 /* 0101 */ + 2 /* block len */;
+ msgtlvlen += 4 /* charset */ + args->msglen;
- if (args->flags & AIM_IMFLAGS_CUSTOMFEATURES)
- msgtlvlen += 2 + args->featureslen;
- else
- msgtlvlen += 2 + sizeof(deffeatures);
-
- if (args->flags & AIM_IMFLAGS_MULTIPART) {
- aim_mpmsg_section_t *sec;
-
- for (sec = args->mpmsg->parts; sec; sec = sec->next) {
- msgtlvlen += 2 /* 0101 */ + 2 /* block len */;
- msgtlvlen += 4 /* charset */ + sec->datalen;
- }
-
- } else {
- msgtlvlen += 2 /* 0101 */ + 2 /* block len */;
- msgtlvlen += 4 /* charset */ + args->msglen;
- }
-
byte_stream_new(&data, msgtlvlen + 128);
/* Generate an ICBM cookie */
@@ -444,52 +401,31 @@ int aim_im_sendch1_ext(OscarData *od, st
/* Features TLV (type 0x0501) */
byte_stream_put16(&data, 0x0501);
- if (args->flags & AIM_IMFLAGS_CUSTOMFEATURES) {
- byte_stream_put16(&data, args->featureslen);
- byte_stream_putraw(&data, args->features, args->featureslen);
- } else {
- byte_stream_put16(&data, sizeof(deffeatures));
- byte_stream_putraw(&data, deffeatures, sizeof(deffeatures));
- }
+ byte_stream_put16(&data, args->featureslen);
+ byte_stream_putraw(&data, args->features, args->featureslen);
- if (args->flags & AIM_IMFLAGS_MULTIPART) {
- aim_mpmsg_section_t *sec;
+ /* Insert message text in a TLV (type 0x0101) */
+ byte_stream_put16(&data, 0x0101);
- /* Insert each message part in a TLV (type 0x0101) */
- for (sec = args->mpmsg->parts; sec; sec = sec->next) {
- byte_stream_put16(&data, 0x0101);
- byte_stream_put16(&data, sec->datalen + 4);
- byte_stream_put16(&data, sec->charset);
- byte_stream_put16(&data, sec->charsubset);
- byte_stream_putraw(&data, (guchar *)sec->data, sec->datalen);
- }
+ /* Message block length */
+ byte_stream_put16(&data, args->msglen + 0x04);
- } else {
+ /* Character set */
+ byte_stream_put16(&data, args->charset);
+ /* Character subset -- we always use 0 here */
+ byte_stream_put16(&data, 0x0);
- /* Insert message text in a TLV (type 0x0101) */
- byte_stream_put16(&data, 0x0101);
+ /* Message. Not terminated */
+ byte_stream_putraw(&data, (guchar *)args->msg, args->msglen);
- /* Message block length */
- byte_stream_put16(&data, args->msglen + 0x04);
-
- /* Character set */
- byte_stream_put16(&data, args->charset);
- byte_stream_put16(&data, args->charsubset);
-
- /* Message. Not terminated */
- byte_stream_putraw(&data, (guchar *)args->msg, args->msglen);
- }
-
/* Set the Autoresponse flag */
if (args->flags & AIM_IMFLAGS_AWAY) {
byte_stream_put16(&data, 0x0004);
byte_stream_put16(&data, 0x0000);
} else {
- if (args->flags & AIM_IMFLAGS_ACK) {
- /* Set the Request Acknowledge flag */
- byte_stream_put16(&data, 0x0003);
- byte_stream_put16(&data, 0x0000);
- }
+ /* Set the Request Acknowledge flag */
+ byte_stream_put16(&data, 0x0003);
+ byte_stream_put16(&data, 0x0000);
if (args->flags & AIM_IMFLAGS_OFFLINE) {
/* Allow this message to be queued as an offline message */
@@ -534,33 +470,6 @@ int aim_im_sendch1_ext(OscarData *od, st
}
/*
- * Simple wrapper for aim_im_sendch1_ext()
- *
- * You cannot use aim_send_im if you need the HASICON flag. You must
- * use aim_im_sendch1_ext directly for that.
- *
- * aim_send_im also cannot be used if you require UNICODE messages, because
- * that requires an explicit message length. Use aim_im_sendch1_ext().
- *
- */
-int aim_im_sendch1(OscarData *od, const char *bn, guint16 flags, const char *msg)
-{
- struct aim_sendimext_args args;
-
- args.destbn = bn;
- args.flags = flags;
- args.msg = msg;
- args.msglen = strlen(msg);
- args.charset = 0x0000;
- args.charsubset = 0x0000;
-
- /* Make these don't get set by accident -- they need aim_im_sendch1_ext */
- args.flags &= ~(AIM_IMFLAGS_CUSTOMFEATURES | AIM_IMFLAGS_HASICON | AIM_IMFLAGS_MULTIPART);
-
- return aim_im_sendch1_ext(od, &args);
-}
-
-/*
* Subtype 0x0006 - Send a chat invitation.
*/
int aim_im_sendch2_chatinvite(OscarData *od, const char *bn, const char *msg, guint16 exchange, const char *roomname, guint16 instance)
@@ -1352,75 +1261,6 @@ int aim_im_sendch4(OscarData *od, const
}
/*
- * XXX - I don't see when this would ever get called...
- */
-static int outgoingim(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
-{
- int ret = 0;
- aim_rxcallback_t userfunc;
- guchar cookie[8];
- guint16 channel;
- GSList *tlvlist;
- char *bn;
- int bnlen;
- guint16 icbmflags = 0;
- guint8 flag1 = 0, flag2 = 0;
- gchar *msg = NULL;
- aim_tlv_t *msgblock;
-
- /* ICBM Cookie. */
- aim_icbm_makecookie(cookie);
-
- /* Channel ID */
- channel = byte_stream_get16(bs);
-
- if (channel != 0x01) {
- purple_debug_misc("oscar", "icbm: ICBM received on unsupported channel. Ignoring. (chan = %04x)\n", channel);
- return 0;
- }
-
- bnlen = byte_stream_get8(bs);
- bn = byte_stream_getstr(bs, bnlen);
-
- tlvlist = aim_tlvlist_read(bs);
-
- if (aim_tlv_gettlv(tlvlist, 0x0003, 1))
- icbmflags |= AIM_IMFLAGS_ACK;
- if (aim_tlv_gettlv(tlvlist, 0x0004, 1))
- icbmflags |= AIM_IMFLAGS_AWAY;
-
- if ((msgblock = aim_tlv_gettlv(tlvlist, 0x0002, 1))) {
- ByteStream mbs;
- int featurelen, msglen;
-
- byte_stream_init(&mbs, msgblock->value, msgblock->length);
-
- byte_stream_get8(&mbs);
- byte_stream_get8(&mbs);
- for (featurelen = byte_stream_get16(&mbs); featurelen; featurelen--)
- byte_stream_get8(&mbs);
- byte_stream_get8(&mbs);
- byte_stream_get8(&mbs);
-
- msglen = byte_stream_get16(&mbs) - 4; /* final block length */
-
- flag1 = byte_stream_get16(&mbs);
- flag2 = byte_stream_get16(&mbs);
-
- msg = byte_stream_getstr(&mbs, msglen);
- }
-
- if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
- ret = userfunc(od, conn, frame, channel, bn, msg, icbmflags, flag1, flag2);
-
- g_free(bn);
- g_free(msg);
- aim_tlvlist_free(tlvlist);
-
- return ret;
-}
-
-/*
* Ahh, the joys of nearly ridiculous over-engineering.
*
* Not only do AIM ICBM's support multiple channels. Not only do they
@@ -1624,8 +1464,6 @@ static int incomingim_ch1_parsemsgs(Osca
} /* while */
- args->icbmflags |= AIM_IMFLAGS_MULTIPART; /* always set */
-
/*
* Clients that support multiparts should never use args->msg, as it
* will point to an arbitrary section.
@@ -2639,16 +2477,10 @@ static int clientautoresp(OscarData *od,
}
/*
- * Subtype 0x000c - Receive an ack after sending an ICBM.
- *
- * You have to have send the message with the AIM_IMFLAGS_ACK flag set
- * (TLV t(0003)). The ack contains the ICBM header of the message you
- * sent.
- *
+ * Subtype 0x000c - Receive an ack after sending an ICBM. The ack contains the ICBM header of the message you sent.
*/
static int msgack(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
- aim_rxcallback_t userfunc;
guint16 ch;
guchar *cookie;
char *bn;
@@ -2658,8 +2490,7 @@ static int msgack(OscarData *od, FlapCon
ch = byte_stream_get16(bs);
bn = byte_stream_getstr(bs, byte_stream_get8(bs));
- if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
- ret = userfunc(od, conn, frame, ch, bn);
+ purple_debug_info("oscar", "Sent message to %s.\n", bn);
g_free(bn);
g_free(cookie);
@@ -2952,8 +2783,6 @@ snachandler(OscarData *od, FlapConnectio
return error(od, conn, mod, frame, snac, bs);
else if (snac->subtype == 0x0005)
return aim_im_paraminfo(od, conn, mod, frame, snac, bs);
- else if (snac->subtype == 0x0006)
- return outgoingim(od, conn, mod, frame, snac, bs);
else if (snac->subtype == 0x0007)
return incomingim(od, conn, mod, frame, snac, bs);
else if (snac->subtype == 0x000a)
============================================================
--- libpurple/protocols/oscar/oscar.h ef1804ff64db9acf7e5f33350d0135b765d4e84f
+++ libpurple/protocols/oscar/oscar.h 268251ceaa55dddc70f10df18e390fe627ead2a2
@@ -845,7 +845,6 @@ void oscar_chat_destroy(struct chat_conn
#define AIM_IMFLAGS_CUSTOMFEATURES 0x0080 /* features field present */
#define AIM_IMFLAGS_EXTDATA 0x0100
#define AIM_IMFLAGS_X 0x0200
-#define AIM_IMFLAGS_MULTIPART 0x0400 /* ->mpmsg section valid */
#define AIM_IMFLAGS_OFFLINE 0x0800 /* send to offline user */
#define AIM_IMFLAGS_TYPINGNOT 0x1000 /* typing notification */
@@ -885,30 +884,22 @@ struct aim_sendimext_args
*/
struct aim_sendimext_args
{
-
/* These are _required_ */
const char *destbn;
guint32 flags; /* often 0 */
- /* Only required if not using multipart messages */
const char *msg;
- int msglen;
+ gsize msglen;
- /* Required if ->msg is not provided */
- aim_mpmsg_t *mpmsg;
-
/* Only used if AIM_IMFLAGS_HASICON is set */
guint32 iconlen;
time_t iconstamp;
guint32 iconsum;
- /* Only used if AIM_IMFLAGS_CUSTOMFEATURES is set */
guint16 featureslen;
guint8 *features;
- /* Only used if AIM_IMFLAGS_CUSTOMCHARSET is set and mpmsg not used */
guint16 charset;
- guint16 charsubset;
};
/*
@@ -926,18 +917,12 @@ struct aim_sendrtfmsg_args
* This information is provided in the Incoming ICBM callback for
* Channel 1 ICBM's.
*
- * Note that although CUSTOMFEATURES and CUSTOMCHARSET say they
- * are optional, both are always set by the current libfaim code.
- * That may or may not change in the future. It is mainly for
- * consistency with aim_sendimext_args.
- *
* Multipart messages require some explanation. If you want to use them,
* I suggest you read all the comments in family_icbm.c.
*
*/
struct aim_incomingim_ch1_args
{
-
/* Always provided */
aim_mpmsg_t mpmsg;
guint32 icbmflags; /* some flags apply only to ->msg, not all mpmsg */
============================================================
--- libpurple/protocols/oscar/encoding.c 57a615e053ce4e4ca04636bae361c2181d3c4f4f
+++ libpurple/protocols/oscar/encoding.c 9466a994460438724264b4196c6ec66850b9edcd
@@ -20,45 +20,17 @@
#include "encoding.h"
-guint32
+guint16
oscar_charset_check(const char *utf8)
{
- int i = 0;
- int charset = AIM_CHARSET_ASCII;
-
- /*
- * Can we get away with using our custom encoding?
- */
- while (utf8[i])
+ while (*utf8++)
{
- if ((unsigned char)utf8[i] > 0x7f) {
+ if ((unsigned char)(*utf8) > 0x7f) {
/* not ASCII! */
- charset = AIM_CHARSET_LATIN_1;
- break;
+ return AIM_CHARSET_UNICODE;
}
- i++;
}
-
- /*
- * Must we send this message as UNICODE (in the UTF-16BE encoding)?
- */
- while (utf8[i])
- {
- /* ISO-8859-1 is 0x00-0xbf in the first byte
- * followed by 0xc0-0xc3 in the second */
- if ((unsigned char)utf8[i] < 0x80) {
- i++;
- continue;
- } else if (((unsigned char)utf8[i] & 0xfc) == 0xc0 &&
- ((unsigned char)utf8[i + 1] & 0xc0) == 0x80) {
- i += 2;
- continue;
- }
- charset = AIM_CHARSET_UNICODE;
- break;
- }
-
- return charset;
+ return AIM_CHARSET_ASCII;
}
gchar *
@@ -259,103 +231,15 @@ oscar_decode_im_part(PurpleAccount *acco
return ret;
}
-void
-oscar_convert_to_best_encoding(PurpleConnection *gc,
- const char *destbn, const gchar *from,
- gchar **msg, int *msglen_int,
- guint16 *charset, guint16 *charsubset)
+gchar *
+oscar_convert_to_best_encoding(const gchar *msg, gsize *result_len, guint16 *charset, gchar **charsetstr)
{
- OscarData *od = purple_connection_get_protocol_data(gc);
- PurpleAccount *account = purple_connection_get_account(gc);
- GError *err = NULL;
- aim_userinfo_t *userinfo = NULL;
- const gchar *charsetstr;
- gsize msglen;
-
- /* Attempt to send as ASCII */
- if (oscar_charset_check(from) == AIM_CHARSET_ASCII) {
- *msg = g_convert(from, -1, "ASCII", "UTF-8", NULL, &msglen, NULL);
- *charset = AIM_CHARSET_ASCII;
- *charsubset = 0x0000;
- *msglen_int = msglen;
- return;
+ guint16 msg_charset = oscar_charset_check(msg);
+ if (charset != NULL) {
+ *charset = msg_charset;
}
-
- /*
- * If we're sending to an ICQ user, and they are in our
- * buddy list, and they are advertising the Unicode
- * capability, and they are online, then attempt to send
- * as UTF-16BE.
- */
- if ((destbn != NULL) && oscar_util_valid_name_icq(destbn))
- userinfo = aim_locate_finduserinfo(od, destbn);
-
- if ((userinfo != NULL) && (userinfo->capabilities & OSCAR_CAPABILITY_UNICODE))
- {
- PurpleBuddy *b;
- b = purple_find_buddy(account, destbn);
- if ((b != NULL) && (PURPLE_BUDDY_IS_ONLINE(b)))
- {
- *msg = g_convert(from, -1, "UTF-16BE", "UTF-8", NULL, &msglen, &err);
- if (*msg != NULL)
- {
- *charset = AIM_CHARSET_UNICODE;
- *charsubset = 0x0000;
- *msglen_int = msglen;
- return;
- }
-
- purple_debug_error("oscar", "Conversion from UTF-8 to UTF-16BE failed: %s.\n",
- err->message);
- g_error_free(err);
- err = NULL;
- }
+ if (charsetstr != NULL) {
+ *charsetstr = msg_charset == AIM_CHARSET_ASCII ? "us-ascii" : "unicode-2-0";
}
-
- /*
- * If this is AIM then attempt to send as ISO-8859-1. If this is
- * ICQ then attempt to send as the user specified character encoding.
- */
- charsetstr = "ISO-8859-1";
- if ((destbn != NULL) && oscar_util_valid_name_icq(destbn))
- charsetstr = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
-
- /*
- * XXX - We need a way to only attempt to convert if we KNOW "from"
- * can be converted to "charsetstr"
- */
- *msg = g_convert(from, -1, charsetstr, "UTF-8", NULL, &msglen, &err);
- if (*msg != NULL) {
- *charset = AIM_CHARSET_LATIN_1;
- *charsubset = 0x0000;
- *msglen_int = msglen;
- return;
- }
-
- purple_debug_info("oscar", "Conversion from UTF-8 to %s failed (%s). Falling back to unicode.\n",
- charsetstr, err->message);
- g_error_free(err);
- err = NULL;
-
- /*
- * Nothing else worked, so send as UTF-16BE.
- */
- *msg = g_convert(from, -1, "UTF-16BE", "UTF-8", NULL, &msglen, &err);
- if (*msg != NULL) {
- *charset = AIM_CHARSET_UNICODE;
- *charsubset = 0x0000;
- *msglen_int = msglen;
- return;
- }
-
- purple_debug_error("oscar", "Error converting a Unicode message: %s\n", err->message);
- g_error_free(err);
- err = NULL;
-
- purple_debug_error("oscar", "This should NEVER happen! Sending UTF-8 text flagged as ASCII.\n");
- *msg = g_strdup(from);
- *msglen_int = strlen(*msg);
- *charset = AIM_CHARSET_ASCII;
- *charsubset = 0x0000;
- return;
+ return g_convert(msg, -1, msg_charset == AIM_CHARSET_ASCII ? "ASCII" : "UTF-16BE", "UTF-8", NULL, result_len, NULL);
}
============================================================
--- libpurple/protocols/oscar/encoding.h 536b447085c84c6a299d2205ba8e7b327f86be38
+++ libpurple/protocols/oscar/encoding.h c557a39d99d80268f04c74ecd18a14bf7bdcac47
@@ -27,7 +27,7 @@
/**
* Determine the simplest encoding we can send this message in.
*/
-guint32 oscar_charset_check(const char *utf8);
+guint16 oscar_charset_check(const char *utf8);
/**
* Take a string of the form charset="bleh" where bleh is
@@ -56,9 +56,6 @@ gchar * oscar_decode_im_part(PurpleAccou
/**
* Figure out what encoding to use when sending a given outgoing message.
*/
-void oscar_convert_to_best_encoding(PurpleConnection *gc,
- const char *destbn, const gchar *from,
- gchar **msg, int *msglen_int,
- guint16 *charset, guint16 *charsubset);
+gchar * oscar_convert_to_best_encoding(const gchar *msg, gsize *result_len, guint16 *charset, gchar **charsetstr);
#endif
\ No newline at end of file
More information about the Commits
mailing list