summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2004-06-07 23:09:42 +0300
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2004-06-08 13:44:27 +0000
commit2b573acec7886e18e5f2804e8915073100dce2e4 (patch)
tree60c48c757c95672d726a096029840f65f872f61b /pp.c
parent7b614c55f5b832a2a6bef87f61ab8323c0d06c60 (diff)
downloadperl-2b573acec7886e18e5f2804e8915073100dce2e4.tar.gz
Re: [PATCH] Re: Lack of error for large string on Solaris
Message-ID: <40C4A156.5030205@iki.fi> p4raw-id: //depot/perl@22904
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/pp.c b/pp.c
index 2d73123117..001b9be795 100644
--- a/pp.c
+++ b/pp.c
@@ -1391,19 +1391,46 @@ PP(pp_repeat)
{
dSP; dATARGET; tryAMAGICbin(repeat,opASSIGN);
{
- register IV count = POPi;
- if (count < 0)
- count = 0;
+ register IV count;
+ dPOPss;
+ if (SvGMAGICAL(sv))
+ mg_get(sv);
+ if (SvIOKp(sv)) {
+ if (SvUOK(sv)) {
+ UV uv = SvUV(sv);
+ if (uv > IV_MAX)
+ count = IV_MAX; /* The best we can do? */
+ else
+ count = uv;
+ } else {
+ IV iv = SvIV(sv);
+ if (iv < 0)
+ count = 0;
+ else
+ count = iv;
+ }
+ }
+ else if (SvNOKp(sv)) {
+ NV nv = SvNV(sv);
+ if (nv < 0.0)
+ count = 0;
+ else
+ count = (IV)nv;
+ }
+ else
+ count = SvIVx(sv);
if (GIMME == G_ARRAY && PL_op->op_private & OPpREPEAT_DOLIST) {
dMARK;
I32 items = SP - MARK;
I32 max;
- static const char list_extend[] = "panic: list extend";
+ static const char oom_list_extend[] =
+ "Out of memory during list extend";
max = items * count;
- MEM_WRAP_CHECK_1(max, SV*, list_extend);
+ MEM_WRAP_CHECK_1(max, SV*, oom_list_extend);
+ /* Did the max computation overflow? */
if (items > 0 && max > 0 && (max < items || max < count))
- Perl_croak(aTHX_ list_extend);
+ Perl_croak(aTHX_ oom_list_extend);
MEXTEND(MARK, max);
if (count > 1) {
while (SP > MARK) {
@@ -1448,6 +1475,8 @@ PP(pp_repeat)
SV *tmpstr = POPs;
STRLEN len;
bool isutf;
+ static const char oom_string_extend[] =
+ "Out of memory during string extend";
SvSetSV(TARG, tmpstr);
SvPV_force(TARG, len);
@@ -1456,7 +1485,10 @@ PP(pp_repeat)
if (count < 1)
SvCUR_set(TARG, 0);
else {
- MEM_WRAP_CHECK_1(count, len, "panic: string extend");
+ IV max = count * len;
+ if (len > ((MEM_SIZE)~0)/count)
+ Perl_croak(aTHX_ oom_string_extend);
+ MEM_WRAP_CHECK_1(max, char, oom_string_extend);
SvGROW(TARG, (count * len) + 1);
repeatcpy(SvPVX(TARG) + len, SvPVX(TARG), len, count - 1);
SvCUR(TARG) *= count;