DO NOT MERGE: Heap buffer overflow in xmlAddID
am: 188e4b516f -s ours
Change-Id: Ie4cc090745ae044b8e4802cdc78079dd8aeb0018
diff --git a/parser.c b/parser.c
index 63ae15f..53a6b7f 100644
--- a/parser.c
+++ b/parser.c
@@ -3420,15 +3420,8 @@
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
return(NULL);
}
- if (ctxt->input->cur > ctxt->input->base && (*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r')) {
- if (ctxt->input->base > ctxt->input->cur - (len + 1)) {
- return(NULL);
- }
+ if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
- }
- if (ctxt->input->base > ctxt->input->cur - len) {
- return(NULL);
- }
return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
}
@@ -8130,14 +8123,6 @@
if (xmlPushInput(ctxt, input) < 0)
return;
} else {
- if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
- ((ctxt->options & XML_PARSE_NOENT) == 0) &&
- ((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
- ((ctxt->options & XML_PARSE_DTDLOAD) == 0) &&
- ((ctxt->options & XML_PARSE_DTDATTR) == 0) &&
- (ctxt->replaceEntities == 0) &&
- (ctxt->validate == 0))
- return;
/*
* TODO !!!
* handle the extra spaces added before and after
diff --git a/uri.c b/uri.c
index b11a8a1..d7f32fc 100644
--- a/uri.c
+++ b/uri.c
@@ -12,7 +12,6 @@
#include "libxml.h"
#include <string.h>
-#include <limits.h>
#include <libxml/xmlmemory.h>
#include <libxml/uri.h>
@@ -335,7 +334,7 @@
cur++;
}
if (uri != NULL)
- uri->port = port & USHRT_MAX; /* port value modulo INT_MAX+1 */
+ uri->port = port & INT_MAX; /* port value modulo INT_MAX+1 */
*str = cur;
return(0);
}
diff --git a/valid.c b/valid.c
index aee6f40..19f84b8 100644
--- a/valid.c
+++ b/valid.c
@@ -4623,13 +4623,13 @@
/* Validity Constraint: ID uniqueness */
if (attrDecl->atype == XML_ATTRIBUTE_ID) {
- if (xmlAddID(ctxt, doc, value, (xmlAttrPtr) attrDecl) == NULL)
+ if (xmlAddID(ctxt, doc, value, (xmlAttrPtr) ns) == NULL)
ret = 0;
}
if ((attrDecl->atype == XML_ATTRIBUTE_IDREF) ||
(attrDecl->atype == XML_ATTRIBUTE_IDREFS)) {
- if (xmlAddRef(ctxt, doc, value, (xmlAttrPtr) attrDecl) == NULL)
+ if (xmlAddRef(ctxt, doc, value, (xmlAttrPtr) ns) == NULL)
ret = 0;
}
diff --git a/xpath.c b/xpath.c
index 2dbced4..06897c7 100644
--- a/xpath.c
+++ b/xpath.c
@@ -4368,7 +4368,7 @@
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
ret->type = XPATH_XSLT_TREE;
- ret->boolval = 0;
+ ret->boolval = 1;
ret->user = (void *) val;
ret->nodesetval = xmlXPathNodeSetCreate(val);
#ifdef XP_DEBUG_OBJ_USAGE
@@ -10691,18 +10691,13 @@
lc = 1;
break;
} else if ((NXT(len) == '(')) {
- /* Node Type or Function */
+ /* Note Type or Function */
if (xmlXPathIsNodeType(name)) {
#ifdef DEBUG_STEP
xmlGenericError(xmlGenericErrorContext,
"PathExpr: Type search\n");
#endif
lc = 1;
-#ifdef LIBXML_XPTR_ENABLED
- } else if (ctxt->xptr &&
- xmlStrEqual(name, BAD_CAST "range-to")) {
- lc = 1;
-#endif
} else {
#ifdef DEBUG_STEP
xmlGenericError(xmlGenericErrorContext,
diff --git a/xpointer.c b/xpointer.c
index d8a2e59..676c510 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -320,45 +320,6 @@
}
/**
- * xmlXPtrNewRangeInternal:
- * @start: the starting node
- * @startindex: the start index
- * @end: the ending point
- * @endindex: the ending index
- *
- * Internal function to create a new xmlXPathObjectPtr of type range
- *
- * Returns the newly created object.
- */
-static xmlXPathObjectPtr
-xmlXPtrNewRangeInternal(xmlNodePtr start, int startindex,
- xmlNodePtr end, int endindex) {
- xmlXPathObjectPtr ret;
-
- /*
- * Namespace nodes must be copied (see xmlXPathNodeSetDupNs).
- * Disallow them for now.
- */
- if ((start != NULL) && (start->type == XML_NAMESPACE_DECL))
- return(NULL);
- if ((end != NULL) && (end->type == XML_NAMESPACE_DECL))
- return(NULL);
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlXPtrErrMemory("allocating range");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlXPathObject));
- ret->type = XPATH_RANGE;
- ret->user = start;
- ret->index = startindex;
- ret->user2 = end;
- ret->index2 = endindex;
- return(ret);
-}
-
-/**
* xmlXPtrNewRange:
* @start: the starting node
* @startindex: the start index
@@ -383,7 +344,17 @@
if (endindex < 0)
return(NULL);
- ret = xmlXPtrNewRangeInternal(start, startindex, end, endindex);
+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+ if (ret == NULL) {
+ xmlXPtrErrMemory("allocating range");
+ return(NULL);
+ }
+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+ ret->type = XPATH_RANGE;
+ ret->user = start;
+ ret->index = startindex;
+ ret->user2 = end;
+ ret->index2 = endindex;
xmlXPtrRangeCheckOrder(ret);
return(ret);
}
@@ -410,8 +381,17 @@
if (end->type != XPATH_POINT)
return(NULL);
- ret = xmlXPtrNewRangeInternal(start->user, start->index, end->user,
- end->index);
+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+ if (ret == NULL) {
+ xmlXPtrErrMemory("allocating range");
+ return(NULL);
+ }
+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+ ret->type = XPATH_RANGE;
+ ret->user = start->user;
+ ret->index = start->index;
+ ret->user2 = end->user;
+ ret->index2 = end->index;
xmlXPtrRangeCheckOrder(ret);
return(ret);
}
@@ -436,7 +416,17 @@
if (start->type != XPATH_POINT)
return(NULL);
- ret = xmlXPtrNewRangeInternal(start->user, start->index, end, -1);
+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+ if (ret == NULL) {
+ xmlXPtrErrMemory("allocating range");
+ return(NULL);
+ }
+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+ ret->type = XPATH_RANGE;
+ ret->user = start->user;
+ ret->index = start->index;
+ ret->user2 = end;
+ ret->index2 = -1;
xmlXPtrRangeCheckOrder(ret);
return(ret);
}
@@ -463,7 +453,17 @@
if (end->type != XPATH_POINT)
return(NULL);
- ret = xmlXPtrNewRangeInternal(start, -1, end->user, end->index);
+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+ if (ret == NULL) {
+ xmlXPtrErrMemory("allocating range");
+ return(NULL);
+ }
+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+ ret->type = XPATH_RANGE;
+ ret->user = start;
+ ret->index = -1;
+ ret->user2 = end->user;
+ ret->index2 = end->index;
xmlXPtrRangeCheckOrder(ret);
return(ret);
}
@@ -486,7 +486,17 @@
if (end == NULL)
return(NULL);
- ret = xmlXPtrNewRangeInternal(start, -1, end, -1);
+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+ if (ret == NULL) {
+ xmlXPtrErrMemory("allocating range");
+ return(NULL);
+ }
+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+ ret->type = XPATH_RANGE;
+ ret->user = start;
+ ret->index = -1;
+ ret->user2 = end;
+ ret->index2 = -1;
xmlXPtrRangeCheckOrder(ret);
return(ret);
}
@@ -506,7 +516,17 @@
if (start == NULL)
return(NULL);
- ret = xmlXPtrNewRangeInternal(start, -1, NULL, -1);
+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+ if (ret == NULL) {
+ xmlXPtrErrMemory("allocating range");
+ return(NULL);
+ }
+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+ ret->type = XPATH_RANGE;
+ ret->user = start;
+ ret->index = -1;
+ ret->user2 = NULL;
+ ret->index2 = -1;
return(ret);
}
@@ -521,8 +541,6 @@
*/
xmlXPathObjectPtr
xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
- xmlNodePtr endNode;
- int endIndex;
xmlXPathObjectPtr ret;
if (start == NULL)
@@ -531,12 +549,7 @@
return(NULL);
switch (end->type) {
case XPATH_POINT:
- endNode = end->user;
- endIndex = end->index;
- break;
case XPATH_RANGE:
- endNode = end->user2;
- endIndex = end->index2;
break;
case XPATH_NODESET:
/*
@@ -544,15 +557,39 @@
*/
if (end->nodesetval->nodeNr <= 0)
return(NULL);
- endNode = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
- endIndex = -1;
break;
default:
/* TODO */
return(NULL);
}
- ret = xmlXPtrNewRangeInternal(start, -1, endNode, endIndex);
+ ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+ if (ret == NULL) {
+ xmlXPtrErrMemory("allocating range");
+ return(NULL);
+ }
+ memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+ ret->type = XPATH_RANGE;
+ ret->user = start;
+ ret->index = -1;
+ switch (end->type) {
+ case XPATH_POINT:
+ ret->user2 = end->user;
+ ret->index2 = end->index;
+ break;
+ case XPATH_RANGE:
+ ret->user2 = end->user2;
+ ret->index2 = end->index2;
+ break;
+ case XPATH_NODESET: {
+ ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
+ ret->index2 = -1;
+ break;
+ }
+ default:
+ STRANGE
+ return(NULL);
+ }
xmlXPtrRangeCheckOrder(ret);
return(ret);
}
@@ -1295,6 +1332,8 @@
ret->here = here;
ret->origin = origin;
+ xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",
+ xmlXPtrRangeToFunction);
xmlXPathRegisterFunc(ret, (xmlChar *)"range",
xmlXPtrRangeFunction);
xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",
@@ -2204,14 +2243,76 @@
* @nargs: the number of args
*
* Implement the range-to() XPointer function
- *
- * Obsolete. range-to is not a real function but a special type of location
- * step which is handled in xpath.c.
*/
void
-xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt,
- int nargs ATTRIBUTE_UNUSED) {
- XP_ERROR(XPATH_EXPR_ERROR);
+xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+ xmlXPathObjectPtr range;
+ const xmlChar *cur;
+ xmlXPathObjectPtr res, obj;
+ xmlXPathObjectPtr tmp;
+ xmlLocationSetPtr newset = NULL;
+ xmlNodeSetPtr oldset;
+ int i;
+
+ if (ctxt == NULL) return;
+ CHECK_ARITY(1);
+ /*
+ * Save the expression pointer since we will have to evaluate
+ * it multiple times. Initialize the new set.
+ */
+ CHECK_TYPE(XPATH_NODESET);
+ obj = valuePop(ctxt);
+ oldset = obj->nodesetval;
+ ctxt->context->node = NULL;
+
+ cur = ctxt->cur;
+ newset = xmlXPtrLocationSetCreate(NULL);
+
+ for (i = 0; i < oldset->nodeNr; i++) {
+ ctxt->cur = cur;
+
+ /*
+ * Run the evaluation with a node list made of a single item
+ * in the nodeset.
+ */
+ ctxt->context->node = oldset->nodeTab[i];
+ tmp = xmlXPathNewNodeSet(ctxt->context->node);
+ valuePush(ctxt, tmp);
+
+ xmlXPathEvalExpr(ctxt);
+ CHECK_ERROR;
+
+ /*
+ * The result of the evaluation need to be tested to
+ * decided whether the filter succeeded or not
+ */
+ res = valuePop(ctxt);
+ range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res);
+ if (range != NULL) {
+ xmlXPtrLocationSetAdd(newset, range);
+ }
+
+ /*
+ * Cleanup
+ */
+ if (res != NULL)
+ xmlXPathFreeObject(res);
+ if (ctxt->value == tmp) {
+ res = valuePop(ctxt);
+ xmlXPathFreeObject(res);
+ }
+
+ ctxt->context->node = NULL;
+ }
+
+ /*
+ * The result is used as the new evaluation set.
+ */
+ xmlXPathFreeObject(obj);
+ ctxt->context->node = NULL;
+ ctxt->context->contextSize = -1;
+ ctxt->context->proximityPosition = -1;
+ valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
}
/**