[Zope-Perl] security
Gisle Aas
gisle@ActiveState.com
25 Jan 2001 11:46:30 -0800
"Chris McDonough" <chrism@digicool.com> writes:
> Thanks for the info!
>
> > For this reason I would not encourage that we actually return perl
> > data in Zope. I might even go as far as adding code to
> > PerlMethod.__call__ that simply stringify 'perl ref' objects returned
> > from PerlMethods. This was actually what used to happen before
> > 'pyperl-beta5'.
>
> Well... I'm not sure that we want to disallow it. We should probably make
> it clear in Zope docs that if you do return a ref, that it's a reference to
> a data structure shared between Perl and Python, and that it shouldn't be
> stored and used across threads. Since in many (most?) cases a ref is not
> only local to the Perl subroutine, but is local to the Python scope in which
> it's used, it should be gc'ed in the course of a single Zope request (which
> almost always takes place within the context of a single Python thread).
Ok. Let's not disable this "feature" then.
> For example, what I think is a good example use of this (although it doesn't
> work yet :-) is in the unrestricted PerlM "finance", which has the arguments
> "exchange" and "symbols", and is called like:
>
> <dtml-let ref="finance('nasdaq', ['MSFT', 'LNUX'])">:
> <dtml-in "ref.keys()">
> <dtml-var sequence-item>: <dtml-var "ref[_['sequence-item']]">
> </dtml-in>
> </dtml-let>
>
> Where the body of the finance module is:
>
> package ZopeExt::finance;
> use Finance::Quote;
> use Python;
>
> sub finance {
> my ($exchange, $symbols) = @_;
> my @symbols = Python::list($symbols);
Python::list() is a constructor function for a python list object.
The passed in $symbols will be a python list object which means that
Python::list($symbols) returns a new list object with a single element
containing a list.
If you want to convert a python list object to a perl array you should
simply do this:
@symbols = @$symbols;
But, then you could simply use @$symbols directly instead of making a
copy.
> my $quoter = Finance::Quote->new;
> my %info = $quoter->fetch($exchange, @symbols);
> my %retn;
> foreach $symbol (@symbols) {
> unless ($info{$symbol,"success"}) {
You probably want something like $info{$symbol}{success}
> $retn{$symbol} = "unknown";
> next;
> }
> $retn{$symbol} = $info{$symbol, "price"};
> }
> return \%retn;
> }
> 1;
Alternative implementation (untested):
my($exchange, $symbols) = @_;
my $quoter = Finance::Quote->new;
my %info = $quoter->fetch($exchange, @symbols);
return Python::dict(map { $_ => ($info->{$_}{success} ? $info->{$_}{price}
: "unknown")
}, @$symbols);
--Gisle