[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