fixing yet another pattern induced XPath bug #314282 reverted back last
* 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
Daniel
diff --git a/ChangeLog b/ChangeLog
index c8204cd..951fb45 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sun Sep 4 14:01:00 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+ * 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 <rrichards@ctindustries.net>
* xmlsave.c: check for NULL to prevent crash with meta elements
diff --git a/include/libxml/pattern.h b/include/libxml/pattern.h
index c058bd9..1aa6704 100644
--- a/include/libxml/pattern.h
+++ b/include/libxml/pattern.h
@@ -67,6 +67,8 @@
XMLPUBFUN int XMLCALL
xmlPatternMaxDepth (xmlPatternPtr comp);
XMLPUBFUN int XMLCALL
+ xmlPatternMinDepth (xmlPatternPtr comp);
+XMLPUBFUN int XMLCALL
xmlPatternFromRoot (xmlPatternPtr comp);
XMLPUBFUN xmlStreamCtxtPtr XMLCALL
xmlPatternGetStreamCtxt (xmlPatternPtr comp);
diff --git a/pattern.c b/pattern.c
index 7dc9f59..a76a58c 100644
--- a/pattern.c
+++ b/pattern.c
@@ -1635,6 +1635,14 @@
*/
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
* we are at the first level only, otherwise on every level.
@@ -2157,7 +2165,33 @@
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 c6ce936..f315e1e 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -2220,6 +2220,9 @@
{
xmlChar *msg;
+ if (ctxt->error == NULL)
+ return;
+
#ifdef DEBUG_ERROR
xmlGenericError(xmlGenericErrorContext, "Show error %d\n", err);
#endif
@@ -2329,7 +2332,7 @@
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 162f6e3..297aa9e 100644
--- a/xpath.c
+++ b/xpath.c
@@ -11003,7 +11003,7 @@
*/
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 @@
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 @@
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) {