summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Dovgal <tony2001@php.net>2006-02-14 22:10:55 +0000
committerAntony Dovgal <tony2001@php.net>2006-02-14 22:10:55 +0000
commitd43d0903624204fbfc88e235a0abc1e3597d5488 (patch)
tree893f464d5c07a70d959bc243e2ab33d64e1020a1
parent3608dd4c11827b8db5f610c95e4beab84cb8b0b7 (diff)
downloadphp-git-d43d0903624204fbfc88e235a0abc1e3597d5488.tar.gz
fix leak in zend_strtod() on big doubles
add new test
-rw-r--r--Zend/tests/zend_strtod.phpt17
-rw-r--r--Zend/zend_strtod.c18
2 files changed, 34 insertions, 1 deletions
diff --git a/Zend/tests/zend_strtod.phpt b/Zend/tests/zend_strtod.phpt
new file mode 100644
index 0000000000..32d1c0abae
--- /dev/null
+++ b/Zend/tests/zend_strtod.phpt
@@ -0,0 +1,17 @@
+--TEST--
+zend_strtod() leaks on big doubles
+--FILE--
+<?php
+var_dump("1139932690.21688500" - "1139932790.21688500");
+var_dump("1139932690000.21688500" - "331139932790.21688500");
+var_dump("339932690.21688500" - "4564645646456463461139932790.21688500");
+var_dump("123123139932690.21688500" - "11399327900000000.21688500");
+
+echo "Done\n";
+?>
+--EXPECTF--
+float(-100)
+float(808792757210)
+float(-4.5646456464565E+27)
+float(-11276204760067000)
+Done
diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c
index 87d755006a..3ad2c5f155 100644
--- a/Zend/zend_strtod.c
+++ b/Zend/zend_strtod.c
@@ -1250,7 +1250,7 @@ zend_strtod
_double rv, rv0;
Long L;
ULong y, z;
- Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+ Bigint *bb, *bb1, *bd, *bd0, *bs, *delta, *tmp;
double result;
CONST char decimal_point = '.';
@@ -1776,5 +1776,21 @@ zend_strtod
if (se)
*se = (char *)s;
result = sign ? -value(rv) : value(rv);
+
+ for (i = 0; i <= Kmax; i++) {
+ Bigint **listp = &freelist[i];
+ while ((tmp = *listp) != NULL) {
+ *listp = tmp->next;
+ free(tmp);
+ }
+ freelist[i] = NULL;
+ }
+
+ while (p5s) {
+ tmp = p5s;
+ p5s = p5s->next;
+ free(tmp);
+ }
+
return result;
}