From: David Brooks Date: Tue, 31 Mar 2009 16:37:12 +0000 (+0000) Subject: Fix incorrect parsing in chan_gtalk when xmpp contains extra whitespaces X-Git-Tag: 1.4.25-rc1~95 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a2933fefef64a962e5a94f8cf6293f921dd27646;p=thirdparty%2Fasterisk.git Fix incorrect parsing in chan_gtalk when xmpp contains extra whitespaces To drill into the xmpp to find the capabilities between channels, chan_gtalk calls iks_child() and iks_next(). iks_child() and iks_next() are functions in the iksemel xml parsing library that traverse xml nodes. The bug here is that both iks_child() and iks_next() will return the next iks_struct node *regardless* of type. chan_gtalk expects the next node to be of type IKS_TAG, which in most cases, it is, but in this case (a call being made from the Empathy IM client), there exists iks_struct nodes which are not IKS_TAG data (they are extraneous whitespaces), and chan_gtalk doesn't handle that case, so capabilities don't match, and a call cannot be made. iks_first_tag() and iks_next_tag(), on the other hand, will not return the very next iks_struct, but will check to see if the next iks_struct is of type IKS_TAG. If it isn't, it will be skipped, and the next struct of type IKS_TAG it finds will be returned. This assures that chan_gtalk will find the iks_struct it is looking for. This fix simply changes all calls to iks_child() and iks_next() to become calls to iks_first_tag() and iks_next_tag(), which resolves the capability matching. The following is a payload listing from Empathy, which, due to the extraneous whitespace, will not be parsed correctly by iksemel: git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@185362 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/channels/chan_gtalk.c b/channels/chan_gtalk.c index ef5e7acab4..32ce3973e0 100644 --- a/channels/chan_gtalk.c +++ b/channels/chan_gtalk.c @@ -649,11 +649,11 @@ static int gtalk_is_answered(struct gtalk *client, ikspak *pak) } /* codec points to the first tag */ - codec = iks_child(iks_child(iks_child(pak->x))); + codec = iks_first_tag(iks_first_tag(iks_first_tag(pak->x))); while (codec) { ast_rtp_set_m_type(tmp->rtp, atoi(iks_find_attrib(codec, "id"))); ast_rtp_set_rtpmap_type(tmp->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0); - codec = iks_next(codec); + codec = iks_next_tag(codec); } /* Now gather all of the codecs that we are asked for */ @@ -1224,12 +1224,12 @@ static int gtalk_newcall(struct gtalk *client, ikspak *pak) } /* codec points to the first tag */ - codec = iks_child(iks_child(iks_child(pak->x))); + codec = iks_first_tag(iks_first_tag(iks_first_tag(pak->x))); while (codec) { ast_rtp_set_m_type(p->rtp, atoi(iks_find_attrib(codec, "id"))); ast_rtp_set_rtpmap_type(p->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0); - codec = iks_next(codec); + codec = iks_next_tag(codec); } /* Now gather all of the codecs that we are asked for */ @@ -1343,11 +1343,11 @@ static int gtalk_add_candidate(struct gtalk *client, ikspak *pak) traversenodes = pak->query; while(traversenodes) { if(!strcasecmp(iks_name(traversenodes), "session")) { - traversenodes = iks_child(traversenodes); + traversenodes = iks_first_tag(traversenodes); continue; } if(!strcasecmp(iks_name(traversenodes), "transport")) { - traversenodes = iks_child(traversenodes); + traversenodes = iks_first_tag(traversenodes); continue; } if(!strcasecmp(iks_name(traversenodes), "candidate")) { @@ -1386,7 +1386,7 @@ static int gtalk_add_candidate(struct gtalk *client, ikspak *pak) gtalk_update_stun(p->parent, p); newcandidate = NULL; } - traversenodes = iks_next(traversenodes); + traversenodes = iks_next_tag(traversenodes); } receipt = iks_new("iq");