diff options
author | Antony Dovgal <tony2001@php.net> | 2006-02-14 22:10:55 +0000 |
---|---|---|
committer | Antony Dovgal <tony2001@php.net> | 2006-02-14 22:10:55 +0000 |
commit | d43d0903624204fbfc88e235a0abc1e3597d5488 (patch) | |
tree | 893f464d5c07a70d959bc243e2ab33d64e1020a1 | |
parent | 3608dd4c11827b8db5f610c95e4beab84cb8b0b7 (diff) | |
download | php-git-d43d0903624204fbfc88e235a0abc1e3597d5488.tar.gz |
fix leak in zend_strtod() on big doubles
add new test
-rw-r--r-- | Zend/tests/zend_strtod.phpt | 17 | ||||
-rw-r--r-- | Zend/zend_strtod.c | 18 |
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; } |