[xslt] possible bug in pattern.c



The latest (cvs) revision of pattern.c (version 1.63) appears to have a bug
causing a crash.

http://cvs.gnome.org/bonsai/cvsquery.cgi?module=libxslt&branch=HEAD&branchty
pe=match&dir=libxslt&file=&filetype=match&who=veillard&whotype=match&sortby=
Date&hours=&date=explicit&mindate=03%2F25%2F02+11%3A15&maxdate=03%2F25%2F02+
11%3A17&cvsroot=%2Fcvs%2Fgnome

To fix bug 76043 you made some changes to pattern.c.  I'd send the proposed
patch but anoncvs is down, see new code at bottom.  The following walks
through the issue

at line 612 list == NULL
line 623 returns a valid xpath object (in my case comp->pattern is
"o:tree-node[@nav-mode][not(@nav-mode = $nav-mode)]"), an empty nodeset
line 640 sets nocache to 1 because the node top level node evaulates to an
element (i.e comes from a result tree fragment), see definition of parent
when line 640 is hit below
line 655 crashes (list still == NULL)


- parent	0x06054170
  	_private	0x00000000
	type	1
+	name	0x060541e0 "fake node libxslt"
+	children	0x060555a8
+	last	0x060555a8
+	parent	0x00000000
+	next	0x00000000
+	prev	0x00000000
+	doc	0x00c4cdf0
+	ns	0x00000000
+	content	0x00000000 ""
+	properties	0x00000000
+	nsDef	0x00000000



598                 if (comp->steps[i + 1].op == XSLT_OP_PREDICATE) {
599                     xmlDocPtr prevdoc, doc;
600                     xmlXPathObjectPtr list;
601                     int index, j;
602                     int nocache = 0;
603 
604                     prevdoc = (xmlDocPtr)
605                         XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra);
606                     index = (int)
607                         XSLT_RUNTIME_EXTRA(ctxt, select->indexExtra);
608                     list = (xmlXPathObjectPtr)
609                         XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra);
610                     
611                     doc = node->doc;
612                     if ((list == NULL) || (prevdoc != doc)) {
613                         xmlChar *query;
614                         xmlXPathObjectPtr newlist;
615                         xmlNodePtr parent = node->parent;
616 
617                         if (comp->pattern[0] == '/')
618                             query = xmlStrdup(comp->pattern);
619                         else {
620                             query = xmlStrdup((const xmlChar *)"//");
621                             query = xmlStrcat(query, comp->pattern);
622                         }
623                         newlist = xmlXPathEval(query, ctxt->xpathCtxt);
624                         xmlFree(query);
625                         if (newlist == NULL)
626                             return(-1);
627                         if (newlist->type != XPATH_NODESET) {
628                             xmlXPathFreeObject(newlist);
629                             return(-1);
630                         }
631                         
632                         if ((parent == NULL) || (node->doc == NULL))
633                             nocache = 1;
634                         else {
635                             while (parent->parent != NULL)
636                                 parent = parent->parent;
637                             if (((parent->type != XML_DOCUMENT_NODE) &&
638                                  (parent->type !=
XML_HTML_DOCUMENT_NODE)) ||
639                                  (parent != (xmlNodePtr) node->doc))
640                                 nocache = 1;
641                         }
642                         if (nocache == 0) {
643                             if (list != NULL)
644                                 xmlXPathFreeObject(list);
645                             list = newlist;
646 
647                             XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra) =
648                                 (void *) list;
649                             XSLT_RUNTIME_EXTRA(ctxt,
select->previousExtra) =
650                                 (void *) doc;
651                             XSLT_RUNTIME_EXTRA_FREE(ctxt,
select->lenExtra) =
652                                 (xmlFreeFunc) xmlXPathFreeObject;
653                         }
654                     }
655                     if ((list->nodesetval == NULL) ||
656                         (list->nodesetval->nodeNr <= 0))
657                         return(0);
658                     /* TODO: store the index and use it for the scan */
659                     if (index == 0) {
660                         for (j = 0;j < list->nodesetval->nodeNr;j++) {
661                             if (list->nodesetval->nodeTab[j] == node) {
662                                 if (nocache == 1)
663                                     xmlXPathFreeObject(list);
664                                 return(1);
665                             }
666                         }
667                     } else {
668                     }
669                     if (nocache == 1)
670                         xmlXPathFreeObject(list);
671                     return(0);
672                 }


Proposed fix:  starting at line 642, changed lines have asterick
			if (nocache == 0) {
			    if (list != NULL)
				xmlXPathFreeObject(list);
			    list = newlist;

			    XSLT_RUNTIME_EXTRA(ctxt, select->lenExtra) =
				(void *) list;
			    XSLT_RUNTIME_EXTRA(ctxt, select->previousExtra)
=
				(void *) doc;
			    XSLT_RUNTIME_EXTRA_FREE(ctxt, select->lenExtra)
=
				(xmlFreeFunc) xmlXPathFreeObject;
*			} else list = newlist;
                     
		    }
		    if ((list->nodesetval == NULL) ||
*			(list->nodesetval->nodeNr <= 0)) {
*			if (nocache == 1)
*			    xmlXPathFreeObject(list);
			return(0);
*			}
		    /* TODO: store the index and use it for the scan */

This works for me, but I am not sure it is the 'correct' fix.






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