StreamPollHandle took the descriptor through the select cast. On a TLS
stream that cast reads: it moves what OpenSSL holds decrypted into the
stream buffer so that stream_select() can report it. Adding a watcher to
an Io\Poll\Context therefore read from the stream, filled the buffer of a
stream set unbuffered with stream_set_read_buffer() and changed
unread_bytes. That is not how the poll API should behave. Adding a handle
is a registration and must leave the stream as it found it, and the data
that moved was not reported by the watcher anyway, as bytes held by the
stream layer are not readiness of the descriptor.
A new cast PHP_STREAM_AS_FD_FOR_POLL returns the descriptor and nothing
else. The socket, TLS, plain and pgsql wrappers answer it, a userspace
wrapper sees it as STREAM_CAST_FOR_SELECT and the stream it returns is
cast the same way, and a filtered stream allows it like the select cast.
StreamPollHandle uses it, so adding a TLS stream leaves its buffer and
unread_bytes as they were. The select cast and stream_select() are
unchanged.
This is fixed in 8.6 because the API is new there and this is the
behaviour it should ship with. Keeping a read inside the registration
would complicate things later: once reads on a TLS stream can suspend,
the cast would become a nested read on a stream with an operation in
flight, and changing the cast then would change the visible behaviour of
a released API.
The conversion of the data parameter to Z_PARAM_PATH_STR() made
pg_lo_write() reject any data containing a null byte, breaking writes of
arbitrary binary payloads which were accepted before. Accept embedded
null bytes again by parsing the data as a length-aware string. Sibling
audit: the other Z_PARAM_PATH* conversions from the same change
(pg_connect(), pg_lo_import(), table/statement identifiers) operate on
paths or SQL text where null-byte rejection is intentional.
Closes GH-23649
Headers required by the generated code (zend_attributes.h, zend_constants.h, zend_enum.h) are collected during generation and emitted as includes at the top of the arginfo file, with the same preprocessor conditions and PHP version guards as the code that needs them.
Removes the manual zend_attributes.h and zend_enum.h includes from sources that only needed them for the arginfo file they include.
pg_update() and pg_delete() list PGSQL_DML_ASYNC among the valid flags in
the error they raise, although their masks reject it and their helpers
assert it is never set. Conversely pg_insert() and pg_update() accept the
whole PGSQL_CONV_OPTS set but only named PGSQL_CONV_FORCE_NULL, so
PGSQL_CONV_IGNORE_DEFAULT and PGSQL_CONV_IGNORE_NOT_NULL are added.
While there, widen php_pgsql_delete()'s assert to PGSQL_DML_NO_CONV,
which pg_delete() accepts and the helper itself consults.
Close GH-23480
Splitting the behavioural change of #23052 out into this and come up with something that is hopefully more sensible and consistent between fast and slow ZPP and the object or class_name Fast ZPP specifier.
The stub spelled it Pgsql\Connection, the only such spelling in the
extension. Resolution is case-insensitive, but Reflection reported a
class name that does not match the declared one.
Close GH-23393
Prevents unavailable optional test services from slowing the suite through repeated connection timeouts. PDO and SNMP availability probes cache the first failure for the duration of one test run, so later SKIPIF checks return immediately.
Only failures are cached; successful probes and test connections are unchanged. PDOs one second timeout applies only to the default availability probe. The caches are private, run-scoped and removed afterwards. A service becoming available mid run is detected on the next test-suite run.
php_pgsql_add_quotes() quotes the string with E'...', but PQescapeStringConn()
does not escape \ unless standard_conforming_strings is off.
PQescapeStringConn() is meant to be used with '', so do that instead.
Fixes GHSA-7qpv-r5mr-78m4
* ftp: For single fd poll calls, use php_pollfd_for_ms
* pgsql: Use php_pollfd_for_ms in compat shim
This is only used on pre-libpq 17.
* fastcgi: Use php_pollfd_for_ms for single fd
This also handles the case where poll isn't available (does that even
matter nowadays?)
* io: Use php_pollfd_for_ms for single fd poll
* cli: Convert to php_pollfd_for from select
This is not a poll call, but it is functionally the same as one; convert
it to the single fd polling function which is clearer to read.
* ext/*: Make `X_from_obj(zend_object *obj)` functions macros
With the introduction of the `ZEND_CONTAINER_OF()` macro we can now preserve
whether or not the `zend_object *` is `const` when extracting the
class-specific struct. This change will allow to use `const zend_object *` in
more locations.
Changes performed with Coccinelle followed by some manual cleanup for comment
and whitespace formatting:
@a@
attribute name zend_always_inline;
type T;
identifier obj;
identifier f;
typedef zend_object;
@@
T* f(zend_object *obj) { return ZEND_CONTAINER_OF(obj, T, std); }
+ #define f(obj) ZEND_CONTAINER_OF(obj, T, std)
@@
identifier a.f;
@@
- f(...) { ... }
@b@
attribute name zend_always_inline;
type T;
identifier obj;
identifier f;
typedef zend_object;
@@
T* f(zend_object *obj) { return ZEND_CONTAINER_OF(obj, T, zo); }
+ #define f(obj) ZEND_CONTAINER_OF(obj, T, zo)
@@
identifier b.f;
@@
- f(...) { ... }
* sockets: Fix build
* odbc: Fix build
* zend_portability: Add `ZEND_CONTAINER_OF()`
* tree-wide: Use `ZEND_CONTAINER_OF()`
Changes made with Coccinelle:
@@
type T_container;
identifier member;
expression e;
@@
- (T_container *)(((char *)(e)) - offsetof(T_container, member))
+ ZEND_CONTAINER_OF(e, T_container, member)
@@
type T_container;
identifier member;
expression e;
typedef uintptr_t;
@@
- (T_container *)(((uintptr_t)(e)) - offsetof(T_container, member))
+ ZEND_CONTAINER_OF(e, T_container, member)
@@
type T_container;
identifier member;
expression e;
@@
- (const T_container *)(((char *)(e)) - offsetof(T_container, member))
+ ZEND_CONTAINER_OF(e, T_container, member)
@@
type T_container;
identifier member;
expression e;
typedef uintptr_t;
@@
- (const T_container *)(((uintptr_t)(e)) - offsetof(T_container, member))
+ ZEND_CONTAINER_OF(e, T_container, member)
* bcmath: Fix `get_bcmath_number_from_obj()` const-correctness
A follow-up change to the new `ZEND_CONTAINER_OF()` macro will preserve the
`const`-ness of the input pointer. By wrapping this macro inside a macro rather
an an inline function we can preserve the `const`-ness across all layers.
* zend_portability: Keep `const`-ness in `ZEND_CONTAINER_OF()`
* zend_portability: Add C++ version to `ZEND_CONTAINER_OF()`
Move object_init_ex() before php_pgsql_fetch_hash() so abstract,
interface and enum errors surface earlier, look up the constructor
via the get_constructor handler (under EG(fake_scope)) so classes
with overridden handlers work, and mark the object as ctor-failed
when the constructor throws.
The ValueError for ctor args on a class without a constructor now
reports argument 4 ($constructor_args) instead of argument 3 ($class).
close GH-21884
There are several issues with this macro:
- It is incorrectly named: It's not an empty default case. It's an unreachable
default case.
- It is hiding control flow in its definition, which can be confusing for
humans and tools (such as Coccinelle) alike, because it looks like it would
be a statement that belongs to the "current" case rather than opening a new
one.
Since this macro is exactly as long as explicitly spelling out its definition
(excluding the useless `break;`), it is not even making the code any more
succinct.
The guards reference undefined VE_PG_LO64, a misspelling of
HAVE_PG_LO64 (removed in GH-14628), making the 64-bit code paths
permanently dead. Remove the guards to unconditionally enable the
64-bit variants for PostgreSQL >= 9.3, consistent with pg_lo_seek().
Dropped from GH-21386 as not suitable for backport.
close GH-21437
Fix `PQTRACE_SUPPRESS_TIMESTAMPS` guard misspelling in pgsql.stub.php.
The guard has been misspelled as `PQTRACE_SUPPPRESS_TIMESTAMPS`
(three P's) since 7ec8ae12c4, preventing the
`PGSQL_TRACE_SUPPRESS_TIMESTAMPS` constant from being registered.
close GH-21386
The current function `CHECK_HEADER_ADD_INCLUDE()` automatically defines
`HAVE_<HEADER_NAME_H>` preprocessor macros, which makes it difficult to
sync with other build systems. Specially, if some `HAVE_` macro is used
in the code and this function defines this macro but Autotools doesn't.
The new `CHECK_HEADER()` function behaves similar except it doesn't
define the `HAVE_<HEADER_NAME_H>` preprocessor macro.
This removes the following unused compile definitions:
HAVE_ARGON2_H
HAVE_AVIF_H
HAVE_BZLIB_H
HAVE_CAPSTONE_CAPSTONE_H
HAVE_CURL_EASY_H
HAVE_DB_H
HAVE_DECODE_H
HAVE_DEPOT_H
HAVE_EDITLINE_READLINE_H
HAVE_ENCHANT_H
HAVE_ENCODE_H
HAVE_FFI_H
HAVE_FIREBIRD_INTERFACE_H
HAVE_FT2BUILD_H
HAVE_GD_H
HAVE_GLIB_H
HAVE_GMP_H
HAVE_HTTPD_H
HAVE_IBASE_H
HAVE_IR_IR_H
HAVE_KECCAKHASH_H
HAVE_LBER_H
HAVE_LDAP_H
HAVE_LIBEXSLT_EXSLT_H
HAVE_LIBINTL_H
HAVE_LIBPQ_FE_H
HAVE_LIBTIDY_TIDY_H
HAVE_LIBXML_PARSER_H
HAVE_LIBXML_TREE_H
HAVE_LIBXML_XMLWRITER_H
HAVE_LIBXSLT_XSLT_H
HAVE_LMDB_H
HAVE_MBSTRING_H
HAVE_MYSQL_H
HAVE_ONIGURUMA_H
HAVE_OPENSSL_SSL_H
HAVE_PNG_H
HAVE_SNMP_H
HAVE_SODIUM_H
HAVE_SQLITE3_H
HAVE_SQLITE3EXT_H
HAVE_SYBFRONT_H
HAVE_TIDY_H
HAVE_TIDY_TIDY_H
HAVE_TIDYBUFFIO_H
HAVE_TIMELIB_CONFIG_H
HAVE_UNICODE_USPOOF_H
HAVE_UNICODE_UTF_H
HAVE_XPM_H
HAVE_ZIP_H
HAVE_ZIPCONF_H
HAVE_ZLIB_H
The following compile definitions are defined explicitly:
- HAVE_ICONV_H
- HAVE_MSCOREE_H
- HAVE_SQL_H
- HAVE_SQLEXT_H
Additionally, the `SETUP_OPENSSL()` function doesn't accept the 6th
argument anymore.
The PHP_PQ_ERROR macro calls php_error_docref() which triggers user error handlers
thus libpq does not have the chance to clean the resources (and empty
connections string are allowed) on failure thus we avoid this macro
and delay the error handling after.
close GH-21165