[ic] $Tag->price() [calc] re-entrancy problems
Mike Heins
mike at perusion.com
Mon Aug 24 13:00:42 UTC 2009
Quoting Mike Heins (mike at perusion.com):
> Quoting Peter (peter at pajamian.dhs.org):
> > Ok, here is the issue. I often times do something like this in
> > CommonAdjust: "&($item->{code} =~ /^FOO/ ? '-30%' : '0')"
> >
> > Basically that is a quick way to discount every product with a sku that
> > begins with FOO by 30%. This has worked great for me in the past ...
> > Until I came up with a situation where I needed to call the price tag
> > from inside an [item-calc] in order to determine if an item is on sale
> > ... I do this:
> >
> > [item-calc]
> > if ($Row->{price} > $Tag->price({code=$Row->{code}, noformat => 1})) {
> > # Some code to run if item is on sale here.
> > }
> > [/item-calc]
> >
> > The idea above is that I can't use [item-price] because I need to see
> > what the price for the code would be without any options applied.
> > Anyways, now here's the problem ... the [price] tag ends up calling
> > tag_calc() when there is an atom in the CommonAdjust that starts with &.
> > This results in a calc re-entrancy issue, and I end up with the
> > following in my error.log:
> > Safe: 'eval "string"' trapped by operation mask at (tag 'calcn') line 1.
> > > (in cleanup) Undefined subroutine &main:: called at
> > /usr/local/perl-5.8.8/lib/5.8.8/x86_64-linux/Safe.pm line 236.
> >
> > Interestingly you can get the exact same error if you attempt to do this:
> > [calcn]
> > $Tag->calc({body => 'return "foo";'});
> > [/calcn]
> >
> > Ok, so the issue boils down to this. I need to find a way to either
> > make [calc] re-entrant (is there an opcode I can SafeUntrap to make it
> > work?) or I need to find another way to be able to do what I'm trying to
> > do. Any suggestions?
>
> Try this patch (untested) in Vend::Data:
>
> --- /r/Data.pm 2009-05-27 17:17:41.000000000 -0400
> +++ /rt/Data.pm 2009-08-24 08:45:20.000000000 -0400
> @@ -1570,7 +1570,7 @@
> $Vend::Interpolate::item = $item;
> $Vend::Interpolate::s = $final;
> $Vend::Interpolate::q = $item->{quantity};
> - $price = Vend::Interpolate::tag_calc($mod);
> + $price = $MVSAFE::Safe ? eval($mod) : Vend::Interpolate::tag_calc($mod);
> undef $Vend::Interpolate::item;
> redo CHAIN;
> }
That's why we test -- this won't work because it will be in the wrong package. In
any case, it won't fix the problem.
You need to do:
SafeUntrap entereval
in interchange.cfg. There is no real way around that.
--
Mike Heins
Perusion -- Expert Interchange Consulting http://www.perusion.com/
phone +1.765.328.4479 <mike at perusion.com>
Some people have twenty years of experience, some people have
one year of experience twenty times over. -- Anonymous
More information about the interchange-users
mailing list