如何修复因不正确的字节计数长度而损坏的序列化字符串?
我正在使用带有图片上传插件的 Hotaru CMS,如果我尝试将图片附加到帖子中,我会收到此错误,否则不会出现错误:
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:
unserialize() [function.unserialize]: 偏移处出错
unserialize() [function.unserialize]: Error at offset
违规代码(错误点与**一致):
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; }**
}
}
表格中的数据,注意末尾有图像信息,我不是 PHP 专家,所以我想知道你们/女孩会怎么想?
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?
临时数据值:
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";}
我想我找到了序列化位...
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
is due to invalid serialization data
due长度无效
unserialize() [function.unserialize]: Error at offset
was dues to invalid serialization data
due to invalid length
快速修复
你可以做的是重新计算序列化数组中元素的长度
您当前的序列化数据
$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";}';
无需重新计算的示例
var_dump(unserialize($data));
输出
Notice: unserialize() [function.unserialize]: Error at offset 337 of 338 bytes
重新计算
$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)
推荐 ..我
不要使用这种快速修复...我建议您使用
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 ..
================================= 编辑 1 ================================
错误
错误是由于使用双引号 "
而不是单引号 '
而产生的,这就是为什么 C:fakepath100.png
被转换为 C:fakepath100.jpg
The Error was generated because of use of double quote "
instead single quote '
that is why C:fakepath100.png
was converted to C:fakepath100.jpg
修复错误
你需要把 $h->vars['submitted_data']
从(注意单很 '
)
You need to change $h->vars['submitted_data']
From (Note the singe quite '
)
替换
$h->vars['submitted_data']['image'] = "C:fakepath100.png" ;
有
$h->vars['submitted_data']['image'] = 'C:fakepath100.png' ;
附加过滤器
你也可以在调用serialize之前添加这个简单的过滤器
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");
如果你有 UTF 字符,你也可以运行
If you have UTF Characters you can also run
$h->vars['submitted_data'] = array_map("utf8_encode",$h->vars['submitted_data']);
如何检测未来序列化数据中的问题
findSerializeError ( $data1 ) ;
输出
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 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 " -> ORD number ", ord ( @$data1 {$i} ), " != ", ord ( @$data2 {$i} ), PHP_EOL;
echo " -> 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 " -> Section Data1 = ", substr_replace ( substr ( $data1, $start, $length ), "<b style="color:green">{$data1 {$i}}</b>", $rpoint, $rlength ), PHP_EOL;
echo " -> Section Data2 = ", substr_replace ( substr ( $data2, $start, $length ), "<b style="color:red">{$data2 {$i}}</b>", $rpoint, $rlength ), PHP_EOL;
}
}
}
保存到数据库的更好方法
$toDatabse = base64_encode(serialize($data)); // Save to database
$fromDatabase = unserialize(base64_decode($data)); //Getting Save Format
相关文章