|
Replies:
8
-
Pages:
1
-
Last Post:
Mar 25, 2004 11:41 AM
by: keno
|
|
|
Posts:
20,296
Registered:
12/6/03
|
|
|
|
secure flyweight pattern objects
Posted:
Feb 15, 2000 11:00 PM
|
|
[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.
|
|
Posts:
20,296
Registered:
12/6/03
|
|
|
|
Re: secure flyweight pattern objects
Posted:
Feb 19, 2000 11:00 PM
in response to:
import-bot
|
|
[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
|
|
Posts:
20,296
Registered:
12/6/03
|
|
|
|
Re: secure flyweight pattern objects
Posted:
Feb 21, 2000 11:00 PM
in response to:
import-bot
|
|
[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!
|
|
Posts:
20,296
Registered:
12/6/03
|
|
|
|
Re: secure flyweight pattern objects
Posted:
Feb 21, 2000 11:00 PM
in response to:
import-bot
|
|
[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
|
|
Posts:
20,296
Registered:
12/6/03
|
|
|
|
Re: secure flyweight pattern objects
Posted:
Feb 21, 2000 11:00 PM
in response to:
import-bot
|
|
[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.
|
|
Posts:
20,296
Registered:
12/6/03
|
|
|
|
Re: secure flyweight pattern objects
Posted:
Feb 21, 2000 11:00 PM
in response to:
import-bot
|
|
[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.
|
|
Posts:
20,296
Registered:
12/6/03
|
|
|
|
Re: secure flyweight pattern objects
Posted:
Feb 22, 2000 11:00 PM
in response to:
import-bot
|
|
[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
|
|
Posts:
20,296
Registered:
12/6/03
|
|
|
|
Re: secure flyweight pattern objects
Posted:
Feb 22, 2000 11:00 PM
in response to:
import-bot
|
|
[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
|
|
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
|
|
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
|
|