From c95ca9b8cd1e9cb94201b96527b666a2e68bd781 Mon Sep 17 00:00:00 2001 From: David Mitchell Date: Sun, 6 Feb 2011 19:48:34 +0000 Subject: fix a s/non-utf8/is-utf8/ bit of nastiness Commit 3e462cdc2087ddf90984010fabd80c30db92bfa0 provided a fix for the s/non-utf8/is-utf8/ case by upgrading TARG to UTF8 after the match, but before the substitution. It used sv_utf8_upgrade() rather than sv_utf8_upgrade_nomg(), so for example, with a tied variable, FETCH would get called again, and all the char* pointers such as s would be left dangling. If the length of the string was unchanged, the code wouldn't notice this. Fix by using the _nomg() variant, and by checking whether the string has been reallocated --- pp_hot.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'pp_hot.c') diff --git a/pp_hot.c b/pp_hot.c index 5a920d4d4d..7316c5aabb 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -2185,12 +2185,13 @@ PP(pp_subst) * http://www.nntp.perl.org/group/perl.perl5.porters/2010/04/msg158809.html */ if (matched && DO_UTF8(dstr) && ! DO_UTF8(TARG)) { - const STRLEN new_len = sv_utf8_upgrade(TARG); + char * const orig_pvx = SvPVX(TARG); + const STRLEN new_len = sv_utf8_upgrade_nomg(TARG); /* If the lengths are the same, the pattern contains only * invariants, can keep going; otherwise, various internal markers * could be off, so redo */ - if (new_len != len) { + if (new_len != len || orig_pvx != SvPVX(TARG)) { goto setup_match; } } -- cgit v1.2.1