diff --git a/ChangeLog b/ChangeLog index c8204cdb..951fb45f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Sun Sep 4 14:01:00 CEST 2005 Daniel Veillard + + * pattern.c xpath.c include/libxml/pattern.h: fixing yet another + pattern induced XPath bug #314282 + * relaxng.c: reverted back last change it was seriously broken + Sat Sep 3 16:51:55 CEST 2005 Rob Richards * xmlsave.c: check for NULL to prevent crash with meta elements diff --git a/include/libxml/pattern.h b/include/libxml/pattern.h index c058bd9f..1aa6704e 100644 --- a/include/libxml/pattern.h +++ b/include/libxml/pattern.h @@ -66,6 +66,8 @@ XMLPUBFUN int XMLCALL xmlPatternStreamable (xmlPatternPtr comp); XMLPUBFUN int XMLCALL xmlPatternMaxDepth (xmlPatternPtr comp); +XMLPUBFUN int XMLCALL + xmlPatternMinDepth (xmlPatternPtr comp); XMLPUBFUN int XMLCALL xmlPatternFromRoot (xmlPatternPtr comp); XMLPUBFUN xmlStreamCtxtPtr XMLCALL diff --git a/pattern.c b/pattern.c index 7dc9f59c..a76a58c5 100644 --- a/pattern.c +++ b/pattern.c @@ -1634,6 +1634,14 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream, * Fast check for ".". */ if (comp->nbStep == 0) { + /* + * / and . are handled at the XPath node set creation + * level by checking min depth + */ + if (stream->flags & XML_PATTERN_XPATH) { + stream = stream->next; + continue; /* while */ + } /* * For non-pattern like evaluation like XML Schema IDCs * or traditional XPath expressions, this will match if @@ -2157,7 +2165,33 @@ xmlPatternMaxDepth(xmlPatternPtr comp) { comp = comp->next; } return(ret); +} +/** + * xmlPatternMinDepth: + * @comp: the precompiled pattern + * + * Check the minimum depth reachable by a pattern, 0 mean the / or . are + * part of the set. + * + * Returns -1 in case of error otherwise the depth, + * + */ +int +xmlPatternMinDepth(xmlPatternPtr comp) { + int ret = 12345678; + if (comp == NULL) + return(-1); + while (comp != NULL) { + if (comp->stream == NULL) + return(-1); + if (comp->stream->nbStep < ret) + ret = comp->stream->nbStep; + if (ret == 0) + return(0); + comp = comp->next; + } + return(ret); } /** diff --git a/relaxng.c b/relaxng.c index c6ce9361..f315e1e1 100644 --- a/relaxng.c +++ b/relaxng.c @@ -2220,6 +2220,9 @@ xmlRelaxNGShowValidError(xmlRelaxNGValidCtxtPtr ctxt, { xmlChar *msg; + if (ctxt->error == NULL) + return; + #ifdef DEBUG_ERROR xmlGenericError(xmlGenericErrorContext, "Show error %d\n", err); #endif @@ -2329,7 +2332,7 @@ xmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt, xmlRelaxNGValidErr err, const xmlChar * arg1, const xmlChar * arg2, int dup) { - if (ctxt == NULL) + if ((ctxt == NULL) || (ctxt->error == NULL)) return; #ifdef DEBUG_ERROR diff --git a/xpath.c b/xpath.c index 162f6e3a..297aa9ee 100644 --- a/xpath.c +++ b/xpath.c @@ -11003,7 +11003,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) */ static xmlXPathObjectPtr xmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp) { - int max_depth; + int max_depth, min_depth; int from_root; int ret, depth; xmlNodePtr cur = NULL, limit = NULL; @@ -11019,6 +11019,9 @@ xmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp) { return(NULL); if (max_depth == -2) max_depth = 10000; + min_depth = xmlPatternMinDepth(comp); + if (min_depth == -1) + return(NULL); from_root = xmlPatternFromRoot(comp); if (from_root < 0) return(NULL); @@ -11030,13 +11033,20 @@ xmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp) { if (retval == NULL) return(NULL); - if ((from_root) && (max_depth == 0)) { - xmlXPathNodeSetAddUnique(retval->nodesetval, (xmlNodePtr) ctxt->doc); - return(retval); - } else if (max_depth == 0) { - xmlXPathNodeSetAddUnique(retval->nodesetval, ctxt->node); + /* + * handle the special cases of / amd . being matched + */ + if (min_depth == 0) { + if (from_root) { + xmlXPathNodeSetAddUnique(retval->nodesetval, (xmlNodePtr) ctxt->doc); + } else { + xmlXPathNodeSetAddUnique(retval->nodesetval, ctxt->node); + } + } + if (max_depth == 0) { return(retval); } + if (from_root) { cur = (xmlNodePtr)ctxt->doc; } else if (ctxt->node != NULL) {