diff options
author | Yves Orton <demerphq@gmail.com> | 2022-12-04 13:58:23 +0100 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2022-12-05 14:52:09 +0100 |
commit | 73dbc8219374856b2b08baa76f8fbdef16c44ea0 (patch) | |
tree | 6dc65c76dbd584f6e32cc5c460af56a6bbb2923b /pp_ctl.c | |
parent | d0a777fffcbb018434bd79aeb7c486a0f95595f1 (diff) | |
download | perl-73dbc8219374856b2b08baa76f8fbdef16c44ea0.tar.gz |
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.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 5 |
1 files changed, 4 insertions, 1 deletions
@@ -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 */ |