diff options
author | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2021-07-12 16:28:43 +1200 |
---|---|---|
committer | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2021-07-12 19:16:22 +1200 |
commit | 028441d22fee121d129126c55938690be38bd3d9 (patch) | |
tree | c7911aaf9fbcd5c895e4ecf516c701e1072a2bc2 /ext/socket/basicsocket.c | |
parent | 0895d57d3115f162dcb6cff82da1834a7241633e (diff) |
Avoid calling `fstat` on things we already know are valid sockets.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4645
Diffstat (limited to 'ext/socket/basicsocket.c')
-rw-r--r-- | ext/socket/basicsocket.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c index 05172100c8..8477a37a6d 100644 --- a/ext/socket/basicsocket.c +++ b/ext/socket/basicsocket.c @@ -10,6 +10,28 @@ #include "rubysocket.h" +#ifdef _WIN32 +#define is_socket(fd) rb_w32_is_socket(fd) +#else +static int +is_socket(int fd) +{ + struct stat sbuf; + + if (fstat(fd, &sbuf) < 0) + rb_sys_fail("fstat(2)"); + return S_ISSOCK(sbuf.st_mode); +} +#endif + +static void +rsock_validate_descriptor(int descriptor) +{ + if (!is_socket(descriptor) || rb_reserved_fd_p(descriptor)) { + rb_syserr_fail(EBADF, "not a socket file descriptor"); + } +} + /* * call-seq: * BasicSocket.for_fd(fd) => basicsocket @@ -22,10 +44,14 @@ * */ static VALUE -bsock_s_for_fd(VALUE klass, VALUE fd) +bsock_s_for_fd(VALUE klass, VALUE _descriptor) { rb_io_t *fptr; - VALUE sock = rsock_init_sock(rb_obj_alloc(klass), NUM2INT(fd)); + + int descriptor = RB_NUM2INT(_descriptor); + rsock_validate_descriptor(descriptor); + + VALUE sock = rsock_init_sock(rb_obj_alloc(klass), descriptor); GetOpenFile(sock, fptr); |