From 73dbc8219374856b2b08baa76f8fbdef16c44ea0 Mon Sep 17 00:00:00 2001 From: Yves Orton Date: Sun, 4 Dec 2022 13:58:23 +0100 Subject: pp_ctl.c - copy hook into %INC not alias it When an @INC hook is executed and it updates %INC it can result in @INC being updated and the hook being destroyed. This seems to be because the SV fetched from @INC is stored into %INC directly, essentially creating an alias (in perl terms) of the original. When the alias is updated, for instance by setting it to be a string, this is reflected in both @INC and %INC. By copying the sv before we store it we avoid this problem. We can't run the test under miniperl as it uses IO layers. This should fix GH #20577. --- pp_ctl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'pp_ctl.c') diff --git a/pp_ctl.c b/pp_ctl.c index 1e6dda7e98..fb760ee183 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -4605,10 +4605,13 @@ S_require_file(pTHX_ SV *sv) (void)hv_store(GvHVn(PL_incgv), unixname, unixlen, newSVpv(tryname,0),0); } else { + /* store the hook in the sv, note we have to *copy* hook_sv, + * we don't want modifications to it to change @INC - see GH #20577 + */ SV** const svp = hv_fetch(GvHVn(PL_incgv), unixname, unixlen, 0); if (!svp) (void)hv_store(GvHVn(PL_incgv), - unixname, unixlen, SvREFCNT_inc_simple(hook_sv), 0 ); + unixname, unixlen, newSVsv(hook_sv), 0 ); } /* Now parse the file */ -- cgit v1.2.1