Unserialize Problem

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
spacebiscuit
Forum Contributor
Posts: 390
Joined: Mon Mar 07, 2005 3:20 pm

Unserialize Problem

Post by spacebiscuit »

Hi guys,

I've passed a multi dimensional array via an html form. Before sending I used the urlencode and serialize functions.

On the receiving page I am using the folowing:

Code: Select all

$var1=stripslashes($_GET['temp']);
Then if I output the variable I get:

Code: Select all

a:21:{i:0;s:1:"2";i:1;s:9:"Joe Bloggs";i:2;s:12:"Company";i:3;s:24:"1 High St";i:4;s:0:"";i:5;s:7:"Town";i:6;s:6:"London2}
So I need to unserialize:

Code: Select all

$va1=unserialize($var1);
However this gives no output output.

Any ideas? Thanks,

Rob.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Unserialize Problem

Post by Weirdan »

Obviously your string is truncated. Also you should never attempt to unserialize user input (anything that comes from a browser) as it poses severe security threat to your host. Use json_encode()/json_decode() if you need a safe way to serialize complex structures.
spacebiscuit
Forum Contributor
Posts: 390
Joined: Mon Mar 07, 2005 3:20 pm

Re: Unserialize Problem

Post by spacebiscuit »

Thanks Weirdan - I will try the json_encode as advised.

What does it mean when my string is truncated?

Rob.
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Unserialize Problem

Post by AbraCadaver »

OK, so I helped them here: viewtopic.php?f=1&t=118406&start=0, but I didn't pay attention to whether it was user input or not. Also, it was a GET var at that point.

GET data must be urlencoded, but POST doesn't, so don't use urlencode(). See what that does.
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
spacebiscuit
Forum Contributor
Posts: 390
Joined: Mon Mar 07, 2005 3:20 pm

Re: Unserialize Problem

Post by spacebiscuit »

Yes you helped me solve this a couple of days ago.

But this is really strange - because I am trying to pass the same multidimensional array in the same form, but this time to a different page. So using the same method that worked before I'm getting no output which is really puzzling.

I will try without url_encode.

I tried with json but I get empty variables.

Rob.
spacebiscuit
Forum Contributor
Posts: 390
Joined: Mon Mar 07, 2005 3:20 pm

Re: Unserialize Problem

Post by spacebiscuit »

Maybe it would be easier if I post all of my code:

Serialization and the form:

Code: Select all

<?
$temp=serialize($_SESSION[del]);
?>

<form method="POST" action="https://paymaster.com/">
 <p><input type="submit" value="Next" name="submit4" align="center"></p> 
 <input type="hidden" name ="callback_url" value="http://www.mysite.com/index.php?submit4=Next&to_pass=<? echo"$temp" ?>">
</form>
Then on the callback_url page:

Code: Select all

$data=unserialize($_GET['to_pass']);
Where I am outputting the data in an email message I am building:

Code: Select all

$subject = "A Test";
$body = "This is a test\n\n";
$body .= "1 - ".$data."\n";
	    			
mail($to, $subject, $body);
Which when the email is received gives me:

Code: Select all

s:720:\"a%3A21%3A%7Bi%3A0%3Bs%3A1%3A%222%22%3Bi%3A1%3Bs%3A9%3A%22Joe+Bloggs%22%3Bi%3A2%3Bs%3A12%3A%22Company%22%3Bi%3A3%3Bs%3A24%3A%221+Hig
It looks as if the variable is being truncated as suggested above. The index which should store the first line of the adress ("1 High St") is being truncated after the 'g'. I'm not sure how or why though.

Does the help?

Thanks,

Rob.
spacebiscuit
Forum Contributor
Posts: 390
Joined: Mon Mar 07, 2005 3:20 pm

Re: Unserialize Problem

Post by spacebiscuit »

Ok I have made some progress of sorts.

After playing around for a few hours and tidying up some errors which I discovered I''m now dumping the unserialized GET variable into a database. It is clear that the variable has been truncated because I get:

Code: Select all

a:21:{i:0;s:1:\"2\";i:1;s:4:\"Name\";i:2;s:7:\"Company\";i:3;s:9:\"1 High St\";i:4;s:0:\"\";i:5;s:7:\"Town XY\"%
The problem is occuring at index 5 - the town name. After the closing quotation there is % sign. What could possibly be causing the truncation?

When I try deserialization or json_decode (with encode before sending) I get empty variables which i am guessing is related to the truncation.

Hmmm - any ideas?

Thanks,

Rob.
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Unserialize Problem

Post by AbraCadaver »

What is the type and length of the field in the db? Show the insert code and any code that modifies the var before the insert.
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
spacebiscuit
Forum Contributor
Posts: 390
Joined: Mon Mar 07, 2005 3:20 pm

Re: Unserialize Problem

Post by spacebiscuit »

Ok so after a good night's sleep I tried this morning to tackle the problem logically.

I set the array as follows so that I know exactly what I am passing:

Code: Select all

$to_pass = array('1234567890','1234567890','1234567890','1234567890','1234567890','1234567890','1234567890','1234567890','1234567890','1234567890');
This array's data again was also truncated when received at the url_success script. Further investiagation revealed that the array truncated after exactly 128 characters. This was confirmed when I checked at what point the original arrays that I was passing truncated. If I set the array above with say just 4 indexes the truncation does not occur.

So does this shine any light on the problem?

Thanks,

Rob.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Unserialize Problem

Post by Weirdan »

robburne wrote: This array's data again was also truncated when received at the url_success script. Further investiagation revealed that the array truncated after exactly 128 characters. This was confirmed when I checked at what point the original arrays that I was passing truncated. If I set the array above with say just 4 indexes the truncation does not occur.

So does this shine any light on the problem?
Kind of. Since you're passing the data via third party it could be that they are truncating it. At this stage I'd contact them to verify this assumption. In the meanwhile you can start storing the data somewhere on your server and passing some kind of identifier instead, something like this:

Code: Select all

<?php
// cart.php // assuming we're passing array of products
$secret = "a piece of very secret data";
mysql_query('insert into PassThroughData set value="' . mysql_real_escape_string(json_encode($_SESSION['products'])) . '"'); // make sure your data does not exceed limits of the column data type
$dataId = mysql_insert_id(); $signature =  hash_hmac('sha1', $dataId, $secret);
?>
<form ........>
  <input type="submit".../>
  <input type="hidden" name="callback_url" value="...........?<?=http_build_query(array('to_pass' => $dataId, 'signature' => $signature))?>"/>
</form>

Code: Select all

<?php
// success.php
$secret = "a piece of very secret data";
$_GET['to_pass'] = (int) $_GET['to_pass'];
if (hash_hmac('sha1', $_GET['to_pass'], $secret) !== $_GET['signature']) {
   die('Go away. Just... go.');
}
$res = mysql_query('select value from PassThroughData where id='  . $_GET['to_pass']); // sanitized by (int) cast above
list($data) = mysql_fetch_row($res);
$data = json_decode($data, true);
// $data now contains what was in $_SESSION['products'] originally
mysql_query('delete from PassThroughData where id=' . $_GET['to_pass']); // cleanup
spacebiscuit
Forum Contributor
Posts: 390
Joined: Mon Mar 07, 2005 3:20 pm

Re: Unserialize Problem

Post by spacebiscuit »

In the same form I can pss an id. Then based on the id I can query the db and retrieve the info to populate the array. However to improve efficieny I wanted to pass the session array via the form to make the code more efficient by not having to query the db.

I know I am splitting hairs here and the results are the same but wanted to getting work this way and besides I think it is good to learn where I am going wrong with this preferred method.

I have emailed the payment provider to ask if they are truncating the data passed - I will let you know.

Thanks,

Rob.
Post Reply