Re: [perl #18107] lc(), uc() and ucfirst() broken inside utf8 regex
Hugo van der Sanden [Tue, 5 Nov 2002 13:30:00 +0000 (13:30 +0000)]
Message-Id: <200211051330.gA5DU0p00718@crypt.compulink.co.uk>

This is half of the fix for #18107. The swash_init() problems
described in <20021105143646.M18101@lustre.dyn.wiw.org> remain,
but can now be seen only with UTF-8 test cases.

p4raw-id: //depot/perl@18109

pp.c

diff --git a/pp.c b/pp.c
index 4c05aab..1a1dcea 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -3323,7 +3323,8 @@ PP(pp_ucfirst)
     register U8 *s;
     STRLEN slen;
 
-    if (DO_UTF8(sv) && (s = (U8*)SvPV(sv, slen)) && slen && UTF8_IS_START(*s)) {
+    SvGETMAGIC(sv);
+    if (DO_UTF8(sv) && (s = (U8*)SvPV_nomg(sv, slen)) && slen && UTF8_IS_START(*s)) {
        U8 tmpbuf[UTF8_MAXLEN_UCLC+1];
        STRLEN ulen;
        STRLEN tculen;
@@ -3340,7 +3341,7 @@ PP(pp_ucfirst)
            SETs(TARG);
        }
        else {
-           s = (U8*)SvPV_force(sv, slen);
+           s = (U8*)SvPV_force_nomg(sv, slen);
            Copy(tmpbuf, s, tculen, U8);
        }
     }
@@ -3348,11 +3349,11 @@ PP(pp_ucfirst)
        if (!SvPADTMP(sv) || SvREADONLY(sv)) {
            dTARGET;
            SvUTF8_off(TARG);                           /* decontaminate */
-           sv_setsv(TARG, sv);
+           sv_setsv_nomg(TARG, sv);
            sv = TARG;
            SETs(sv);
        }
-       s = (U8*)SvPV_force(sv, slen);
+       s = (U8*)SvPV_force_nomg(sv, slen);
        if (*s) {
            if (IN_LOCALE_RUNTIME) {
                TAINT;
@@ -3363,8 +3364,7 @@ PP(pp_ucfirst)
                *s = toUPPER(*s);
        }
     }
-    if (SvSMAGICAL(sv))
-       mg_set(sv);
+    SvSETMAGIC(sv);
     RETURN;
 }
 
@@ -3375,7 +3375,8 @@ PP(pp_lcfirst)
     register U8 *s;
     STRLEN slen;
 
-    if (DO_UTF8(sv) && (s = (U8*)SvPV(sv, slen)) && slen && UTF8_IS_START(*s)) {
+    SvGETMAGIC(sv);
+    if (DO_UTF8(sv) && (s = (U8*)SvPV_nomg(sv, slen)) && slen && UTF8_IS_START(*s)) {
        STRLEN ulen;
        U8 tmpbuf[UTF8_MAXLEN_UCLC+1];
        U8 *tend;
@@ -3393,7 +3394,7 @@ PP(pp_lcfirst)
            SETs(TARG);
        }
        else {
-           s = (U8*)SvPV_force(sv, slen);
+           s = (U8*)SvPV_force_nomg(sv, slen);
            Copy(tmpbuf, s, ulen, U8);
        }
     }
@@ -3401,11 +3402,11 @@ PP(pp_lcfirst)
        if (!SvPADTMP(sv) || SvREADONLY(sv)) {
            dTARGET;
            SvUTF8_off(TARG);                           /* decontaminate */
-           sv_setsv(TARG, sv);
+           sv_setsv_nomg(TARG, sv);
            sv = TARG;
            SETs(sv);
        }
-       s = (U8*)SvPV_force(sv, slen);
+       s = (U8*)SvPV_force_nomg(sv, slen);
        if (*s) {
            if (IN_LOCALE_RUNTIME) {
                TAINT;
@@ -3416,8 +3417,7 @@ PP(pp_lcfirst)
                *s = toLOWER(*s);
        }
     }
-    if (SvSMAGICAL(sv))
-       mg_set(sv);
+    SvSETMAGIC(sv);
     RETURN;
 }
 
@@ -3428,6 +3428,7 @@ PP(pp_uc)
     register U8 *s;
     STRLEN len;
 
+    SvGETMAGIC(sv);
     if (DO_UTF8(sv)) {
        dTARGET;
        STRLEN ulen;
@@ -3435,7 +3436,7 @@ PP(pp_uc)
        U8 *send;
        U8 tmpbuf[UTF8_MAXLEN_UCLC+1];
 
-       s = (U8*)SvPV(sv,len);
+       s = (U8*)SvPV_nomg(sv,len);
        if (!len) {
            SvUTF8_off(TARG);                           /* decontaminate */
            sv_setpvn(TARG, "", 0);
@@ -3465,11 +3466,11 @@ PP(pp_uc)
        if (!SvPADTMP(sv) || SvREADONLY(sv)) {
            dTARGET;
            SvUTF8_off(TARG);                           /* decontaminate */
-           sv_setsv(TARG, sv);
+           sv_setsv_nomg(TARG, sv);
            sv = TARG;
            SETs(sv);
        }
-       s = (U8*)SvPV_force(sv, len);
+       s = (U8*)SvPV_force_nomg(sv, len);
        if (len) {
            register U8 *send = s + len;
 
@@ -3485,8 +3486,7 @@ PP(pp_uc)
            }
        }
     }
-    if (SvSMAGICAL(sv))
-       mg_set(sv);
+    SvSETMAGIC(sv);
     RETURN;
 }
 
@@ -3497,6 +3497,7 @@ PP(pp_lc)
     register U8 *s;
     STRLEN len;
 
+    SvGETMAGIC(sv);
     if (DO_UTF8(sv)) {
        dTARGET;
        STRLEN ulen;
@@ -3504,7 +3505,7 @@ PP(pp_lc)
        U8 *send;
        U8 tmpbuf[UTF8_MAXLEN_UCLC+1];
 
-       s = (U8*)SvPV(sv,len);
+       s = (U8*)SvPV_nomg(sv,len);
        if (!len) {
            SvUTF8_off(TARG);                           /* decontaminate */
            sv_setpvn(TARG, "", 0);
@@ -3551,12 +3552,12 @@ PP(pp_lc)
        if (!SvPADTMP(sv) || SvREADONLY(sv)) {
            dTARGET;
            SvUTF8_off(TARG);                           /* decontaminate */
-           sv_setsv(TARG, sv);
+           sv_setsv_nomg(TARG, sv);
            sv = TARG;
            SETs(sv);
        }
 
-       s = (U8*)SvPV_force(sv, len);
+       s = (U8*)SvPV_force_nomg(sv, len);
        if (len) {
            register U8 *send = s + len;
 
@@ -3572,8 +3573,7 @@ PP(pp_lc)
            }
        }
     }
-    if (SvSMAGICAL(sv))
-       mg_set(sv);
+    SvSETMAGIC(sv);
     RETURN;
 }