[Zope-Perl] question regarding perl based methods and dtml

Gisle Aas gisle@ActiveState.com
21 Aug 2000 18:06:43 +0200


Joseph Wayne Norton <norton@arseed.co.jp> writes:

> I am experimenting with a few simple ways to integrate perl methods
> within a dtml document.  I have 2 perl based methods, m_pl and
> grep_pl, that are simply wrappers around the perl functions m and
> grep.
> 
> I am facing trouble when passing a list object to the grep_pl method.
> I'm not sure how to call the objectIds method first and then have a
> list object passed as the argument 'list' to grep_pl method. Secondly,
> are there any restrictions on having a list as a return value?
> 
> Any ideas?
> 
> thanks,
> 
> - j
> 
> 
> I have a dtml document , 'test_dtml',  as follows:
> 
>         <dtml-var standard_html_header>
>         <h2><dtml-var title_or_id></h2>
>         <p>
>           <dtml-with "PARENTS[0]">
>         
>           <p> <b> ObjectIds </b> </p>
>           <dtml-in objectIds>
>              <dtml-var sequence-item> <br>
>           </dtml-in>
>         
>           <p> <b> ObjectIds w/ m </b> </p>
>           <dtml-in objectIds>
>              <dtml-if "m_pl('/test/', _['sequence-item'])">
>                <dtml-var sequence-item> <br>
>              </dtml-if>
>           </dtml-in>
>         
>           <p> <b> ObjectIds w/ grep </b> </p>
>           <dtml-in "grep_pl('/test/', objectIds())">
>              <dtml-var sequence-item> <br>
>           </dtml-in>
>         
>           </dtml-with>
>         </p>
>         <dtml-var standard_html_footer>
> 
> and the method "m_pl" with arguments "pattern, expr"
> 
>         my $ret;
>         
>         eval "\$ret = (\$expr =~ $pattern)";

Using eval like this is a grand security risk, but you probably know
that.  You are now opening up your server to anyone that can view the
m_pl URL.  If we ever get security to work for PerlMethods, then eval
"" will probably simply be banned.

>         die "$pattern, $expr: $@" if ($@);
>         
>         $ret;
> 
> and finally the method "grep_pl" with arguments "expr, list":
> 
>         my @ret;
>         
>         eval "\@ret = grep $expr, \@{$list}";

You probably want to say \@\$list instead.  Here $list is a python
list object reference with stringify overloading, so $list expands to
a string of python code.  Luckily for you the syntax for a list of
strings is the same in both perl and python so it worked.

>         die "$expr, $list: $@" if ($@);
>         
>         @ret;

Zope always calls perl methods in scalar context, and the expression
@ret in scalar context is the number of elements in the array, i.e. an
integer.  Zope then raise an exception in DocumentTemplate/DT_In.py
when it tries to evaluate len() of an integer.

Returning \@ret should actually work, but it looks like Zope then
calls the validate() method which does not like the look of perl
arrays which results in a ValidationError exception (which turn into
an Unauthorized response on the webpage).

The thing that works is to force the return value to become a python
tuple or list with code like:

  return Python::list(@ret);

or

  return Python::tuple(@ret);

Perhaps it is also possible to influence the md.validate() method
somehow and teach it to accept perl arrays, but I don't know the Zope
source well enough too tell.  Somebody else who knows?

Regards,
Gisle