php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #14755 105.05$ becomes 105.5$ !!! - I found the fix.
Submitted: 2001-12-29 13:22 UTC Modified: 2002-03-06 14:53 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: giancarlo at niccolai dot ws Assigned: derick (profile)
Status: Closed Package: InterBase related
PHP Version: 4.1.1 OS: ALL
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 ws
New email:
PHP Version: OS:

 

 [2001-12-29 13:22 UTC] giancarlo at niccolai dot ws
Hello. I found a nasty bug in interbase extension, and I 
have the solution here. You have only to put it in the 
source code; I would but I don't know how to do this. I 
already posted the authors, but with no result.

104.05$ become 104.5$ !!!
When traslating scaled numeric fields (i.e. with 
decimals), the routine _php_ibase_var_pval is faulty;

here is the original code:

#ifdef SQL_INT64
   case SQL_INT64:
      val->type = IS_STRING;
      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

You can clearly see that this code is fine if the decimal 
part has no 0s before the first non 0 cipher. Here is
my correction:

#ifdef SQL_INT64
   case SQL_INT64:
      val->type = IS_STRING;
      /* Experimental section by Giancarlo Niccolai */
      if (scale) {
         int i, len;
         char dt[20];
         double number = (double) ((ISC_INT64)
			(*((ISC_INT64 *)data)));
         for (i = 0; i < -scale; i++)
            number /= 10;
         sprintf(dt, "%%0.%df", -scale);
	 val->value.str.len = sprintf (string_data, dt , 
number);
      }
      else {
	val->value.str.len = sprintf (string_data, "%Ld",
		(ISC_INT64) (*((ISC_INT64 *)data)));
      }
      /* End of experimental section */
      val->value.str.val = estrdup(string_data);
   break;
#endif


Please, since Interbase is used for e-commerce, all the 
php-interbase applications can be at risk, if the site 
deals with cents...



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-01-02 11:30 UTC] sander@php.net
This is a fix for 12383. Can somebody look into it and apply the fix?
 [2002-03-06 06:21 UTC] giancarlo at niccolai dot ws
Hi; I am the original fixer...
Noticed that 

for (i = 0; i < -scale; i++)
            number /= 10;

can be substituted with
	number /= - 10 *  scale;

with a boost on performance. (remember that interbase 
stores the "scale" as a negative number).
 [2002-03-06 06:33 UTC] derick@php.net
Assinging to me to check out before release

Derick
 [2002-03-06 14:53 UTC] derick@php.net
Fixed in CVS
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 07 22:01:27 2024 UTC