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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
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: Tue Dec 03 05:01:32 2024 UTC