]> git.vpit.fr Git - perl/modules/Scope-Upper.git/blobdiff - Upper.xs
Sanitize and check unwind targets
[perl/modules/Scope-Upper.git] / Upper.xs
index 486c28b5ef4707f665e3e2d2752d2849c5d2de7f..231acccc4dbf105c942243cdb2502a5cf28f4ea9 100644 (file)
--- a/Upper.xs
+++ b/Upper.xs
@@ -527,18 +527,18 @@ STATIC void su_unwind(pTHX_ void *ud_) {
  OP fakeop;
  I32 cxix  = ud->cxix;
  I32 items = ud->items - 1;
- I32 gimme, mark = 0;
+ I32 gimme, mark;
 
  if (cxstack_ix > cxix)
   dounwind(cxix);
 
  /* Hide the level */
- PL_stack_sp--;
+ if (items >= 0)
+  PL_stack_sp--;
 
- gimme = GIMME_V;
- if (cxix > 0)
-  mark = cxstack[cxix - 1].blk_oldsp;
+ mark = PL_markstack[cxstack[cxix].blk_oldmarksp];
 
+ gimme = GIMME_V;
  if (gimme == G_SCALAR) {
   *PL_markstack_ptr = PL_stack_sp - PL_stack_base;
   PL_stack_sp += items;
@@ -598,20 +598,19 @@ XS(XS_Scope__Upper_unwind) {
 #else
  dXSARGS;
 #endif
- I32 cxix;
+ I32 from = 0, cxix = cxstack_ix;
  su_ud_unwind *ud;
  SV *level;
- if (!items)
-  Perl_croak(aTHX_ "Usage: Scope::Upper::unwind(..., level)");
  PERL_UNUSED_VAR(cv); /* -W */
  PERL_UNUSED_VAR(ax); /* -Wall */
- level = ST(items - 1);
- cxix = SvOK(level) ? SvIV(level) : 0;
- if (cxix < 0)
-  cxix = 0;
- else if (cxix > cxstack_ix)
-  cxix = cxstack_ix;
- cxix = cxstack_ix - cxix;
+ if (items) {
+  from = SvIV(ST(items - 1));
+  if (from < 0)
+   from = 0;
+  else if (from > cxix)
+   from = cxix;
+ }
+ cxix -= from;
  do {
   PERL_CONTEXT *cx = cxstack + cxix;
   switch (CxTYPE(cx)) {