summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2019-06-14 06:22:57 +0900
committerGitHub <[email protected]>2019-06-14 06:22:57 +0900
commit27109d1ae0ce3d8ac3f242988f475b7fb354b68f (patch)
treeb3acb175c0b27b4af256949bdbb0b2031a00dd23
parent1a98b94100a6331753bae17e158d053b129ad1d3 (diff)
parent9bd692bc67ee302bcbc359d0841458339c440fb4 (diff)
downloadmruby-27109d1ae0ce3d8ac3f242988f475b7fb354b68f.tar.gz
mruby-27109d1ae0ce3d8ac3f242988f475b7fb354b68f.zip
Merge pull request #4505 from shuujii/fix-class-name-validation-in-Struct.new
Fix class name validation in `Struct.new`
-rw-r--r--include/mruby/class.h1
-rw-r--r--mrbgems/mruby-struct/src/struct.c2
-rw-r--r--mrbgems/mruby-struct/test/struct.rb4
-rw-r--r--src/class.c14
4 files changed, 13 insertions, 8 deletions
diff --git a/include/mruby/class.h b/include/mruby/class.h
index a68724538..c79a487b5 100644
--- a/include/mruby/class.h
+++ b/include/mruby/class.h
@@ -88,6 +88,7 @@ MRB_API struct RClass* mrb_class_real(struct RClass* cl);
mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym);
+mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int);
mrb_value mrb_class_find_path(mrb_state*, struct RClass*);
void mrb_gc_mark_mt(mrb_state*, struct RClass*);
size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c
index 1df135a9f..539127bf8 100644
--- a/mrbgems/mruby-struct/src/struct.c
+++ b/mrbgems/mruby-struct/src/struct.c
@@ -212,7 +212,7 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *kl
/* old style: should we warn? */
mrb_to_str(mrb, name);
id = mrb_obj_to_sym(mrb, name);
- if (!is_const_id(mrb, mrb_sym2name_len(mrb, id, NULL))) {
+ if (!mrb_const_name_p(mrb, RSTRING_PTR(name), RSTRING_LEN(name))) {
mrb_name_error(mrb, id, "identifier %S needs to be constant", name);
}
if (mrb_const_defined_at(mrb, mrb_obj_value(klass), id)) {
diff --git a/mrbgems/mruby-struct/test/struct.rb b/mrbgems/mruby-struct/test/struct.rb
index 91e8cecc6..9f2ff1cdc 100644
--- a/mrbgems/mruby-struct/test/struct.rb
+++ b/mrbgems/mruby-struct/test/struct.rb
@@ -181,6 +181,10 @@ assert("Struct.new does not allow array") do
end
end
+assert("Struct.new does not allow invalid class name") do
+ assert_raise(NameError) { Struct.new("Test-", :a) }
+end
+
assert("Struct.new generates subclass of Struct") do
begin
original_struct = Struct
diff --git a/src/class.c b/src/class.c
index 6ceaa0cfa..373f2aec7 100644
--- a/src/class.c
+++ b/src/class.c
@@ -77,6 +77,12 @@ mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb
mrb_obj_iv_set_force(mrb, (struct RObject*)c, nsym, name);
}
+mrb_bool
+mrb_const_name_p(mrb_state *mrb, const char *name, mrb_int len)
+{
+ return len > 0 && ISUPPER(name[0]) && mrb_ident_p(name+1, len-1);
+}
+
static void
setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id)
{
@@ -1852,18 +1858,12 @@ mrb_mod_undef(mrb_state *mrb, mrb_value mod)
return mrb_nil_value();
}
-static mrb_bool
-const_name_p(mrb_state *mrb, const char *name, mrb_int len)
-{
- return len > 0 && ISUPPER(name[0]) && mrb_ident_p(name+1, len-1);
-}
-
static void
check_const_name_sym(mrb_state *mrb, mrb_sym id)
{
mrb_int len;
const char *name = mrb_sym2name_len(mrb, id, &len);
- if (!const_name_p(mrb, name, len)) {
+ if (!mrb_const_name_p(mrb, name, len)) {
mrb_name_error(mrb, id, "wrong constant name %S", mrb_sym2str(mrb, id));
}
}