From: Zefram Date: Fri, 15 Jan 2010 16:13:17 +0000 (+0100) Subject: [perl #62646] Maximum string length with substr X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b6d1426f94a845fb8fece8b6ad0b7d9f35f2d62e;p=p5sagit%2Fp5-mst-13.2.git [perl #62646] Maximum string length with substr (This is only a partial fix, since it doesn't handle lvalue substr) --- diff --git a/pp.c b/pp.c index c659b13..4735c94 100644 --- a/pp.c +++ b/pp.c @@ -3079,12 +3079,12 @@ PP(pp_substr) { dVAR; dSP; dTARGET; SV *sv; - I32 len = 0; + IV len = 0; STRLEN curlen; STRLEN utf8_curlen; - I32 pos; - I32 rem; - I32 fail; + IV pos; + IV rem; + IV fail; const I32 lvalue = PL_op->op_flags & OPf_MOD || LVRET; const char *tmps; const I32 arybase = CopARYBASE_get(PL_curcop); @@ -3147,7 +3147,7 @@ PP(pp_substr) rem = curlen; else if (len >= 0) { rem = pos+len; - if (rem > (I32)curlen) + if (rem > (IV)curlen) rem = curlen; } else { @@ -3167,8 +3167,8 @@ PP(pp_substr) RETPUSHUNDEF; } else { - const I32 upos = pos; - const I32 urem = rem; + const IV upos = pos; + const IV urem = rem; if (utf8_curlen) sv_pos_u2b(sv, &pos, &rem); tmps += pos; diff --git a/t/re/substr.t b/t/re/substr.t index c3fa6e1..49fd97b 100644 --- a/t/re/substr.t +++ b/t/re/substr.t @@ -24,7 +24,7 @@ $SIG{__WARN__} = sub { require './test.pl'; -plan(334); +plan(338); run_tests() unless caller; @@ -682,4 +682,19 @@ is($x, "\x{100}\x{200}\xFFb"); is(substr($a,1,1), 'b'); } +# [perl #62646] offsets exceeding 32 bits on 64-bit system +SKIP: { + skip("32-bit system", 4) unless ~0 > 0xffffffff; + my $a = "abc"; + my $r; + $w = 0; + $r = substr($a, 0xffffffff, 1); + is($r, undef); + is($w, 1); + $w = 0; + $r = substr($a, 0xffffffff+1, 1); + is($r, undef); + is($w, 1); +} + }