diff options
author | Tony Cook <tony@develop-help.com> | 2023-01-23 15:28:12 +1100 |
---|---|---|
committer | Tony Cook <tony@develop-help.com> | 2023-01-25 09:26:27 +1100 |
commit | af62106ad344b13fde54d2c0d5e7e0d0bab96054 (patch) | |
tree | c2f835b80175fdfd0e3ff533e6271dda9a1aeac8 /mg.c | |
parent | fa1fe46855cd623ff0f787f3025c3c3f14cd57b4 (diff) | |
download | perl-af62106ad344b13fde54d2c0d5e7e0d0bab96054.tar.gz |
check the IO object exists when writing to IO magic variables
pp_select() ensures that the GV in PL_defoutgv has an IO object
when it the default output is set, but can't prevent that GV
being cleared afterwards, resulting in a seg fault when the
variable is written.
To prevent this, check PL_defoutgv has an IO object before trying
to write to it.
Fixes #20733
Diffstat (limited to 'mg.c')
-rw-r--r-- | mg.c | 52 |
1 files changed, 41 insertions, 11 deletions
@@ -3072,25 +3072,55 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) IoLINES(GvIOp(PL_last_in_gv)) = SvIV(sv); break; case '^': - Safefree(IoTOP_NAME(GvIOp(PL_defoutgv))); - IoTOP_NAME(GvIOp(PL_defoutgv)) = savesvpv(sv); - IoTOP_GV(GvIOp(PL_defoutgv)) = gv_fetchsv(sv, GV_ADD, SVt_PVIO); + { + IO * const io = GvIO(PL_defoutgv); + if (!io) + break; + + Safefree(IoTOP_NAME(io)); + IoTOP_NAME(io) = savesvpv(sv); + IoTOP_GV(io) = gv_fetchsv(sv, GV_ADD, SVt_PVIO); + } break; case '~': - Safefree(IoFMT_NAME(GvIOp(PL_defoutgv))); - IoFMT_NAME(GvIOp(PL_defoutgv)) = savesvpv(sv); - IoFMT_GV(GvIOp(PL_defoutgv)) = gv_fetchsv(sv, GV_ADD, SVt_PVIO); + { + IO * const io = GvIO(PL_defoutgv); + if (!io) + break; + + Safefree(IoFMT_NAME(io)); + IoFMT_NAME(io) = savesvpv(sv); + IoFMT_GV(io) = gv_fetchsv(sv, GV_ADD, SVt_PVIO); + } break; case '=': - IoPAGE_LEN(GvIOp(PL_defoutgv)) = (SvIV(sv)); + { + IO * const io = GvIO(PL_defoutgv); + if (!io) + break; + + IoPAGE_LEN(io) = (SvIV(sv)); + } break; case '-': - IoLINES_LEFT(GvIOp(PL_defoutgv)) = (SvIV(sv)); - if (IoLINES_LEFT(GvIOp(PL_defoutgv)) < 0L) - IoLINES_LEFT(GvIOp(PL_defoutgv)) = 0L; + { + IO * const io = GvIO(PL_defoutgv); + if (!io) + break; + + IoLINES_LEFT(io) = (SvIV(sv)); + if (IoLINES_LEFT(io) < 0L) + IoLINES_LEFT(io) = 0L; + } break; case '%': - IoPAGE(GvIOp(PL_defoutgv)) = (SvIV(sv)); + { + IO * const io = GvIO(PL_defoutgv); + if (!io) + break; + + IoPAGE(io) = (SvIV(sv)); + } break; case '|': { |