summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2021-03-13 19:12:00 +0100
committerNick Wellnhofer <wellnhofer@aevum.de>2021-03-13 19:14:27 +0100
commitd25460da14cd31ab807c77580da5a8efcacae97b (patch)
tree35b6152b51cb912bb763c0439154f55b763a23a3
parente20c9c148c725e2933efa143ee6a543a5cae4204 (diff)
downloadlibxml2-d25460da14cd31ab807c77580da5a8efcacae97b.tar.gz
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.
-rw-r--r--xpath.c40
1 files 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);