summaryrefslogtreecommitdiff
path: root/xpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'xpath.c')
-rw-r--r--xpath.c50
1 files changed, 34 insertions, 16 deletions
diff --git a/xpath.c b/xpath.c
index 8c35e30..8f6545a 100644
--- a/xpath.c
+++ b/xpath.c
@@ -2648,9 +2648,10 @@ xmlXPathPopExternal (xmlXPathParserContextPtr ctxt) {
#define UPPER_DOUBLE 1E9
#define LOWER_DOUBLE 1E-5
+#define LOWER_DOUBLE_EXP 5
#define INTEGER_DIGITS DBL_DIG
-#define FRACTION_DIGITS (DBL_DIG + 1)
+#define FRACTION_DIGITS (DBL_DIG + 1 + (LOWER_DOUBLE_EXP))
#define EXPONENT_DIGITS (3 + 2)
/**
@@ -2701,8 +2702,16 @@ xmlXPathFormatNumber(double number, char buffer[], int buffersize)
*ptr = 0;
}
} else {
- /* 3 is sign, decimal point, and terminating zero */
- char work[DBL_DIG + EXPONENT_DIGITS + 3];
+ /*
+ For the dimension of work,
+ DBL_DIG is number of significant digits
+ EXPONENT is only needed for "scientific notation"
+ 3 is sign, decimal point, and terminating zero
+ LOWER_DOUBLE_EXP is max number of leading zeroes in fraction
+ Note that this dimension is slightly (a few characters)
+ larger than actually necessary.
+ */
+ char work[DBL_DIG + EXPONENT_DIGITS + 3 + LOWER_DOUBLE_EXP];
int integer_place, fraction_place;
char *ptr;
char *after_fraction;
@@ -2725,24 +2734,25 @@ xmlXPathFormatNumber(double number, char buffer[], int buffersize)
size = snprintf(work, sizeof(work),"%*.*e",
integer_place, fraction_place, number);
while ((size > 0) && (work[size] != 'e')) size--;
- after_fraction = work + size;
}
else {
/* Use regular notation */
- if (absolute_value > 0.0)
- integer_place = 1 + (int)log10(absolute_value);
- else
- integer_place = 0;
- fraction_place = (integer_place > 0)
- ? DBL_DIG - integer_place
- : DBL_DIG;
+ if (absolute_value > 0.0) {
+ integer_place = (int)log10(absolute_value);
+ if (integer_place > 0)
+ fraction_place = DBL_DIG - integer_place - 1;
+ else
+ fraction_place = DBL_DIG - integer_place;
+ } else {
+ fraction_place = 1;
+ }
size = snprintf(work, sizeof(work), "%0.*f",
fraction_place, number);
- after_fraction = work + size;
}
/* Remove fractional trailing zeroes */
+ after_fraction = work + size;
ptr = after_fraction;
while (*(--ptr) == '0')
;
@@ -3184,6 +3194,11 @@ xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
turtle_comparison:
+ if (miscNode1 != NULL)
+ node1 = miscNode1;
+ if (miscNode2 != NULL)
+ node2 = miscNode2;
+
if (node1 == node2->prev)
return(1);
if (node1 == node2->next)
@@ -4602,12 +4617,13 @@ xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) {
return(ret);
l = xmlXPathNodeSetGetLength(nodes);
- for (i = l; i > 0; i--) {
+ for (i = l - 1; i >= 0; i--) {
cur = xmlXPathNodeSetItem(nodes, i);
if (cur == node)
break;
xmlXPathNodeSetAddUnique(ret, cur);
}
+ xmlXPathNodeSetSort(ret); /* bug 413451 */
return(ret);
}
@@ -5573,7 +5589,10 @@ xmlXPathCastNumberToString (double val) {
*/
xmlChar *
xmlXPathCastNodeToString (xmlNodePtr node) {
- return(xmlNodeGetContent(node));
+xmlChar *ret;
+ if ((ret = xmlNodeGetContent(node)) == NULL)
+ ret = xmlStrdup((const xmlChar *) "");
+ return(ret);
}
/**
@@ -14678,8 +14697,7 @@ xmlXPathCompiledEvalInternal(xmlXPathCompExprPtr comp,
do {
tmp = valuePop(pctxt);
if (tmp != NULL) {
- if (tmp != NULL)
- stack++;
+ stack++;
xmlXPathReleaseObject(ctxt, tmp);
}
} while (tmp != NULL);