Deal of the Day

Home » Main » Manning Forums » 1999 » Object Oriented Perl

Thread: secure flyweight pattern objects

Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 8 - Pages: 1 - Last Post: Mar 25, 2004 11:41 AM by: keno
import-bot

Posts: 20,296
Registered: 12/6/03
secure flyweight pattern objects
Posted: Feb 15, 2000 11:00 PM
  Click to reply to this thread Reply

[Originally posted by joey]

I was disappointed in the approach you took to secure the flyweight pattern
soldier objects in chapter 11. Yes, the number would be hard to guess, but not
_too_ hard. The random number is 15 digets long. Perl can run more than
2000000 subroutine calls a second here, so it'd only take 16 years or so to
guess the variable and crack it. Factor in moore's law and projects like
distributed.net, and I'm not especially comfortable with that. Call me
paranoid. :-)

Anyway, there's a better way, which you just narrowly missed. Make the class
data include a private, lexically scoped hash (or better, a RefHash) where the
keys are object references, and the values are object id's. Then each method
of the class takes $_[0], looks up the reference in the hash to get the object
id, and proceeds on its way. You don't put anything of value in the actual
scalar that gets blessed into the class; it's just a placeholder.

I'm using this technique in Perlmoo, a MOO that is written entirely in perl,
which will have people running arbitrary perl code in Safe's inside it, so I'm
interested to know if you see any hidden weaknesses in it.


import-bot

Posts: 20,296
Registered: 12/6/03
Re: secure flyweight pattern objects
Posted: Feb 19, 2000 11:00 PM   in response to: import-bot in response to: import-bot
  Click to reply to this thread Reply

[Originally posted by damian]

> I was disappointed in the approach you took to secure the flyweight pattern
> soldier objects in chapter 11. Yes, the number would be hard to guess, but not
> _too_ hard. The random number is 15 digets long. Perl can run more than
> 2000000 subroutine calls a second here, so it'd only take 16 years or so to
> guess the variable and crack it. Factor in moore's law and projects like
> distributed.net, and I'm not especially comfortable with that. Call me
> paranoid. :-)

You're paranoid. :-)


> Anyway, there's a better way, which you just narrowly missed. Make the class
> data include a private, lexically scoped hash (or better, a RefHash) where the
> keys are object references, and the values are object id's. Then each method
> of the class takes $_[0], looks up the reference in the hash to get the object
> id, and proceeds on its way. You don't put anything of value in the actual
> scalar that gets blessed into the class; it's just a placeholder.

Oh, that's lovely. Use the *address* of an object as the key to its data.
Wonderful. I'll definitely steal that for the next edition ;-)


> I'm using this technique in Perlmoo, a MOO that is written entirely in perl,
> which will have people running arbitrary perl code in Safe's inside it, so I'm
> interested to know if you see any hidden weaknesses in it.

The only disadvantage is that it's no longer possible to send proxies for
specific objects back (see section 11.3.3). Of course that just means that
you *have* to use the technique described in 11.3.5).

Thanks for this elegant technique. I'll be sure you're properly
attributed in Ed. 2.

Damian


import-bot

Posts: 20,296
Registered: 12/6/03
Re: secure flyweight pattern objects
Posted: Feb 21, 2000 11:00 PM   in response to: import-bot in response to: import-bot
  Click to reply to this thread Reply

[Originally posted by joey]

> The only disadvantage is that it's no longer possible to send proxies for
> specific objects back (see section 11.3.3). Of course that just means that
> you *have* to use the technique described in 11.3.5).

Ah, but see, you need not send proxies back. The class has the references
(assumming you used a refhash), and can send back the actual objects.

> Thanks for this elegant technique. I'll be sure you're properly
> attributed in Ed. 2.

Thanks, that makes my day!


import-bot

Posts: 20,296
Registered: 12/6/03
Re: secure flyweight pattern objects
Posted: Feb 21, 2000 11:00 PM   in response to: import-bot in response to: import-bot
  Click to reply to this thread Reply

[Originally posted by damian]

> > The only disadvantage is that it's no longer possible to send proxies for
> > specific objects back (see section 11.3.3). Of course that just means that
> > you *have* to use the technique described in 11.3.5).
>
> Ah, but see, you need not send proxies back. The class has the references
> (assumming you used a refhash), and can send back the actual objects.

I'd still be inclined to use a regular hash and a ref to an element of the
data hash (as described in 11.3.5). The stringification of the ref when used
as a hash key will do no harm, and avoiding RefHashes is a big win -- like
all tied variables they are an order or magnitude slower than normal hashes.

Damian


import-bot

Posts: 20,296
Registered: 12/6/03
Re: secure flyweight pattern objects
Posted: Feb 21, 2000 11:00 PM   in response to: import-bot in response to: import-bot
  Click to reply to this thread Reply

[Originally posted by mhughes]

Could one of you gurus post a simple sample? This dunderhead can use all the
help I can get in understanding what you are talking about.


import-bot

Posts: 20,296
Registered: 12/6/03
Re: secure flyweight pattern objects
Posted: Feb 21, 2000 11:00 PM   in response to: import-bot in response to: import-bot
  Click to reply to this thread Reply

[Originally posted by joey]

> > Ah, but see, you need not send proxies back. The class has the references
> > (assumming you used a refhash), and can send back the actual objects.
>
> I'd still be inclined to use a regular hash and a ref to an element of the
> data hash (as described in 11.3.5). The stringification of the ref when used
> as a hash key will do no harm, and avoiding RefHashes is a big win -- like
> all tied variables they are an order or magnitude slower than normal hashes.

Fair enough.

What I'm doing is real life is maintaining 2 hashes, one maps stringified
references to object id numbers and the other maps object id numbers to real
references. Thus no real overhead and all the benefits of using a refhash.


import-bot

Posts: 20,296
Registered: 12/6/03
Re: secure flyweight pattern objects
Posted: Feb 22, 2000 11:00 PM   in response to: import-bot in response to: import-bot
  Click to reply to this thread Reply

[Originally posted by damian]

> Could one of you gurus post a simple sample? This dunderhead can use all the
> help I can get in understanding what you are talking about.

Don't put yourself down. The only dunderhead is the
person who doesn't realize they're not following the
conversation ;-)

We're discussing a clever variation on Listing 11.3 (p.307-308)
in which, instead of generating a unique random key for each
Soldier object, we just use the address of the blessed scalar itself.

The constructor would become:

sub new
{
my ($class, %args) = @_;

my $dataref = {%_fields};
foreach my $field ( keys %_fields )
{
$dataref->{$field} = $args{$field}
if defined $args{$field};
}

# NO SPECIAL KEY VALUE NEEDED...
$data_ref->{_key} = undef;

# ...BECAUSE THE REF TO THE _key ENTRY *IS* THE KEY!
my $key = $data_ref->{_key};
$_soldiers{$key} = $data_ref;

bless $key, $class
}

Note that, unlike the version shown in Listing 11.3,
here the _key field has no meaningful value. That's
because its own address (i.e. $data_ref{_key})
become the key under which $data_ref is stored
in the %_soldiers table.

Then, to look up the data for an object, we just
use the object reference itself (i.e. $_[0] in any
method) as the key back into the %_soldiers table:

sub get_name
{
return $_soldiers{$_[0]}->{name};
}

Clean, secure, and elegant.
Wish I'd thought of it first ;-)

Damian


import-bot

Posts: 20,296
Registered: 12/6/03
Re: secure flyweight pattern objects
Posted: Feb 22, 2000 11:00 PM   in response to: import-bot in response to: import-bot
  Click to reply to this thread Reply

[Originally posted by damian]

Oops, the dreaded "backslash bug" strikes again:

> The constructor would become:
>
> sub new
> {
> my ($class, %args) = @_;
>
> my $dataref = {%_fields};
> foreach my $field ( keys %_fields )
> {
> $dataref->{$field} = $args{$field}
> if defined $args{$field};
> }
>
> # NO SPECIAL KEY VALUE NEEDED...
> $data_ref->{_key} = undef;
>
> # ...BECAUSE THE REF TO THE _key ENTRY *IS* THE KEY!
> my $key = $data_ref->{_key};

my $key = \$data_ref->{_key}; # THE BACKSLASH IS CRITICAL!

> $_soldiers{$key} = $data_ref;
>
> bless $key, $class
> }

In other words, the (stringified) address of the
_key attribute is the key under which the complete
object data is stored in %_soldiers.

Damian


keno

Posts: 1
From: Minnesota
Registered: 3/24/04
Re: secure flyweight pattern objects
Posted: Mar 25, 2004 11:41 AM   in response to: import-bot in response to: import-bot
  Click to reply to this thread Reply

Yes, this is lovely, but for one detail. Remember that the stringification of the reference after it's blessed into the class is not the same as the stringification of the reference before it was blessed.

$ perl -le '$ref={}; print "$ref"; bless $ref, "MyPkg"; print "$ref"'
HASH(0x10121190)
MyPkg=HASH(0x10121190)
$

Blessing will at least add "$class=", and if the stringification operator is overloaded, "$_[0]" might be very expensive, or not unique. So, we need something like this:

sub key
{
my( $self ) = @_;
my $class = ref $self;
bless $self, "_key_"; # dummy class to defeat q("") overloading
( my $key = "$self" ) =~ s/^_key_=//; # strip class name
bless $self, $class; # restore blessing
return $key;
}

to get the lookup key. So the usage would be like this:

sub get_name
{
return $_soldiers{$_[0]->key}->{name};
}

If we don't mind the performance hit from dispatching the key method, we might also like to factor it out into a Keyable package, and push 'Keyable' onto our @Soldier::ISA.

Legend
Gold: 300 + pts
Silver: 100 - 299 pts
Bronze: 25 - 99 pts
Manning Author
Manning Staff