Skip to content

Commit 66d150f

Browse files
committed
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.
1 parent 3e25f6d commit 66d150f

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

pp_sys.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -2707,13 +2707,14 @@ PP(pp_ssockopt)
27072707
case OP_SSOCKOPT: {
27082708
const char *buf;
27092709
int aint;
2710+
SvGETMAGIC(sv);
27102711
if (SvPOKp(sv)) {
27112712
STRLEN l;
2712-
buf = SvPV_const(sv, l);
2713+
buf = SvPVbyte_nomg(sv, l);
27132714
len = l;
27142715
}
27152716
else {
2716-
aint = (int)SvIV(sv);
2717+
aint = (int)SvIV_nomg(sv);
27172718
buf = (const char *) &aint;
27182719
len = sizeof(int);
27192720
}

t/io/socket.t

+28
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,34 @@ SKIP: {
281281
), "0\n", {}, "fresh socket not inherited across exec");
282282
}
283283

284+
SKIP:
285+
{
286+
my $val;
287+
{
288+
package SetsockoptMagic;
289+
sub TIESCALAR { bless {}, shift }
290+
sub FETCH { $val }
291+
}
292+
# setsockopt() magic
293+
socket(my $sock, PF_INET, SOCK_STREAM, $tcp);
294+
$val = 0;
295+
# set a known value
296+
ok(setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, 1),
297+
"set known SO_REUSEADDR");
298+
is(getsockopt($sock, SOL_SOCKET, SO_REUSEADDR), pack("i", 1),
299+
"check that worked");
300+
tie my $m, "SetsockoptMagic";
301+
# trigger the magic with the value 0
302+
$val = pack("i", 0);
303+
my $temp = $m;
304+
305+
$val = 1;
306+
ok(setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, $m),
307+
"set SO_REUSEADDR from magic");
308+
is(getsockopt($sock, SOL_SOCKET, SO_REUSEADDR), pack("i", 1),
309+
"check SO_REUSEADDR set correctly");
310+
}
311+
284312
done_testing();
285313

286314
my @child_tests;

0 commit comments

Comments
 (0)