On Tue, 2007-10-09 at 12:40 -0400, Andrew Ballard wrote:
> On 10/9/07, Robert Cummings <[EMAIL PROTECTED]> wrote:
> > $sucker = new TryToViolateEncapsulation();
> > $sucker = (array)$sucker;
> >
> > $keys = array_keys( $sucker );
> > $sucker[reset( $keys )] = 500;
> >
> > $sucker = serialize( (object)$sucker );
> > $sucker = 'O:25:"TryToViolateEncapsulation"'.substr( $sucker, 14 );
> > $sucker = unserialize( $sucker );
> >
> > print_r( $sucker );
> >
> > :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
> >
> > Maybe next time you'll have a challenge for me ;) And don't whine about
> > how I achieved what I did.
> >
> >
> That's a bit disturbing. Ok, while we're bending things a bit, I'll
> make it a *little* tougher. :-)
>
> class TryToViolateEncapsulation {
> private $someInt = 0;
>
> const MAX_INT = 100;
> const MIN_INT = 0;
>
> public function getSomeInt() {
> return $this->someInt;
> }
>
> public function setSomeInt($someInt) {
> $success = false; // assume failure
> $someInt = (int) $someInt;
> if($this->isValid($someInt)) {
> $this->someInt = $someInt;
> $success = true;
> } else {
> throw new InvalidArgumentException('Invalid value passed to
> setSomeInt');
> }
>
> return $success;
> }
>
> private function isValid($someInt) {
> $isValid = true;
> if($someInt < TryToViolateEncapsulation::MIN_INT || $someInt >
> TryToViolateEncapsulation::MAX_INT) {
> $isValid = false;
> }
> return $isValid;
> }
>
> public function __wakeup() {
> $this->setSomeInt($this->someInt);
> }
> }
class Tricky extends TryToViolateEncapsulation
{
function __wakeup()
{
}
function bleh( TryToViolateEncapsulation $obj )
{
echo 'Gotta love it!!'."\n";
}
}
function objectCast( &$object, $class )
{
$newObject =
'O:'.strlen( $class ).':"'.$class.'"'
.substr( serialize( (object)(array)$object ), 14 );
$newObject = unserialize( $newObject );
$object = $newObject;
}
function arraySetPrivateField( &$objectArray, $className, $fieldName, $value )
{
$objectArray["\x00$className\x00$fieldName"] = $value;
}
$sucker = new TryToViolateEncapsulation();
$sucker = (array)$sucker;
arraySetPrivateField( $sucker, 'TryToViolateEncapsulation', 'someInt', 300 );
objectCast( $sucker, 'Tricky' );
print_r( $sucker );
$sucker->bleh( $sucker );
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Certainly you'll notice I've extended the original class,
overriden the __wakeup() call and basically used inheritance
and polymorphism to my advantage. The object is now of a
different class but will serve in all contexts that one
expects the parent class unless an explicit class type check
is made. I think it's sufficient though since I've still
modified the private member variable of the parent ;)
> Of course, my gripe with __wakeup is that it is essentially a PHP
> implementation function that, IMO, should be private. However, it must
> be declared public for it to work, and that means that anyone outside
> the class can call it whenever they want.
>
> While I'm not totally sold on OOP for web pages, I still like PHP5
> because of the OO enhancements over PHP4. Can you code without them?
> Sure. I can cut my grass with a push mower, too -- but I tend to like
> my lawn tractor much better.
>
> However, thank you for demonstrating that I need to be MUCH more
> careful when building objects to validate member values each time they
> are used, and not just when they are set.
I would argue that this kind of tampering isn't worth checking for on
every unserialize.
Cheers,
Rob.
--
...........................................................
SwarmBuy.com - http://www.swarmbuy.com
Leveraging the buying power of the masses!
...........................................................
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php