Jump to content
Sign in to follow this  
Jeisson

preg_replace to preg_replace_callback

Recommended Posts

I have problems with a script. The error log says I should change the preg_replace to preg_replace_callback

 

I dont know how to do it, so please help.

function __unserialize($string) {
  $unserialized = stripslashes($string);
  $unserialized = preg_replace('!s:(\d+):"(.*?)";!e', "'s:'.strlen('$2').':\"$2\";'", $unserialized );
  return unserialize($unserialized);
}

Edit: I did try to do it. so if you want to see what I tried I ofcourse can show. But it reutned a blank screen

Edited by Jeisson

Share this post


Link to post
Share on other sites

What is this weird function even supposed to do? First you blindly remove all backslash escapes in the serialized input -- where are those coming from? Magic Quotes are long dead. Then you change the string lengths, appearently to repair the serialized string which you just screwed up.

 

Who wrote that? What is the idea behind it?

Share this post


Link to post
Share on other sites

You can't just do a one-for-one swap with preg_replace_callback(). Have you checked out the manual page on the function? http://php.net/manual/en/function.preg-replace-callback.php

 

The second parameter needs to be a function name. It'll be passed the matches and you should return the string you want from there. Within that function is where you'd do the strlen() part. 

 

function update($matches) {
    return('s:' . strlen($matches[2]) . ":\"{$matches[2]}\";";
}
$unserialized = preg_replace_callback('!s:(\d+):"(.*?)";!',"update_function",$unserialized );

 

It's been a while since I've done this, so forgive any errors, but hopefully that gives you the idea. If you check out the manual page, you can also do an anonymous function, rather than defining update() or whatever you want to call it. 

 

-John

Edited by Sepodati

Share this post


Link to post
Share on other sites

Careful with literal answers. Yes, you can mechanically replace one function call with another. That doesn't mean any of this even makes sense. In fact, I very much doubt that. It looks like an incompetent hack which is supposed to counter another incompetent hack.

 

Or do you know more? In that case, please explain the background of the above __unserialize() function.

Share this post


Link to post
Share on other sites

I don't know anymore than you. I agree the whole thing looks suspect. 

Share this post


Link to post
Share on other sites

Plus __unserialize doesn't use a return value. Er, no.

 

Did you get that code from this user comment? Don't. We can help you with your original problem if you want to describe that.

Edited by requinix

Share this post


Link to post
Share on other sites

Thank  you for your answers.

the script is supposed to add correct filenames from .dat files

so that in the html there would be correct images. these are chosen with drop boxes.

also  populate the dropboxes.

this script i got from customer. it used to work a few years ago.

 

 

hope this part help

function rowColour($row) {return ($row % 2 == 0 ? "listrow01" : "listrow02");}
function readObjectsFromFile($file_name){
  $file_rows = file($file_name);
  $object_list = array();
  for($i=0;$i<count($file_rows);$i++){
    $object = __unserialize($file_rows[$i]);
    $object_list[count($object_list)] = $object;
  }
  return $object_list;
}
function getFramesFromFile(){
  $frames_list = readObjectsFromFile("styles/frames/frames.dat");
  return $frames_list;
}
function getMirrorsFromFile(){
  $mirrors_list = readObjectsFromFile("styles/mirrors/mirrors.dat");
  return $mirrors_list;
}
function getPricesFromFile(){
  $prices_list = readObjectsFromFile("prices.dat");
  return $prices_list;
}

function getDefaultDoorFromFile($index){
  $door_list = readObjectsFromFile("styles/defaultdoor.dat");
  $door = $door_list[$index];
  return $door;
}
function getDefaultFrame($index){
  $door = getDefaultDoorFromFile($index);
  return $door->frame;
}

function __serialize($object) {
  $serialized = serialize($object);
  return htmlentities($serialized,ENT_QUOTES);
}

Share this post


Link to post
Share on other sites

What a clusterfuck.

 

The __serialize() function is completely broken, because it applies HTML-escaping (WTF?) to the serialized output, making it impossible to deserialize it again without prior HTML-decoding -- but there's no decoding anywhere in the code. So if this ... thing actually worked at some point, then either the function has never been used, or the application is so fudged up that the defects have started to cancel out each other.

 

Then you have this stripslashes() thingy which indicates your customer had the ancient Magic Quotes "feature" turned on in the past which then broke the serialization procedure. But Magic Quotes don't even exist in any halfway modern PHP version, so in the worst case, you now have a mixture of quoted strings and unquoted strings.

 

What can you do? Run away. Or go through the painful trial-and-error procedure of checking which piece of data is broken in which way.

Edited by Jacques1

Share this post


Link to post
Share on other sites

ok thanks :)

i think I'll suggest a complete rewrite. I am not good at php, so I would do this in javascript.

but thanks for your analyzis and advice. I appreciate

Share this post


Link to post
Share on other sites

The data is obviously managed server-side, so I don't see how JavaScript is going to help you. A rewrite also doesn't necessarily mean you can start from scratch. What about the existing data?

 

I'd be very careful with making promises and getting even more involved into the project. Obviously I don't know the entire application, but the above code doesn't look like this was ever managed by professional programmers.

Share this post


Link to post
Share on other sites

I know what the customer wants it to do. And the serverside data is now in a text file .dat

I put the same data in a .json file and fetch the data from there and handle it with javascript. I don't see a problem there.

 

However I found out this code actually works on the current customer server. But not on my test server(s). 

 

Thanks for all comments.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.