Ticket #3083: ignore-fucked-up-xmlns.patch

File ignore-fucked-up-xmlns.patch, 7.2 KB (added by dwd, 18 months ago)

Seems to now be 100% working. Returns two bogus namespaces for undeclared namespaces. Running for personal use quite happily.

  • src/common/xmpp/simplexml.py

     
    4949                replication (and using replication only to move upwards on the classes tree). 
    5050        """ 
    5151        FORCE_NODE_RECREATION=0 
    52         def __init__(self, tag=None, attrs={}, payload=[], parent=None, node=None): 
     52        def __init__(self, tag=None, attrs={}, payload=[], parent=None, nsp=None, node_built=False, node=None): 
    5353                """ Takes "tag" argument as the name of node (prepended by namespace, if needed and separated from it 
    5454                        by a space), attrs dictionary as the set of arguments, payload list as the set of textual strings 
    5555                        and child nodes that this node carries within itself and "parent" argument that is another node 
     
    6262                                node=str(node) 
    6363                        if not isinstance(node, Node):  
    6464                                node=NodeBuilder(node,self) 
     65                                node_built = True 
    6566                        else: 
    66                                 self.name,self.namespace,self.attrs,self.data,self.kids,self.parent = node.name,node.namespace,{},[],[],node.parent 
     67                                self.name,self.namespace,self.attrs,self.data,self.kids,self.parent,self.nsd = node.name,node.namespace,{},[],[],node.parent,{} 
    6768                                for key  in node.attrs.keys(): self.attrs[key]=node.attrs[key] 
    6869                                for data in node.data: self.data.append(data) 
    6970                                for kid  in node.kids: self.kids.append(kid) 
    70                 else: self.name,self.namespace,self.attrs,self.data,self.kids,self.parent = 'tag','',{},[],[],None 
    71  
    72                 if tag: self.namespace, self.name = ([self.namespace]+tag.split())[-2:] 
    73                 if parent: self.parent = parent 
    74                 if self.parent and not self.namespace: self.namespace=self.parent.namespace 
    75                 for attr in attrs.keys(): 
     71                                for k,v in node.nsd.items(): self.nsd[k] = v 
     72                else: self.name,self.namespace,self.attrs,self.data,self.kids,self.parent,self.nsd = 'tag','',{},[],[],None,{} 
     73                if parent: 
     74                        self.parent = parent 
     75                self.nsp_cache = {} 
     76                if nsp: 
     77                        for k,v in nsp.items(): self.nsp_cache[k] = v 
     78                for attr,val in attrs.items(): 
     79                        if attr == 'xmlns': 
     80                                self.nsd[u''] = val 
     81                        elif attr.startswith('xmlns:'): 
     82                                self.nsd[attr[6:]] = val 
    7683                        self.attrs[attr]=attrs[attr] 
     84                if tag: 
     85                        if node_built: 
     86                                pfx,self.name = (['']+tag.split(':'))[-2:] 
     87                                self.namespace = self.lookup_nsp(pfx) 
     88                        else: 
     89                                if ' ' in tag: 
     90                                        self.namespace,self.name = tag.split() 
     91                                else: 
     92                                        self.name = tag 
    7793                if isinstance(payload, basestring): payload=[payload] 
    7894                for i in payload: 
    7995                        if isinstance(i, Node): self.addChild(node=i) 
    8096                        else: self.data.append(ustr(i)) 
     97         
     98        def lookup_nsp(self,pfx=''): 
     99                ns = self.nsd.get(pfx,None) 
     100                if ns is None: 
     101                        ns = self.nsp_cache.get(pfx,None) 
     102                if ns is None: 
     103                        if self.parent: 
     104                                ns = self.parent.lookup_nsp(pfx) 
     105                                self.nsp_cache[pfx] = ns 
     106                        else: 
     107                                return 'http://www.gajim.org/xmlns/undeclared' 
     108                return ns 
    81109 
    82110        def __str__(self,fancy=0): 
    83111                """ Method used to dump node into textual representation. 
     
    85113                s = (fancy-1) * 2 * ' ' + "<" + self.name 
    86114                if self.namespace: 
    87115                        if not self.parent or self.parent.namespace!=self.namespace: 
    88                                 s = s + ' xmlns="%s"'%self.namespace 
     116                                if 'xmlns' not in self.attrs: 
     117                                        s = s + ' xmlns="%s"'%self.namespace 
    89118                for key in self.attrs.keys(): 
    90119                        val = ustr(self.attrs[key]) 
    91120                        s = s + ' %s="%s"' % ( key, XMLescape(val) ) 
     
    111140        def addChild(self, name=None, attrs={}, payload=[], namespace=None, node=None): 
    112141                """ If "node" argument is provided, adds it as child node. Else creates new node from 
    113142                        the other arguments' values and adds it as well.""" 
    114                 if namespace: name=namespace+' '+name 
    115143                if node: 
    116144                        newnode=node 
    117145                        node.parent = self 
    118146                else: newnode=Node(tag=name, parent=self, attrs=attrs, payload=payload) 
     147                if namespace: 
     148                        newnode.setNamespace(namespace) 
    119149                self.kids.append(newnode) 
    120150                return newnode 
    121151        def addData(self, data): 
     
    294324                        "data" (if provided) feeded to parser immidiatedly after instance init. 
    295325                        """ 
    296326                self.DEBUG(DBG_NODEBUILDER, "Preparing to handle incoming XML stream.", 'start') 
    297                 self._parser = xml.parsers.expat.ParserCreate(namespace_separator=' ') 
     327         
     328                self._parser = xml.parsers.expat.ParserCreate() 
    298329                self._parser.StartElementHandler       = self.starttag 
    299330                self._parser.EndElementHandler         = self.endtag 
    300331                self._parser.StartNamespaceDeclHandler = self.handle_namespace_start 
    301332                self._parser.CharacterDataHandler    = self.handle_cdata 
    302333                self.Parse = self._parser.Parse 
    303  
     334                 
    304335                self.__depth = 0 
    305336                self.__last_depth = 0 
    306337                self.__max_depth = 0 
    307338                self._dispatch_depth = 1 
    308339                self._document_attrs = None 
     340                self._document_nsp = None 
    309341                self._mini_dom=initial_node 
    310342                self.last_is_data = 1 
    311343                self._ptr=None 
    312344                self.data_buffer = None 
    313                 self.namespaces={"http://www.w3.org/XML/1998/namespace":'xml:'} 
    314                 self.xmlns="http://www.w3.org/XML/1998/namespace" 
    315  
    316                 if data:  
     345                if data: 
    317346                        self._parser.Parse(data,1) 
    318347         
    319348        def check_data_buffer(self): 
     
    333362        def starttag(self, tag, attrs): 
    334363                """XML Parser callback. Used internally""" 
    335364                self.check_data_buffer() 
    336                 attlist=attrs.keys()       # 
    337                 for attr in attlist:       # FIXME: Crude hack. And it also slows down the whole library considerably. 
    338                         sp=attr.rfind(" ")     # 
    339                         if sp==-1: continue    # 
    340                         ns=attr[:sp]           # 
    341                         attrs[self.namespaces[ns]+attr[sp+1:]]=attrs[attr] 
    342                         del attrs[attr]        # 
    343365                self._inc_depth() 
    344366                self.DEBUG(DBG_NODEBUILDER, "DEPTH -> %i , tag -> %s, attrs -> %s" % (self.__depth, tag, `attrs`), 'down') 
    345367                if self.__depth == self._dispatch_depth: 
    346368                        if not self._mini_dom :  
    347                                 self._mini_dom = Node(tag=tag, attrs=attrs) 
     369                                self._mini_dom = Node(tag=tag, attrs=attrs, nsp = self._document_nsp, node_built=True) 
    348370                        else:  
    349                                 Node.__init__(self._mini_dom,tag=tag, attrs=attrs) 
     371                                Node.__init__(self._mini_dom,tag=tag, attrs=attrs, nsp = self._document_nsp, node_built=True) 
    350372                        self._ptr = self._mini_dom 
    351373                elif self.__depth > self._dispatch_depth: 
    352                         self._ptr.kids.append(Node(tag=tag,parent=self._ptr,attrs=attrs)) 
     374                        self._ptr.kids.append(Node(tag=tag,parent=self._ptr,attrs=attrs, node_built=True)) 
    353375                        self._ptr = self._ptr.kids[-1] 
    354376                if self.__depth == 1: 
    355                         self._document_attrs = attrs 
    356                         ns, name = (['']+tag.split())[-2:] 
     377                        self._document_attrs = {} 
     378                        self._document_nsp = {} 
     379                        nsp, name = (['']+tag.split(':'))[-2:] 
     380                        for attr,val in attrs.items(): 
     381                                if attr == 'xmlns': 
     382                                        self._document_nsp[u''] = val 
     383                                elif attr.startswith('xmlns:'): 
     384                                        self._document_nsp[attr[6:]] = val 
     385                                else: 
     386                                        self._document_attrs[attr] = val 
     387                        ns = self._document_nsp.get(nsp, 'http://www.gajim.org/xmlns/undeclared-root') 
    357388                        self.stream_header_received(ns, name, attrs) 
    358389                if not self.last_is_data and self._ptr.parent:  
    359390                        self._ptr.parent.data.append('') 
     
    383414        def handle_namespace_start(self, prefix, uri): 
    384415                """XML Parser callback. Used internally""" 
    385416                self.check_data_buffer() 
    386                 if prefix: self.namespaces[uri]=prefix+':' 
    387                 else: self.xmlns=uri 
    388417        def DEBUG(self, level, text, comment=None): 
    389418                """ Gets all NodeBuilder walking events. Can be used for debugging if redefined.""" 
    390419        def getDom(self): 
     
    425454                tags though. F.e. "<b>some text <br>some more text</b>" will not work.""" 
    426455        return NodeBuilder(xml).getDom() 
    427456 
    428 # vim: se ts=3: 
    429  No newline at end of file 
     457# vim: se ts=3: