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:
parent
e76022f41c
commit
9ee1877e4a
Notes:
git
2023-07-06 16:27:34 +00:00
@ -17548,6 +17548,7 @@ variable.$(OBJEXT): {$(VPATH)}rubyparser.h
|
|||||||
variable.$(OBJEXT): {$(VPATH)}shape.h
|
variable.$(OBJEXT): {$(VPATH)}shape.h
|
||||||
variable.$(OBJEXT): {$(VPATH)}st.h
|
variable.$(OBJEXT): {$(VPATH)}st.h
|
||||||
variable.$(OBJEXT): {$(VPATH)}subst.h
|
variable.$(OBJEXT): {$(VPATH)}subst.h
|
||||||
|
variable.$(OBJEXT): {$(VPATH)}symbol.h
|
||||||
variable.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
|
variable.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
|
||||||
variable.$(OBJEXT): {$(VPATH)}thread_native.h
|
variable.$(OBJEXT): {$(VPATH)}thread_native.h
|
||||||
variable.$(OBJEXT): {$(VPATH)}transient_heap.h
|
variable.$(OBJEXT): {$(VPATH)}transient_heap.h
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
require_relative '../../spec_helper'
|
require_relative '../../spec_helper'
|
||||||
require_relative 'fixtures/module'
|
|
||||||
|
|
||||||
ruby_version_is "3.3" do
|
ruby_version_is "3.3" do
|
||||||
describe "Module#set_temporary_name" do
|
describe "Module#set_temporary_name" do
|
||||||
@ -14,6 +13,15 @@ ruby_version_is "3.3" do
|
|||||||
m.name.should be_nil
|
m.name.should be_nil
|
||||||
end
|
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
|
it "can't assign empty string as name" do
|
||||||
m = Module.new
|
m = Module.new
|
||||||
-> { m.set_temporary_name("") }.should raise_error(ArgumentError, "empty class/module name")
|
-> { 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
|
it "can't assign a constant name as a temporary name" do
|
||||||
m = Module.new
|
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
|
end
|
||||||
|
|
||||||
it "can't assign name to permanent module" do
|
it "can't assign name to permanent module" do
|
||||||
|
37
variable.c
37
variable.c
@ -35,6 +35,7 @@
|
|||||||
#include "ruby/util.h"
|
#include "ruby/util.h"
|
||||||
#include "transient_heap.h"
|
#include "transient_heap.h"
|
||||||
#include "shape.h"
|
#include "shape.h"
|
||||||
|
#include "symbol.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
#include "vm_core.h"
|
#include "vm_core.h"
|
||||||
#include "ractor_core.h"
|
#include "ractor_core.h"
|
||||||
@ -134,6 +135,38 @@ rb_mod_name(VALUE mod)
|
|||||||
return classname(mod, &permanent);
|
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:
|
* call-seq:
|
||||||
* mod.set_temporary_name(string) -> self
|
* 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");
|
rb_raise(rb_eArgError, "empty class/module name");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rb_is_const_name(name)) {
|
if (is_constant_path(name)) {
|
||||||
rb_raise(rb_eArgError, "name must not be valid constant name");
|
rb_raise(rb_eArgError, "name must not be valid constant path");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the temporary classpath to the given name:
|
// Set the temporary classpath to the given name:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user