From b448305b6dd1c15337d24d7019534a018d1adc46 Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Mon, 2 Jul 2012 09:49:17 -0700 Subject: op.c:newFOROP: Fall back to realloc for unslabbed ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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.) --- ext/XS-APItest/APItest.xs | 19 +++++++++++++++++++ ext/XS-APItest/t/op.t | 3 +++ 2 files changed, 22 insertions(+) (limited to 'ext/XS-APItest') 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'; -- cgit v1.2.1