From fa751c7dd62406c44f739c0277796561010915b5 Mon Sep 17 00:00:00 2001 From: SakiTakamachi Date: Sun, 14 Jan 2024 00:30:21 +0900 Subject: [PATCH] Fix GH-13119 (#13125) Fixed an issue where pdo_firebird float and double type values were wrong. Changed from using `%F` format with `zend_strpprintf` to using `%H` format with `zend_strpprintf_unchecked`. Fixes GH-13119 Closes GH-13125 --- NEWS | 4 ++ ext/pdo_firebird/firebird_statement.c | 9 +++- ext/pdo_firebird/tests/gh10908.phpt | 12 ++--- ext/pdo_firebird/tests/gh13119.phpt | 77 +++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 ext/pdo_firebird/tests/gh13119.phpt diff --git a/NEWS b/NEWS index 25e241987d6..e5014b67ebe 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,10 @@ PHP NEWS . Fixed LibreSSL undefined reference when OPENSSL_NO_ENGINE not set. (David Carlier). +- PDO_Firebird: + . Fix GH-13119 (Changed to convert float and double values ​​into strings using + `H` format). (SakiTakamachi) + - Phar: . Fixed bug #71465 (PHAR doesn't know about litespeed). (nielsdos) diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index 4ad51ab483d..1fe894cd631 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 a1e8271ffd1..bcd3bb1e200 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 00000000000..29524e3d3bf --- /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" + } +}