Skip to content

Commit fda14ed

Browse files
committed
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: Fix GH-25021: SQLite createFunction corrupts large integers
2 parents 6737867 + 9c69d7c commit fda14ed

5 files changed

Lines changed: 70 additions & 6 deletions

File tree

‎ext/pdo_sqlite/sqlite_driver.c‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,11 @@ static int do_callback(zend_fcall_info_cache *fcc, int argc, sqlite3_value **arg
403403
/* get the value */
404404
switch (sqlite3_value_type(argv[i])) {
405405
case SQLITE_INTEGER:
406+
#ifdef ZEND_ENABLE_ZVAL_LONG64
407+
ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int64(argv[i]));
408+
#else
406409
ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int(argv[i]));
410+
#endif
407411
break;
408412

409413
case SQLITE_FLOAT:
@@ -441,7 +445,11 @@ static int do_callback(zend_fcall_info_cache *fcc, int argc, sqlite3_value **arg
441445
if (!Z_ISUNDEF(retval)) {
442446
switch (Z_TYPE(retval)) {
443447
case IS_LONG:
448+
#ifdef ZEND_ENABLE_ZVAL_LONG64
449+
sqlite3_result_int64(context, Z_LVAL(retval));
450+
#else
444451
sqlite3_result_int(context, Z_LVAL(retval));
452+
#endif
445453
break;
446454

447455
case IS_NULL:

‎ext/pdo_sqlite/sqlite_statement.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_d
120120
}
121121
} else {
122122
convert_to_long(parameter);
123-
#if ZEND_LONG_MAX > 2147483647
123+
#ifdef ZEND_ENABLE_ZVAL_LONG64
124124
if (SQLITE_OK == sqlite3_bind_int64(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
125125
return 1;
126126
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
GH-25021 (UDF isn't using sqlite3_*_int64 API)
3+
--EXTENSIONS--
4+
pdo_sqlite
5+
--FILE--
6+
<?php
7+
8+
$conn = new PDO('sqlite::memory:');
9+
10+
$conn->sqliteCreateFunction('my_udf_pass_int', static fn(int $v): int => $v);
11+
12+
foreach ([
13+
10,
14+
PHP_INT_MIN,
15+
PHP_INT_MAX,
16+
] as $v) {
17+
$stmt = $conn->prepare('select my_udf_pass_int(:v)');
18+
$stmt->bindValue(':v', $v, PDO::PARAM_INT);
19+
$stmt->execute();
20+
$result = $stmt->fetch();
21+
22+
var_dump($result[0] === $v);
23+
}
24+
?>
25+
--EXPECTF--
26+
Deprecated: Method PDO::sqliteCreateFunction() is deprecated since 8.5, use Pdo\Sqlite::createFunction() instead in %s on line %d
27+
bool(true)
28+
bool(true)
29+
bool(true)

‎ext/sqlite3/sqlite3.c‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ static void sqlite_value_to_zval(php_sqlite3_db_object *db_obj, sqlite3_stmt *st
632632
switch (sqlite3_column_type(stmt, column)) {
633633
case SQLITE_INTEGER:
634634
val = sqlite3_column_int64(stmt, column);
635-
#if LONG_MAX <= 2147483647
635+
#ifndef ZEND_ENABLE_ZVAL_LONG64
636636
if (val > ZEND_LONG_MAX || val < ZEND_LONG_MIN) {
637637
const char *text = (const char *) sqlite3_column_text(stmt, column);
638638
if (UNEXPECTED(text == NULL)) {
@@ -644,7 +644,7 @@ static void sqlite_value_to_zval(php_sqlite3_db_object *db_obj, sqlite3_stmt *st
644644
} else {
645645
#endif
646646
ZVAL_LONG(data, (zend_long) val);
647-
#if LONG_MAX <= 2147483647
647+
#ifndef ZEND_ENABLE_ZVAL_LONG64
648648
}
649649
#endif
650650
break;
@@ -806,7 +806,7 @@ static int sqlite3_do_callback(zend_fcall_info_cache *fcc, uint32_t argc, sqlite
806806
for (i = 0; i < argc; i++) {
807807
switch (sqlite3_value_type(argv[i])) {
808808
case SQLITE_INTEGER:
809-
#if ZEND_LONG_MAX > 2147483647
809+
#ifdef ZEND_ENABLE_ZVAL_LONG64
810810
ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int64(argv[i]));
811811
#else
812812
ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int(argv[i]));
@@ -857,7 +857,7 @@ static int sqlite3_do_callback(zend_fcall_info_cache *fcc, uint32_t argc, sqlite
857857
if (!Z_ISUNDEF(retval)) {
858858
switch (Z_TYPE(retval)) {
859859
case IS_LONG:
860-
#if ZEND_LONG_MAX > 2147483647
860+
#ifdef ZEND_ENABLE_ZVAL_LONG64
861861
sqlite3_result_int64(context, Z_LVAL(retval));
862862
#else
863863
sqlite3_result_int(context, Z_LVAL(retval));
@@ -1654,7 +1654,7 @@ static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
16541654
switch (param->type) {
16551655
case SQLITE_INTEGER:
16561656
convert_to_long(parameter);
1657-
#if ZEND_LONG_MAX > 2147483647
1657+
#ifdef ZEND_ENABLE_ZVAL_LONG64
16581658
return_code = sqlite3_bind_int64(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));
16591659
#else
16601660
return_code = sqlite3_bind_int(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));

‎ext/sqlite3/tests/gh25021-udf.phpt‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
GH-25021 (UDF isn't using sqlite3_*_int64 API)
3+
--EXTENSIONS--
4+
sqlite3
5+
--FILE--
6+
<?php
7+
8+
$conn = new SQLite3(':memory:');
9+
10+
$conn->createFunction('my_udf_pass_int', static fn(int $v): int => $v);
11+
12+
foreach ([
13+
10,
14+
PHP_INT_MIN,
15+
PHP_INT_MAX,
16+
] as $v) {
17+
$stmt = $conn->prepare('select my_udf_pass_int(:v)');
18+
$stmt->bindValue(':v', $v, SQLITE3_INTEGER);
19+
$result = $stmt->execute()->fetchArray();
20+
21+
var_dump($result[0] === $v);
22+
}
23+
?>
24+
--EXPECT--
25+
bool(true)
26+
bool(true)
27+
bool(true)

0 commit comments

Comments
 (0)