develooper Front page | perl.perl5.porters | Postings from December 2004

Re: [perl #33185] UTF-8 string substitution corrupts memory

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
December 30, 2004 12:41
Subject:
Re: [perl #33185] UTF-8 string substitution corrupts memory
Message ID:
20041230204127.GH77507@plum.flirble.org
On Thu, Dec 30, 2004 at 06:56:49PM +0000, Nicholas Clark wrote:
> The realistic fix is going to be to make it save and restore correctly for
> the class of operations that your code represents. I don't have the
> experience with the regexp engine to know where to look to quickly find the
> correct solution, but I believe that several other people on the
> perl5-porters mailing list do.

OK. I underestimate my brute force and ignorance. With a watchpoint on
my_perl->Tbostr, a backtrace at the first point of modification is:

0  Perl_pp_match (my_perl=0x800200) at pp_hot.c:1288
#1  0x000cfd70 in Perl_runops_debug (my_perl=0x800200) at dump.c:1572
#2  0x0001fde0 in Perl_call_sv (my_perl=0x800200, sv=0x4c, flags=6) at perl.c:2134
#3  0x00024308 in S_call_list_body (my_perl=0x800200, cv=0x888224) at perl.c:4721
#4  0x00023e34 in Perl_call_list (my_perl=0x800200, oldscope=3, paramList=0x80b278) at perl.c:4650
#5  0x00014de4 in Perl_newATTRSUB (my_perl=0x800200, floor=3, o=0x0, proto=0x888224, attrs=0x0, block=0x111e050) at op.c:4482
#6  0x00011228 in Perl_utilize (my_perl=0x800200, aver=1, floor=3, version=0x111e100, idop=0x63a360, arg=0x111df60) at op.c:3039
#7  0x00011434 in Perl_vload_module (my_perl=0x800200, flags=2, name=0x1, ver=0x111df60, args=0x4599e0) at op.c:3141
#8  0x00011284 in Perl_load_module (my_perl=0x68a7e0, flags=8430128, name=0x1, ver=0x68a7e0) at op.c:3093
#9  0x000b139c in Perl_swash_init (my_perl=0x800200, pkg=0xeaf84 "utf8", name=0xe7ef0 "", listsv=0x32b14c, minbits=1, none=0) at utf8.c:1587
#10 0x000df018 in Perl_regclass_swash (my_perl=0x800200, node=0x80a230, doinit=1 '\001', listsvp=0x0, altsvp=0xbfffee34) at regexec.c:4337
#11 0x000df254 in S_reginclass (my_perl=0x800200, n=0x6e31c4, p=0x111e017 "\202", lenp=0x0, do_utf8=1 '\001') at regexec.c:4388
#12 0x000d5854 in S_find_byclass (my_perl=0x800200, prog=0x6e3180, c=0x6e31c4, s=0x111e017 " perl.c:1853
#17 0x0001f03c in perl_run (my_perl=0x800200) at perl.c:1771
#18 0x0000289c in main (argc=4, argv=0xbffff730, env=0x1) at perlmain.c:98

where the culprit is #9, which was exercising this code *before* saving the
regexp engine context:

    if (!gv_fetchmeth(stash, "SWASHNEW", 8, -1)) {	/* demand load utf8 */
	ENTER;
	errsv_save = newSVsv(ERRSV);
	Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, newSVpvn(pkg,pkg_len),
			 Nullsv);
	if (!SvTRUE(ERRSV))
	    sv_setsv(ERRSV, errsv_save);
	SvREFCNT_dec(errsv_save);
	LEAVE;
    }

The appended patch seems to cure the problem for me, but I'm not confident
that it's the correct way.

Nicholas Clark

==== //depot/perl/utf8.c#212 - /Users/nick/p4perl/perl/utf8.c ====
--- /tmp/tmp.26186.0    Thu Dec 30 19:46:18 2004
+++ /Users/nick/p4perl/perl/utf8.c      Thu Dec 30 19:24:46 2004
@@ -1581,6 +1581,8 @@ Perl_swash_init(pTHX_ char* pkg, char* n
     HV *stash = gv_stashpvn(pkg, pkg_len, FALSE);
     SV* errsv_save;

+    ENTER;
+    save_re_context();
     if (!gv_fetchmeth(stash, "SWASHNEW", 8, -1)) {     /* demand load utf8 */
        ENTER;
        errsv_save = newSVsv(ERRSV);
@@ -1601,10 +1603,8 @@ Perl_swash_init(pTHX_ char* pkg, char* n
     PUSHs(sv_2mortal(newSViv(minbits)));
     PUSHs(sv_2mortal(newSViv(none)));
     PUTBACK;
-    ENTER;
     SAVEI32(PL_hints);
     PL_hints = 0;
-    save_re_context();
     if (IN_PERL_COMPILETIME) {
        /* XXX ought to be handled by lex_start */
        SAVEI32(PL_in_my);

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About