[libxml2] Fix XPath NaN/Inf for older GCC versions



commit d25460da14cd31ab807c77580da5a8efcacae97b
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Sat Mar 13 19:12:00 2021 +0100

    Fix XPath NaN/Inf for older GCC versions
    
    The DBL_MAX approach could lead to errors caused by excess precision.
    Switch back to the division-by-zero approach with a work-around for
    MSVC and use the extern globals instead of macro expressions.

 xpath.c | 40 +++++++++++++++++-----------------------
 1 file changed, 17 insertions(+), 23 deletions(-)
---
diff --git a/xpath.c b/xpath.c
index 6ee7e57e..4b72cff5 100644
--- a/xpath.c
+++ b/xpath.c
@@ -488,14 +488,6 @@ int wrap_cmp( xmlNodePtr x, xmlNodePtr y );
  *                                                                     *
  ************************************************************************/
 
-#ifndef INFINITY
-#define INFINITY (DBL_MAX * DBL_MAX)
-#endif
-
-#ifndef NAN
-#define NAN (INFINITY / INFINITY)
-#endif
-
 double xmlXPathNAN;
 double xmlXPathPINF;
 double xmlXPathNINF;
@@ -507,9 +499,11 @@ double xmlXPathNINF;
  */
 void
 xmlXPathInit(void) {
-    xmlXPathNAN = NAN;
-    xmlXPathPINF = INFINITY;
-    xmlXPathNINF = -INFINITY;
+    /* MSVC doesn't allow division by zero in constant expressions. */
+    double zero = 0.0;
+    xmlXPathNAN = 0.0 / zero;
+    xmlXPathPINF = 1.0 / zero;
+    xmlXPathNINF = -xmlXPathPINF;
 }
 
 /**
@@ -538,9 +532,9 @@ xmlXPathIsInf(double val) {
 #ifdef isinf
     return isinf(val) ? (val > 0 ? 1 : -1) : 0;
 #else
-    if (val >= INFINITY)
+    if (val >= xmlXPathPINF)
         return 1;
-    if (val <= -INFINITY)
+    if (val <= -xmlXPathPINF)
         return -1;
     return 0;
 #endif
@@ -5873,10 +5867,10 @@ xmlXPathCastNodeToNumber (xmlNodePtr node) {
     double ret;
 
     if (node == NULL)
-       return(NAN);
+       return(xmlXPathNAN);
     strval = xmlXPathCastNodeToString(node);
     if (strval == NULL)
-       return(NAN);
+       return(xmlXPathNAN);
     ret = xmlXPathCastStringToNumber(strval);
     xmlFree(strval);
 
@@ -5897,7 +5891,7 @@ xmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns) {
     double ret;
 
     if (ns == NULL)
-       return(NAN);
+       return(xmlXPathNAN);
     str = xmlXPathCastNodeSetToString(ns);
     ret = xmlXPathCastStringToNumber(str);
     xmlFree(str);
@@ -5917,13 +5911,13 @@ xmlXPathCastToNumber(xmlXPathObjectPtr val) {
     double ret = 0.0;
 
     if (val == NULL)
-       return(NAN);
+       return(xmlXPathNAN);
     switch (val->type) {
     case XPATH_UNDEFINED:
 #ifdef DEBUG_EXPR
        xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n");
 #endif
-       ret = NAN;
+       ret = xmlXPathNAN;
        break;
     case XPATH_NODESET:
     case XPATH_XSLT_TREE:
@@ -5943,7 +5937,7 @@ xmlXPathCastToNumber(xmlXPathObjectPtr val) {
     case XPATH_RANGE:
     case XPATH_LOCATIONSET:
        TODO;
-       ret = NAN;
+       ret = xmlXPathNAN;
        break;
     }
     return(ret);
@@ -7570,7 +7564,7 @@ xmlXPathModValues(xmlXPathParserContextPtr ctxt) {
     CHECK_TYPE(XPATH_NUMBER);
     arg1 = ctxt->value->floatval;
     if (arg2 == 0)
-       ctxt->value->floatval = NAN;
+       ctxt->value->floatval = xmlXPathNAN;
     else {
        ctxt->value->floatval = fmod(arg1, arg2);
     }
@@ -10000,7 +9994,7 @@ xmlXPathStringEvalNumber(const xmlChar *str) {
     if (cur == NULL) return(0);
     while (IS_BLANK_CH(*cur)) cur++;
     if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) {
-        return(NAN);
+        return(xmlXPathNAN);
     }
     if (*cur == '-') {
        isneg = 1;
@@ -10036,7 +10030,7 @@ xmlXPathStringEvalNumber(const xmlChar *str) {
 
         cur++;
        if (((*cur < '0') || (*cur > '9')) && (!ok)) {
-           return(NAN);
+           return(xmlXPathNAN);
        }
         while (*cur == '0') {
            frac = frac + 1;
@@ -10069,7 +10063,7 @@ xmlXPathStringEvalNumber(const xmlChar *str) {
       }
     }
     while (IS_BLANK_CH(*cur)) cur++;
-    if (*cur != 0) return(NAN);
+    if (*cur != 0) return(xmlXPathNAN);
     if (isneg) ret = -ret;
     if (is_exponent_negative) exponent = -exponent;
     ret *= pow(10.0, (double)exponent);


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