The maxiters upper limit sanity check (guarding against
Jarkko Hietaniemi [Thu, 28 Dec 2000 23:57:05 +0000 (23:57 +0000)]
non-progress) assumed bytes instead of characters in s///
and split().

p4raw-id: //depot/perl@8245

pp.c
pp_hot.c

diff --git a/pp.c b/pp.c
index 4a46de5..eac7532 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -5745,7 +5745,7 @@ PP(pp_split)
     AV *ary;
     register IV limit = POPi;                  /* note, negative is forever */
     SV *sv = POPs;
-    bool doutf8 = DO_UTF8(sv);
+    bool do_utf8 = DO_UTF8(sv);
     STRLEN len;
     register char *s = SvPV(sv, len);
     char *strend = s + len;
@@ -5754,7 +5754,8 @@ PP(pp_split)
     register SV *dstr;
     register char *m;
     I32 iters = 0;
-    I32 maxiters = (strend - s) + 10;
+    STRLEN slen = do_utf8 ? utf8_length((U8*)s, (U8*)strend) : (strend - s);
+    I32 maxiters = slen + 10;
     I32 i;
     char *orig;
     I32 origlimit = limit;
@@ -5848,7 +5849,7 @@ PP(pp_split)
            sv_setpvn(dstr, s, m-s);
            if (make_mortal)
                sv_2mortal(dstr);
-           if (doutf8)
+           if (do_utf8)
                (void)SvUTF8_on(dstr);
            XPUSHs(dstr);
 
@@ -5870,7 +5871,7 @@ PP(pp_split)
            sv_setpvn(dstr, s, m-s);
            if (make_mortal)
                sv_2mortal(dstr);
-           if (doutf8)
+           if (do_utf8)
                (void)SvUTF8_on(dstr);
            XPUSHs(dstr);
            s = m;
@@ -5895,12 +5896,12 @@ PP(pp_split)
                sv_setpvn(dstr, s, m-s);
                if (make_mortal)
                    sv_2mortal(dstr);
-               if (doutf8)
+               if (do_utf8)
                    (void)SvUTF8_on(dstr);
                XPUSHs(dstr);
                /* The rx->minlen is in characters but we want to step
                 * s ahead by bytes. */
-               s = m + (doutf8 ? SvCUR(csv) : len);
+               s = m + (do_utf8 ? SvCUR(csv) : len);
            }
        }
        else {
@@ -5914,17 +5915,17 @@ PP(pp_split)
                sv_setpvn(dstr, s, m-s);
                if (make_mortal)
                    sv_2mortal(dstr);
-               if (doutf8)
+               if (do_utf8)
                    (void)SvUTF8_on(dstr);
                XPUSHs(dstr);
                /* The rx->minlen is in characters but we want to step
                 * s ahead by bytes. */
-               s = m + (doutf8 ? SvCUR(csv) : len); /* Fake \n at the end */
+               s = m + (do_utf8 ? SvCUR(csv) : len); /* Fake \n at the end */
            }
        }
     }
     else {
-       maxiters += (strend - s) * rx->nparens;
+       maxiters += slen * rx->nparens;
        while (s < strend && --limit
 /*            && (!rx->check_substr
                   || ((s = CALLREG_INTUIT_START(aTHX_ rx, sv, s, strend,
@@ -5945,7 +5946,7 @@ PP(pp_split)
            sv_setpvn(dstr, s, m-s);
            if (make_mortal)
                sv_2mortal(dstr);
-           if (doutf8)
+           if (do_utf8)
                (void)SvUTF8_on(dstr);
            XPUSHs(dstr);
            if (rx->nparens) {
@@ -5960,7 +5961,7 @@ PP(pp_split)
                        dstr = NEWSV(33, 0);
                    if (make_mortal)
                        sv_2mortal(dstr);
-                   if (doutf8)
+                   if (do_utf8)
                        (void)SvUTF8_on(dstr);
                    XPUSHs(dstr);
                }
@@ -5981,7 +5982,7 @@ PP(pp_split)
        sv_setpvn(dstr, s, l);
        if (make_mortal)
            sv_2mortal(dstr);
-       if (doutf8)
+       if (do_utf8)
            (void)SvUTF8_on(dstr);
        XPUSHs(dstr);
        iters++;
index c362665..d02f57e 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1821,6 +1821,8 @@ PP(pp_subst)
     STRLEN len;
     int force_on_match = 0;
     I32 oldsave = PL_savestack_ix;
+    bool do_utf8;
+    STRLEN slen;
 
     /* known replacement string? */
     dstr = (pm->op_pmflags & PMf_CONST) ? POPs : Nullsv;
@@ -1831,6 +1833,7 @@ PP(pp_subst)
        EXTEND(SP,1);
     }
     PL_reg_sv = TARG;
+    do_utf8 = DO_UTF8(PL_reg_sv);
     if (SvFAKE(TARG) && SvREADONLY(TARG))
        sv_force_normal(TARG);
     if (SvREADONLY(TARG)
@@ -1853,9 +1856,10 @@ PP(pp_subst)
        DIE(aTHX_ "panic: pp_subst");
 
     strend = s + len;
-    maxiters = 2*(strend - s) + 10;    /* We can match twice at each
-                                          position, once with zero-length,
-                                          second time with non-zero. */
+    slen = do_utf8 ? utf8_length(s, strend) : len;
+    maxiters = 2 * slen + 10;  /* We can match twice at each
+                                  position, once with zero-length,
+                                  second time with non-zero. */
 
     if (!rx->prelen && PL_curpm) {
        pm = PL_curpm;