[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