Am 08.02.2013 11:09, schrieb Thomas Gamper:
Am 07.02.2013 17:59, schrieb Thomas Gamper:
Am 07.02.2013 17:56, schrieb Csaba Raduly:
On Thu, Feb 7, 2013 at 4:47 PM, Thomas Gamper  wrote:
Hi!

I ran into issues with libxml2 xml validation with schemas as soon as i started using the xsi:nil attribute. Attached you find a reduced version of the schema I am using (zenotrack-pilot.xsd + all the dependencies it needs)
and two test cases:

GetNextMessageResponse.xml which does not validate with with xmllint
(xmllint --schema zenotrack-pilot.xsd GetNextMessageResponse.xml)
GetMessagesResponse, which is extremely similar to the first testcase, but
does validate with xmllint (xmllint --schema zenotrack-pilot.xsd
GetMessagesResponse.xml)

I did try libxml2 2.7.7, 2.7.8 and 2.9.0. I did a debug build of libxml2 2.9.0 on Win64 and stepped with the debugger through the code, but it is simply to complex for me to understand what is actually going on. All I saw was that the nil attribute was recognized as such, but later one validation
failed for reasons I do not understand.

Probably I am not seeing the obvious, but still I would like to ask for help
if there is actually something wrong with libxml2 in this case.
It is almost certainly a bug in libxml2: I tried your files with a
validator based on Xerces-C and both passed.

Csaba
The validator integrated into Visual Studio seems to validate both files fine too.

Thanks,
TOM
Ok, I found where the different behavior comes from:
xmlschemas.c line 26072 where xmlRegExecPushString is called inside xmlSchemaValidatorPopElem, right when we are leaving the offending node (Message element, child of GetNextMessageResponse element)

libxml2.dll!xmlRegExecPushStringInternal(_xmlRegExecCtxt * exec=0x000000000cb6e200, const unsigned char * value=0x0000000000000000, void * data=0x0000000000000000, int compound=0) Zeile 3786 C libxml2.dll!xmlRegExecPushString(_xmlRegExecCtxt * exec=0x000000000cb6e200, const unsigned char * value=0x0000000000000000, void * data=0x0000000000000000) Zeile 4133 C libxml2.dll!xmlSchemaValidatorPopElem(_xmlSchemaValidCtxt * vctxt=0x000000000c973890) Zeile 26072 + 0x13 Bytes C > libxml2.dll!xmlSchemaVDocWalk(_xmlSchemaValidCtxt * vctxt=0x000000000c973890) Zeile 27977 + 0xd Bytes C libxml2.dll!xmlSchemaVStart(_xmlSchemaValidCtxt * vctxt=0x000000000c973890) Zeile 28087 + 0xa Bytes C libxml2.dll!xmlSchemaValidateDoc(_xmlSchemaValidCtxt * ctxt=0x000000000c973890, _xmlDoc * doc=0x00000000080f9ba0) Zeile 28166 C


GetMessagesResponse

xmlRegExecPushStringInternal is called, which in turn calls xmlRegCompactPushString in xmlregexp.c line 3787
and returns 0.

GetNextMessageResponse

xmlRegExecPushStringInternal is called, which in turn does not call xmlRegCompactPushString,
and returns -1.

xmlschemas.c line 26073
if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode))))

The check works with ret == 0, but not with ret = -1. This poses two questions:
Is the check wrong?
Or is the regexp matching doing something wrong?

Thanks,
TOM
So, attached you find a patch diffed against git master which fixes the issue. There is no point doing a regexp validation of further content if there actually *IS* no further content because the element is nil. I also checked that validation of an element which has xsi:nil="true" but contains child elements still fails as it should.

Cheers,
TOM
diff --git a/xmlschemas.c b/xmlschemas.c
index d6a47e4..6d317b3 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -26063,6 +26063,11 @@ xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
                    "AUTOMATON create on '%s'\n", inode->localName);
 #endif
            }
+
+           /*
+           * Do not check further content if the node has been nilled
+           */
+           if (!INODE_NILLED(inode)) {
            /*
            * Get hold of the still expected content, since a further
            * call to xmlRegExecPushString() will loose this information.
@@ -26070,7 +26075,7 @@ xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
            xmlRegExecNextValues(inode->regexCtxt,
                &nbval, &nbneg, &values[0], &terminal);
            ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
-           if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
+           if (ret<0) {
                /*
                * Still missing something.
                */
@@ -26087,17 +26092,17 @@ xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
                    inode->localName);
 #endif
            } else {
+               ret = 0;
+           }
+           }
                /*
                * Content model is satisfied.
                */
-               ret = 0;
 #ifdef DEBUG_AUTOMATA
                xmlGenericError(xmlGenericErrorContext,
                    "AUTOMATON succeeded on '%s'\n",
                    inode->localName);
 #endif
-           }
-
        }
     }
     if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
_______________________________________________
xml mailing list, project page  http://xmlsoft.org/
xml@gnome.org
https://mail.gnome.org/mailman/listinfo/xml

Reply via email to