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:
40
xpath.c
40
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 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);
|
||||||
|
Reference in New Issue
Block a user