[Pidgin] #3532: Jabber does not parse correctly incomming messages

Pidgin trac at pidgin.im
Mon Nov 19 12:09:06 EST 2007


#3532: Jabber does not parse correctly incomming messages
---------------------+------------------------------------------------------
  Reporter:  emilal  |       Owner:  seanegan          
      Type:  defect  |      Status:  assigned          
  Priority:  minor   |   Milestone:                    
 Component:  XMPP    |     Version:  2.2.1             
Resolution:          |    Keywords:  Jabber not working
   Pending:  0       |  
---------------------+------------------------------------------------------
Comment (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!

-- 
Ticket URL: <http://developer.pidgin.im/ticket/3532#comment:8>
Pidgin <http://pidgin.im>
Pidgin


More information about the Tracker mailing list