SPECS/libxml2/libxml2-2.9.4-support-cve-2016-5131.patch
2281892e
 From d77e5fc4bcdb7da748c9cca116a601ae4df60d21
 To a005199330b86dada19d162cae15ef9bdcb6baa8
 Bring upstream patches to support CVE-2016-5131 fix
 as one of the tests failed with just applying the CVE fix.
 
 diff --git a/relaxng.c b/relaxng.c
 index 56a3344..3d3e69c 100644
 --- a/relaxng.c
 +++ b/relaxng.c
 @@ -2088,6 +2088,7 @@ xmlRelaxNGGetErrorString(xmlRelaxNGValidErr err, const xmlChar * arg1,
                           const xmlChar * arg2)
  {
      char msg[1000];
 +    xmlChar *result;
  
      if (arg1 == NULL)
          arg1 = BAD_CAST "";
 @@ -2215,7 +2216,7 @@ xmlRelaxNGGetErrorString(xmlRelaxNGValidErr err, const xmlChar * arg1,
          snprintf(msg, 1000, "Unknown error code %d\n", err);
      }
      msg[1000 - 1] = 0;
 -    xmlChar *result = xmlCharStrdup(msg);
 +    result = xmlCharStrdup(msg);
      return (xmlEscapeFormatString(&result));
  }
  
 diff --git a/result/XPath/xptr/viderror b/result/XPath/xptr/viderror
 new file mode 100644
 index 0000000..d589882
 --- /dev/null
 +++ b/result/XPath/xptr/viderror
 @@ -0,0 +1,4 @@
 +
 +========================
 +Expression: xpointer(non-existing-fn()/range-to(id('chapter2')))
 +Object is empty (NULL)
 diff --git a/runtest.c b/runtest.c
 index bb74d2a..1861577 100644
 --- a/runtest.c
 +++ b/runtest.c
 @@ -2317,10 +2317,19 @@ static FILE *xpathOutput;
  static xmlDocPtr xpathDocument;
  
  static void
 +ignoreGenericError(void *ctx ATTRIBUTE_UNUSED,
 +        const char *msg ATTRIBUTE_UNUSED, ...) {
 +}
 +
 +static void
  testXPath(const char *str, int xptr, int expr) {
 +    xmlGenericErrorFunc handler = ignoreGenericError;
      xmlXPathObjectPtr res;
      xmlXPathContextPtr ctxt;
  
 +    /* Don't print generic errors to stderr. */
 +    initGenericErrorDefaultFunc(&handler);
 +
      nb_tests++;
  #if defined(LIBXML_XPTR_ENABLED)
      if (xptr) {
 @@ -2349,6 +2358,9 @@ testXPath(const char *str, int xptr, int expr) {
      xmlXPathDebugDumpObject(xpathOutput, res, 0);
      xmlXPathFreeObject(res);
      xmlXPathFreeContext(ctxt);
 +
 +    /* Reset generic error handler. */
 +    initGenericErrorDefaultFunc(NULL);
  }
  
  /**
 diff --git a/test/XPath/xptr/viderror b/test/XPath/xptr/viderror
 new file mode 100644
 index 0000000..da8c53b
 --- /dev/null
 +++ b/test/XPath/xptr/viderror
 @@ -0,0 +1 @@
 +xpointer(non-existing-fn()/range-to(id('chapter2')))
 diff --git a/xmlschemas.c b/xmlschemas.c
 index e1b3a4f..d42afb7 100644
 --- a/xmlschemas.c
 +++ b/xmlschemas.c
 @@ -3168,8 +3168,8 @@ xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
  		"valid.");
  	}
  	if (expected) {
 -	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
  	    xmlChar *expectedEscaped = xmlCharStrdup(expected);
 +	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
  	    msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
  	    FREE_AND_NULL(expectedEscaped);
  	    msg = xmlStrcat(msg, BAD_CAST "'.\n");
 @@ -27391,6 +27391,7 @@ xmlSchemaSAXHandleStartElementNs(void *ctx,
      * attributes yet.
      */
      if (nb_attributes != 0) {
 +	int valueLen, k, l;
  	xmlChar *value;
  
          for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
 @@ -27400,12 +27401,31 @@ xmlSchemaSAXHandleStartElementNs(void *ctx,
  	    * libxml2 differs from normal SAX here in that it escapes all ampersands
  	    * as &#38; instead of delivering the raw converted string. Changing the
  	    * behavior at this point would break applications that use this API, so
 -	    * we are forced to work around it. There is no danger of accidentally
 -	    * decoding some entity other than &#38; in this step because without
 -	    * unescaped ampersands there can be no other entities in the string.
 +	    * we are forced to work around it.
  	    */
 -	    value = xmlStringLenDecodeEntities(vctxt->parserCtxt, attributes[j+3],
 -		attributes[j+4] - attributes[j+3], XML_SUBSTITUTE_REF, 0, 0, 0);
 +	    valueLen = attributes[j+4] - attributes[j+3];
 +	    value = xmlMallocAtomic(valueLen + 1);
 +	    if (value == NULL) {
 +		xmlSchemaVErrMemory(vctxt,
 +		    "allocating string for decoded attribute",
 +		    NULL);
 +		goto internal_error;
 +	    }
 +	    for (k = 0, l = 0; k < valueLen; l++) {
 +		if (k < valueLen - 4 &&
 +		    attributes[j+3][k+0] == '&' &&
 +		    attributes[j+3][k+1] == '#' &&
 +		    attributes[j+3][k+2] == '3' &&
 +		    attributes[j+3][k+3] == '8' &&
 +		    attributes[j+3][k+4] == ';') {
 +		    value[l] = '&';
 +		    k += 5;
 +		} else {
 +		    value[l] = attributes[j+3][k];
 +		    k++;
 +		}
 +	    }
 +	    value[l] = '\0';
  	    /*
  	    * TODO: Set the node line.
  	    */
 diff --git a/xpath.c b/xpath.c
 index 113bce6..d992841 100644
 --- a/xpath.c
 +++ b/xpath.c
 @@ -3342,13 +3342,13 @@ xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
       * compute depth to root
       */
      for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
 -	if (cur == node1)
 +	if (cur->parent == node1)
  	    return(1);
  	depth2++;
      }
      root = cur;
      for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
 -	if (cur == node2)
 +	if (cur->parent == node2)
  	    return(-1);
  	depth1++;
      }
 @@ -14005,9 +14005,14 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
                  xmlNodeSetPtr oldset;
                  int i, j;
  
 -                if (op->ch1 != -1)
 +                if (op->ch1 != -1) {
                      total +=
                          xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
 +                    CHECK_ERROR0;
 +                }
 +                if (ctxt->value == NULL) {
 +                    XP_ERROR0(XPATH_INVALID_OPERAND);
 +                }
                  if (op->ch2 == -1)
                      return (total);