diff options
| -rw-r--r-- | mrbgems/mruby-io/src/io.c | 38 | ||||
| -rw-r--r-- | mrbgems/mruby-io/test/io.rb | 4 |
2 files changed, 42 insertions, 0 deletions
diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 50265ba25..a79db4f17 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"); } diff --git a/mrbgems/mruby-io/test/io.rb b/mrbgems/mruby-io/test/io.rb index 458d2cdc2..2088a61e3 100644 --- a/mrbgems/mruby-io/test/io.rb +++ b/mrbgems/mruby-io/test/io.rb @@ -24,6 +24,10 @@ def assert_io_open(meth) end end io2.close unless meth == :open + + assert_raise(RuntimeError) { IO.__send__(meth, 1023) } # For Windows + assert_raise(RuntimeError) { IO.__send__(meth, 1 << 26) } + assert_raise(RuntimeError) { IO.__send__(meth, 1 << 32) } if (1 << 32).kind_of?(Integer) end end |
