This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
In S_parse_body(), don't "leak" linestr_sv until global destruction.
authorNicholas Clark <nick@ccl4.org>
Sat, 25 Feb 2012 23:22:41 +0000 (00:22 +0100)
committerNicholas Clark <nick@ccl4.org>
Sat, 17 Mar 2012 10:44:36 +0000 (11:44 +0100)
This commit ensures that linestr_sv is properly cleaned up, if allocated.

The local variable linestr_sv was added by commit 009d90df4e17a415 in 2007,
to replace use of PL_linestr in S_parse_body(). However, that commit didn't
add any code to free linestr_sv at the end of S_parse_body(), meaning that
the SV sticks around until global destruction.

Subsequent code simplification possible by the removal of suidperl reveals
that linestr_sv is only needed for the '-x' option, so it's safe to avoid
allocating it up front. Additionally, during '-x' processing, Perl_sv_gets()
will upgrade the target SV to SVt_PV and allocate the string buffer as needed,
so there's no need to pre-upgrade or pre-allocate the SV in S_parse_body().
This slightly reduces the amount of code.

perl.c

diff --git a/perl.c b/perl.c
index e060948..1737893 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -1799,15 +1799,12 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
 #ifdef USE_SITECUSTOMIZE
     bool minus_f = FALSE;
 #endif
-    SV *linestr_sv = newSV_type(SVt_PVIV);
+    SV *linestr_sv = NULL;
     bool add_read_e_script = FALSE;
     U32 lex_start_flags = 0;
 
     PERL_SET_PHASE(PERL_PHASE_START);
 
-    SvGROW(linestr_sv, 80);
-    sv_setpvs(linestr_sv,"");
-
     init_main_stash();
 
     {
@@ -2103,6 +2100,8 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
            forbid_setid('x', suidscript);
            /* Hence you can't get here if suidscript is true */
 
+           linestr_sv = newSV_type(SVt_PV);
+           lex_start_flags |= LEX_START_COPIED;
            find_beginning(linestr_sv, rsfp);
            if (cddir && PerlDir_chdir( (char *)cddir ) < 0)
                Perl_croak(aTHX_ "Can't chdir to %s",cddir);
@@ -2231,6 +2230,9 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
 #endif
 
     lex_start(linestr_sv, rsfp, lex_start_flags);
+    if(linestr_sv)
+       SvREFCNT_dec(linestr_sv);
+
     PL_subname = newSVpvs("main");
 
     if (add_read_e_script)