On 15 April 2010 17:51, Vincent Pit <perl@profvince.com> wrote:
> There are a few places in the core where the cx->blk_eval.old_namesv member
> is read after LEAVE happens. This is bad because LEAVE can call arbitrary
> code ; in particular, it can call a destructor that does call_sv(cv,
> G_EVAL), in which case the old eval context cx gets overwritten by the new
> one and cx->blk_eval.old_namesv points to garbage.
>
> The attached patch fixes this issue by making POPEVAL() pop
> cx->blk_eval.old_namesv to a local variable "namesv". It can fix obscure
> "panic: restartop" or "Unknown errors" bugs, though it's hard to think of a
> pure-Perl regression test for it.
>
> It's not suitable for 5.12.1 because the POPEVAL() public macro is changed
> in such a way third-party extensions that use it need to declare the new
> "namesv" variable.
Why don't you declare namesv in the POPEVAL block ?
--- a/cop.h
+++ b/cop.h
@@ -436,11 +436,13 @@ struct block_eval {
#define POPEVAL(cx) \
STMT_START { \
+ SV *namesv; \
PL_in_eval = CxOLD_IN_EVAL(cx); \
optype = CxOLD_OP_TYPE(cx); \
PL_eval_root = cx->blk_eval.old_eval_root; \
- if (cx->blk_eval.old_namesv) \
- sv_2mortal(cx->blk_eval.old_namesv); \
+ namesv = cx->blk_eval.old_namesv; \
+ if (namesv) \
+ sv_2mortal(namesv); \
} STMT_END
Thread Previous
|
Thread Next