[ic] $Tag->price() [calc] re-entrancy problems

Mike Heins mike at perusion.com
Mon Aug 24 12:47:00 UTC 2009


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;
 			}
-- 
Mike Heins
Perusion -- Expert Interchange Consulting    http://www.perusion.com/
phone +1.765.328.4479  <mike at perusion.com>

Nature, to be commanded, must be obeyed. -- Francis Bacon



More information about the interchange-users mailing list