[xml] Fix for bug 105992 incorrect? (and a patch)



I started seeing http://bugzilla.gnome.org/show_bug.cgi?id=105992 again, but this time on namespace declarations that were *not* the same as current element. For example, in the following XML file, the xmlns:a attribute passed through OK but xmlns:b was declared invalid:

<?xml version="1.0"?>
<!DOCTYPE a:outer [

<!ELEMENT a:outer EMPTY>
<!ATTLIST a:outer xmlns:a CDATA #FIXED 'urn:namespace'>
<!ATTLIST a:outer xmlns:b CDATA #FIXED 'urn:namespaceb'>
]>

<a:outer />


Thinking that this was simply bug 105992 popping up in a different place, I looked at the fix to see if there was a case that was missed. After some digging, I believe that the current fix is incorrect. I'll present 3 different situations: the code pre 2.5.4, the code as it stands now, and my proposed fix.

pre-2.5.4:

When validating namespace attributes, my_attribute() calls xmlValidateOneNamespace() passing the newly created xmlNsPtr, and the prefix of the *current element* that it received as an argument. xmlValidateOneNamespace() uses this prefix to create a qname for looking up attributes in the DTD. However, xmlCheckDefaultedAttributes() calls attribute(), which passes NULL to my_attribute() as the prefix. Hence, all #FIXED namespace attributes are declared invalid on qualified elments. In the above example it looks up 'xmlns:a' and 'xmlns:b' for element 'outer' and doesn't find either in the DTD because the element is 'a:outer', not 'outer'

current libxml2:

The fix for 105992 substituted the namespace declaration's prefix (eg. the 'a' in 'xmlns:a') for the element prefix in the call to xmlValidateOneNamespace(). This worked for the testcase submitted with the bug since the element prefix and namespace prefix were the same. However, it fails in the above testcase where you declare a namespace with a different prefix. xmlValidateOneNamespace() looks for 'xmlns:a' in 'a:outer' and finds it. But then it looks for 'xmlns:b' in 'b:outer' and doesn't find it because 'b:outer' doesn't exist.

My proposed fix (attached):

This patch reverts the previous fix, since we really do want to pass the element prefix, not the namespace declaration prefix. It also modifies xmlCheckDefaultedAttributes() to call my_attribute() with the element prefix. Now the prefix has the correct value ('a') in xmlValidateOneNamespace() and is able to find both namespace attributes in the DTD.


Thanks,
Brent

-------------------------------------------------------------------------

"The programmer, like the poet, works only slightly removed from pure
 thought-stuff.  He builds his castles in the air, from air, creating
 by exertion of the imagination.  Few media of creation are so
 flexible, so easy to polish and rework, so readily capable of
 realizing grand conceptual structures."
                        -- Frederick Brooks, Jr., The Mythical Man Month
--- SAX.c.orig  Sun Mar 23 04:20:44 2003
+++ SAX.c       Wed Mar 26 09:49:33 2003
@@ -968,7 +968,7 @@
         if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
            ctxt->myDoc && ctxt->myDoc->intSubset)
            ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
-                                          ctxt->node, name, nsret, value);
+                                          ctxt->node, prefix, nsret, value);
        if (name != NULL) 
            xmlFree(name);
        if (nval != NULL)
@@ -1236,7 +1236,7 @@
                            }
                        }
                        if (att == NULL) {
-                           attribute(ctxt, fulln, attr->defaultValue);
+                           my_attribute(ctxt, fulln, attr->defaultValue, prefix);
                        }
                        xmlFree(fulln);
                    }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]