]> granicus.if.org Git - php/commitdiff
MF51:
authorAntony Dovgal <tony2001@php.net>
Tue, 14 Feb 2006 22:11:36 +0000 (22:11 +0000)
committerAntony Dovgal <tony2001@php.net>
Tue, 14 Feb 2006 22:11:36 +0000 (22:11 +0000)
fix leak in zend_strtod() on big doubles
add new test

Zend/tests/zend_strtod.phpt [new file with mode: 0644]
Zend/zend_strtod.c

diff --git a/Zend/tests/zend_strtod.phpt b/Zend/tests/zend_strtod.phpt
new file mode 100644 (file)
index 0000000..32d1c0a
--- /dev/null
@@ -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
index 1810c5bf2743f67c06a728848afab668181eaa18..3a50af29c82137e4eed5a94626851d2e63491f94 100644 (file)
@@ -1252,7 +1252,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 = '.';
@@ -1778,6 +1778,22 @@ 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;
        }