xmlnode: lack of namespace_map and prefixes in parsed xml

Michal Witkowski neuro at o2.pl
Wed Nov 26 11:32:53 EST 2008


Hi

I've found a solution to my problem. It seems that jabber protocol uses a different parser 
declared in protocols/jabber/parser.c.  To my astonishment, it fails to put libxml2's 
namespaces and prefixes into xmlnode structures. 

The values are already there, but aren't copied. So, I took xmlnode.c's parser and put the 
missing bits into jabber/parser.c.  I've made a patch fixing the issue and I hope it's made 
properly. Is there a chance that this would get commited and be in future versions of 
pidgin? I mean it doesn't add any overhead, as libxml2 already provides the data.

PS. I'm sorry if this appears in another thread

Michal

Patch:
*** ../../../../../temp/pidgin-2.5.2/libpurple/protocols/jabber/parser.c        2008-08-25 
05:06:05.000000000 +0200                                 
--- parser.c    2008-11-26 17:26:35.000000000 +0100                                                                                                 
*************** jabber_parser_element_start_libxml(void                                                                                             
*** 37,43 ****                                                                                                                                      
  {                                                                                                                                                 
        JabberStream *js = user_data;                                                                                                               
        xmlnode *node;                                                                                                                              
!       int i;                                                                                                                                      
                                                                                                                                                    
        if(!element_name) {                                                                                                                         
                return;                                                                                                                             
--- 37,43 ----                                                                                                                                      
  {                                                                                                                                                 
        JabberStream *js = user_data;                                                                                                               
        xmlnode *node;                                                                                                                              
!       int i, j;                                                                                                                                   
                                                                                                                                                    
        if(!element_name) {                                                                                                                         
                return;                                                                                                                             
*************** jabber_parser_element_start_libxml(void                                                                                             
*** 57,63 ****                                                                                                                                      
                                g_free(js->stream_id);                                                                                              
                                js->stream_id = attrib;                                                                                             
                        } else {                                                                                                                    
!                               g_free(attrib);                                                                                                     
                        }                                                                                                                           
                }                                                                                                                                   
                if(js->protocol_version == JABBER_PROTO_0_9)                                                                                        
--- 57,63 ----                                                                                                                                      
                                g_free(js->stream_id);                                                                                              
                                js->stream_id = attrib;
                        } else {
!                               g_free(attrib);
                        }
                }
                if(js->protocol_version == JABBER_PROTO_0_9)
*************** jabber_parser_element_start_libxml(void
*** 72,79 ****
--- 72,92 ----
                else
                        node = xmlnode_new((const char*) element_name);
                xmlnode_set_namespace(node, (const char*) namespace);
+               xmlnode_set_prefix(node, (const char *)prefix);

+               if (nb_namespaces != 0) {
+                       node->namespace_map = g_hash_table_new_full(
+                               g_str_hash, g_str_equal, g_free, g_free);
+
+                       for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
+                               const char *key = (const char *)namespaces[j];
+                               const char *val = (const char *)namespaces[j + 1];
+                               g_hash_table_insert(node->namespace_map,
+                                       g_strdup(key ? key : ""), g_strdup(val ? val : 
""));
+                       }
+               }
                for(i=0; i < nb_attributes * 5; i+=5) {
+                       const char *prefix = (const char *)attributes[i + 1];
                        char *txt;
                        int attrib_len = attributes[i+4] - attributes[i+3];
                        char *attrib = g_malloc(attrib_len + 1);
*************** jabber_parser_element_start_libxml(void
*** 90,95 ****
--- 103,111 ----
                        attrib = purple_unescape_html(txt);
                        g_free(txt);
                        xmlnode_set_attrib_with_namespace(node, (const char*) 
attributes[i], attrib_ns, attrib);
+                       if (prefix && *prefix) {
+                               node->prefix = g_strdup(prefix);
+                       }
                        g_free(attrib);
                        g_free(attrib_ns);
                }




On Wednesday 26 November 2008 16:10:17 you wrote:
> Hi,
>
> I'm writing a WS-Notification consumer for SOAP messages transported via
> XMPP. I'm using the "jabber-receiving-xmlnode" signal to capture the
> messages. However, the WS-NT specification relies heavily on XML
> namespaces, prefixes and scoping.
>
> It seems that pidgin's XML DOM implementation is borked. For example, take
> this XMPP-SOAP- Notify message received over the wire:
>  <message to='dest' id='528493536683'
> from='source'>
>   <SOAP-ENV:Envelope
> xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
>
>     <SOAP-ENV:Header>
>       <wsa5:MessageID xmlns:wsa5='http://www.w3.org/2005/08/addressing'>
>       1234</wsa5:MessageID>
>       <wsa5:From xmlns:wsa5='http://www.w3.org/2005/08/addressing'>
>         <wsa5:Address>source</wsa5:Address>
>       </wsa5:From>
>       <wsa5:To xmlns:wsa5='http://www.w3.org/2005/08/addressing'
>       SOAP-ENV:mustUnderstand='1'>dest</wsa5:To>
>       <wsa5:Action xmlns:wsa5='http://www.w3.org/2005/08/addressing'
>       SOAP-ENV:mustUnderstand='1'>
>      
> http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer/Notify</wsa5:Actio
>n> </SOAP-ENV:Header>
>     <SOAP-ENV:Body>
>       <wsnt:Notify xmlns:wsnt='http://docs.oasis-open.org/wsn/b-2'>
>         <wsnt:NotificationMessage>
>           <wsnt:Topic
> Dialect='http://docs.oasis-open.org/wsn/t-1/TopicExpression/Full'>
> <TopicExpression xmlns='http://docs.oasis-open.org/wsn/b-2'
> Dialect='http://docs.oasis-open.org/wsn/t-1/TopicExpression/Full'
> xmlns:tns='urn:fedstage:fedcomputing:notification-topic:1.0'
> tns:someargument='somevalue'>
>             tns:job/control/resumed</TopicExpression>
>           </wsnt:Topic>
>           <wsnt:Message>SampleNotification</wsnt:Message>
>         </wsnt:NotificationMessage>
>       </wsnt:Notify>
>     </SOAP-ENV:Body>
>   </SOAP-ENV:Envelope>
> </message>
>
> Now, take a look at what XMPP console spat out:
>
> <message to='dest' id='528493536683' from='source'>
> 	<Envelope xmlns='http://schemas.xmlsoap.org/soap/envelope/'>
> 		<Header>
> 			<MessageID xmlns='http://www.w3.org/2005/08/addressing'>1234</MessageID>
> 			<From xmlns='http://www.w3.org/2005/08/addressing'>
> 				<Address>source</Address>
> 			</From>
> 			<To xmlns='http://www.w3.org/2005/08/addressing'
> mustUnderstand='1'>dest</To> <Action
> xmlns='http://www.w3.org/2005/08/addressing'
> mustUnderstand='1'>http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer
>/Notify</Action> </Header>
> 		<Body>
> 			<Notify xmlns='http://docs.oasis-open.org/wsn/b-2'>
> 				<NotificationMessage>
> 					<Topic
> Dialect='http://docs.oasis-open.org/wsn/t-1/TopicExpression/Full'>
> <TopicExpression
> Dialect='http://docs.oasis-open.org/wsn/t-1/TopicExpression/Full'
> someargument='somevalue'>tns:job/control/resumed</TopicExpression>
>
> 					</Topic>
> 					<Message>SampleNotification</Message>
> 				</NotificationMessage>
> 			</Notify>
> 		</Body>
> 	</Envelope>
> </message>
>
> What's working:
> xmlnode contains the correct xmlns for the XMLNODE_TYPE_TAG nodes (for
> example, <Envelope> has a correct namespace of
> 'http://schemas.xmlsoap.org/soap/envelope/'). The inheritance of namespaces
> is correct, for example NotificationMessage has xmlns set to the same value
> as Notify.
>
> What's not working:
> 1. prefixes don't make it into xmlnode structures despite the fact that
> they should according to line 585 of xmlnode.c it happens both for tags and
> attribs 2. xmlns information for XMLNODE_TYPE_ATTRIB nodes is missing. Take
> for example the tns:someargument='somevalue' attribute of TopicExpression.
> It should have it's xmlns set to
> 'urn:fedstage:fedcomputing:notification-topic:1.0', but instead NULL is
> there. 3. Nodes containing declarations of namespace maps do not retain
> them. Take for example: <TopicExpression
> xmlns='http://docs.oasis-open.org/wsn/b-2'
>            
> Dialect='http://docs.oasis-open.org/wsn/t-1/TopicExpression/Full'
> xmlns:tns='urn:fedstage:fedcomputing:notification-topic:1.0'
> tns:someargument='somevalue'>
> turned into:
> <TopicExpression
> Dialect='http://docs.oasis-open.org/wsn/t-1/TopicExpression/Full'
> someargument='somevalue'>
> Despite the fact that in lines 587-597 of xmlnode.c namespace map are
> stored inside the xmlnode structure.
>
> All these symptoms are related to xmlnode's transported over the
> jabber-receiving-xmlnode signal. Maybe some of this information get's
> stripped out along the way?
>
> Maybe it's a problem with libxml2, maybe it's a problem with pidgin's xml
> dom. Maybe theres a special switch/define/magic flag which turns that
> parsing on I don't know of? I've got pidgin 2.5.2 and libxml2 2.6.32. Could
> anyone please help me?
>
> Michal




More information about the Devel mailing list