386 Commits
Author SHA1 Message Date
Gina Peter Banyard 97a581232f ext/sqlite3: user zend_string* instead of char* for extension global (#24303)
This allows us to prevent a needless strlen() computation
2026-10-14 12:44:03 +01:00
Ilia Alshanetsky e5934f427c Fix GH-22051: report errors from SQLite3Result reset and finalize
SQLite3Stmt::reset() reports a failed sqlite3_reset() through
php_sqlite3_error(), but SQLite3Result::reset() returned false silently
and SQLite3Result::finalize() ignored the result. Both now surface the
underlying SQLite error the same way; finalize() keeps its : true return
type and reports without altering the return value.

Fixes GH-22051
Closes GH-22363
2026-09-30 08:46:27 -04:00
Ilia Alshanetsky 1f397a9488 Merge branch 'PHP-8.5'
* PHP-8.5:
  ext/sqlite3: reject close() from inside a callback
2026-09-16 09:03:49 -04:00
Ilia Alshanetsky 0b0784a66e Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  ext/sqlite3: reject close() from inside a callback
2026-09-16 09:03:20 -04:00
Ilia Alshanetsky 7300fa520d ext/sqlite3: reject close() from inside a callback
SQLite3::close() called from within a userland function, aggregate,
collation or authorizer callback freed the registered statements and
functions while sqlite3 was still executing, corrupting the active
statement and crashing the request. Track callback re-entry with a
per-database counter shared by all four callback kinds and throw an
Error from close() while it is non-zero; the database stays usable and
can be closed after the query completes.

Closes GH-23650
2026-09-16 09:02:46 -04:00
ndossche 430a21f40b Merge branch 'PHP-8.5'
* PHP-8.5:
  sqlite3: Fix leak when trying to close db if blob stream is still open
2026-08-03 22:55:56 +02:00
ndossche d2f92b3139 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  sqlite3: Fix leak when trying to close db if blob stream is still open
2026-08-03 22:55:51 +02:00
ndossche eaac0378e3 sqlite3: Fix leak when trying to close db if blob stream is still open
Discovered coincidentally with ESSS [1], even though I was actually using
it for something else.

[1] https://github.com/csl-ugent/ESSS

Closes GH-22992.
2026-08-03 22:55:04 +02:00
Arnaud Le Blanc 32402df2b5 php_printf: introduce %pS to replace custom specifier %S (#22930)
The string formater supports custom format specifiers such as 'S' (zend_string*), but format strings using these specifiers do not pass the compiler's type checks that are performed on functions tagged with ZEND_ATTRIBUTE_FORMAT:

    Zend/zend_compile.c: In function 'zend_compile_closure_binding':
    Zend/zend_compile.c:8586:62: error: format '%S' expects argument of type 'wchar_t *', but argument 3 has type 'zend_string *' {aka 'struct _zend_string *'} [-Werror=format=]
     8586 |                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use variable $%S twice", var_name);
          |                                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  ~~~~~~~~
          |                                                                                               |
          |                                                                                               zend_string * {aka struct _zend_string *}

As a result we can not use these specifiers without resorting to workarounds:

 * Use variants of formatting functions that do not have ZEND_ATTRIBUTE_FORMAT [1]
 * Or declare the format string separately [2]

Here I re-introduce %S as %pS. The compiler will only see a %p specifier followed by the ordinary literal character S, so it will be happy about an argument of type zend_string*.

This trick can be applied to more custom specifiers.

[1] https://github.com/php/php-src/blob/0b5d9801ec3b53e84388239a5b9f85d005318b64/Zend/zend_compile.c#L8586-L8587
[2] https://github.com/php/php-src/blob/edc169e7705d5e4411865e9be92b50e82be78f4e/Zend/zend_partial.c#L680
2026-08-03 16:34:27 +02:00
Ilia Alshanetsky 7522c49630 ext/sqlite3: reject NUL bytes in SQLite3::escapeString() (#22774)
escapeString() used sqlite3_mprintf("%q"), which stops at the first C NUL.
PHP strings are length-aware and may embed NULs, so values such as "a\0b"
were silently truncated to "a" when interpolated into SQL. Prepared binds
pass an explicit length and are unaffected.

ext/pdo_sqlite rejected the same inputs for PDO::quote in 0a10f6db26
(GH-13952), on 8.5 and up. That check consults the connection's error mode;
escapeString() is static and has no connection, so it throws instead.

Closes GH-22774
2026-07-17 07:09:41 -04:00
Ilia Alshanetsky 5ce795bec1 Fix GH-20964: fseek() on php://memory with PHP_INT_MIN causes undefined behavior (#21433)
Negate after casting to unsigned instead of before, avoiding signed
integer overflow when offset is ZEND_LONG_MIN. The same pattern existed
in the pdo_sqlite and sqlite3 stream seek handlers.

Closes GH-20964
Closes GH-20927
2026-06-20 19:01:46 -04:00
ndossche 8bbe4b4119 Merge branch 'PHP-8.5'
* PHP-8.5:
  sqlite: fix error checks for column retrieval
2026-06-11 22:40:31 +02:00
ndossche 50decba4a8 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  sqlite: fix error checks for column retrieval
2026-06-11 22:39:50 +02:00
ndossche 407c45debc sqlite: fix error checks for column retrieval
These can return NULL on OOM.
And for blobs, it can return NULL for empty blobs (so *no* failure,
just an edge case). Passing NULL to memcpy is UB, so we have to
check for a NULL pointer there to avoid UB.

Closes GH-22045.
2026-06-11 22:36:27 +02:00
Nora Dossche cde32beade sqlite3: fix internal return type violation in escapeString() (#22026)
If this call fails due to an internal libsqlite3 error, then the
function will return NULL (as that's the default value set by the VM).
However, the function is marked with a non-nullable string return type.
Therefore this will result in a type violation and a fatal error in
debug mode.
Either we solve it by making the function nullable or throw.
I chose the latter as it is less of a footgun.
2026-05-15 12:05:10 +02:00
Tim Düsterhus 7114314c5a tree-wide: Replace XtOffsetOf by its definition (#21899)
`offsetof()` is in `stddef.h` and thus always available. The extra macro is an
unnecessary layer of indirection.
2026-04-28 22:12:56 +02:00
Ben Ramsey a0f032ec3d license-update: ext/sqlite3 source headers
RFC: https://wiki.php.net/rfc/php_license_update
2026-04-11 21:20:54 -05:00
David Carlier 555e65242f Merge branch 'PHP-8.5'
* PHP-8.5:
  ext/sqlite3: fix wrong pointer types passed to the free list comparator.
2026-04-10 20:56:14 +01:00
David Carlier 7744eab933 ext/sqlite3: fix wrong pointer types passed to the free list comparator.
SQLite3Stmt::close() and SQLite3Result::finalize() passed
php_sqlite3_stmt pointer types instead of sqlite3_stmt pointers
to zend_llist_del_element, causing the comparator to never match
and both methods to silently become no-ops.

Regression introduced in 5eae6d1405 ("Don't store the object
zval directly").

close GH-21483
2026-04-10 20:55:52 +01:00
Weilin Du 2918caee20 ext/*: Remove break after return (#21485) 2026-03-23 20:30:13 +01:00
Alexandre Daubois 11a95749b1 Convert more zend_parse_parameters_none() to fast ZPP (#21330) 2026-03-04 14:07:46 +01:00
Peter Kokot 435e67e075 Remove HAVE_SQLITE3_{CLOSE_V2,ERRSTR} (#18963)
As of PHP 8.5 the minimum required SQLite library is 3.7.17, and this
removes the following preprocessor macros checks:

- HAVE_SQLITE3_CLOSE_V2 (sqlite3_close_v2() function is available since
  SQLite 3.7.14.)
- HAVE_SQLITE3_ERRSTR (sqlite3_errstr() function is available since
  SQLite 3.7.15)
- SQLITE_VERSION_NUMBER should be now always greater than 3006011
  (3.6.11).
2026-02-11 13:13:18 +01:00
David CARLIER 8f55b0850f ext/sqlite3: Sqlite3::openBlob() code path simplification. (#20969)
* ext/sqlite3: Sqlite3::openBlob() code path simplification.

since the stream is opened in non persistent mode, the failure code path
is dead (so are the missing leaks fixes).
2026-01-20 21:34:50 +00:00
Niels Dossche 0d7e53535b Fix NUL byte truncation in sqlite3 TEXT column handling
As a bonus, this should probably also be a tad faster.

Closes GH-20704.
2025-12-15 22:47:41 +01:00
Niels Dossche ec337122d5 Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix GH-20699: SQLite3Result fetchArray return array|false, null returned
2025-12-14 23:18:21 +01:00
Niels Dossche 0ef52c3d89 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix GH-20699: SQLite3Result fetchArray return array|false, null returned
2025-12-14 23:18:16 +01:00
Niels Dossche f3d5dd0feb Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix GH-20699: SQLite3Result fetchArray return array|false, null returned
2025-12-14 23:17:58 +01:00
Niels Dossche acd0898bdf Fix GH-20699: SQLite3Result fetchArray return array|false, null returned
Closes GH-20701.
2025-12-14 23:17:31 +01:00
Niels Dossche 197a455bc0 sqlite3: remove nonsensical return_value dtor (#20360) 2025-11-02 23:47:10 +01:00
Tim Düsterhus 56c98cb077 sqlite3: Use true / false instead of 1 / 0 when assigning to bool
Changes done with Coccinelle:

    @@
    bool b;
    @@

    - b = 0
    + b = false

    @@
    bool b;
    @@

    - b = 1
    + b = true
2025-09-24 18:51:40 +02:00
Niels Dossche 6d15475815 sqlite3: Split off column name cache generation
Also no need to reset the cache unconditionally in fetchAll().
2025-06-24 22:09:54 +02:00
Niels Dossche e7678cdaa4 sqlite3: Use Z_TRY_ADDREF 2025-06-24 22:09:54 +02:00
David Carlier 375316d0e2 ext/sqlite3: Sqlite3Result::fetchAll()
support associative and indexes arrays for results.

close GH-1884
2025-06-23 08:01:31 +01:00
David Carlier 22bd2ae63f ext/sqlite3: explain statement support addition.
similar to what have been done for pdo/sqlite as having statement
explain support to simulate how a query would operate or
for more advanced users, analysing the VM routines used
for possible optimisations.

close GH-18853
2025-06-23 07:57:45 +01:00
Jakub Zelenka 89934b405e Merge branch 'PHP-8.4' 2025-06-21 20:17:15 +02:00
Jakub Zelenka bbac59148c Merge branch 'PHP-8.3' into PHP-8.4 2025-06-21 20:16:13 +02:00
Jakub Zelenka a36b8fdc94 Fix GH-13264: fgets() and stream_get_line() do not return false on filter fatal error
This happens because there are no checks in php_stream_fill_read_buffer
calls. This should not fail always but only on fatal error so special
flag is needed for that.

Closes GH-18778
2025-06-21 20:13:09 +02:00
David Carlier 058c0348fd ext/sqlite3: adding busy() call.
checks if the prepared statement had been fetched but did not complete yet.

close GH-18843
2025-06-13 06:08:44 +01:00
David CARLIER bd8c770439 ext/sqlite3: querySingle amd fetchArray methods optimisations. (#18385)
pre-allocated size for the former and packed array.
2025-04-21 16:37:34 +01:00
Niels Dossche 1fa15abe92 Remove pointless call to zval_ptr_dtor() in sqlite3 (#17906)
This is IS_LONG.
2025-02-23 21:04:47 +01:00
Niels Dossche 6a4b0c922c Merge branch 'PHP-8.4'
* PHP-8.4:
  Fix memory leaks in pdo_sqlite callback registration
  Fix cycle leak in sqlite3 setAuthorizer()
2025-02-23 16:36:06 +01:00
Niels Dossche 76035090b6 Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix cycle leak in sqlite3 setAuthorizer()
2025-02-23 16:35:25 +01:00
Niels Dossche 353f21487f Fix cycle leak in sqlite3 setAuthorizer()
Closes GH-17903.
2025-02-23 16:34:41 +01:00
Niels Dossche 9ee08999f4 Convert initialised to bool 2025-02-10 08:42:11 +01:00
Niels Dossche dbf7d4402c Convert is_prepared_statement to bool 2025-02-10 08:42:11 +01:00
Niels Dossche 5eae6d1405 Don't store the object zval directly 2025-02-10 08:42:11 +01:00
Niels Dossche c0d910d506 Get rid of always-false intern checks
These checks are always false because we're receiving a valid
zend_object.
2025-02-10 08:42:11 +01:00
Niels Dossche bc74cff479 Get rid of unnecessary wrapping a statement in a free list object
This simplifies the code and reduces memory usage.
2025-02-10 08:42:11 +01:00
Niels Dossche 43ac692a09 Use faster string operations in sqlite3 2025-02-10 08:42:11 +01:00
Niels Dossche b2c891f88e Avoid string duplications in sqlite drivers (#17115)
These string duplications are necessary to unregister the callback
later. We can just keep using zend_string to avoid memory duplications.
2024-12-18 17:32:11 +01:00