From: Nicholas Clark Date: Sun, 13 Jul 2008 20:22:25 +0000 (+0000) Subject: The assert()ions in sv_chop() that the passed in pointer is within the X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=6c65d5f9331797a0b303b34e8a76d4c0ea75e4d0;p=p5sagit%2Fp5-mst-13.2.git The assert()ions in sv_chop() that the passed in pointer is within the SV's buffer should be full-on panics, as bogus values passed in can cause later heap corruption, which is a bad thing (TM). p4raw-id: //depot/perl@34138 --- diff --git a/pod/perldiag.pod b/pod/perldiag.pod index f5c61d7..c512559 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -3189,6 +3189,11 @@ then discovered it wasn't a subroutine or eval context. (P) scan_num() got called on something that wasn't a number. +=item panic: sv_chop %s + +(P) The sv_chop() routine was passed a position that is not within the +scalar's string buffer. + =item panic: sv_insert (P) The sv_insert() routine was told to remove more string than there diff --git a/sv.c b/sv.c index cdae779..c2b4171 100644 --- a/sv.c +++ b/sv.c @@ -4389,6 +4389,7 @@ Perl_sv_chop(pTHX_ register SV *const sv, register const char *const ptr) #ifdef DEBUGGING const U8 *real_start; #endif + STRLEN max_delta; PERL_ARGS_ASSERT_SV_CHOP; @@ -4399,12 +4400,17 @@ Perl_sv_chop(pTHX_ register SV *const sv, register const char *const ptr) /* Nothing to do. */ return; } - assert(ptr > SvPVX_const(sv)); + /* SvPVX(sv) may move in SV_CHECK_THINKFIRST(sv), but after this line, + nothing uses the value of ptr any more. */ + if (ptr <= SvPVX_const(sv)) + Perl_croak(aTHX_ "panic: sv_chop ptr=%p, start=%p, end=%p", + ptr, SvPVX_const(sv), SvPVX_const(sv) + max_delta); SV_CHECK_THINKFIRST(sv); - if (SvLEN(sv)) - assert(delta <= SvLEN(sv)); - else - assert(delta <= SvCUR(sv)); + max_delta = SvLEN(sv) ? SvLEN(sv) : SvCUR(sv); + if (delta > max_delta) + Perl_croak(aTHX_ "panic: sv_chop ptr=%p (was %p), start=%p, end=%p", + SvPVX_const(sv) + delta, ptr, SvPVX_const(sv), + SvPVX_const(sv) + max_delta); if (!SvOOK(sv)) { if (!SvLEN(sv)) { /* make copy of shared string */