Database: Replace `str_contains()` and `str_ends_with()` usage in `wpdb` methods.

This avoids fatal errors on PHP < 8.0 if the file is included directly outside of WordPress core, e.g. by HyperDB.

While WordPress core does include polyfills for these functions, they are not directly loaded in the `wpdb` class.

Follow-up to [54384], [55157], [55158], [55988], [55990].

Props dd32, ryelle, joedolson.
See #58206.
Built from https://develop.svn.wordpress.org/trunk@55994


git-svn-id: http://core.svn.wordpress.org/trunk@55506 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Sergey Biryukov 2023-06-23 12:17:24 +00:00
parent cbe4f15279
commit 3e3c741d08
3 changed files with 35 additions and 9 deletions

View File

@ -73,7 +73,7 @@ foreach ( $load as $handle ) {
$content = get_file( $path ) . "\n"; $content = get_file( $path ) . "\n";
// str_starts_with() is not used here, as wp-includes/compat.php is not loaded in this file. // Note: str_starts_with() is not used here, as wp-includes/compat.php is not loaded in this file.
if ( 0 === strpos( $style->src, '/' . WPINC . '/css/' ) ) { if ( 0 === strpos( $style->src, '/' . WPINC . '/css/' ) ) {
$content = str_replace( '../images/', '../' . WPINC . '/images/', $content ); $content = str_replace( '../images/', '../' . WPINC . '/images/', $content );
$content = str_replace( '../js/tinymce/', '../' . WPINC . '/js/tinymce/', $content ); $content = str_replace( '../js/tinymce/', '../' . WPINC . '/js/tinymce/', $content );

View File

@ -1496,8 +1496,14 @@ class wpdb {
return; return;
} }
// This is not meant to be foolproof -- but it will catch obviously incorrect usage. /*
if ( ! str_contains( $query, '%' ) ) { * This is not meant to be foolproof -- but it will catch obviously incorrect usage.
*
* Note: str_contains() is not used here, as this file can be included
* directly outside of WordPress core, e.g. by HyperDB, in which case
* the polyfills from wp-includes/compat.php are not loaded.
*/
if ( false === strpos( $query, '%' ) ) {
wp_load_translations_early(); wp_load_translations_early();
_doing_it_wrong( _doing_it_wrong(
'wpdb::prepare', 'wpdb::prepare',
@ -1564,7 +1570,12 @@ class wpdb {
$type = substr( $placeholder, -1 ); $type = substr( $placeholder, -1 );
if ( 'f' === $type && true === $this->allow_unsafe_unquoted_parameters if ( 'f' === $type && true === $this->allow_unsafe_unquoted_parameters
&& str_ends_with( $split_query[ $key - 1 ], '%' ) /*
* Note: str_ends_with() is not used here, as this file can be included
* directly outside of WordPress core, e.g. by HyperDB, in which case
* the polyfills from wp-includes/compat.php are not loaded.
*/
&& '%' === substr( $split_query[ $key - 1 ], -1, 1 )
) { ) {
/* /*
@ -1625,7 +1636,12 @@ class wpdb {
* Second, if "%s" has a "%" before it, even if it's unrelated (e.g. "LIKE '%%%s%%'"). * Second, if "%s" has a "%" before it, even if it's unrelated (e.g. "LIKE '%%%s%%'").
*/ */
if ( true !== $this->allow_unsafe_unquoted_parameters if ( true !== $this->allow_unsafe_unquoted_parameters
|| ( '' === $format && ! str_ends_with( $split_query[ $key - 1 ], '%' ) ) /*
* Note: str_ends_with() is not used here, as this file can be included
* directly outside of WordPress core, e.g. by HyperDB, in which case
* the polyfills from wp-includes/compat.php are not loaded.
*/
|| ( '' === $format && '%' !== substr( $split_query[ $key - 1 ], -1, 1 ) )
) { ) {
$placeholder = "'%" . $format . "s'"; $placeholder = "'%" . $format . "s'";
} }
@ -4038,8 +4054,14 @@ class wpdb {
$db_version = $this->db_version(); $db_version = $this->db_version();
$db_server_info = $this->db_server_info(); $db_server_info = $this->db_server_info();
// Account for MariaDB version being prefixed with '5.5.5-' on older PHP versions. /*
if ( '5.5.5' === $db_version && str_contains( $db_server_info, 'MariaDB' ) * Account for MariaDB version being prefixed with '5.5.5-' on older PHP versions.
*
* Note: str_contains() is not used here, as this file can be included
* directly outside of WordPress core, e.g. by HyperDB, in which case
* the polyfills from wp-includes/compat.php are not loaded.
*/
if ( '5.5.5' === $db_version && false !== strpos( $db_server_info, 'MariaDB' )
&& PHP_VERSION_ID < 80016 // PHP 8.0.15 or older. && PHP_VERSION_ID < 80016 // PHP 8.0.15 or older.
) { ) {
// Strip the '5.5.5-' prefix and set the version to the correct value. // Strip the '5.5.5-' prefix and set the version to the correct value.
@ -4067,8 +4089,12 @@ class wpdb {
/* /*
* libmysql has supported utf8mb4 since 5.5.3, same as the MySQL server. * libmysql has supported utf8mb4 since 5.5.3, same as the MySQL server.
* mysqlnd has supported utf8mb4 since 5.0.9. * mysqlnd has supported utf8mb4 since 5.0.9.
*
* Note: str_contains() is not used here, as this file can be included
* directly outside of WordPress core, e.g. by HyperDB, in which case
* the polyfills from wp-includes/compat.php are not loaded.
*/ */
if ( str_contains( $client_version, 'mysqlnd' ) ) { if ( false !== strpos( $client_version, 'mysqlnd' ) ) {
$client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $client_version ); $client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $client_version );
return version_compare( $client_version, '5.0.9', '>=' ); return version_compare( $client_version, '5.0.9', '>=' );
} else { } else {

View File

@ -16,7 +16,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '6.3-alpha-55993'; $wp_version = '6.3-alpha-55994';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.