In op_size, add break statement missing for OPc_PVOP.
Nicholas Clark [Sat, 23 Apr 2011 20:55:48 +0000 (21:55 +0100)]
This has been missing since op_size was added in 0.60. Without it, PVOPs would
run on into the OPc_LOOP case, which would likely SEGV as it would consider
the char *op_pv as OP *op_first, and non-existent op_last, op_redoop, op_nextop
and op_lastop.

CHANGES
Size.xs
t/code.t

diff --git a/CHANGES b/CHANGES
index f07437e..364bc47 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,7 @@ Revision history for Perl extension Devel::Size.
 
 0.74_52 2011-04-23 nicholas
  * Fix potential SEGVs for OP_AELEMFAST on a lexical (eg $foo[3])
+ * Fix likely SEGVs for PVOPs (missing break)
 
 0.74_51 2011-04-22 nicholas
  * Don't count PL_sv_{undef,no,yes} in the size returned
diff --git a/Size.xs b/Size.xs
index 2a210e3..b849cc1 100644 (file)
--- a/Size.xs
+++ b/Size.xs
@@ -419,6 +419,7 @@ op_size(pTHX_ const OP * const baseop, struct state *st)
          TAG;break;
        case OPc_PVOP: TAG;
            check_new_and_strlen(st, cPVOPx(baseop)->op_pv);
+           TAG;break;
        case OPc_LOOP: TAG;
            st->total_size += sizeof(struct loop);
            op_size(aTHX_ cLOOPx(baseop)->op_first, st);
index ab5d514..3ac711a 100644 (file)
--- a/t/code.t
+++ b/t/code.t
@@ -1,7 +1,7 @@
 #!/usr/bin/perl -w
 
 use strict;
-use Test::More tests => 10;
+use Test::More tests => 12;
 use Devel::Size ':all';
 
 sub zwapp;
@@ -40,3 +40,8 @@ cmp_ok($anon_proto_size, '>', $anon_size + length prototype $anon_proto,
     cmp_ok($aelemfast, '>', $aelemfast_lex,
           'aelemfast for a package variable is larger');
 }
+
+my $short_pvop = total_size(sub {goto GLIT});
+my $long_pvop = total_size(sub {goto KREEK_KREEK_CLANK_CLANK});
+cmp_ok($short_pvop, '>', $anon_size, 'OPc_PVOP can be measured');
+is($long_pvop, $short_pvop + 19, 'the only size difference is the label length');