diff options
author | Benoit Daloze <eregontp@gmail.com> | 2023-07-06 13:25:21 +0200 |
---|---|---|
committer | Benoit Daloze <eregontp@gmail.com> | 2023-07-06 18:27:13 +0200 |
commit | 9ee1877e4ab535253b4f61302b9102d20e11db5a (patch) | |
tree | 94679e283f1dcac08f1e6a72cde81b71b49bd055 /variable.c | |
parent | e76022f41cd74d297189d85d74a18d9e7821fd94 (diff) |
Ensure the name given to Module#set_temporary_name is not a valid constant path
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/8035
Diffstat (limited to 'variable.c')
-rw-r--r-- | variable.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/variable.c b/variable.c index c6c70e1391..79ff8c459c 100644 --- a/variable.c +++ b/variable.c @@ -35,6 +35,7 @@ #include "ruby/util.h" #include "transient_heap.h" #include "shape.h" +#include "symbol.h" #include "variable.h" #include "vm_core.h" #include "ractor_core.h" @@ -134,6 +135,38 @@ rb_mod_name(VALUE mod) return classname(mod, &permanent); } +// Similar to logic in rb_mod_const_get() +static bool +is_constant_path(VALUE name) +{ + const char *path = RSTRING_PTR(name); + const char *pend = RSTRING_END(name); + rb_encoding *enc = rb_enc_get(name); + + const char *p = path; + + if (p >= pend || !*p) { + return false; + } + + while (p < pend) { + if (p + 2 <= pend && p[0] == ':' && p[1] == ':') { + p += 2; + } + + const char *pbeg = p; + while (p < pend && *p != ':') p++; + + if (pbeg == p) return false; + + if (rb_enc_symname_type(pbeg, p - pbeg, enc, 0) != ID_CONST) { + return false; + } + } + + return true; +} + /* * call-seq: * mod.set_temporary_name(string) -> self @@ -196,8 +229,8 @@ rb_mod_set_temporary_name(VALUE mod, VALUE name) rb_raise(rb_eArgError, "empty class/module name"); } - if (rb_is_const_name(name)) { - rb_raise(rb_eArgError, "name must not be valid constant name"); + if (is_constant_path(name)) { + rb_raise(rb_eArgError, "name must not be valid constant path"); } // Set the temporary classpath to the given name: |