--- xpath.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) Index: libxml2-2.13.5/xpath.c =================================================================== --- libxml2-2.13.5.orig/xpath.c +++ libxml2-2.13.5/xpath.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -104,14 +105,32 @@ #define XPATH_MAX_STACK_DEPTH 1000000 /* - * XPATH_MAX_NODESET_LENGTH: + * XPATH_DEFAULT_MAX_NODESET_LENGTH: * when evaluating an XPath expression nodesets are created and we - * arbitrary limit the maximum length of those node set. 10000000 is - * an insanely large value which should never be reached under normal - * circumstances, one would first need to construct an in memory tree + * arbitrary limit the maximum length of those node set. Default value is + * 10000000, an insanely large value which should never be reached under + * normal circumstances, one would first need to construct an in memory tree * with more than 10 millions nodes. + * + * Adjustable via LIBXML_MAX_NODESET_LENGTH env variable. + * Absolute maximum is INT_MAX. */ -#define XPATH_MAX_NODESET_LENGTH 10000000 +#define XPATH_DEFAULT_MAX_NODESET_LENGTH 10000000 + +int +get_max_nodeset_len() { + const char *max_nodeset_len_str = getenv("LIBXML_MAX_NODESET_LENGTH"); + int max_nodeset_len = XPATH_DEFAULT_MAX_NODESET_LENGTH; + + if (max_nodeset_len_str != NULL) { + max_nodeset_len = strtol(max_nodeset_len_str, NULL, 10); + + if (max_nodeset_len <= 0 || max_nodeset_len > INT_MAX) + max_nodeset_len = XPATH_DEFAULT_MAX_NODESET_LENGTH; + } + + return max_nodeset_len; +} /* * XPATH_MAX_RECRUSION_DEPTH: @@ -2881,7 +2900,7 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, } else if (cur->nodeNr == cur->nodeMax) { xmlNodePtr *temp; - if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) + if (cur->nodeMax >= get_max_nodeset_len()) return(-1); temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 * sizeof(xmlNodePtr)); @@ -2933,7 +2952,7 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xm } else if (cur->nodeNr == cur->nodeMax) { xmlNodePtr *temp; - if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) + if (cur->nodeMax >= get_max_nodeset_len()) return(-1); temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 * sizeof(xmlNodePtr)); @@ -2983,7 +3002,7 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr c } else if (cur->nodeNr == cur->nodeMax) { xmlNodePtr *temp; - if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) + if (cur->nodeMax >= get_max_nodeset_len()) return(-1); temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 * sizeof(xmlNodePtr)); @@ -3071,7 +3090,7 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, } else if (val1->nodeNr == val1->nodeMax) { xmlNodePtr *temp; - if (val1->nodeMax >= XPATH_MAX_NODESET_LENGTH) + if (val1->nodeMax >= get_max_nodeset_len()) goto error; temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 2 * sizeof(xmlNodePtr)); @@ -3157,7 +3176,7 @@ xmlXPathNodeSetMergeAndClear(xmlNodeSetP } else if (set1->nodeNr >= set1->nodeMax) { xmlNodePtr *temp; - if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) + if (set1->nodeMax >= get_max_nodeset_len()) goto error; temp = (xmlNodePtr *) xmlRealloc( set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr)); @@ -3212,7 +3231,7 @@ xmlXPathNodeSetMergeAndClearNoDupls(xmlN } else if (set1->nodeNr >= set1->nodeMax) { xmlNodePtr *temp; - if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) + if (set1->nodeMax >= get_max_nodeset_len()) goto error; temp = (xmlNodePtr *) xmlRealloc( set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));