summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-io/src
diff options
context:
space:
mode:
authordearblue <[email protected]>2020-04-11 11:18:47 +0900
committerdearblue <[email protected]>2020-04-12 14:18:36 +0900
commit3c03385e2e5f4d1d87c5ebcd35c92a41619c9f96 (patch)
tree1767442eab662dbcf9f892a06d53e853add80560 /mrbgems/mruby-io/src
parent63c7ff341a53a689209e67f9f1c885fcff596cf8 (diff)
downloadmruby-3c03385e2e5f4d1d87c5ebcd35c92a41619c9f96.tar.gz
mruby-3c03385e2e5f4d1d87c5ebcd35c92a41619c9f96.zip
Check the file descriptor with `IO#initialize`; resolve #4966
Diffstat (limited to 'mrbgems/mruby-io/src')
-rw-r--r--mrbgems/mruby-io/src/io.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c
index 8b0dcb244..c7273bce8 100644
--- a/mrbgems/mruby-io/src/io.c
+++ b/mrbgems/mruby-io/src/io.c
@@ -645,6 +645,43 @@ mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy)
return copy;
}
+static void
+check_file_descriptor(mrb_state *mrb, mrb_int fd)
+{
+ struct stat sb;
+ int fdi = (int)fd;
+
+#if MRB_INT_MIN < INT_MIN || MRB_INT_MAX > INT_MAX
+ if (fdi != fd) {
+ goto badfd;
+ }
+#endif
+
+#ifdef _WIN32
+ {
+ DWORD err;
+ int len = sizeof(err);
+
+ if (getsockopt(fdi, SOL_SOCKET, SO_ERROR, (char*)&err, &len) == 0) {
+ return;
+ }
+ }
+
+ if (fdi < 0 || fdi > _getmaxstdio()) {
+ goto badfd;
+ }
+#endif /* _WIN32 */
+
+ if (fstat(fdi, &sb) != 0) {
+ goto badfd;
+ }
+
+ return;
+
+badfd:
+ mrb_sys_fail(mrb, "bad file descriptor");
+}
+
mrb_value
mrb_io_initialize(mrb_state *mrb, mrb_value io)
{
@@ -656,6 +693,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
mode = opt = mrb_nil_value();
mrb_get_args(mrb, "i|oo", &fd, &mode, &opt);
+ check_file_descriptor(mrb, fd);
if (mrb_nil_p(mode)) {
mode = mrb_str_new_cstr(mrb, "r");
}