php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #19243 Seg Fault Restoring Session Variables with References to Objects
Submitted: 2002-09-05 05:03 UTC Modified: 2002-10-03 17:58 UTC
Votes:5
Avg. Score:3.8 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:1 (50.0%)
From: fdruseikis at sc dot rr dot com Assigned:
Status: Closed Package: Session related
PHP Version: 4.2.2 + php4-200209060600 OS: Linux RH 7.0
Private report: No CVE-ID: None
 [2002-09-05 05:03 UTC] fdruseikis at sc dot rr dot com
The following script demonstrates a problem with restoring session variables that have references to objects.

Variables o1 and o2 are supposed to be globals refering to the same object instance.  First GET request initializes; POST request changes state.  Crash occurs on first POST or second GET.

Apache 1.3.26 reports a segmentation fault.  Browser (lynx) indicates "Unexpected Network Read Error; ..." 

If you remove 'o2' from session_register() and initialize the reference to o1 in the POST the crash goes away.

Fred Druseikis

-------------------- <snip> -----------------------------

<?php
# vim: ts=4 filetype=php

# segmentation fault on restore of object references

class TFoo {
	var $c;
	function TFoo($c) {
		$this->c = $c;
	}
	function inc() {
		$this->c++;
	}
}

	global $o1, $o2;
	session_register('o1', 'o2' );
	session_start();

	if( $_SERVER['REQUEST_METHOD'] == 'GET' ) {
		echo "GET<br>";
		$o1 =& new TFoo(42);
		$o2 =& $o1;
	}

	if( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
		echo "POST<br>";
	}

	$o1->inc();
	$o2->inc();

	echo "<tt>o1</tt><br><pre>"; print_r($o1); echo "</pre>";
	echo "<tt>o2</tt><br><pre>"; print_r($o2); echo "</pre>";

?>
<html>
<head>
</head>
<body>
<form action='/web/a/register/foo.php' method='post' >
<input type='text' name='x' value='42' />
<input type='submit' name='submit' value='Submit' />
</form>
</body>
</html>

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-09-05 06:19 UTC] yohgaki@php.net
Don't do that. It will never work.
We should raise error and ignore references.


 [2002-09-05 08:05 UTC] fdruseikis at sc dot rr dot com
BTW this is not a problem if the references are not global, for example, interior variables in an array instead.  For example,
 $x = array(9,8,7);
 $o1 = array(1,2,3,null,null);
 $o1[2] =& $x;
 $o1[3] =& $x;

This array clearly has references within it and shares the array named by $x.

Conclusion: It would seem to have something to do with restoring a reference to something that is already global.

IMO the serialization formats clearly intend to support serializing/deserializing of references.  The system provided deserializer needs to restore references correctly by implementing the inverse of the process that the serializer performed, which appearantly is not working correctly.  All the information you need is in the session file.  It also means that the closure of all references implict in an object (or array) need to be captured, which is clearly being done in the array example above.

Not to put too fine a point on it: "This kind of thing is done in Java all the time."

If your recommendation is taken, then you need to clarify the restriction in the documentation on references and in the session functions.  You're talking about a rat's nest of exceptions here.  Sometimes works for arrays, don't work for globals, etc.

It would be easier to make it work.

Give me a hint - where is the de/serializer implemented?
 [2002-09-05 15:04 UTC] kalowsky@php.net
Can you try one of the new snapshots please?  There has been some work on the way sessions are delt with, and while I don't think it fixes this problem... hey it's worth a shot.  Regardless, I don't think what you're doing is really going to ever work.  I agree with yohgaki that we should throw some warnings or something. 
 [2002-09-05 15:48 UTC] sniper@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php4-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php4-win32-latest.zip


 [2002-09-05 16:41 UTC] fdruseikis at sc dot rr dot com
I'll give it a try.
 [2002-09-05 16:48 UTC] kalowsky@php.net
keeping set as feedback
 [2002-09-06 08:03 UTC] fdruseikis at sc dot rr dot com
I tried the script on this build: php4-200209060300 (linux)

No segfault.

However, both variables $o1 and $o2 are saved (and restored) as null.  This results in a "Fatal Error: Call to a member function on a non-object in ..."

Both $o1 and $o2 should refer to the original (singleton) object instance.
 [2002-09-06 08:16 UTC] fdruseikis at sc dot rr dot com
Also: doesn't save/restore arrays either.
 [2002-09-06 09:24 UTC] fdruseikis at sc dot rr dot com
To elaborate on what I see: In php4.3.0-dev If there are any references within an array/object you don't serialize it.  Otherwise it is serialized.

So, array( 1, 2, 3) and array( new TFoo(1), new TFoo(2) )
save and restore.  However, in php4.3.0-dev

 global $a;
 $a = array(null,null)
 $a[0] =& new TFoo(1);
 $a[1] =& $a[0];

$a serializes as null.

This would be a change from 4.2.2, which permits this latter example (but segfaults on the global $o1, $o2 of the original bug report).  In 4.2.2 $a example does not segfault and the restored array has references to the same object instance.

Did you want to take away functionality?
 [2002-09-06 09:38 UTC] kalowsky@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php4-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php4-win32-latest.zip

Once again, as code has changed yet again.  Give it a try. :)
 [2002-09-06 10:23 UTC] fdruseikis at sc dot rr dot com
php4-latest = php4-200209060600

No discernable difference.  Same as previously reported;  No segfault and objects not serialized if they contain interior references.
 [2002-09-06 10:50 UTC] fdruseikis at sc dot rr dot com
This last build is really broken.  It won't even serialize strings and integers.
 [2002-09-07 17:39 UTC] kalowsky@php.net
Updating version
 [2002-09-11 06:13 UTC] fdruseikis at sc dot rr dot com
I'm having trouble building 200209101800 because it requires sablot-0.96;  I haven't given up yet ...
 [2002-09-12 17:28 UTC] fdruseikis at sc dot rr dot com
tried 200209101800
does not seg-fault.
also does not serialize references.
 [2002-09-12 22:10 UTC] sniper@php.net
Yes, that's perfectly ok. References are not serializeable.

 [2002-10-03 17:58 UTC] sas@php.net
References are of course serializable -- the session extension was borked in the latest CVS for some time. These issues have been resolved and your test case works correctly as expected.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sun Dec 07 20:00:01 2025 UTC