diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index 4ad51ab483d96..1fe894cd631df 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -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); @@ -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))); break; #ifdef SQL_BOOLEAN case SQL_BOOLEAN: diff --git a/ext/pdo_firebird/tests/gh10908.phpt b/ext/pdo_firebird/tests/gh10908.phpt index a1e8271ffd19b..bcd3bb1e20024 100644 --- a/ext/pdo_firebird/tests/gh10908.phpt +++ b/ext/pdo_firebird/tests/gh10908.phpt @@ -79,8 +79,8 @@ Array Array ( - [DBL] => 1.000000 - [0] => 1.000000 + [DBL] => 1 + [0] => 1 ) Array @@ -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 diff --git a/ext/pdo_firebird/tests/gh13119.phpt b/ext/pdo_firebird/tests/gh13119.phpt new file mode 100644 index 0000000000000..29524e3d3bf95 --- /dev/null +++ b/ext/pdo_firebird/tests/gh13119.phpt @@ -0,0 +1,77 @@ +--TEST-- +GH-13119 (float, double value is incorrect) +--EXTENSIONS-- +pdo_firebird +--SKIPIF-- + +--XLEAK-- +A bug in firebird causes a memory leak when calling `isc_attach_database()`. +See https://github.com/FirebirdSQL/firebird/issues/7849 +--FILE-- +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-- +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" + ["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" + } +}