зеркало из https://github.com/github/ruby.git
Ensure the name given to Module#set_temporary_name is not a valid constant path
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
This commit is contained in:
Родитель
e76022f41c
Коммит
9ee1877e4a
|
@ -17548,6 +17548,7 @@ variable.$(OBJEXT): {$(VPATH)}rubyparser.h
|
|||
variable.$(OBJEXT): {$(VPATH)}shape.h
|
||||
variable.$(OBJEXT): {$(VPATH)}st.h
|
||||
variable.$(OBJEXT): {$(VPATH)}subst.h
|
||||
variable.$(OBJEXT): {$(VPATH)}symbol.h
|
||||
variable.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
|
||||
variable.$(OBJEXT): {$(VPATH)}thread_native.h
|
||||
variable.$(OBJEXT): {$(VPATH)}transient_heap.h
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/module'
|
||||
|
||||
ruby_version_is "3.3" do
|
||||
describe "Module#set_temporary_name" do
|
||||
|
@ -14,6 +13,15 @@ ruby_version_is "3.3" do
|
|||
m.name.should be_nil
|
||||
end
|
||||
|
||||
it "can assign a temporary name which is not a valid constant path" do
|
||||
m = Module.new
|
||||
m.set_temporary_name("a::B")
|
||||
m.name.should == "a::B"
|
||||
|
||||
m.set_temporary_name("Template['foo.rb']")
|
||||
m.name.should == "Template['foo.rb']"
|
||||
end
|
||||
|
||||
it "can't assign empty string as name" do
|
||||
m = Module.new
|
||||
-> { m.set_temporary_name("") }.should raise_error(ArgumentError, "empty class/module name")
|
||||
|
@ -21,7 +29,14 @@ ruby_version_is "3.3" do
|
|||
|
||||
it "can't assign a constant name as a temporary name" do
|
||||
m = Module.new
|
||||
-> { m.set_temporary_name("Object") }.should raise_error(ArgumentError, "name must not be valid constant name")
|
||||
-> { m.set_temporary_name("Object") }.should raise_error(ArgumentError, "name must not be valid constant path")
|
||||
end
|
||||
|
||||
it "can't assign a constant path as a temporary name" do
|
||||
m = Module.new
|
||||
-> { m.set_temporary_name("A::B") }.should raise_error(ArgumentError, "name must not be valid constant path")
|
||||
-> { m.set_temporary_name("::A") }.should raise_error(ArgumentError, "name must not be valid constant path")
|
||||
-> { m.set_temporary_name("::A::B") }.should raise_error(ArgumentError, "name must not be valid constant path")
|
||||
end
|
||||
|
||||
it "can't assign name to permanent module" do
|
||||
|
|
37
variable.c
37
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:
|
||||
|
|
Загрузка…
Ссылка в новой задаче