[wp-trac] [WordPress Trac] #52723: Admin options.php default value to NULL for option_value may lead to MySQL Integrity constraint violation error, potential other bugs
WordPress Trac
noreply at wordpress.org
Fri Mar 5 14:26:35 UTC 2021
#52723: Admin options.php default value to NULL for option_value may lead to MySQL
Integrity constraint violation error, potential other bugs
----------------------------+-----------------------------
Reporter: pinoceniccola | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: General | Version:
Severity: normal | Keywords:
Focuses: administration |
----------------------------+-----------------------------
It looks like `wp-admin/options.php` set a `null` value by default for any
unchecked option:
https://core.trac.wordpress.org/browser/trunk/src/wp-
admin/options.php#L306
Now, this leads to execute queries like this by `update_option`:
UPDATE `wp_options` SET `option_value` = NULL WHERE `option_name` =
'default_pingback_flag'
Which is wrong, given the schema explicitly set `option_value` to `NOT
NULL`:
https://core.trac.wordpress.org/browser/trunk/src/wp-
admin/includes/schema.php#L144
This would trigger an integrity constraint violation error by MySQL when
in (default) strict mode:
Error! SQLSTATE[23000]: Integrity constraint violation: 1048 Column
'option_value' cannot be null
To get around this (and for other reasons too, I presume), WordPress
currently tries to disable any MySQL strict mode in the `$wpdb` class,
with the effect that MySQL silently "fix" the error itself:
https://core.trac.wordpress.org/browser/trunk/src/wp-includes/wp-
db.php#L567
https://core.trac.wordpress.org/browser/trunk/src/wp-includes/wp-
db.php#L826
But **not every environment support this**, so there are people out there
who cannot save options and they are confused about the reason why, for
example:
https://www.reddit.com/r/Wordpress/comments/l61rvs/cannot_disable_avatars/
https://wordpress.org/support/topic/discussion-comment-settings-saved-
changes-are-not-taking-effect-at-all/
https://wordpress.org/support/topic/wordpress-database-error-column-
option_value-cannot-be-null/
A simple solution would be to set a different default value (`0` or even
an empty string) in `wp-admin/options.php` and, ''better yet'', **cast any
`NULL` value to the same different default value in both `update_option`
and `add_option`**.
Please note that, without a fix, **this bug may also lead to other nasty
side effects**.
As a quick fix/test, I successful got around this with this simple filter:
{{{#!php
<?php
add_action( 'init', 'p_options_fix' );
function p_options_fix() {
add_filter( 'pre_update_option', 'p_options_fix_not_null', 10, 3
);
function p_options_fix_not_null( $value, $option, $old_value ) {
// The fix: cast NULL values to 0
$value = ( is_null($value) ) ? 0 : $value;
return $value;
}
}
}}}
But I think this is something that should be really fixed in the core.
Thank you.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/52723>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list