[Maypole] Problems with stringify and Class::DBI::FromCGI

From: Aaron Trevena (teejay at droogs.org)
Date: Fri Sep 10 2004 - 10:47:00 BST


I have just spent a few hours tracking down an inexplicable silent death
(the first I have had with CDBI or Maypole) in my Maypole application.

It appears that when the validate method is called in Class::DBI::FromCGI,
it is calling stringify() on the class it creates, this appeared to be
happening when it tried to discover the type of the id field of my class,
it would also appear that at this point warnings get swallowed. I hate
this as much as I hate silent death bugs (when debugging I ensure that all
the methods I suspect to be called do a warn '[package::name] method_name
called..').Therefore it took a while to work out that it was my stringify
method being called.

So anyway, Class::DBI::FromCGI calls validate on itself, which then
appears to call stringify - somebody please correct me if I am wrong, then
if your stringify calls some methods on itself that fetch related objects,
then you get a segfault, everytime you try and insert a new object of that
class, with the code reaching the id field, attempting to call ' my $type
= $them->untaint_type($field) or next; ' and dying silently, taking one of
your apache processes down with it.

There is a workaround for this..

I added a condition to my stringify method in the problem class before
getting values from related objects, the new class is shown here :

###########

package Pukka::Product;

use base qw(Pukka::DBI);
use Data::Dumper;

__PACKAGE__->set_up_table( "product" );
__PACKAGE__->has_a( variety => 'Pukka::Variety');
__PACKAGE__->has_a( size => 'Pukka::Size');

sub stringify_self {
     warn "[Pukka::Product] stringify called";
     my $self = shift;
     my $stringified = 1;
     if ($self->id) {
         my $variety = $self->variety;
         warn "[Pukka::Product] got variety\n";
         my $size = $self->size;
         warn "[Pukka::Product] got size\n";
         warn "[Pukka::Product] variety : $variety\n";
         warn "[Pukka::Product] size : $size\n";
         $stringified = join(' ',$self->{items},'x', $size->name,
$variety->name);
         warn "[Pukka::Product] stringified : $stringified\n",
     }
     return $stringified;
}

1;

###########

As you can see its a fairly common construct in any catalogue type
application, so this problem is likely to occur frequently where have this
type of relationship between classes. Note that Pukka::Variety has_many
Pukka::Product, this may contribute to the problem when validating.

One final note : never ever print @_ or any variable that may refer to or
possibly include $self or any code that may return $self from inside
stringify - one apache mod_perl process grew to over 90 MB in a couple of
seconds when I was debugging this problem and mistakenly copy & pasted a '
warn "func_name called by ", caller(), " with ", @_, "\n" ' into the
stringify method. The perl compiler didn't catch the deep recursion and
there were no warnings unless you checked top or noticed that your machine
had slowed to a crawl.

I believe there could be a fix for both of these

The code that calls stringify_self could be wrapped to ensure that it
doesn't call itself, warn about it and return -1 - this would be a tiny
patch to CDBI and should have next to no impact on CDBI behaviour or
performance.

The code that gets types in CGI::Untaint (I think that could be where the
problem is) needs to be more careful about stringifying objects before
they are saved to the db and should stop swallowing warnings. I'm not sure
entirely what is going on there and now I have a work-around I'm not
inclined to spend any time in that code.

Cheers,

A. (learning in public so you don't have to)

ps - happy to move this thread to the cdbi mailing list if people want,
just thought that this problem is likely to have an impact on maypole
developers which rely on Class::DBI::FromCGI heavily.

-- 
Aaron J Trevena - Perl Hacker, Kung Fu Geek, Internet Consultant
AutoDia --- Automatic UML and HTML Specifications from Perl, C++ 
and Any Datasource with a Handler.     http://droogs.org/autodia

_______________________________________________ maypole mailing list maypole at lists.netthink.co.uk http://lists.netthink.co.uk/listinfo/maypole



This archive was generated by hypermail 2.1.3 : Thu Feb 24 2005 - 22:25:56 GMT