two patches from Alvaro Herrera to avoid problem when running out of

* xpath.c: two patches from Alvaro Herrera to avoid problem when
  running out of memory in XPath evaluations.
Daniel

svn path=/trunk/; revision=3721
diff --git a/ChangeLog b/ChangeLog
index cab04cf..f6305b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Apr  1 09:59:22 CEST 2008 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: two patches from Alvaro Herrera to avoid problem when
+	  running out of memory in XPath evaluations.
+
 Mon Mar 31 11:23:19 CEST 2008 Daniel Veillard <daniel@veillard.com>
 
 	* parser.c: lot of out of memory handling fixes from Ashwin
diff --git a/xpath.c b/xpath.c
index 22a3f9d..a52c44a 100644
--- a/xpath.c
+++ b/xpath.c
@@ -3663,6 +3663,8 @@
     if (val2 == NULL) return(val1);
     if (val1 == NULL) {
 	val1 = xmlXPathNodeSetCreate(NULL);
+    if (val1 == NULL)
+        return (NULL);
 #if 0
 	/*
 	* TODO: The optimization won't work in every case, since
@@ -3776,6 +3778,8 @@
     if (val1 == NULL) {
 	val1 = xmlXPathNodeSetCreate(NULL);
     }
+    if (val1 == NULL)
+        return (NULL);
 
     /* @@ with_ns to check whether namespace nodes should be looked at @@ */
 
@@ -3852,7 +3856,9 @@
 	xmlNodePtr n1, n2;
 
 	if (set1 == NULL)
-	    	set1 = xmlXPathNodeSetCreate(NULL);
+            set1 = xmlXPathNodeSetCreate(NULL);
+        if (set1 == NULL)
+            return (NULL);
 
 	initNbSet1 = set1->nodeNr;        
 	for (i = 0;i < set2->nodeNr;i++) {
@@ -3962,6 +3968,8 @@
 
 	if (set1 == NULL)
 	    set1 = xmlXPathNodeSetCreate(NULL);
+        if (set1 == NULL)
+            return (NULL);
    
 	for (i = 0;i < set2->nodeNr;i++) {
 	    n2 = set2->nodeTab[i];
@@ -4281,8 +4289,9 @@
         ret = xmlXPathNewNodeSet(NULL);
     else {
         ret = xmlXPathNewNodeSet(val->nodeTab[0]);
-        for (i = 1; i < val->nodeNr; ++i)
-            xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]);
+        if (ret)
+            for (i = 1; i < val->nodeNr; ++i)
+                xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]);
     }
 
     return (ret);
@@ -4381,6 +4390,8 @@
     int i, l1;
     xmlNodePtr cur;
 
+    if (ret == NULL)
+        return(ret);
     if (xmlXPathNodeSetIsEmpty(nodes1))
 	return(ret);
     if (xmlXPathNodeSetIsEmpty(nodes2))
@@ -4418,6 +4429,8 @@
 	return(nodes);
 
     ret = xmlXPathNodeSetCreate(NULL);
+    if (ret == NULL)
+        return(ret);
     l = xmlXPathNodeSetGetLength(nodes);
     hash = xmlHashCreate (l);
     for (i = 0; i < l; i++) {
@@ -4506,6 +4519,8 @@
 	return(nodes);
 
     ret = xmlXPathNodeSetCreate(NULL);
+    if (ret == NULL)
+        return(ret);
     if (xmlXPathNodeSetIsEmpty(nodes) ||
 	(!xmlXPathNodeSetContains(nodes, node)))
 	return(ret);
@@ -4608,6 +4623,8 @@
 	return(nodes);
 
     ret = xmlXPathNodeSetCreate(NULL);
+    if (ret == NULL)
+        return(ret);
     if (xmlXPathNodeSetIsEmpty(nodes) ||
 	(!xmlXPathNodeSetContains(nodes, node)))
 	return(ret);
@@ -8432,6 +8449,8 @@
     if (ids == NULL) return(NULL);
 
     ret = xmlXPathNodeSetCreate(NULL);
+    if (ret == NULL)
+        return(ret);
 
     while (IS_BLANK_CH(*cur)) cur++;
     while (*cur != 0) {
@@ -8499,6 +8518,11 @@
 	int i;
 
 	ret = xmlXPathNodeSetCreate(NULL);
+        /*
+         * FIXME -- in an out-of-memory condition this will behave badly.
+         * The solution is not clear -- we already popped an item from
+         * ctxt, so the object is in a corrupt state.
+         */
 
 	if (obj->nodesetval != NULL) {
 	    for (i = 0; i < obj->nodesetval->nodeNr; i++) {
@@ -12481,6 +12505,7 @@
 	    outSeq = seq;
 	else
 	    outSeq = xmlXPathNodeSetCreate(NULL);
+        /* XXX what if xmlXPathNodeSetCreate returned NULL here? */
     }
     if ((seq != NULL) && (seq != outSeq)) {
 	 xmlXPathFreeNodeSet(seq);
@@ -12976,6 +13001,7 @@
 	* key() evaluation are attempted on the predicate
 	*/	
 	newset = xmlXPathNodeSetCreate(NULL);
+        /* XXX what if xmlXPathNodeSetCreate returned NULL? */
 	
 	for (i = 0; i < oldset->nodeNr; i++) {
 	    /*