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
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
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.
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
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
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
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.
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.
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
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).
* 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).
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
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