1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-23 01:52:48 +03:00

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.
This commit is contained in:
Nick Wellnhofer
2021-03-13 19:12:00 +01:00
parent e20c9c148c
commit d25460da14

40
xpath.c
View File

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