summaryrefslogtreecommitdiff
path: root/ext/XS-APItest
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-07-02 09:49:17 -0700
committerFather Chrysostomos <sprout@cpan.org>2012-07-02 22:40:27 -0700
commitb448305b6dd1c15337d24d7019534a018d1adc46 (patch)
tree4bd2316a4d2eebeb47b9a19a5c19ef0100a51a56 /ext/XS-APItest
parent5a27f6f2ee4c5634fe0f9a617041d6549b37f1b2 (diff)
downloadperl-b448305b6dd1c15337d24d7019534a018d1adc46.tar.gz
op.c:newFOROP: Fall back to realloc for unslabbed ops
When an op is allocated, PL_compcv is checked to see whether it can hold an op slab if it does not hold one already. If PL_compcv is not usable, for whatever reason, it falls back to malloc. Since the new slab allocator was added in commit 8be227a, newFOROP has been assuming, probably correctly, that its listop which it needs to enlarge to a loopop was allocated by slab. Since newFOROP is an API function, we should err on the safe side and check first whether the op is slab-allocated, falling back to realloc if it is not. To trigger this potential bug, one has to set things up such that there is a usable pad available, but no usable PL_compcv. I said ‘probably correctly’ above because this situation is highly unlikely and probably indicative of bugs elsewhere. (But we should still err on the side of safety.)
Diffstat (limited to 'ext/XS-APItest')
-rw-r--r--ext/XS-APItest/APItest.xs19
-rw-r--r--ext/XS-APItest/t/op.t3
2 files changed, 22 insertions, 0 deletions
diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs
index 8138ad585d..57c8fd078d 100644
--- a/ext/XS-APItest/APItest.xs
+++ b/ext/XS-APItest/APItest.xs
@@ -3360,6 +3360,25 @@ OUTPUT:
#endif
+bool
+test_newFOROP_without_slab()
+CODE:
+ {
+ const I32 floor = start_subparse(0,0);
+ CV * const cv = PL_compcv;
+ /* The slab allocator does not like CvROOT being set. */
+ CvROOT(PL_compcv) = (OP *)1;
+ op_free(newFOROP(0, 0, newOP(OP_PUSHMARK, 0), 0, 0));
+ CvROOT(PL_compcv) = NULL;
+ SvREFCNT_dec(PL_compcv);
+ LEAVE_SCOPE(floor);
+ /* If we have not crashed yet, then the test passes. */
+ RETVAL = TRUE;
+ }
+OUTPUT:
+ RETVAL
+
+
MODULE = XS::APItest PACKAGE = XS::APItest::AUTOLOADtest
int
diff --git a/ext/XS-APItest/t/op.t b/ext/XS-APItest/t/op.t
index 8a92a249a1..258f573268 100644
--- a/ext/XS-APItest/t/op.t
+++ b/ext/XS-APItest/t/op.t
@@ -10,3 +10,6 @@ use_ok('XS::APItest');
*hint_fetch = *hint_fetch = \&XS::APItest::Hash::refcounted_he_fetch;
require '../../t/op/caller.pl';
+
+ok test_newFOROP_without_slab(),
+ 'no assertion failures when allocating FOROP without slab';