From 2556cd3f51112221b991503751b84852a9ffeac6 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 24 Dec 2020 10:27:59 +0900 Subject: Bypass check for warning_category on internal calls --- common.mk | 1 + error.c | 63 +++++++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/common.mk b/common.mk index 20c6de7843..aec160cbb5 100644 --- a/common.mk +++ b/common.mk @@ -5015,6 +5015,7 @@ error.$(OBJEXT): $(top_srcdir)/internal/compilers.h error.$(OBJEXT): $(top_srcdir)/internal/error.h error.$(OBJEXT): $(top_srcdir)/internal/eval.h error.$(OBJEXT): $(top_srcdir)/internal/gc.h +error.$(OBJEXT): $(top_srcdir)/internal/hash.h error.$(OBJEXT): $(top_srcdir)/internal/imemo.h error.$(OBJEXT): $(top_srcdir)/internal/io.h error.$(OBJEXT): $(top_srcdir)/internal/load.h diff --git a/error.c b/error.c index 5e3e4e358b..cc861e08b0 100644 --- a/error.c +++ b/error.c @@ -30,6 +30,7 @@ #include "internal.h" #include "internal/error.h" #include "internal/eval.h" +#include "internal/hash.h" #include "internal/io.h" #include "internal/load.h" #include "internal/object.h" @@ -77,8 +78,9 @@ static ID id_category; static ID id_deprecated; static ID id_experimental; static VALUE sym_category; -static VALUE warning_categories; -static VALUE warning_category_t_map; +static struct { + st_table *id2enum, *enum2id; +} warning_categories; extern const char ruby_description[]; @@ -162,13 +164,24 @@ rb_warning_category_mask(VALUE category) rb_warning_category_t rb_warning_category_from_name(VALUE category) { - VALUE cat_value; + st_data_t cat_value; + ID cat_id; Check_Type(category, T_SYMBOL); - cat_value = rb_hash_aref(warning_categories, category); - if (cat_value == Qnil) { + if (!(cat_id = rb_check_id(&category)) || + !st_lookup(warning_categories.id2enum, cat_id, &cat_value)) { rb_raise(rb_eArgError, "unknown category: %"PRIsVALUE, category); } - return NUM2INT(cat_value); + return (rb_warning_category_t)cat_value; +} + +static VALUE +rb_warning_category_to_name(rb_warning_category_t category) +{ + st_data_t id; + if (!st_lookup(warning_categories.enum2id, category, &id)) { + rb_raise(rb_eArgError, "invalid category: %d", (int)category); + } + return id ? ID2SYM(id) : Qnil; } void @@ -312,11 +325,8 @@ rb_warning_warn_arity(void) static VALUE rb_warn_category(VALUE str, VALUE category) { - if (category != Qnil) { - category = rb_to_symbol_type(category); - if (!RTEST(rb_hash_aref(warning_categories, category))) { - rb_raise(rb_eArgError, "invalid warning category used: %s", rb_id2name(SYM2ID(category))); - } + if (RUBY_DEBUG && !NIL_P(category)) { + rb_warning_category_from_name(category); } if (rb_warning_warn_arity() == 1) { @@ -386,7 +396,7 @@ rb_category_compile_warn(rb_warning_category_t category, const char *file, int l va_start(args, fmt); str = warn_vsprintf(NULL, file, line, fmt, args); va_end(args); - rb_warn_category(str, rb_hash_fetch(warning_category_t_map, INT2NUM(category))); + rb_warn_category(str, rb_warning_category_to_name(category)); } static VALUE @@ -418,7 +428,7 @@ rb_category_warn(rb_warning_category_t category, const char *fmt, ...) { if (!NIL_P(ruby_verbose)) { with_warning_string(mesg, 0, fmt) { - rb_warn_category(mesg, rb_hash_fetch(warning_category_t_map, INT2NUM(category))); + rb_warn_category(mesg, rb_warning_category_to_name(category)); } } } @@ -450,7 +460,7 @@ rb_category_warning(rb_warning_category_t category, const char *fmt, ...) { if (RTEST(ruby_verbose)) { with_warning_string(mesg, 0, fmt) { - rb_warn_category(mesg, rb_hash_fetch(warning_category_t_map, INT2NUM(category))); + rb_warn_category(mesg, rb_warning_category_to_name(category)); } } } @@ -562,6 +572,11 @@ rb_warn_m(rb_execution_context_t *ec, VALUE exc, VALUE msgs, VALUE uplevel, VALU RBASIC_SET_CLASS(str, rb_cString); } + if (!NIL_P(category)) { + category = rb_to_symbol_type(category); + rb_warning_category_from_name(category); + } + if (exc == rb_mWarning) { rb_must_asciicompat(str); rb_write_error_str(str); @@ -2846,18 +2861,14 @@ Init_Exception(void) sym_category = ID2SYM(id_category); - warning_categories = rb_ident_hash_new(); - rb_gc_register_mark_object(warning_categories); - rb_hash_aset(warning_categories, ID2SYM(id_deprecated), INT2NUM(RB_WARN_CATEGORY_DEPRECATED)); - rb_hash_aset(warning_categories, ID2SYM(id_experimental), INT2NUM(RB_WARN_CATEGORY_EXPERIMENTAL)); - rb_obj_freeze(warning_categories); - - warning_category_t_map = rb_ident_hash_new(); - rb_gc_register_mark_object(warning_category_t_map); - rb_hash_aset(warning_category_t_map, INT2NUM(RB_WARN_CATEGORY_NONE), Qnil); - rb_hash_aset(warning_category_t_map, INT2NUM(RB_WARN_CATEGORY_DEPRECATED), ID2SYM(id_deprecated)); - rb_hash_aset(warning_category_t_map, INT2NUM(RB_WARN_CATEGORY_EXPERIMENTAL), ID2SYM(id_experimental)); - rb_obj_freeze(warning_category_t_map); + warning_categories.id2enum = rb_init_identtable(); + st_add_direct(warning_categories.id2enum, id_deprecated, RB_WARN_CATEGORY_DEPRECATED); + st_add_direct(warning_categories.id2enum, id_experimental, RB_WARN_CATEGORY_EXPERIMENTAL); + + warning_categories.enum2id = rb_init_identtable(); + st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_NONE, 0); + st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_DEPRECATED, id_deprecated); + st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_EXPERIMENTAL, id_experimental); } void -- cgit v1.2.3