WordPress.org

Make WordPress Core

Opened 2 years ago

Closed 23 months ago

#20773 closed defect (bug) (wontfix)

update_option can't store serialized binary in wp_options.option_value column

Reported by: mmaunder Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.3.2
Component: General Keywords:
Focuses: Cc:

Description

If a plugin developer tries to use update_option to store an array containing binary data, the array is not deserialized correctly and update_option instead returns the start of the serialized string.

Test script you can use in a plugin:

$test = get_option('mdm', false);
error_log(var_export($test, true));
$binOn = true;
update_option('mdm', array(md5('asdf', $binOn), md5('qwer', $binOn), md5('sss', $binOn)));

If we:

alter table wp_options modify option_value longblob;

Then it works correctly.

Because wp_options currently stores serialized PHP data as longtext instead of longblob, the database receives the full binary data but truncates it when trying to store it as utf8 characters. Making the column binary appears to fix the issue because the database gives PHP back exactly what was inserted.

The obvious answer is: create your own tables if you want to store binary.

But I'm reporting this because I worry that it may have more subtle effects like incorrectly storing I18N chars when serialized.

Change History (5)

comment:1 follow-up: scribu2 years ago

What exactly are you trying to store?

comment:2 in reply to: ↑ 1 mmaunder2 years ago

Replying to scribu:

What exactly are you trying to store?

Binary md5 hashes as the example shows. However this isn't a support request so I'm not sure my specific case is relevant. The bug is about the general inability for update_option to store a serialized php structure containing binary data. At the very least the problem should be in the docs.

comment:3 scribu2 years ago

The use-case is always relevant when considering an enhancement or API bug. No point adding it if there are better ways to do it.

So: why do the hashes need to be binary?

Version 0, edited 2 years ago by scribu (next)

comment:4 mmaunder23 months ago

I use my own tables in a plugin to do something similar to what update_option() does. I discovered my longtext column type wouldn't work when serialize/deserializeing binary data. I use binary md5's in a virus scanning plugin because they use less space. So I fixed it in my own tables and then it occurred to me that WP also uses longtext, so I wrote a test script and discovered the same issue I have with WP's update_option function.

comment:5 scribu23 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

Ok, thanks for reporting the issue. However, I don't think it makes sense to switch to longblob because:

  1. There's no compelling use-case to justify the costs of such a change (schema changes are expensive).
  2. It's harder to search through a longblob column, since MySQL doesn't know the encoding of the data anymore

Feel free to update the Codex, if you think it would be useful for others.

Note: See TracTickets for help on using tickets.