diff options
Diffstat (limited to 'mrbgems/mruby-io/src/io.c')
| -rw-r--r-- | mrbgems/mruby-io/src/io.c | 38 |
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"); } |
