WPDB: Capture error in wpdb::$last_error when insert fails instead of silently failing for invalid data or value too long.

Instead of silently failing when attempting to insert a value into a field, this commit saves the error in the `wpdb::$last_error` property.

Sets `last_error` with an error message if:
* `wpdb::query()` fails for invalid data
* `wpdb::process_fields()` fails to process the value(s) for the field(s) where the value could be too long or contain invalid data

Sets `last_query` if `wpdb::query()` fails for invalid data.

If `__()` is not available, uses non-translated error message to ensure the error is captured.

There is no change to wpdb aborting when an error occurs.

Adds tests.

Props dlt101, mnelson4, dd32, pento, hellofromTonya, davidbaumwald, sergeybiryukov, johnbillion, swissspidy, datainterlock, anandau14, anthonyeden, asif2bd, audrasjb, chaion07, dpegasusm, fpcsjames, galbaras, jdgrimes, justindocanto, kwisatz, liammitchell, lucasw89, lukecarbis, nettsite, nlpro, procodewp, psufan, richardfoley, skunkbad, travisnorthcutt, woodyhayday, zoiec.
Fixes #37267.

git-svn-id: https://develop.svn.wordpress.org/trunk@52176 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Tonya Mork
2021-11-16 02:57:53 +00:00
parent 32225077fc
commit 648eb03768
2 changed files with 195 additions and 1 deletions
+35 -1
View File
@@ -2015,7 +2015,15 @@ class wpdb {
// to flush again, just to make sure everything is clear.
$this->flush();
if ( $stripped_query !== $query ) {
$this->insert_id = 0;
$this->insert_id = 0;
$this->last_query = $query;
if ( function_exists( '__' ) ) {
$this->last_error = __( 'WordPress database error: Could not perform query because it contains invalid data.' );
} else {
$this->last_error = 'WordPress database error: Could not perform query because it contains invalid data.';
}
return false;
}
}
@@ -2535,6 +2543,32 @@ class wpdb {
$converted_data = $this->strip_invalid_text( $data );
if ( $data !== $converted_data ) {
$problem_fields = array();
foreach ( $data as $field => $value ) {
if ( $value !== $converted_data[ $field ] ) {
$problem_fields[] = $field;
}
}
if ( 1 === count( $problem_fields ) ) {
if ( function_exists( '__' ) ) {
/* translators: %s Database field where the error occurred. */
$message = __( 'WordPress database error: Processing the value for the following field failed: %s. The supplied value may be too long or contains invalid data.' );
} else {
$message = 'WordPress database error: Processing the value for the following field failed: %s. The supplied value may be too long or contains invalid data.';
}
} else {
if ( function_exists( '__' ) ) {
/* translators: %s Database fields where the error occurred. */
$message = __( 'WordPress database error: Processing the value for the following fields failed: %s. The supplied value may be too long or contains invalid data.' );
} else {
$message = 'WordPress database error: Processing the value for the following fields failed: %s. The supplied value may be too long or contains invalid data.';
}
}
$this->last_error = sprintf( $message, implode( ', ', $problem_fields ) );
return false;
}