diff options
author | Nobuyoshi Nakada <[email protected]> | 2020-07-26 11:52:19 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <[email protected]> | 2021-09-17 11:14:04 +0900 |
commit | 178ee1e801acb33d13b3e8a630f6ca4926c68fbc (patch) | |
tree | fbc3b2dd31c4a3007580959b79ad08c4dbf36029 /class.c | |
parent | 8f41c791b19a47e2dfa39b0a6d12ef964098536a (diff) |
Already initialized modules cannot be replaced [Bug #17048]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4858
Diffstat (limited to 'class.c')
-rw-r--r-- | class.c | 43 |
1 files changed, 42 insertions, 1 deletions
@@ -248,6 +248,12 @@ rb_class_new(VALUE super) return rb_class_boot(super); } +VALUE +rb_class_s_alloc(VALUE klass) +{ + return rb_class_boot(0); +} + static void clone_method(VALUE old_klass, VALUE new_klass, ID mid, const rb_method_entry_t *me) { @@ -345,12 +351,35 @@ copy_tables(VALUE clone, VALUE orig) static bool ensure_origin(VALUE klass); +static inline bool +RMODULE_UNINITIALIZED(VALUE module) +{ + return RCLASS_SUPER(module) == rb_cBasicObject; +} + +void +rb_module_check_initialiable(VALUE mod) +{ + if (!RMODULE_UNINITIALIZED(mod)) { + rb_raise(rb_eTypeError, "already initialized module"); + } + RB_OBJ_WRITE(mod, &RCLASS(mod)->super, 0); +} + /* :nodoc: */ VALUE rb_mod_init_copy(VALUE clone, VALUE orig) { - if (RB_TYPE_P(clone, T_CLASS)) { + switch (BUILTIN_TYPE(clone)) { + case T_CLASS: + case T_ICLASS: class_init_copy_check(clone, orig); + break; + case T_MODULE: + rb_module_check_initialiable(clone); + break; + default: + break; } if (!OBJ_INIT_COPY(clone, orig)) return clone; @@ -775,6 +804,15 @@ rb_define_class_id_under(VALUE outer, ID id, VALUE super) } VALUE +rb_module_s_alloc(VALUE klass) +{ + VALUE mod = class_alloc(T_MODULE, klass); + RCLASS_M_TBL_INIT(mod); + RB_OBJ_WRITE(mod, &RCLASS(mod)->super, rb_cBasicObject); + return mod; +} + +VALUE rb_module_new(void) { VALUE mdl = class_alloc(T_MODULE, rb_cModule); @@ -878,6 +916,9 @@ ensure_includable(VALUE klass, VALUE module) { rb_class_modify_check(klass); Check_Type(module, T_MODULE); + if (RMODULE_UNINITIALIZED(module)) { + rb_raise(rb_eArgError, "uninitialized module"); + } if (!NIL_P(rb_refinement_module_get_refined_class(module))) { rb_raise(rb_eArgError, "refinement module is not allowed"); } |