From 511f1d6d91af0f1d141953aa6d50e0361e6a083e Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Wed, 24 Mar 2021 12:02:54 +1100 Subject: [PATCH] fix magic and upgraded SV handling for setsockopt()'s OPTVAL The code here checked SV flags before fetching magic, potentially getting confused if magic fetched changed flags. This also fixes handling for upgraded SVs, but I'm not sure that can be tested sufficiently portably. --- pp_sys.c | 5 +++-- t/io/socket.t | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/pp_sys.c b/pp_sys.c index 7d0af1f43e5c..de7145267de0 100644 --- a/pp_sys.c +++ b/pp_sys.c @@ -2707,13 +2707,14 @@ PP(pp_ssockopt) case OP_SSOCKOPT: { const char *buf; int aint; + SvGETMAGIC(sv); if (SvPOKp(sv)) { STRLEN l; - buf = SvPV_const(sv, l); + buf = SvPVbyte_nomg(sv, l); len = l; } else { - aint = (int)SvIV(sv); + aint = (int)SvIV_nomg(sv); buf = (const char *) &aint; len = sizeof(int); } diff --git a/t/io/socket.t b/t/io/socket.t index 2dce1a7d08c1..6eb44fa91d79 100644 --- a/t/io/socket.t +++ b/t/io/socket.t @@ -281,6 +281,34 @@ SKIP: { ), "0\n", {}, "fresh socket not inherited across exec"); } +SKIP: +{ + my $val; + { + package SetsockoptMagic; + sub TIESCALAR { bless {}, shift } + sub FETCH { $val } + } + # setsockopt() magic + socket(my $sock, PF_INET, SOCK_STREAM, $tcp); + $val = 0; + # set a known value + ok(setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, 1), + "set known SO_REUSEADDR"); + isnt(getsockopt($sock, SOL_SOCKET, SO_REUSEADDR), pack("i", 0), + "check that worked"); + tie my $m, "SetsockoptMagic"; + # trigger the magic with the value 0 + $val = pack("i", 0); + my $temp = $m; + + $val = 1; + ok(setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, $m), + "set SO_REUSEADDR from magic"); + isnt(getsockopt($sock, SOL_SOCKET, SO_REUSEADDR), pack("i", 0), + "check SO_REUSEADDR set correctly"); +} + done_testing(); my @child_tests;