• Resolved Noah Hearle

    (@designextreme)


    In the process of developing my plugin I discovered that in some rare circumstances data that is set using the update_option() function will result in invalid serialized data being stored in the database. It was causing the data in my Google Review plugin to be result and losing all previously collected data.

    It is likely to be the maybe_serialize() function – one or more of the characters may be causing an incorrect string length count, or something similar to this.

    I have test data available to can replicate this error. This is an excerpt:

    a:101:{s:45:"1570449412_4_bcb7bc02734e48f0a14afe817e028808";a:16:{s:2:"id";i:1;s:8:"place_id";s:27:"ChIJ37ukkHcFdkgRq7UEJ1_6j5I";s:5:"order";i:1;s:7:"checked";i:1582008103;s:9:"retrieved";i:1582007925;s:8:"imported";b:0;s:13:"time_estimate";b:0;s:6:"status";b:1;s:11:"author_name";s:5:"Naz A";s:10:"author_url";s:65:"https://www.google.com/maps/contrib/117241935186177377572/reviews";s:8:"language";s:2:"en";s:17:"profile_photo_url";s:110:"https://lh4.ggpht.com/-1oyiszUUupc/AAAAAAAAAAI/AAAAAAAAAAA/6lWQROyZ-gs/s128-c0x00000000-cc-rp-mo-ba4/photo.jpg";s:6:"rating";i:4;s:25:"relative_time_description";s:12:"4 months ago";s:4:"text";s:331:"They have a lovely wrap selection from 12 - 5.  I've always 
     ... 
    s:10:"author_url";s:57:"https://www.google.com/maps/contrib/102840331523623566629";s:8:"language";N;s:17:"profile_photo_url";s:110:"https://lh6.googleusercontent.com/-8TFGw3UWN30/AAAAAAAAAAI/AAAAAAAAAAA/qpEGZELDfFw/s40-c-rp-mo-br100/photo.jpg";s:6:"rating";d:4;s:25:"relative_time_description";s:11:"2 weeks ago";s:4:"text";N;s:4:"time";i:1580774400;s:7:"checked";N;s:9:"retrieved";N;s:8:"imported";i:1582008103;s:13:"time_estimate";b:1;s:6:"status";b:1;}}

    All the best,

    Noah

    The page I need help with: [log in to see the link]

Viewing 6 replies - 1 through 6 (of 6 total)
  • Thread Starter Noah Hearle

    (@designextreme)

    I found the trigger of this problem – it was an emoticon. After a little trial and error, I isolated this string as the cause…

    Never had this food before and would highly recommend it fresh amazing food and great friendly helpful service will definitely be returning ๐Ÿ˜

    Hopefully this will help you develop a more robust approach to handling such data.

    All the best,

    Noah

    P.S. This is actually a problem with the current version of WordPress, so please move it accordingly.

    • This reply was modified 6 years, 3 months ago by Noah Hearle.

    You can see if the problem has been reported or not, and open a ticket if not:
    https://core.trac.ww.wp.xz.cn/

    Moderator Ipstenu (Mika Epstein)

    (@ipstenu)

    ๐Ÿณ๏ธโ€๐ŸŒˆ Advisor and Activist

    Without seeing your code, we cannot really help you out here, however it’s important to know that you should never be attempting to serialize code when you save it.

    It’s unnecessary to unserialize and serialize data you save via option updates. The post, comment and user meta functions, and the functions for options and transients (and site meta) all transparently serialize and unserialize data for you.

    If you use serialize, that means that youโ€™re serializing the data, then update_option is serializing serialized data, then get_option is unserializing it once, and unserialize is unserializing it again. The same is true of using json_encode.

    Plus neither actually sanitize or validate anything.

    Thread Starter Noah Hearle

    (@designextreme)

    @ipstenu I am aware of the points you mentioned.

    As the data was not being stored correctly, I added my own sanity check for the data roughly as follows:

    <?php
    
    global $wpdb;
    $this->reviews = get_option(__CLASS__ . '_reviews');
    $review_backup = $this->reviews;
    /*
    Changes to $this->reviews
    */
    update_option(__CLASS__ . '_reviews', $this->reviews, 'no');
    $review_verify = get_option(__CLASS__ . '_reviews');
    $review_verify = $wpdb->get_var($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", __CLASS__ . '_reviews'));
    $review_verify = (is_string($review_verify)) ? maybe_unserialize($review_verify) : array();
    if (!is_array($review_verify) || is_array($review_verify) && count($review_verify) != count($this->reviews))
    {
    	/* Restore data 
    	$this->reviews = $review_backup;
    	update_option(__CLASS__ . '_reviews', $this->reviews, 'no');
    }
    
    ?>

    You can see it is not using maybe_unserialize() to get any data for use – only to verify that it is valid.

    Moderator Ipstenu (Mika Epstein)

    (@ipstenu)

    ๐Ÿณ๏ธโ€๐ŸŒˆ Advisor and Activist

    Thank you for the context! Without it, we’re kind of grasping at straws and have to jump to the beginning that you may already know ๐Ÿ™‚

    Thread Starter Noah Hearle

    (@designextreme)

    @ipstenu I did a test on another website with the database using a different encoding. This time it did store the same data successfully.

    Collation: latin1_swedish_ci – emoticons in array of data, not so good…
    Collation: utf8_general_ci – emoticons in array of data, not so good…
    Collation: utf8mb4_unicode_520_ci – works

    This should help you replicate the issue.

    All the best,

    Noah

Viewing 6 replies - 1 through 6 (of 6 total)

The topic ‘Invalid serialized data stored by maybe_serialize() function’ is closed to new replies.