php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #12383 $105.04 becomes $105.4!!!
Submitted: 2001-07-25 19:53 UTC Modified: 2002-03-06 14:50 UTC
From: giancarlo at niccolai dot org Assigned:
Status: Closed Package: InterBase related
PHP Version: 4.0.6 OS: LINUX
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: giancarlo at niccolai dot org
New email:
PHP Version: OS:

 

 [2001-07-25 19:53 UTC] giancarlo at niccolai dot org
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.



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-03-06 14:50 UTC] derick@php.net
Fixed in CVS, thx for this excellent report.

Derick
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 30 14:01:28 2024 UTC