Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#3532 closed defect (worksforme)

Jabber does not parse correctly incomming messages

Reported by: emilal Owned by: seanegan
Milestone: Component: XMPP
Version: 2.2.1 Keywords: Jabber not working
Cc: fpang@…

Description

The incoming messages from Gtalk (Jabber) does not parce correctly and stay without message body. The code from Jabber/message.c try to execute:

} else if(!strcmp(child->name, "body") && !strcmp(xmlns,"jabber:client")) {

if(!jm->body) {

char *msg = xmlnode_to_str(child, NULL); jm->body = purple_strdup_withhtml(msg); g_free(msg);

}

The xmlns is not "jabber:client", but xmlns='http://jabber.org/protocol/chatstates'

That way, the "received-im-msg" callback is not called, and message not received. I saw this change is introduced from 2.1.0 (working version) to 2.2.1. The previose code does not try: && !strcmp(xmlns,"jabber:client")) - so is working.

The bug is reproducible for both example - nullclient.c and finch.

Attachments (1)

pidgin-2.2.2-fix_3532.patch (1.3 KB) - added by paulo.matos 11 years ago.

Download all attachments as: .zip

Change History (25)

comment:1 Changed 11 years ago by deryni

  • pending changed from 0 to 1

Can you paste the xml of the messages that fail please? They will be visible in the Debug Window output.

comment:2 Changed 11 years ago by emilal

  • pending changed from 1 to 0

Use Gtalk client to reproduce the problem.

The expected string "jabber:client" does not exist in xmlns, so the message is not parsed correctly. The code from 2.1.0 works correctly. Here is the troubled XML:

<message xmlns='vcard-temp:x:update' to='yyy@…' type='chat' id='54' from='xxx@…/Talk.v1048CB2BBDC'>

<body>Testing message....</body> <active xmlns='http://jabber.org/protocol/chatstates'/> <x xmlns='google:nosave' value='disabled'/> <record xmlns='http://jabber.org/protocol/archive' otr='false'/>

</message>

comment:3 Changed 11 years ago by seanegan

  • Component changed from plugins to XMPP
  • Owner set to seanegan
  • pending changed from 0 to 1
  • Status changed from new to assigned

The xmlns of that <body> element is indeed, jabber:client. It's set in the <stream/> element that starts the XML stream, and inherited here. The chatstates xmlns is specific to the <active/> element.

Are you saying that if you remove that namespace check, that messages are received fine? If so, it's an error with the XML parsing. This is the only complaint about this, though.

comment:4 Changed 11 years ago by seanegan

deryni just pointed out to me that the <message> element has an xmlns set on it as well. So, you're right that the <body/> is no longer in the 'jabber:client' namespace, but in the 'vcard-temp:x:update' namespace.

That's totally bused. It looks like that message is coming from version 104 of the Google Talk client?

comment:5 Changed 11 years ago by emilal

  • pending changed from 1 to 0

Right, I used Google Talk Client v. 1.0.0.104 to reproduce the problem.

comment:6 Changed 11 years ago by paulo.matos

Having the same problem here. Messages sent by GTalk are not being shown in GUI either. Any workaround this?

comment:7 Changed 11 years ago by paulo.matos

Forgot to mention before: this is happening on 2.2.2.0. Priority shoud be changed on this!!! It breakes Jabber protocol!!

comment:8 Changed 11 years ago by emilal

I dont know why after I isolated the problem the fix is not yet applied...

Thw workaround is to modify message.c file in jabber protocl folder. Find the jabber_message_parse function and copy with this function:

void jabber_message_parse(JabberStream? *js, xmlnode *packet) {

JabberMessage? *jm; const char *type; xmlnode *child;

jm = g_new0(JabberMessage?, 1); jm->js = js; jm->sent = time(NULL); jm->delayed = FALSE;

type = xmlnode_get_attrib(packet, "type");

if(type) {

if(!strcmp(type, "normal"))

jm->type = JABBER_MESSAGE_NORMAL;

else if(!strcmp(type, "chat"))

jm->type = JABBER_MESSAGE_CHAT;

else if(!strcmp(type, "groupchat"))

jm->type = JABBER_MESSAGE_GROUPCHAT;

else if(!strcmp(type, "headline"))

jm->type = JABBER_MESSAGE_HEADLINE;

else if(!strcmp(type, "error"))

jm->type = JABBER_MESSAGE_ERROR;

else

jm->type = JABBER_MESSAGE_OTHER;

} else {

jm->type = JABBER_MESSAGE_NORMAL;

}

jm->from = g_strdup(xmlnode_get_attrib(packet, "from")); jm->to = g_strdup(xmlnode_get_attrib(packet, "to")); jm->id = g_strdup(xmlnode_get_attrib(packet, "id"));

for(child = packet->child; child; child = child->next) {

const char *xmlns = xmlnode_get_namespace(child); if(!xmlns)

xmlns = "";

if(child->type != XMLNODE_TYPE_TAG)

continue;

if(!strcmp(child->name, "subject") ) {

if(!jm->subject)

jm->subject = xmlnode_get_data(child);

} else if(!strcmp(child->name, "thread") ) {

if(!jm->thread_id)

jm->thread_id = xmlnode_get_data(child);

} else if(!strcmp(child->name, "body") ) {

if(!jm->body) {

char *msg = xmlnode_to_str(child, NULL); jm->body = purple_strdup_withhtml(msg); g_free(msg);

}

} else if(!strcmp(child->name, "html") ) {

if(!jm->xhtml && xmlnode_get_child(child, "body")) {

char *c; jm->xhtml = xmlnode_to_str(child, NULL); /* Convert all newlines to whitespace. Technically, even regular, non-XML HTML is supposed to ignore newlines, but Pidgin has, as convention

  • treated \n as a newline for compatibility with other protocols

*/

for (c = jm->xhtml; *c != '\0'; c++) {

if (*c == '\n')

*c = ' ';

}

}

} else if(!strcmp(child->name, "active") && !strcmp(xmlns,"http://jabber.org/protocol/chatstates")) {

jm->chat_state = JM_STATE_ACTIVE; jm->typing_style |= JM_TS_JEP_0085;

} else if(!strcmp(child->name, "composing") && !strcmp(xmlns,"http://jabber.org/protocol/chatstates")) {

jm->chat_state = JM_STATE_COMPOSING; jm->typing_style |= JM_TS_JEP_0085;

} else if(!strcmp(child->name, "paused") && !strcmp(xmlns,"http://jabber.org/protocol/chatstates")) {

jm->chat_state = JM_STATE_PAUSED; jm->typing_style |= JM_TS_JEP_0085;

} else if(!strcmp(child->name, "inactive") && !strcmp(xmlns,"http://jabber.org/protocol/chatstates")) {

jm->chat_state = JM_STATE_INACTIVE; jm->typing_style |= JM_TS_JEP_0085;

} else if(!strcmp(child->name, "gone") && !strcmp(xmlns,"http://jabber.org/protocol/chatstates")) {

jm->chat_state = JM_STATE_GONE; jm->typing_style |= JM_TS_JEP_0085;

} else if(!strcmp(child->name, "event") && !strcmp(xmlns,"http://jabber.org/protocol/pubsub#event")) {

xmlnode *items; jm->type = JABBER_MESSAGE_EVENT; for(items = xmlnode_get_child(child,"items"); items; items = items->next)

jm->eventitems = g_list_append(jm->eventitems, items);

} else if(!strcmp(child->name, "attention") && !strcmp(xmlns,"http://www.xmpp.org/extensions/xep-0224.html#ns")) {

jm->hasBuzz = TRUE;

} else if(!strcmp(child->name, "error")) {

const char *code = xmlnode_get_attrib(child, "code"); char *code_txt = NULL; char *text = xmlnode_get_data(child);

if(code)

code_txt = g_strdup_printf(_(" (Code %s)"), code);

if(!jm->error)

jm->error = g_strdup_printf("%s%s", text ? text : "",

code_txt ? code_txt : "");

g_free(code_txt); g_free(text);

} else if(!strcmp(child->name, "delay") && xmlns && !strcmp(xmlns,"urn:xmpp:delay")) {

const char *timestamp = xmlnode_get_attrib(child, "stamp"); jm->delayed = TRUE; if(timestamp)

jm->sent = purple_str_to_time(timestamp, TRUE, NULL, NULL, NULL);

} else if(!strcmp(child->name, "x")) {

if(xmlns && !strcmp(xmlns, "jabber:x:event")) {

if(xmlnode_get_child(child, "composing")) {

if(jm->chat_state == JM_STATE_ACTIVE)

jm->chat_state = JM_STATE_COMPOSING;

jm->typing_style |= JM_TS_JEP_0022;

}

} else if(xmlns && !strcmp(xmlns, "jabber:x:delay")) {

const char *timestamp = xmlnode_get_attrib(child, "stamp"); jm->delayed = TRUE; if(timestamp)

jm->sent = purple_str_to_time(timestamp, TRUE, NULL, NULL, NULL);

} else if(xmlns && !strcmp(xmlns, "jabber:x:conference") &&

jm->type != JABBER_MESSAGE_GROUPCHAT_INVITE && jm->type != JABBER_MESSAGE_ERROR) {

const char *jid = xmlnode_get_attrib(child, "jid"); if(jid) {

jm->type = JABBER_MESSAGE_GROUPCHAT_INVITE; g_free(jm->to); jm->to = g_strdup(jid);

}

} else if(xmlns && !strcmp(xmlns,

"http://jabber.org/protocol/muc#user") &&

jm->type != JABBER_MESSAGE_ERROR) {

xmlnode *invite = xmlnode_get_child(child, "invite"); if(invite) {

xmlnode *reason, *password; const char *jid = xmlnode_get_attrib(invite, "from"); g_free(jm->to); jm->to = jm->from; jm->from = g_strdup(jid); if((reason = xmlnode_get_child(invite, "reason"))) {

g_free(jm->body); jm->body = xmlnode_get_data(reason);

} if((password = xmlnode_get_child(child, "password")))

jm->password = xmlnode_get_data(password);

jm->type = JABBER_MESSAGE_GROUPCHAT_INVITE;

}

} else {

jm->etc = g_list_append(jm->etc, child);

}

}

}

if(jm->hasBuzz)

handle_buzz(jm);

switch(jm->type) {

case JABBER_MESSAGE_NORMAL: case JABBER_MESSAGE_CHAT:

handle_chat(jm); break;

case JABBER_MESSAGE_HEADLINE:

handle_headline(jm); break;

case JABBER_MESSAGE_GROUPCHAT:

handle_groupchat(jm); break;

case JABBER_MESSAGE_GROUPCHAT_INVITE:

handle_groupchat_invite(jm); break;

case JABBER_MESSAGE_EVENT:

jabber_handle_event(jm); break;

case JABBER_MESSAGE_ERROR:

handle_error(jm); break;

case JABBER_MESSAGE_OTHER:

purple_debug(PURPLE_DEBUG_INFO, "jabber",

"Received message of unknown type: %s\n", type);

break;

} jabber_message_free(jm);

}

Enjoy!

comment:9 Changed 11 years ago by emilal

Of coarse, recompile all your projects to enable this replacement!

comment:10 Changed 11 years ago by deryni

The reason your "fix" has not been applied is that it is in fact not correct. First of all the namespace of body at that point in the code given your example message is 'vcard-temp:x:update' not 'http://jabber.org/protocol/chatstates' as you commented, and the fact that the <body/> tag is not in the jabber:client namespace is a bug. This is an issue in the Google Talk client that we can't fix. Therefore it is up to Google to fix this. And we don't as a rule use the 'Priority' field of a ticket so raising it would not have the effect you want.

comment:11 Changed 11 years ago by seanegan

Can you send me the Gmail accounts of both the senders and receivers of that message? Does this happen with messages from everyone to you?

comment:12 follow-up: Changed 11 years ago by emilal

I don't know whether my fix is "correct" or not, but I want to have working version of libpurple. And if Google is going to make some changes in protocol implementation, please follow them and give an working solution.

For now the libpurple is broken, and I think is not issue to argue whether the fix is proper or not from your viewpoint.

You can easily reproduce the error - send message from Google Talk client v.1.0.0.104 to any libpurple client.

comment:13 in reply to: ↑ 12 Changed 11 years ago by nosnilmot

Replying to emilal:

You can easily reproduce the error - send message from Google Talk client v.1.0.0.104 to any libpurple client.

You might be able to reproduce it easily, but I can't.

comment:14 follow-up: Changed 11 years ago by emilal

Seems we got different DNS server resolution...and different xml's. My name resolution for talk.google.com is 72.14.253.125, i.e. talk.google.com:5222.

Corresponding message is:

(10:01:09) jabber: Recv (ssl)(321): <message to="test@…" type="chat" id="37" from="gtalk_client@…/Talk.v10454F5546A"><body>Testing Gtalk client</body><active xmlns="http://jabber.org/protocol/chatstates"/><nos:x value="disabled" xmlns:nos="google:nosave"/><arc:record otr="false" xmlns:arc="http://jabber.org/protocol/archive"/></message>

Changed 11 years ago by paulo.matos

comment:15 Changed 11 years ago by paulo.matos

emilal, I just attached patch to 2.2.2 with your suggested fix, so other users can do the fix quickly.

I've tested it and it works now.

By the way, to me, talk.google.com points to 209.85.137.125.

The receiving problem happened for all gtalk users without exceptions.

Cheers,

-- Paulo Matos

comment:16 in reply to: ↑ 14 Changed 11 years ago by seanegan

Replying to emilal:

(10:01:09) jabber: Recv (ssl)(321): <message to="test@…" type="chat" id="37" from="gtalk_client@…/Talk.v10454F5546A"><body>Testing Gtalk client</body><active xmlns="http://jabber.org/protocol/chatstates"/><nos:x value="disabled" xmlns:nos="google:nosave"/><arc:record otr="false" xmlns:arc="http://jabber.org/protocol/archive"/></message>

This message stanza looks correct, and you should have no problem receiving it. The first stanza is incorrect; there's either a bug in the Google Talk client that's sending invalid stanzas, or a bug in the Google Talk server which is re-writing them (or, potentially, some sort of IM firewall in between that's re-writing them. Is this in a corporate environment where these are common?)

I work on the Google Talk team. If you send me the account names of those involved (by e-mail to seanegan@… if you're uncomfortable giving them here), I can look into what's up.

comment:17 Changed 11 years ago by maxslug

Same bug seen. Pidgin 2.3.1 compiled from source for an older linux w/ newer dependencies. Behind corporate firewall.

comment:18 Changed 11 years ago by maxslug

Oops, forgot to mention, the patch cured the problem.

comment:19 follow-up: Changed 11 years ago by dankots

I'm also having this problem. I've built Pidgin 2.3.1, on Red Hat Enterprise Linux 4. I see the messages received from google talk in the Debug Window, but they do not make it to the chat window.

This patch did not work for me.

Is this the same issue as: http://developer.pidgin.im/ticket/3266 ?

Any update on your attempt to get Google Talk team to fix their side?

comment:20 in reply to: ↑ 19 Changed 11 years ago by dankots

Ok, the patch works, I didn't install it right the first time. Thanks!

Replying to dankots:

I'm also having this problem. I've built Pidgin 2.3.1, on Red Hat Enterprise Linux 4. I see the messages received from google talk in the Debug Window, but they do not make it to the chat window.

This patch did not work for me.

Is this the same issue as: http://developer.pidgin.im/ticket/3266 ?

Any update on your attempt to get Google Talk team to fix their side?

comment:21 Changed 11 years ago by datallah

cc me

comment:22 Changed 11 years ago by kingsly

Gtalk was unusable for me since Nov 07 ... upgrading libxml2 fixed it for me.

Details can be found at http://developer.pidgin.im/ticket/3266#comment:14

comment:23 Changed 11 years ago by seanegan

  • Resolution set to worksforme
  • Status changed from assigned to closed

closing since it looks like this is the fault of old libxml2's.

comment:24 Changed 11 years ago by datallah

This is the relevant libxml2 bug: http://bugzilla.gnome.org/show_bug.cgi?id=164142

Note: See TracTickets for help on using tickets.
All information, including names and email addresses, entered onto this website or sent to mailing lists affiliated with this website will be public. Do not post confidential information, especially passwords!