Skip to content

Fix GH-13119: Changed to convert float and double values ​​into strings using H format #13125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions ext/pdo_firebird/firebird_statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ static zend_always_inline double get_double_from_sqldata(const ISC_SCHAR *sqldat
READ_AND_RETURN_USING_MEMCPY(double, sqldata);
}

static zend_always_inline float get_float_from_sqldata(const ISC_SCHAR *sqldata)
{
READ_AND_RETURN_USING_MEMCPY(float, sqldata);
}

static zend_always_inline ISC_TIMESTAMP get_isc_timestamp_from_sqldata(const ISC_SCHAR *sqldata)
{
READ_AND_RETURN_USING_MEMCPY(ISC_TIMESTAMP, sqldata);
Expand Down Expand Up @@ -459,11 +464,11 @@ static int firebird_stmt_get_col(
break;
case SQL_FLOAT:
/* TODO: Why is this not returned as the native type? */
ZVAL_STR(result, zend_strpprintf(0, "%F", *(float*)var->sqldata));
ZVAL_STR(result, zend_strpprintf_unchecked(0, "%.8H", get_float_from_sqldata(var->sqldata)));
break;
case SQL_DOUBLE:
/* TODO: Why is this not returned as the native type? */
ZVAL_STR(result, zend_strpprintf(0, "%F", get_double_from_sqldata(var->sqldata)));
ZVAL_STR(result, zend_strpprintf_unchecked(0, "%.16H", get_double_from_sqldata(var->sqldata)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we need the unchecked variant now that we only pass one parameter. As I thought, the reason for the unchecked is to be able to pass the precision without the compiler freaking out.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!
Do you think it's better to use zend_strpprintf?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the compiler doesn't complain, yes :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you would expect, the compiler complained to me :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then the current PR is fine :)

break;
#ifdef SQL_BOOLEAN
case SQL_BOOLEAN:
Expand Down
12 changes: 6 additions & 6 deletions ext/pdo_firebird/tests/gh10908.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ Array

Array
(
[DBL] => 1.000000
[0] => 1.000000
[DBL] => 1
[0] => 1
)

Array
Expand All @@ -103,10 +103,10 @@ Array
[1] => ABC
[NUM] => 12.340
[2] => 12.340
[DBL] => 1.000000
[3] => 1.000000
[FLT] => 2.000000
[4] => 2.000000
[DBL] => 1
[3] => 1
[FLT] => 2
[4] => 2
[TS] => 2023-03-24 17:39:00
[5] => 2023-03-24 17:39:00
[MYDATE] => 2023-03-24
Expand Down
77 changes: 77 additions & 0 deletions ext/pdo_firebird/tests/gh13119.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
--TEST--
GH-13119 (float, double value is incorrect)
--EXTENSIONS--
pdo_firebird
--SKIPIF--
<?php require('skipif.inc'); ?>
--XLEAK--
A bug in firebird causes a memory leak when calling `isc_attach_database()`.
See https://github.com/FirebirdSQL/firebird/issues/7849
--FILE--
<?php

require("testdb.inc");

$dbh->exec('CREATE TABLE gh13119 (f_val FLOAT, d_val DOUBLE PRECISION)');

$dbh->exec('INSERT INTO gh13119 VALUES (0.1, 0.1)');
$dbh->exec('INSERT INTO gh13119 VALUES (0.0000000000000001, 0.0000000000000001)');
$dbh->exec('INSERT INTO gh13119 VALUES (12.000000, 12.00000000000000)');
$dbh->exec('INSERT INTO gh13119 VALUES (12.000001, 12.00000000000001)');
$dbh->exec('INSERT INTO gh13119 VALUES (12.345678, 12.34567890123456)');
$dbh->exec('INSERT INTO gh13119 VALUES (0.0000000000000000012345678, 0.000000000000000001234567890123456)');

$stmt = $dbh->query('select * from gh13119');
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
?>
--CLEAN--
<?php
require 'testdb.inc';
@$dbh->exec('DROP TABLE gh13119');
unset($dbh);
?>
--EXPECT--
array(6) {
[0]=>
array(2) {
["F_VAL"]=>
string(3) "0.1"
["D_VAL"]=>
string(3) "0.1"
}
[1]=>
array(2) {
["F_VAL"]=>
string(7) "1.0E-16"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder whether the use of scientific notation breaks BC somehow though, although in arithmetic they might not as they're numeric strings.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do the calculations, so I think it's okay.

https://3v4l.org/DL0bk

["D_VAL"]=>
string(7) "1.0E-16"
}
[2]=>
array(2) {
["F_VAL"]=>
string(2) "12"
["D_VAL"]=>
string(2) "12"
}
[3]=>
array(2) {
["F_VAL"]=>
string(9) "12.000001"
["D_VAL"]=>
string(17) "12.00000000000001"
}
[4]=>
array(2) {
["F_VAL"]=>
string(9) "12.345678"
["D_VAL"]=>
string(17) "12.34567890123456"
}
[5]=>
array(2) {
["F_VAL"]=>
string(13) "1.2345678E-18"
["D_VAL"]=>
string(21) "1.234567890123456E-18"
}
}