From: [EMAIL PROTECTED]
Operating system: LINUX
PHP version: 4.0.6
PHP Bug Type: InterBase related
Bug description: $105.04 becomes $105.4!!!
AAAARRRRGGG!! Interbase module has this orrible bug. It
transforms any BIG INTEGER (ISC_INT64) type with decimal
points are stripped of it's zeroes between decimal point
and the first non-zero decimal cipher
I.E. 150.0045 becomes 150.45.
This bug is very fast to find in the code, because the
transformation from Interbase to PHP data is done with an
instruction like
sprintf (buffer, "%f.%f", [find integer part], [find
fractional part]); and no control over the zeroes in the
fractional part. Even wrose, this calculus are done with 2
heavy double "pow" calls, divisions and modules (with an
horrible waste of time...
Now, if I had done an error like that in a programming
execice, my teacher would have given "2" to me, (that is,
F), even if I have studied Economics, not IT. How could
this error have survived since now? It could cost a very
high price for users, if you think that all the
transactions in dollars, euros, punds and any currency
with a fractional part IS WRONG!
Now, I have patced the source; find the static int
_php_ibase_var_pval function in the interbase.c file, ad
substitute what is inside the #ifdef SQL_INT64 with the
following code:
#ifdef SQL_INT64
case SQL_INT64:
/* Experimental section by Giancarlo
Niccolai */
if (scale) {
int i, len;
sprintf (string_data, "%Ld",
(ISC_INT64) (*((ISC_INT64 *)data)));
len = strlen(string_data);
for (i = 0; i <= -scale; i ++)
string_data[len-i+1] =
string_data[len-i];
string_data[len-i+1] = '.';
val->value.str.len = len+1;
val->value.str.val =
estrdup(string_data);
}
else {
val->value.str.len = sprintf
(string_data, "%Ld", (ISC_INT64) (*((ISC_INT64 *)data)));
val->type = IS_STRING;
val->value.str.val =
estrdup(string_data);
}
/* End of experimental section */
val->type = IS_STRING;
/* OLD CODE */
/*val->value.str.len =
sprintf(string_data, "%Ld.%Ld",
(ISC_INT64) (*((ISC_INT64 *)data)
/ (int) pow(10.0, (double) -scale)),
(ISC_INT64) abs((int)
(*((ISC_INT64 *)data) % (int) pow(10.0, (double)
-scale))));
val->value.str.val =
estrdup(string_data);*/
break;
#endif
The code is faster (you'll have in the wrost case of all
about 18 iterations on a char array), cleaner and work
always.
Now, I hope you'll put this code in the PHP dists as soon
as possible, and give a STRONG evidence of this problem in
your site, possibily warining all PHP-INTERBASE users,
that, as I know, are a LOT.
P.S. I found the same error in the PERL DBD::Interbase
module; I will soon track it down and send a remark to the
perl community.
Thanks in advance,
Giancarlo Niccolai.
--
Edit bug report at: http://bugs.php.net/?id=12383&edit=1
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]