Make WordPress Core

Opened 6 months ago

Last modified 5 months ago

#63751 new defect (bug)

wpdb->set_prefix() throws deprecation notice for preg_match() when setup-config.php is loaded

Reported by: jerclarke's profile jerclarke Owned by:
Milestone: Awaiting Review Priority: normal
Severity: minor Version: 6.8.2
Component: Database Keywords:
Focuses: coding-standards, php-compatibility Cc:

Description

A bit esoteric, but this is throwing a reliable deprecation notice in my logs when bots visit /wp-admin/setup-config.php:

[25-Jul-2025 18:59:23] PHP deprecated: "preg_match(): Passing null to parameter #2 ($subject) of type string is deprecated" file: /[...]/wp-includes/class-wpdb.php:1007 url: [...]/wp-admin/setup-config.php 

The code throwing the error:

public function set_prefix( $prefix, $set_table_names = true ) {

	if ( preg_match( '|[^a-z0-9_]|i', $prefix ) ) {
		return new WP_Error( 'invalid_db_prefix', 'Invalid database prefix' );
	}

The immediate cause is obvious: preg_match() is run without checking that $prefix has any content, and in PHP 8.x you're not allowed to pass empty strings to it.

The "real" cause, I don't know. Why is there no $prefix available when normally there would be? Should there be?

These WP_INSTALLING files like setup-config.php are a mystery to me, and seem relatively untested especially with these PHP 8.x edge-cases.

My goal with this ticket is just to clean up the deprecation warning.

It seems to me all that needs to be done is to check that !empty( $prefix) before doing the preg_replace(), so:

public function set_prefix( $prefix, $set_table_names = true ) {

	if ($prefix && preg_match( '|[^a-z0-9_]|i', $prefix ) ) {
		return new WP_Error( 'invalid_db_prefix', 'Invalid database prefix' );
	}

Seems to me that would resolve the notice and have the exact same effect as the old code.

Thank you for helping fix this 🙏🏻

Change History (2)

#1 @sabernhardt
6 months ago

The "real" cause, I don't know. Why is there no $prefix available when normally there would be? Should there be?

The cause is highly important to understanding how to fix it. I think the real solution would be found outside the wpdb class.

However, if its set_prefix method should require a $prefix (#16229), then returning the invalid_db_prefix error could stop the operations:

if ( ! $prefix || preg_match( '|[^a-z0-9_]|i', $prefix ) ) {
	return new WP_Error( 'invalid_db_prefix', 'Invalid database prefix' );
}

#2 @jerclarke
5 months ago

Fair enough, I'm not clear on whether the prefix can be empty or not. The current behavior implies an empty one is acceptable, so I would default to preserving the behavior and just silencing the notice.

If anyone wants to confirm that this would be accepted either way, it would probably be fine.

Note: See TracTickets for help on using tickets.