unserialize()[function.unserialize]:偏移时出错 [英] unserialize() [function.unserialize]: Error at offset

查看:1139
本文介绍了unserialize()[function.unserialize]:偏移时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在图片上传插件中使用Hotaru CMS,如果我尝试附加图片到帖子,我会收到此错误,否则没有错误。



违规代码(与**匹配的错误):

  / ** 
*检索提交步骤数据
*
* @param $ key - 设置
时为空* @return bool
* /
public function loadSubmitData($ h,$ key ='')
{
//删除此表中超过30分钟的所有内容:
$ this-> deleteTempData($ h-> db);

if(!$ key){return false; }

$ cleanKey = preg_replace('/ [^ a-z0-9] + /','',$ key);
if(strcmp($ key,$ cleanKey)!= 0){
return false;
} else {
$ sql =SELECT tempdata_value FROM。 TABLE_TEMPDATA。 WHERE tempdata_key =%s ORDER BY tempdata_updatedts DESC LIMIT 1;
$ submitted_data = $ h-> db-> get_var($ h-> db-> prepare($ sql,$ key));
** if($ submitted_data){return unserialize($ submitted_data); } else {return false; } **
}
}

表中的数据,注意到结束bit有图像信息,我不是PHP的专家,所以我想知道你们/ gals可能认为什么?



tempdata_value:

  a:10:{s:16:submit_editorial; b:0; s:15:submit_orig_url; s:13:www.bbc。 co.uk; s:12:submit_title; s:14:找不到标题; s:14:submit_content; s:12:dnfsdkfjdfdf; s:15:submit_category; i:2 ; s:11:submit_tags; s:3:bbc; s:9:submit_id; b:0; s:16:submit_subscribe; i:0; s:15:submit_comments :4:open; s:5:image; s:19:C:fakepath100.jpg;} 

编辑:我想我找到了序列化位...

  / ** 
*保存提交步骤数据
*
* @return bool
* /
public function saveSubmitData($ h)
{
// delete everything在此表中超过30分钟:
$ this-> deleteTempData($ h-> db);

$ sid = preg_replace('/ [^ a-z0-9] + / i','',session_id());
$ key = md5(microtime()。$ sid。rand());
$ sql =INSERT INTO。 TABLE_TEMPDATA。 (tempdata_key,tempdata_value,tempdata_updateby)VALUES(%s,%s,%d);
$ h-> db-> query($ h-> db-> prepare($ sql,$ key,serialize($ h-> vars ['submitted_data']),$ h- > currentUser-> id));
return $ key;
}


解决方案

unserialize()[function.unserialize]:偏移处的错误是由于长度无效而导致的无效序列化数据



快速修复



你可以做的是重新计算长度序列化数组中的元素



您当前的序列化数据

  $ data ='a:10:{s:16:submit_editorial; b:0; s:15:submit_orig_url; s:13:www.bbc.co.uk ; s:12:submit_title; s:14:找不到标题; s:14:submit_content; s:12:dnfsdkfjdfdf; s:15:submit_category; i:2; 11:submit_tags; s:3:bbc; s:9:submit_id; b:0; s:16:submit_subscribe; i:0; s:15:submit_comments open; s:5:image; s:19:C:fakepath100.jpg;}'; 

不重新计算的示例

  var_dump(unserialize($ data)); 

输出

 注意:unserialize()[function.unserialize]:在338字节的偏移337处出错

重新计算



  $ data = preg_replace('!s:(\d +): 。*?);! e','s:'。strlen('$ 2')。':\$ 2\;',$ data); 
var_dump(unserialize($ data));

输出

  array 
'submit_editorial'=> boolean false
'submit_orig_url'=> string'www.bbc.co.uk'(length = 13)
'submit_title'=> string'No title found'(length = 14)
'submit_content'=> string'dnfsdkfjdfdf'(length = 12)
'submit_category'=> int 2
'submit_tags'=> string'bbc'(length = 3)
'submit_id'=> boolean false
'submit_subscribe'=> int 0
'submit_comments'=> string'open'(length = 4)
'image'=> string'C:fakepath100.jpg'(length = 17)

.. I



而不是使用这种快速修复...我建议你更新问题与




  • 如何串行处理资料


  • 如何储存资料

    li>


========================== ====== EDIT 1 =============================



错误



错误是由于使用双引号而不是单引号',这就是为什么 C:\fakepath\100.png 转换为 C:fakepath100.jpg



修复错误

您需要更改 $ h-> vars ['submitted_data'] >')



取代

  $ h-> vars ['submitted_data'] ['image'] =C:\fakepath\100.png; 

使用

  $ h-> vars ['submitted_data'] ['image'] ='C:\fakepath\100.png'; 

其他过滤器



您还可以在调用serialize之前添加这个简单的过滤器

  function satitize(& $ value,$ key)
{
$ value = addslashes($ value);
}

array_walk($ h-> vars ['submitted_data'],satitize);

如果您有UTF字符,也可以运行

  $ h-> vars ['submitted_data'] = array_map(utf8_encode,$ h-> vars ['submitted_data']); 

如何检测未来序列化数据中的问题 b
$ b

  findSerializeError($ data1); 

输出

  Diffrence 9!= 7 
- > ORD number 57!= 55
- >行号= 315
- > Section Data1 = pen; s:5:image; s:19:C:fakepath100.jpg
- > Section Data2 = pen; s:5:image; s:17:C:fakepath100.jpg
^ -------错误(元素长度)

findSerializeError 函数

  function findSerializeError($ data1){
echo< pre>;
$ data2 = preg_replace('!s:(\d +):(。*?);! e','s:'。strlen('$ 2')。':\$ 2 \;',$ data1);
$ max =(strlen($ data1)> strlen($ data2))? strlen($ data1):strlen($ data2);

echo $ data1。 PHP_EOL;
echo $ data2。 PHP_EOL;

for($ i = 0; $ i
if(@ $ data1 {$ i}!== @ $ data2 {$ i}){

echoDiffrence,@ $ data1 {$ i},!=,@ $ data2 {$ i},PHP_EOL;
echo\t-> ORD number,ord(@ $ data1 {$ i}),!=,ord(@ $ data2 {$ i}),PHP_EOL;
echo\t-> Line Number = $ i。 PHP_EOL;

$ start =($ i - 20);
$ start =($ start< 0)? 0:$ start;
$ length = 40;

$ point = $ max - $ i;
if($ point< 20){
$ rlength = 1;
$ rpoint = - $ point;
} else {
$ rpoint = $ length - 20;
$ rlength = 1;
}

echo\t-> Section Data1 =,substr_replace(substr($ data1,$ start,$ length),< b style = \color :green\> {$ data1 {$ i}}< / b>,$ rpoint,$ rlength),PHP_EOL;
echo\t-> Section Data2 =,substr_replace(substr($ data2,$ start,$ length),< b style = \color:red\> {$ data2 {$ i}}< / b>,$ rpoint,$ rlength),PHP_EOL;
}

}

}

保存到数据库的更好方法

  $ toDatabse = base64_encode ); //保存到数据库
$ fromDatabase = unserialize(base64_decode($ data)); //获取保存格式


I am using Hotaru CMS with the Image Upload plugin, I get this error if I try to attach an image to a post, otherwise there is no error.

The offending code (error points to line with **):

/**
     * Retrieve submission step data
     *
     * @param $key - empty when setting
     * @return bool
     */
    public function loadSubmitData($h, $key = '')
    {
        // delete everything in this table older than 30 minutes:
        $this->deleteTempData($h->db);

        if (!$key) { return false; }

        $cleanKey = preg_replace('/[^a-z0-9]+/','',$key);
        if (strcmp($key,$cleanKey) != 0) {
            return false;
        } else {
            $sql = "SELECT tempdata_value FROM " . TABLE_TEMPDATA . " WHERE tempdata_key = %s ORDER BY tempdata_updatedts DESC LIMIT 1";
            $submitted_data = $h->db->get_var($h->db->prepare($sql, $key));
            **if ($submitted_data) { return unserialize($submitted_data); } else { return false; }** 
        }
    }

Data from the table, notice the end bit has the image info, I am not an expert in PHP so I was wondering what you guys/gals might think?

tempdata_value:

a:10:{s:16:"submit_editorial";b:0;s:15:"submit_orig_url";s:13:"www.bbc.co.uk";s:12:"submit_title";s:14:"No title found";s:14:"submit_content";s:12:"dnfsdkfjdfdf";s:15:"submit_category";i:2;s:11:"submit_tags";s:3:"bbc";s:9:"submit_id";b:0;s:16:"submit_subscribe";i:0;s:15:"submit_comments";s:4:"open";s:5:"image";s:19:"C:fakepath100.jpg";}

Edit: I think I've found the serialize bit...

/**
     * Save submission step data
     *
     * @return bool
     */
    public function saveSubmitData($h)
    {
        // delete everything in this table older than 30 minutes:
        $this->deleteTempData($h->db);

        $sid = preg_replace('/[^a-z0-9]+/i', '', session_id());
        $key = md5(microtime() . $sid . rand());
        $sql = "INSERT INTO " . TABLE_TEMPDATA . " (tempdata_key, tempdata_value, tempdata_updateby) VALUES (%s,%s, %d)";
        $h->db->query($h->db->prepare($sql, $key, serialize($h->vars['submitted_data']), $h->currentUser->id));
        return $key;
    }

解决方案

unserialize() [function.unserialize]: Error at offset was dues to invalid serialization data due to invalid length

Quick Fix

What you can do is is recalculating the length of the elements in serialized array

You current serialized data

$data = 'a:10:{s:16:"submit_editorial";b:0;s:15:"submit_orig_url";s:13:"www.bbc.co.uk";s:12:"submit_title";s:14:"No title found";s:14:"submit_content";s:12:"dnfsdkfjdfdf";s:15:"submit_category";i:2;s:11:"submit_tags";s:3:"bbc";s:9:"submit_id";b:0;s:16:"submit_subscribe";i:0;s:15:"submit_comments";s:4:"open";s:5:"image";s:19:"C:fakepath100.jpg";}';

Example without recalculation

var_dump(unserialize($data));

Output

Notice: unserialize() [function.unserialize]: Error at offset 337 of 338 bytes

Recalculating

$data = preg_replace('!s:(\d+):"(.*?)";!e', "'s:'.strlen('$2').':\"$2\";'", $data);
var_dump(unserialize($data));

Output

array
  'submit_editorial' => boolean false
  'submit_orig_url' => string 'www.bbc.co.uk' (length=13)
  'submit_title' => string 'No title found' (length=14)
  'submit_content' => string 'dnfsdkfjdfdf' (length=12)
  'submit_category' => int 2
  'submit_tags' => string 'bbc' (length=3)
  'submit_id' => boolean false
  'submit_subscribe' => int 0
  'submit_comments' => string 'open' (length=4)
  'image' => string 'C:fakepath100.jpg' (length=17)

Recommendation .. I

Instead of using this kind of quick fix ... i"ll advice you update the question with

  • How you are serializing your data

  • How you are Saving it ..

================================ EDIT 1 ===============================

The Error

The Error was generated because of use of double quote " instead single quote ' that is why C:\fakepath\100.png was converted to C:fakepath100.jpg

To fix the error

You need to change $h->vars['submitted_data'] From (Note the singe quite ' )

Replace

 $h->vars['submitted_data']['image'] = "C:\fakepath\100.png" ;

With

 $h->vars['submitted_data']['image'] = 'C:\fakepath\100.png' ;

Additional Filter

You can also add this simple filter before you call serialize

function satitize(&$value, $key)
{
    $value = addslashes($value);
}

array_walk($h->vars['submitted_data'], "satitize");

If you have UTF Characters you can also run

 $h->vars['submitted_data'] = array_map("utf8_encode",$h->vars['submitted_data']);

How to detect the problem in future serialized data

  findSerializeError ( $data1 ) ;

Output

Diffrence 9 != 7
    -> ORD number 57 != 55
    -> Line Number = 315
    -> Section Data1  = pen";s:5:"image";s:19:"C:fakepath100.jpg
    -> Section Data2  = pen";s:5:"image";s:17:"C:fakepath100.jpg
                                            ^------- The Error (Element Length)

findSerializeError Function

function findSerializeError($data1) {
    echo "<pre>";
    $data2 = preg_replace ( '!s:(\d+):"(.*?)";!e', "'s:'.strlen('$2').':\"$2\";'",$data1 );
    $max = (strlen ( $data1 ) > strlen ( $data2 )) ? strlen ( $data1 ) : strlen ( $data2 );

    echo $data1 . PHP_EOL;
    echo $data2 . PHP_EOL;

    for($i = 0; $i < $max; $i ++) {

        if (@$data1 {$i} !== @$data2 {$i}) {

            echo "Diffrence ", @$data1 {$i}, " != ", @$data2 {$i}, PHP_EOL;
            echo "\t-> ORD number ", ord ( @$data1 {$i} ), " != ", ord ( @$data2 {$i} ), PHP_EOL;
            echo "\t-> Line Number = $i" . PHP_EOL;

            $start = ($i - 20);
            $start = ($start < 0) ? 0 : $start;
            $length = 40;

            $point = $max - $i;
            if ($point < 20) {
                $rlength = 1;
                $rpoint = - $point;
            } else {
                $rpoint = $length - 20;
                $rlength = 1;
            }

            echo "\t-> Section Data1  = ", substr_replace ( substr ( $data1, $start, $length ), "<b style=\"color:green\">{$data1 {$i}}</b>", $rpoint, $rlength ), PHP_EOL;
            echo "\t-> Section Data2  = ", substr_replace ( substr ( $data2, $start, $length ), "<b style=\"color:red\">{$data2 {$i}}</b>", $rpoint, $rlength ), PHP_EOL;
        }

    }

}

A better way to save to Database

$toDatabse = base64_encode(serialize($data));  // Save to database
$fromDatabase = unserialize(base64_decode($data)); //Getting Save Format 

这篇关于unserialize()[function.unserialize]:偏移时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆