Re: bug in zend_multiply.h
| From: | Ard Biesheuvel | Date: | Sat, 13 Mar 2004 11:25:12 +0000 |
| Subject: | Re: bug in zend_multiply.h | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-8501@lists.php.net to get a copy of this message | ||
Andi Gutmans wrote:
Can you run this by Sascha <sascha@schumann.cx> who wrote this code?I sent him a message but he never responded. -- Ard > Thanks, > > Andi > > At 04:50 PM 3/9/2004 +0100, Ard Biesheuvel wrote: > >> This code fails on 64-bit archs because it relies on the accuracy of a >> double to be sufficient to represent LONG_MAX. The patch adresses it >> by checking for overflow by reversing the calculation instead of >> casting to a double and back to long. >> >> >> #include "build/php5-cvs/Zend/zend_multiply.h" >> >> #define LONG_MIN (1L << (8*sizeof(long)-1)) >> #define LONG_MAX ~LONG_MIN >> >> int main() >> { >> long res = 0; >> double d = 0; >> int overflow; >> >> /* obviously (LONG_MAX-1) * 1 can be represented by a long */ >> ZEND_SIGNED_MULTIPLY_LONG(LONG_MAX-1,1,res,d,overflow); >> >> printf("res: %ld/%.4f, %soverflow\n", result, d, overflow?"":"no "); >> return 0; >> } >> >> >> >> -- >> Ard >> >> >> --- Zend/zend_multiply.h Sun Mar 7 13:59:35 2004 >> +++ Zend/zend_multiply.h.new Wed Mar 3 09:14:04 2004 >> @@ -33,13 +33,13 @@ >> #else >> >> #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \ >> - double __tmpvar = (double) (a) * (double) >> (b); \ >> + long __tmpvar = (a) * (b); \ >> >> \ >> - if (__tmpvar >= LONG_MAX || __tmpvar <= LONG_MIN) >> { \ >> - (dval) = __tmpvar; \ >> + if ((a) != 0 && __tmpvar / (a) != (b)) >> { \ >> + (dval) = (double)(a) * >> (double)(b); \ >> (usedval) = 1; \ >> } else { \ >> - (lval) = (a) * (b); \ >> + (lval) = __tmpvar; \ >> (usedval) = 0; \ >> } >> \ >> } while (0) >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php