একটি ভুল বাইট গণনা দৈর্ঘ্য দ্বারা দূষিত হয়েছে এমন সিরিয়ালযুক্ত স্ট্রিং কীভাবে মেরামত করবেন?


98

আমি চিত্র আপলোড প্লাগইন সহ হোতারু সিএমএস ব্যবহার করছি, যদি আমি কোনও পোস্টে কোনও চিত্র সংযুক্ত করার চেষ্টা করি তবে আমি এই ত্রুটিটি পেয়েছি, অন্যথায় কোনও ত্রুটি নেই:

আনসিরিয়ালাইজ () [ফাংশন.উনসিরিয়ালাইজ]: অফসেটে ত্রুটি

আপত্তিজনক কোড (ত্রুটিটি ** এর সাথে সামঞ্জস্য করে):

/**
     * 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; }** 
        }
    }

টেবিল থেকে ডেটা, লক্ষ্য করুন শেষ বিটের চিত্রের তথ্য রয়েছে, আমি পিএইচপি-তে কোনও বিশেষজ্ঞ নই তাই আমি ভাবছিলাম যে আপনি / ছেলেরা কী ভাবতে পারে?

টেম্পডাটা_মূল্য:

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";}

সম্পাদনা: আমার মনে হয় আমি সিরিয়ালটিকে কিছুটা খুঁজে পেয়েছি ...

/**
     * 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;
    }

4
আমার জন্য এটির জন্য দ্রুত সমাধানটি সিরিয়ালাইজ / আনসিরিয়ালাইজ করার আগে বেস 64__এনকোড / ডিকোড ব্যবহার করা হয়েছিল। davidwalsh.name/php-serialize- unserialize
ভ্যালেনটিন দেশপা

4
আমি জানি না তবে কেন আমার যোগ করা সমাধানের সাথে সমাধান হয়েছে,@unserialize($product->des_txtmopscol);
ভাভিন রানা

4
@ ভাবিনরানা যোগ @করা সমাধানের সময় ত্রুটি নয়, এটি চুপ করে যাওয়া ত্রুটি - আসলে সেই কৌশলটি দিয়ে কিছুই "স্থির হয় না"।
মিকম্যাকুসা

উত্তর:


219

unserialize() [function.unserialize]: Error at offsetinvalid serialization dataঅবৈধ দৈর্ঘ্যের কারণে বকেয়া ছিল

দ্রুত ঠিক করা

আপনি যা করতে পারেন তা হ'ল recalculating the 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)

সুপারিশ .. আই

এই জাতীয় দ্রুত সমাধানটি ব্যবহার না করে ... আমি আপনাকে পরামর্শটি দিয়ে আপডেট করব

  • আপনি কীভাবে আপনার ডেটা সিরিয়ালাইজ করছেন

  • আপনি এটি কীভাবে সংরক্ষণ করছেন ..

=============================== সম্পাদনা 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' ;

অতিরিক্ত ফিল্টার

সিরিয়ালাইজ করার আগে আপনি এই সাধারণ ফিল্টারটি যুক্ত করতে পারেন

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

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

আপনার যদি ইউটিএফ অক্ষর থাকে তবে আপনি চালাতেও পারেন

 $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 "\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(serialize($data));  // Save to database
$fromDatabase = unserialize(base64_decode($data)); //Getting Save Format 

4
বাবা, আমি আপনার আশ্চর্যজনক findSerializeErrorফাংশনটি ব্যবহার করেছি এবং প্রচুর ত্রুটি পেয়েছি। দয়া করে আমার বিষয়টি
ম্যাক্স কোরেটস্কিই

4
base64এটি ডাটাবেসে যুক্ত করার আগে নিবন্ধটি ব্যবহার করুন ... এটি নাল চরিত্রটি সংরক্ষণ করবে
বাবা

4
এটি ডাটাবেসে সংরক্ষণের জন্য আরও ভাল উপায় নয়। এটি হ'ল যদি না আপনি ডাটাবেসের উদ্দেশ্যটিকে সম্পূর্ণ অবহেলা করতে চান। আপনি কীভাবে এনক্রিপ্ট করা মানগুলির একটি গোছায় একটি অনুসন্ধান সম্পাদন করতে যাচ্ছেন? ফোটা উল্লেখ না, উগ। সঠিক এনকোডিং হ'ল সঠিক উত্তর।
দেজি

4
যদি পিএইচপি 5.5 ব্যবহার করে থাকেন তবে @ r00tAcc3ss উত্তরটি দেখুন! stackoverflow.com/a/21389439/1003020
ভিনিসিয়াস গার্সিয়া

6
আপনি এই ভুল পান তাহলে "preg_replace (): / E পরিবর্তক আর সমর্থিত নয়, ব্যবহার preg_replace_callback পরিবর্তে" php7 মধ্যে - এই উত্তর কাজ করে stackoverflow.com/a/21389439/2011434
BenB

84

মন্তব্য করার মতো যথেষ্ট খ্যাতি আমার নেই, সুতরাং আমি আশা করি উপরের "সঠিক" উত্তরটি ব্যবহার করে লোকেরা এটি দেখেছে:

পিএইচপি 5.5 থেকে প্রিগ_রেপ্লেস (/) এ / ই সংশোধক সম্পূর্ণরূপে হ্রাস পেয়েছে এবং উপরের প্রিগ_ম্যাচটি ত্রুটিযুক্ত হবে। পিএইচপি ডকুমেন্টেশন তার জায়গায় preg_match_callback ব্যবহার করার পরামর্শ দেয়।

উপরের প্রস্তাবিত প্রিগ_ম্যাচের বিকল্প হিসাবে দয়া করে নীচের সমাধানটি সন্ধান করুন।

$fixed_data = preg_replace_callback ( '!s:(\d+):"(.*?)";!', function($match) {      
    return ($match[1] == strlen($match[2])) ? $match[0] : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
},$bad_data );

4
পৃষ্ঠায় এটি কেবলমাত্র একমাত্র উত্তরের মতো বলে মনে হচ্ছে যা প্রকৃতপক্ষে প্রথম ক্যাপচার গোষ্ঠীকে ভাল ব্যবহারের জন্য রাখে। যদিও বুদ্ধিমানের প্রোগ্রামিং শুধুমাত্র প্রতিস্থাপন করা যেখানে বাইট গণনা হয় আসলে ভুল, এই সমাধান ক্যাশে নেই strlen()এবং সেইজন্য অপ্রয়োজনীয় ফাংশন কল করে তোলে। ব্যক্তিগতভাবে, আমি একটি ইনলাইন শর্তটি খুব ভার্জোজ বলে মনে করি তবে এই স্নিপেটটি ভাল কারণে ভাল কাজ করে।
মিকম্যাকুসা

4
এটি আমার জন্য নিম্নলিখিত রেজেক্সের সাথে কাজ করেছে '!s:(\d+):"(.*?)";!s'(পাশাপাশি একটি নতুন 'লাইন নিতে শেষ হওয়া')। নীচে অ্যাডিলবো মন্তব্যে ধন্যবাদ।
আরনোহোলো

13

আর একটি কারণ unserialize()ব্যর্থ হয়েছে কারণ আপনি ভুলভাবে সিরিয়ালযুক্ত ডেটা ডাটাবেসে রেখেছেন এখানে অফিশিয়াল ব্যাখ্যা দেখুন । যেহেতু serialize()বাইনারি ডেটা এবং পিএইচপি ভেরিয়েবলগুলি এনকোডিং পদ্ধতিগুলির যত্ন করে না, সুতরাং এটি পাঠ্যর মধ্যে রাখলে, ভারচার () এই ত্রুটি ঘটায়।

সমাধান: আপনার টেবিলের বিএলওবিতে সিরিয়ালযুক্ত ডেটা সঞ্চয় করুন।


এটি লারাভেল ৫ এ আমার সমস্যার সমাধান করেছে I আমি কলামের সংজ্ঞাটি স্ট্রিং () থেকে বাইনারি () এ পরিবর্তন করেছি।
ডাব্লুএনরোজেনবার্গ

ওপির প্রশ্নটিতে মাইএসকিএল কলামের ধরণের সমস্যা আছে বলে মনে হয় না। এটি imageমানটির উপর একটি ভুল বাইট গণনা দ্বারা দৃশ্যত দূষিত rupted আপনার উত্তরটি ওপি-র নির্দিষ্ট প্রশ্নের সাথে সম্পর্কিত নয়। : আপনি আপনার পরামর্শ সরাতে পারেন stackoverflow.com/q/5544749/2943403
mickmackusa

11

দ্রুত ঠিক করা

সিরিয়ালযুক্ত অ্যারেতে উপাদানগুলির দৈর্ঘ্যের পুনরায় গণনা করা - তবে এটি অবচিত হয়েছে (প্রিগ_রেপ্লেস) ব্যবহার করবেন না - ভাল ব্যবহার করুন preg_replace_callback:

সম্পাদনা: নতুন সংস্করণ এখন শুধু ভুল দৈর্ঘ্য কিন্তু এটি ফিক্স লাইন ব্রেক এবং aczent সঙ্গে সঠিক অক্ষর গণনা (ধন্যবাদ mickmackusa )

// New Version
$data = preg_replace_callback('!s:\d+:"(.*?)";!s', function($m) { return "s:" . strlen($m[1]) . ':"'.$m[1].'";'; }, $data);

4
এই ভুল সমাধানটিতে 8 টি আপগেট কীভাবে থাকবে? আমি ভাবতে চাইছি কত লোক অজান্তেই এই ওয়ান-লাইনারটি অনুলিপি করেছিল। : [দুঃখী মুখ] এখানে যা এই স্নিপেট ব্যর্থ হবে দুটি উপায়ে প্রমাণ 3v4l.org/Cf6Nh @ আমার পরিশ্রুত প্যাটার্ন এবং কাস্টম প্রতিস্থাপন দেখুন stackoverflow.com/a/55074706/2943403
mickmackusa

4
আমার সমাধানটি এখন অন্য পৃষ্ঠায় নেই কারণ এটি বিপর্যয়করভাবে ক্ষতিগ্রস্থ সিরিয়ালাইজড স্ট্রিংয়ের জন্য একটি ভুল সমাধান ছিল। আমি আমার স্নিপেটটি এই পৃষ্ঠায় যুক্ত করেছি এবং ব্যাখ্যা এবং বিক্ষোভ সরবরাহ করেছি। stackoverflow.com/a/55566407/2943403
mickmackusa

5

আপনার অক্ষরটি ভুল হওয়ায় এই ত্রুটি ঘটেছে।

খোলা ট্যাগের পরে চরসেট সেট করুন:

header('Content-Type: text/html; charset=utf-8');

এবং আপনার ডাটাবেসে চরসেট utf8 সেট করুন:

mysql_query("SET NAMES 'utf8'");

চার্সেটের কারণে দুর্নীতি হয়েছে তা বোঝাতে ওপির পোস্ট করা প্রশ্নের মধ্যে আমি কোনও ইঙ্গিত দেখছি না। আপনার দাবিটি রক্ষা করতে নিখরচায়, তবে যতদূর আমি বলতে পারি যে কেউ ম্যানুয়ালি imageমানটি আপডেট করেছে এবং বাইট গণনা আপডেট করতে ব্যর্থ হয়েছে। অন্যথায় অবহিত না হলে আমাকে ধরে নিতে হবে যে এই উত্তরটি ওপির প্রশ্নের জন্য ভুল।
মিকম্যাকুসা

4

মাল্টিবাইট অক্ষর হ্যান্ডলিং সহ নিম্নলিখিত ফাংশনটি ব্যবহার করে আপনি ভাঙা সিরিয়ালাইজ স্ট্রিং ঠিক করতে পারেন ।

function repairSerializeString($value)
{

    $regex = '/s:([0-9]+):"(.*?)"/';

    return preg_replace_callback(
        $regex, function($match) {
            return "s:".mb_strlen($match[2]).":\"".$match[2]."\""; 
        },
        $value
    );
}

এই উত্তরটি যা সুপারিশ করছে তার মূলটি কেবল ভুল এবং সম্ভবত পুরোপুরি বৈধ সিরিয়ালযুক্ত স্ট্রিংগুলি ক্ষতিগ্রস্থ করবে। এই স্নিপেটটি ব্যবহার / বিশ্বাসযোগ্য হওয়া উচিত নয়।
মিকম্যাকুসা

@ মিকম্যাকুসা আমি আপনার বক্তব্য পাচ্ছি না, আপনি কি দয়া করে এটি করার সর্বোত্তম উপায়ের পরামর্শ দিতে পারেন? বা এই উত্তরে সম্পাদনার পরামর্শ দিন ..
রাজেজ মেনিয়া

আমি এখানে একটি সঠিক সমাধান সরবরাহ করেছি: স্ট্যাকওভারফ্লো.com/ a/ 55566407 / 2943403 এবং ব্যাখ্যা করেছেন যে mb_strlen()এটি অনুপযুক্ত কারণ serialize()বাইট গণনাটি সঞ্চয় করে, চরিত্রের সংখ্যাটি নয়। আপনার উত্তরটিকে সঠিক হিসাবে সম্পাদনা করা কেবলমাত্র পৃষ্ঠায় অপ্রয়োজনীয় পরামর্শ তৈরি করবে।
মিকম্যাকুসা

4
$badData = 'a:2:{i:0;s:16:"as:45:"d";
Is \n";i:1;s:19:"as:45:"d";
Is \r\n";}';

আপনি প্রস্তাবিত রেজিক্সগুলি ব্যবহার করে একটি ভাঙা সিরিয়ালাইজ স্ট্রিং ঠিক করতে পারবেন না:

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

// or

$data = preg_replace_callback(
    '/s:(\d+):"(.*?)";/',
    function($m){
        return 's:' . strlen($m[2]) . ':"' . $m[2] . '";';
    },
    $badData
);
var_dump(@unserialize($data)); // Output: bool(false)

আপনি নিম্নলিখিত রেজেক্স ব্যবহার করে ভাঙা সিরিয়ালাইজ স্ট্রিং ঠিক করতে পারেন:

$data = preg_replace_callback(
    '/(?<=^|\{|;)s:(\d+):\"(.*?)\";(?=[asbdiO]\:\d|N;|\}|$)/s',
    function($m){
        return 's:' . strlen($m[2]) . ':"' . $m[2] . '";';
    },
    $badData
);

var_dump(@unserialize($data));

আউটপুট

array(2) {
  [0] =>
  string(17) "as:45:"d";
Is \n"
  [1] =>
  string(19) "as:45:"d";
Is \r\n"
}

বা

array(2) {
  [0] =>
  string(16) "as:45:"d";
Is \n"
  [1] =>
  string(18) "as:45:"d";
Is \r\n"
}

4
ধন্যবাদ মিকম্যাকুসা মাল্টিবাইট এনকোডিংগুলির সাথে কোনও সমস্যা সমাধান করা হয়েছে।
Путилин

4
public function unserializeKeySkills($string) {
    $output = array();
    $string = trim(preg_replace('/\s\s+/', ' ',$string));
    $string = preg_replace_callback('!s:(\d+):"(.*?)";!', function($m) { return 's:'.strlen($m[2]).':"'.$m[2].'";'; }, utf8_encode( trim(preg_replace('/\s\s+/', ' ',$string)) ));
    try {
        $output =  unserialize($string);
    } catch (\Exception $e) {
        \Log::error("unserialize Data : " .print_r($string,true));
    }
    return $output;
}

পিএইচপি আনসিরিয়ালাইজ করুন
পারদীপ

এই সমাধানটি অনেক ক্ষেত্রে উপযুক্ত নয়। এটি এই ধারণাটি তৈরি করে যে প্রত্যেকে 2 বা আরও বেশি শ্বেত স্পেস অক্ষরগুলিকে একটি আক্ষরিক স্থানে এবং trim()প্রতিটি মিলিত স্ট্রাস্ট্রিতে রূপান্তর করতে সিরিয়ালযুক্ত স্ট্রিংয়ের মানগুলিকে রূপান্তর করতে চায় । এই পয়েন্টটি একাই এই সমাধানটিকে সুপারিশ করা অসম্ভব করে তোলে। তদ্ব্যতীত, এটি নিউলাইন চরিত্রগুলিতে শ্বাসরোধ করবে এবং অকারণে পূর্ব-বিদ্যমান বাইট গণনাটি ক্যাপচার করবে যা কেবল কোনওভাবেই ওভাররাইট করা যাচ্ছে। অবশেষে, এটি একটি "কেবল কোড উত্তর" এবং ভবিষ্যতের গবেষকদের শিক্ষিত / ক্ষমতায়নের জন্য তারা সামান্য কিছু করার কারণে এই ধরণের উত্তরগুলি স্বল্প-মূল্যযুক্ত।
মিকম্যাকুসা

2

সরকারী দস্তাবেজ বলেছেন মিথ্যা এবং সেট E_NOTICE ফেরত পাঠাবেন

তবে যেহেতু আপনি ত্রুটি পেয়েছেন তারপরে ত্রুটি প্রতিবেদন E_NOTICE দ্বারা ট্রিগার করা সেট করা আছে

আপনাকে মিথ্যা ফেরত পাঠানোর অনুমতি দেওয়ার জন্য এখানে একটি স্থিরতা রয়েছে unserialize

$old_err=error_reporting(); 
error_reporting($old_err & ~E_NOTICE);
$object = unserialize($serialized_data);
error_reporting($old_err);

আপনি বেস 64 এনকোড / ডিকোড ব্যবহার বিবেচনা করতে পারেন

$string=base64_encode(serialize($obj));
unserialize(base64_decode($string));

base64_encodeআমার জন্য কৌশলটি। আমি যদি বলি আমরা serializeকমান্ড লাইনের উপর দিয়ে ডেটা পাস করছি এবং দেখে মনে হচ্ছে কিছু অদ্ভুত চরিত্রগুলি এটি সঠিকভাবে কাজ করা থেকে বিরত করছে।
কুইকশিফটিন

base64_encode()ওপি কর্তৃক জিজ্ঞাসিত প্রশ্নের সমাধান নয়। ওপি-র প্রশ্ন / ইস্যুটি বিশেষত এই বিষয়টি নিয়ে কাজ করছে যে (সম্ভবত সিরিয়ালাইজড স্ট্রিংয়ের "চূড়ান্ত অ্যারে উপাদান" -এ কোনও অনুপযুক্ত সাবস্ট্রিং প্রতিস্থাপনের কাজটি করা হয়েছে) সিরিয়ালযুক্ত স্ট্রিংয়ে একটি ভুল বাইট গণনা রয়েছে। দয়া করে কেবল এমন উত্তরগুলি পোস্ট করুন যা জিজ্ঞাসিত প্রশ্নের সরাসরি সমাধান করে।
মিকম্যাকুসা

2

এই প্রশ্নের দুর্নীতিটি সিরিয়ালযুক্ত স্ট্রিংয়ের শেষে একক স্ট্রাস্টিংয়ের সাথে বিচ্ছিন্ন হয়ে সম্ভবত ম্যানুয়ালি এমন কোনও ব্যক্তি দ্বারা প্রতিস্থাপন করা হয়েছিল যিনি অলসভাবে imageফাইলের নাম আপডেট করতে চেয়েছিলেন । এই সত্যটি নীচে আমার অপারেশন লিঙ্কে অপের পোস্টের ডেটা ব্যবহার করে স্পষ্ট হবে - সংক্ষেপে, এর C:fakepath100.jpgদৈর্ঘ্য নেই 19, এটি হওয়া উচিত 17

যেহেতু সিরিয়ালযুক্ত স্ট্রিং দুর্নীতিটি একটি ভুল বাইট / চরিত্রের গণনা সংখ্যার মধ্যে সীমাবদ্ধ, নীচেরগুলি সঠিক বাইট গণনা মান সহ দূষিত স্ট্রিং আপডেট করার ক্ষেত্রে সূক্ষ্ম কাজ করবে।

নিম্নলিখিত রেজেক্স ভিত্তিক প্রতিস্থাপন কেবলমাত্র বাইট গণনা নিরাময়ে কার্যকর হবে, আরও কিছু নয়।

দেখে মনে হচ্ছে আগের পোস্টগুলির অনেকগুলিই অন্য কারও কাছ থেকে কেবলমাত্র একটি রেজেক্স প্যাটার্নটি অনুলিপি করছে। সম্ভাব্য দূষিত বাইট গণনা নম্বর ক্যাপচার করার কোনও কারণ নেই যদি এটি প্রতিস্থাপনে ব্যবহৃত হয় না। এছাড়াও, sস্ট্রিংয়ের মানটিতে নতুন লাইন / লাইন রিটার্ন থাকে এমন ক্ষেত্রে প্যাটার্ন সংশোধক যুক্ত করা যুক্তিসঙ্গত অন্তর্ভুক্তি।

* যারা সিরিয়ালাইজেশনের সাথে মাল্টিবাইট অক্ষরগুলির চিকিত্সা সম্পর্কে সচেতন নয় তাদের জন্য আপনার অবশ্যই mb_strlen()কাস্টম কলব্যাক ব্যবহার করা উচিত নয় কারণ এটি বাইট গণনা যা চরিত্রের গণনা নয় , আমার আউটপুট দেখুন ...

কোড: ( ওপির ডেটা সহ ডেমো সহ ডেমো ) ( স্বেচ্ছাসেবী নমুনা ডেটার সাথে ডেমো ) ( শর্ত প্রতিস্থাপনের সাথে ডেমো )

$corrupted = <<<STRING
a:4:{i:0;s:3:"three";i:1;s:5:"five";i:2;s:2:"newline1
newline2";i:3;s:6:"garçon";}
STRING;

$repaired = preg_replace_callback(
        '/s:\d+:"(.*?)";/s',
        //  ^^^- matched/consumed but not captured because not used in replacement
        function ($m) {
            return "s:" . strlen($m[1]) . ":\"{$m[1]}\";";
        },
        $corrupted
    );

echo $corrupted , "\n" , $repaired;
echo "\n---\n";
var_export(unserialize($repaired));

আউটপুট:

a:4:{i:0;s:3:"three";i:1;s:5:"five";i:2;s:2:"newline1
Newline2";i:3;s:6:"garçon";}
a:4:{i:0;s:5:"three";i:1;s:4:"five";i:2;s:17:"newline1
Newline2";i:3;s:7:"garçon";}
---
array (
  0 => 'three',
  1 => 'five',
  2 => 'newline1
Newline2',
  3 => 'garçon',
)

খরগোশের গর্তের এক পা নীচে ..."; উপরেরটি স্ট্রিংয়ের মানতে ডাবল উদ্ধৃতি উপস্থিত থাকলেও ঠিকঠাক কাজ করে, তবে যদি স্ট্রিংয়ের মানটিতে বা অন্য কোনও বানরচোলক সংবলিত থাকে তবে আপনাকে আরও কিছুটা এগিয়ে যেতে হবে এবং "বর্ণমালার" প্রয়োগ করতে হবে। আমার নতুন প্যাটার্ন

নেতৃস্থানীয় যে পরীক্ষা করে s:

  • পুরো ইনপুট স্ট্রিং শুরু বা
  • পূর্ববর্তী দ্বারা ;

এবং চেক যে "; :

  • পুরো ইনপুট স্ট্রিং এর শেষে বা
  • অনুসরণ করেছে } বা
  • তারপরে স্ট্রিং বা পূর্ণসংখ্যা ঘোষণা s:বা ori:

আমি প্রতিটি সম্ভাবনা পরীক্ষা করি নি; প্রকৃতপক্ষে, আমি সিরিয়ালযুক্ত স্ট্রিংয়ের সমস্ত সম্ভাবনার সাথে তুলনামূলকভাবে অপরিচিত কারণ আমি সিরিয়ালযুক্ত ডেটার সাথে কাজ করার জন্য নির্বাচন করি না - সর্বদা আধুনিক অ্যাপ্লিকেশনগুলিতে জেএসন। যদি অতিরিক্ত সম্ভাব্য নেতৃস্থানীয় বা অনুসরণীয় অক্ষর থাকে তবে একটি মন্তব্য করুন এবং আমি চেহারাগুলি বাড়িয়ে দেব।

বর্ধিত স্নিপেট: ( ডেমো )

$corrupted_byte_counts = <<<STRING
a:12:{i:0;s:3:"three";i:1;s:5:"five";i:2;s:2:"newline1
newline2";i:3;s:6:"garçon";i:4;s:111:"double " quote \"escaped";i:5;s:1:"a,comma";i:6;s:9:"a:colon";i:7;s:0:"single 'quote";i:8;s:999:"semi;colon";s:5:"assoc";s:3:"yes";i:9;s:1:"monkey";wrenching doublequote-semicolon";s:3:"s:";s:9:"val s: val";}
STRING;

$repaired = preg_replace_callback(
        '/(?<=^|;)s:\d+:"(.*?)";(?=$|}|[si]:)/s',
        //^^^^^^^^--------------^^^^^^^^^^^^^-- some additional validation
        function ($m) {
            return 's:' . strlen($m[1]) . ":\"{$m[1]}\";";
        },
        $corrupted_byte_counts
    );

echo "corrupted serialized array:\n$corrupted_byte_counts";
echo "\n---\n";
echo "repaired serialized array:\n$repaired";
echo "\n---\n";
print_r(unserialize($repaired));

আউটপুট:

corrupted serialized array:
a:12:{i:0;s:3:"three";i:1;s:5:"five";i:2;s:2:"newline1
newline2";i:3;s:6:"garçon";i:4;s:111:"double " quote \"escaped";i:5;s:1:"a,comma";i:6;s:9:"a:colon";i:7;s:0:"single 'quote";i:8;s:999:"semi;colon";s:5:"assoc";s:3:"yes";i:9;s:1:"monkey";wrenching doublequote-semicolon";s:3:"s:";s:9:"val s: val";}
---
repaired serialized array:
a:12:{i:0;s:5:"three";i:1;s:4:"five";i:2;s:17:"newline1
newline2";i:3;s:7:"garçon";i:4;s:24:"double " quote \"escaped";i:5;s:7:"a,comma";i:6;s:7:"a:colon";i:7;s:13:"single 'quote";i:8;s:10:"semi;colon";s:5:"assoc";s:3:"yes";i:9;s:39:"monkey";wrenching doublequote-semicolon";s:2:"s:";s:10:"val s: val";}
---
Array
(
    [0] => three
    [1] => five
    [2] => newline1
newline2
    [3] => garçon
    [4] => double " quote \"escaped
    [5] => a,comma
    [6] => a:colon
    [7] => single 'quote
    [8] => semi;colon
    [assoc] => yes
    [9] => monkey";wrenching doublequote-semicolon
    [s:] => val s: val
)

1

আপনার সাথে কোলেশন প্রকারটি পরিবর্তন করতে utf8_unicode_ciহবে এবং সমস্যাটি স্থির হবে।


ওপেনের নমুনা ডেটাতে কোন নির্দিষ্ট চরিত্রটি বিশ্বাস করেন যে কোলেশন পরিবর্তন করে পরিবর্তিত হবে utf8_unicode_ci? আমি এই সম্পর্কে আমার সন্দেহ আছে।
মিকম্যাকুসা

এটি আসলে আমার জন্যও কাজ করেছে (r00tAcc3ss 'উত্তর বাদে) কারও কাছ থেকে কোনও শব্দ কেন স্পষ্ট করে বলছে? ব্যাকগ্রাউন্ড হিসাবে, আমি একটি API কল থেকে রিসোর্সস্পেস অ্যাপ্লিকেশনটিতে ডেটা নিয়ে যাই, এটি একটি অ্যারেতে সঞ্চয় করি, এটি সিরিয়ালায়িত করি এবং এটি সংরক্ষণ করি। সিরিয়ালযুক্ত ডেটা সংরক্ষণ করার সমস্যা ছিল তাই আমাকে এটি ইউটিএফ -8 এ ম্যানুয়ালি এনকোড করতে হয়েছিল, আমি ডিবিতে কোলেশন এবং চরিত্র সেট নিয়ে ঘুরে বেড়াচ্ছিলাম এবং অবশেষে utf8_general_ci কোলেশন রেখে গিয়েছিলাম, যখন আমি এটিকে utf8_unicode_ci এ পরিবর্তন করেছি, এটি কাজ করেছিল ।
রবার্তো বেসেরা

1

আমার ক্ষেত্রে আমি BLOBমাইএসকিউএল ডিবি এর ক্ষেত্রে সিরিয়ালযুক্ত তথ্য সংরক্ষণ করছিলাম যা স্পষ্টতই পুরো মানটি ধারণ করতে যথেষ্ট বড় ছিল না এবং এটি কেটে ফেলেছিল। এই জাতীয় একটি স্ট্রিং স্পষ্টতই unserialized করা যায়নি।
একবার সেই ক্ষেত্রটিকে MEDIUMBLOBসমস্যাটি থেকে বিকশিত করে। এছাড়াও এটা টেবিলের বিকল্পগুলিতে স্যুইচ করতে প্রয়োজন হতে পারে ROW_FORMATকরতে DYNAMICবা COMPRESSED


আমার কাছে - যদিও আমার TEXTক্ষেত্র ছিল এবং যেমনটি 65 কেবিতে কাটা হয়েছে।
অ্যান্টনি

এই প্রশ্নটি কাটা কাটা হয় না। ওপি-র প্রশ্ন / ইস্যুটি বিশেষত এই বিষয়টি নিয়ে কাজ করছে যে (সম্ভবত সিরিয়ালাইজড স্ট্রিংয়ের "চূড়ান্ত অ্যারে উপাদান" -এ কোনও অনুপযুক্ত সাবস্ট্রিং প্রতিস্থাপনের কাজটি করা হয়েছে) সিরিয়ালযুক্ত স্ট্রিংয়ে একটি ভুল বাইট গণনা রয়েছে। দয়া করে কেবল এমন উত্তরগুলি পোস্ট করুন যা জিজ্ঞাসিত প্রশ্নের সরাসরি সমাধান করে।
মিকম্যাকুসা

1

সাফল্য ছাড়াই এই পৃষ্ঠায় কিছু জিনিস চেষ্টা করার পরে আমি পৃষ্ঠা-উত্সটিতে নজর রেখেছিলাম এবং মন্তব্য করেছিলেন যে সিরিয়ালযুক্ত স্ট্রিংয়ের সমস্ত উদ্ধৃতি এইচটিএমএল-সত্তা দ্বারা প্রতিস্থাপন করা হয়েছে। এই সত্তাগুলি ডিকোডিং অনেক মাথাব্যথা এড়াতে সহায়তা করে:

$myVar = html_entity_decode($myVar);

এই প্রশ্নটি সিরিয়ালযুক্ত স্ট্রিংয়ে এইচটিএমএল এনকোডযুক্ত সত্তাগুলি থেকে ভোগে না। ওপি-র প্রশ্ন / ইস্যুটি বিশেষত এই বিষয়টি নিয়ে কাজ করছে যে (সম্ভবত সিরিয়ালাইজড স্ট্রিংয়ের "চূড়ান্ত অ্যারে উপাদান" -এ কোনও অনুপযুক্ত সাবস্ট্রিং প্রতিস্থাপনের কাজটি করা হয়েছে) সিরিয়ালযুক্ত স্ট্রিংয়ে একটি ভুল বাইট গণনা রয়েছে। দয়া করে কেবল এমন উত্তরগুলি পোস্ট করুন যা জিজ্ঞাসিত প্রশ্নের সরাসরি সমাধান করে।
মিকম্যাকুসা

@ মিকম্যাকুসা এই প্রশ্নটি প্রায় 7 বছরের পুরানো এবং আমার উত্তর ~ 1,5। তবুও সুন্দর যে আপনি এতটা নিযুক্ত!
ডেভিড

আমি তাই পৃষ্ঠাগুলি পছন্দ - তরুণ এবং বৃদ্ধ। আমি এমন গবেষকদের সন্ধান করছি যা একটি ভাল উত্তর এবং খুব উত্তম নয় এমন উত্তরের মধ্যে পার্থক্য জানে না। দুর্ভাগ্যজনক এই পৃষ্ঠাটি অফ-টপিক পরামর্শে পূর্ণ।
মিকম্যাকুসা

দুর্দান্ত! ইতিমধ্যে কোটিটি নিয়ন্ত্রণ এবং ভোটদান রয়েছে, তবে আমি আপনাকে থামানোর কোন কারণ নেই ;-)
ডেভিড

ওহ না, একবার দেখুন। আপোভোটেড উত্তর রয়েছে যা ডাউনভোট হওয়া উচিত। অনেক লোক পার্থক্য করতে পারে না। এই পৃষ্ঠায়, ভোটের তালিকাই গুণমান / যথাযথতার কোনও ইঙ্গিত নয়। আমি আমার সময়কে ডাউনভোটিংয়ে নষ্ট করব না কারণ আমার ডাউনভোটটি ট্যালিতে কোনও ছাঁটাই করবে না। আমি যা করতে পারি তা হ'ল ভাল / খারাপ / কুরুচিপূর্ণ কি তা বোঝাতে মন্তব্য করা leave
মিকম্যাকুসা

1

দূষিত সিরিয়ালযুক্ত স্ট্রিং ঠিক করার জন্য এখানে একটি অনলাইন সরঞ্জাম

আমি যুক্ত করতে চাই যে এটি বেশিরভাগ ডিবি এবং সিরিয়ালাইজেশন ডেটা ( বিশেষতঃ) এর অনুসন্ধান এবং প্রতিস্থাপনের কারণে ঘটে happenskey length ) প্রতি প্রতিস্থাপন এবং যে "দুর্নীতি" ঘটায় আপডেট না হয়ে যায়।

তবুও, উপরের সরঞ্জামটি সিরিয়ালাইজেশন ডেটা ( এখানে থেকে অনুলিপি করা ) ঠিক করতে নিম্নলিখিত যুক্তি ব্যবহার করে ।

function error_correction_serialise($string){
    // at first, check if "fixing" is really needed at all. After that, security checkup.
    if ( unserialize($string) !== true &&  preg_match('/^[aOs]:/', $string) ) {
         $string = preg_replace_callback( '/s\:(\d+)\:\"(.*?)\";/s',    function($matches){return 's:'.strlen($matches[2]).':"'.$matches[2].'";'; },   $string );
    }
    return $string;
} 

0

এই সমস্যার আর একটি কারণ কলামের ধরণের "পেলোড" সেশন টেবিল হতে পারে। আপনার যদি সেশনে বিশাল ডেটা থাকে তবে একটি পাঠ্য কলামটি পর্যাপ্ত হবে না। আপনার মিডিয়ামটেক্সট বা এমনকি লংটেক্সট প্রয়োজন হবে।


এই প্রশ্নটি কাটা কাটা হয় না। ওপি-র প্রশ্ন / ইস্যুটি বিশেষত এই বিষয়টি নিয়ে কাজ করছে যে (সম্ভবত সিরিয়ালাইজড স্ট্রিংয়ের "চূড়ান্ত অ্যারে উপাদান" -এ কোনও অনুপযুক্ত সাবস্ট্রিং প্রতিস্থাপনের কাজটি করা হয়েছে) সিরিয়ালযুক্ত স্ট্রিংয়ে একটি ভুল বাইট গণনা রয়েছে। দয়া করে কেবল এমন উত্তরগুলি পোস্ট করুন যা জিজ্ঞাসিত প্রশ্নের সরাসরি সমাধান করে।
মিকম্যাকুসা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.