зеркало из https://github.com/github/ruby.git
[ruby/io-console] Check rawmode option names strictly
https://github.com/ruby/io-console/commit/aa8fc7e947
This commit is contained in:
Родитель
7390eb43fe
Коммит
678bcfcaa6
|
@ -75,7 +75,7 @@ getattr(int fd, conmode *t)
|
|||
#define SET_LAST_ERROR (0)
|
||||
#endif
|
||||
|
||||
static ID id_getc, id_console, id_close, id_min, id_time, id_intr;
|
||||
static ID id_getc, id_console, id_close;
|
||||
#if ENABLE_IO_GETPASS
|
||||
static ID id_gets, id_chomp_bang;
|
||||
#endif
|
||||
|
@ -112,18 +112,34 @@ rb_f_send(int argc, VALUE *argv, VALUE recv)
|
|||
}
|
||||
#endif
|
||||
|
||||
enum rawmode_opt_ids {
|
||||
kwd_min,
|
||||
kwd_time,
|
||||
kwd_intr,
|
||||
rawmode_opt_id_count
|
||||
};
|
||||
static ID rawmode_opt_ids[rawmode_opt_id_count];
|
||||
|
||||
typedef struct {
|
||||
int vmin;
|
||||
int vtime;
|
||||
int intr;
|
||||
} rawmode_arg_t;
|
||||
|
||||
#ifndef UNDEF_P
|
||||
# define UNDEF_P(obj) ((obj) == Qundef)
|
||||
#endif
|
||||
#ifndef NIL_OR_UNDEF_P
|
||||
# define NIL_OR_UNDEF_P(obj) (NIL_P(obj) || UNDEF_P(obj))
|
||||
#endif
|
||||
|
||||
static rawmode_arg_t *
|
||||
rawmode_opt(int *argcp, VALUE *argv, int min_argc, int max_argc, rawmode_arg_t *opts)
|
||||
{
|
||||
int argc = *argcp;
|
||||
rawmode_arg_t *optp = NULL;
|
||||
VALUE vopts = Qnil;
|
||||
VALUE optvals[rawmode_opt_id_count];
|
||||
#ifdef RB_SCAN_ARGS_PASS_CALLED_KEYWORDS
|
||||
argc = rb_scan_args(argc, argv, "*:", NULL, &vopts);
|
||||
#else
|
||||
|
@ -138,19 +154,20 @@ rawmode_opt(int *argcp, VALUE *argv, int min_argc, int max_argc, rawmode_arg_t *
|
|||
}
|
||||
#endif
|
||||
rb_check_arity(argc, min_argc, max_argc);
|
||||
if (!NIL_P(vopts)) {
|
||||
VALUE vmin = rb_hash_aref(vopts, ID2SYM(id_min));
|
||||
VALUE vtime = rb_hash_aref(vopts, ID2SYM(id_time));
|
||||
VALUE intr = rb_hash_aref(vopts, ID2SYM(id_intr));
|
||||
if (rb_get_kwargs(vopts, rawmode_opt_ids,
|
||||
0, rawmode_opt_id_count, optvals)) {
|
||||
VALUE vmin = optvals[kwd_min];
|
||||
VALUE vtime = optvals[kwd_time];
|
||||
VALUE intr = optvals[kwd_intr];
|
||||
/* default values by `stty raw` */
|
||||
opts->vmin = 1;
|
||||
opts->vtime = 0;
|
||||
opts->intr = 0;
|
||||
if (!NIL_P(vmin)) {
|
||||
if (!NIL_OR_UNDEF_P(vmin)) {
|
||||
opts->vmin = NUM2INT(vmin);
|
||||
optp = opts;
|
||||
}
|
||||
if (!NIL_P(vtime)) {
|
||||
if (!NIL_OR_UNDEF_P(vtime)) {
|
||||
VALUE v10 = INT2FIX(10);
|
||||
vtime = rb_funcall3(vtime, '*', 1, &v10);
|
||||
opts->vtime = NUM2INT(vtime);
|
||||
|
@ -165,6 +182,7 @@ rawmode_opt(int *argcp, VALUE *argv, int min_argc, int max_argc, rawmode_arg_t *
|
|||
opts->intr = 0;
|
||||
optp = opts;
|
||||
break;
|
||||
case Qundef:
|
||||
case Qnil:
|
||||
break;
|
||||
default:
|
||||
|
@ -1633,9 +1651,11 @@ Init_console(void)
|
|||
#endif
|
||||
id_console = rb_intern("console");
|
||||
id_close = rb_intern("close");
|
||||
id_min = rb_intern("min");
|
||||
id_time = rb_intern("time");
|
||||
id_intr = rb_intern("intr");
|
||||
#define init_rawmode_opt_id(name) \
|
||||
rawmode_opt_ids[kwd_##name] = rb_intern(#name)
|
||||
init_rawmode_opt_id(min);
|
||||
init_rawmode_opt_id(time);
|
||||
init_rawmode_opt_id(intr);
|
||||
#ifndef HAVE_RB_F_SEND
|
||||
id___send__ = rb_intern("__send__");
|
||||
#endif
|
||||
|
|
|
@ -49,6 +49,14 @@ class TestIO_Console < Test::Unit::TestCase
|
|||
assert_include(e.message, IO::NULL)
|
||||
end
|
||||
end
|
||||
|
||||
def test_bad_keyword
|
||||
assert_raise_with_message(ArgumentError, /unknown keyword:.*bad/) do
|
||||
File.open(IO::NULL) do |f|
|
||||
f.raw(bad: 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defined?(PTY) and defined?(IO.console) and TestIO_Console.class_eval do
|
||||
|
|
Загрузка…
Ссылка в новой задаче