From 3ece38366080f6c862e243d152476572ba15268a Mon Sep 17 00:00:00 2001 From: nobu Date: Sun, 9 Aug 2009 21:55:55 +0000 Subject: * marshal.c (class2path, w_unique, w_extended, w_class, w_uclass): deal with non-ascii class path. [ruby-core:24790] * marshal.c (r_unique, path2class, path2module, obj_alloc_by_path), (r_object0): ditto. * variable.c (rb_path_to_class): new encoding-aware function to get a class from its name. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24488 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 11 ++++++++ common.mk | 2 +- include/ruby/intern.h | 3 ++- marshal.c | 72 ++++++++++++++++++++++++++++----------------------- variable.c | 19 +++++++++++--- version.h | 4 +-- 6 files changed, 70 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index 08bb6ca048..184da3ba5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Mon Aug 10 06:55:45 2009 Nobuyoshi Nakada + + * marshal.c (class2path, w_unique, w_extended, w_class, w_uclass): + deal with non-ascii class path. [ruby-core:24790] + + * marshal.c (r_unique, path2class, path2module, obj_alloc_by_path), + (r_object0): ditto. + + * variable.c (rb_path_to_class): new encoding-aware function to + get a class from its name. + Sun Aug 9 21:14:03 2009 Hidetoshi NAGAI * ext/tk/extconf.rb (search_tclConfig): last change isn't enough. diff --git a/common.mk b/common.mk index 1f9b1ca9f1..6a3f1036ab 100644 --- a/common.mk +++ b/common.mk @@ -602,7 +602,7 @@ time.$(OBJEXT): {$(VPATH)}time.c $(RUBY_H_INCLUDES) \ $(ENCODING_H_INCLUDES) util.$(OBJEXT): {$(VPATH)}util.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h variable.$(OBJEXT): {$(VPATH)}variable.c $(RUBY_H_INCLUDES) \ - {$(VPATH)}node.h {$(VPATH)}util.h + {$(VPATH)}node.h {$(VPATH)}util.h {$(VPATH)}encoding.h version.$(OBJEXT): {$(VPATH)}version.c $(RUBY_H_INCLUDES) \ {$(VPATH)}version.h $(srcdir)/revision.h diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 8e6e152827..e9ddae164b 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -760,7 +760,8 @@ VALUE rb_mod_name(VALUE); VALUE rb_class_path(VALUE); void rb_set_class_path(VALUE, VALUE, const char*); void rb_set_class_path_string(VALUE, VALUE, VALUE); -VALUE rb_path2class(const char*); +VALUE rb_path_to_class(VALUE); +DEPRECATED(VALUE rb_path2class(const char*)); void rb_name_class(VALUE, ID); VALUE rb_class_name(VALUE); void rb_autoload(VALUE, ID, const char*); diff --git a/marshal.c b/marshal.c index 610df7c9b4..3e6937f1d4 100644 --- a/marshal.c +++ b/marshal.c @@ -168,18 +168,28 @@ mark_dump_arg(void *ptr) rb_mark_hash(p->compat_tbl); } -static VALUE -class2path(VALUE klass) +static void +must_not_be_anonymous(const char *type, VALUE path) { - VALUE path = rb_class_path(klass); char *n = RSTRING_PTR(path); + if (!rb_enc_asciicompat(rb_enc_get(path))) { + /* cannot occur? */ + rb_raise(rb_eTypeError, "can't dump non-ascii %s name", type); + } if (n[0] == '#') { - rb_raise(rb_eTypeError, "can't dump anonymous %s %s", - (TYPE(klass) == T_CLASS ? "class" : "module"), - n); + rb_raise(rb_eTypeError, "can't dump anonymous %s %s", type, + (int)RSTRING_LEN(path), n); } - if (rb_path2class(n) != rb_class_real(klass)) { +} + +static VALUE +class2path(VALUE klass) +{ + VALUE path = rb_class_path(klass); + + must_not_be_anonymous((TYPE(klass) == T_CLASS ? "class" : "module"), path); + if (rb_path_to_class(path) != rb_class_real(klass)) { rb_raise(rb_eTypeError, "%s can't be referred to", n); } return path; @@ -412,12 +422,10 @@ w_symbol(ID id, struct dump_arg *arg) } static void -w_unique(const char *s, struct dump_arg *arg) +w_unique(VALUE s, struct dump_arg *arg) { - if (s[0] == '#') { - rb_raise(rb_eTypeError, "can't dump anonymous class %s", s); - } - w_symbol(rb_intern(s), arg); + must_not_be_anonymous("class", s); + w_symbol(rb_intern_str(s), arg); } static void w_object(VALUE,struct dump_arg*,int); @@ -433,8 +441,6 @@ hash_each(VALUE key, VALUE value, struct dump_call_arg *arg) static void w_extended(VALUE klass, struct dump_arg *arg, int check) { - const char *path; - if (check && FL_TEST(klass, FL_SINGLETON)) { if (RCLASS_M_TBL(klass)->num_entries || (RCLASS_IV_TBL(klass) && RCLASS_IV_TBL(klass)->num_entries > 1)) { @@ -443,7 +449,7 @@ w_extended(VALUE klass, struct dump_arg *arg, int check) klass = RCLASS_SUPER(klass); } while (BUILTIN_TYPE(klass) == T_ICLASS) { - path = rb_class2name(RBASIC(klass)->klass); + VALUE path = rb_class_name(RBASIC(klass)->klass); w_byte(TYPE_EXTENDED, arg); w_unique(path, arg); klass = RCLASS_SUPER(klass); @@ -453,8 +459,7 @@ w_extended(VALUE klass, struct dump_arg *arg, int check) static void w_class(char type, VALUE obj, struct dump_arg *arg, int check) { - volatile VALUE p; - char *path; + VALUE path; st_data_t real_obj; VALUE klass; @@ -464,8 +469,7 @@ w_class(char type, VALUE obj, struct dump_arg *arg, int check) klass = CLASS_OF(obj); w_extended(klass, arg, check); w_byte(type, arg); - p = class2path(rb_class_real(klass)); - path = RSTRING_PTR(p); + path = class2path(rb_class_real(klass)); w_unique(path, arg); } @@ -478,7 +482,7 @@ w_uclass(VALUE obj, VALUE super, struct dump_arg *arg) klass = rb_class_real(klass); if (klass != super) { w_byte(TYPE_UCLASS, arg); - w_unique(RSTRING_PTR(class2path(klass)), arg); + w_unique(class2path(klass), arg); } } @@ -967,7 +971,7 @@ mark_load_arg(void *ptr) static VALUE r_entry(VALUE v, struct load_arg *arg); static VALUE r_object(struct load_arg *arg); static ID r_symbol(struct load_arg *arg); -static VALUE path2class(const char *path); +static VALUE path2class(VALUE path); static int r_byte(struct load_arg *arg) @@ -1143,10 +1147,10 @@ r_symbol(struct load_arg *arg) } } -static const char* +static VALUE r_unique(struct load_arg *arg) { - return rb_id2name(r_symbol(arg)); + return rb_id2str(r_symbol(arg)); } static VALUE @@ -1222,29 +1226,31 @@ r_ivar(VALUE obj, struct load_arg *arg) } static VALUE -path2class(const char *path) +path2class(VALUE path) { - VALUE v = rb_path2class(path); + VALUE v = rb_path_to_class(path); if (TYPE(v) != T_CLASS) { - rb_raise(rb_eArgError, "%s does not refer to class", path); + rb_raise(rb_eArgError, "%.*s does not refer to class", + (int)RSTRING_LEN(path), RSTRING_PTR(path)); } return v; } static VALUE -path2module(const char *path) +path2module(VALUE path) { - VALUE v = rb_path2class(path); + VALUE v = rb_path_to_class(path); if (TYPE(v) != T_MODULE) { - rb_raise(rb_eArgError, "%s does not refer to module", path); + rb_raise(rb_eArgError, "%.*s does not refer to module", + (int)RSTRING_LEN(path), RSTRING_PTR(path)); } return v; } static VALUE -obj_alloc_by_path(const char *path, struct load_arg *arg) +obj_alloc_by_path(VALUE path, struct load_arg *arg) { VALUE klass; st_data_t data; @@ -1615,7 +1621,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) { volatile VALUE str = r_bytes(arg); - v = rb_path2class(RSTRING_PTR(str)); + v = rb_path_to_class(str); v = r_entry(v, arg); v = r_leave(v, arg); } @@ -1625,7 +1631,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) { volatile VALUE str = r_bytes(arg); - v = path2class(RSTRING_PTR(str)); + v = path2class(str); v = r_entry(v, arg); v = r_leave(v, arg); } @@ -1635,7 +1641,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) { volatile VALUE str = r_bytes(arg); - v = path2module(RSTRING_PTR(str)); + v = path2module(str); v = r_entry(v, arg); v = r_leave(v, arg); } diff --git a/variable.c b/variable.c index 1cea104bf0..65f0484cbc 100644 --- a/variable.c +++ b/variable.c @@ -14,6 +14,7 @@ #include "ruby/ruby.h" #include "ruby/st.h" #include "ruby/util.h" +#include "ruby/encoding.h" #include "node.h" void rb_vm_change_state(void); @@ -249,19 +250,23 @@ rb_set_class_path(VALUE klass, VALUE under, const char *name) } VALUE -rb_path2class(const char *path) +rb_path_to_class(VALUE pathname) { - const char *pbeg, *p; + rb_encoding *enc = rb_enc_get(pathname); + const char *pbeg, *p, *path = RSTRING_PTR(pathname); ID id; VALUE c = rb_cObject; + if (!rb_enc_asciicompat(enc)) { + rb_raise(rb_eArgError, "invalid class path encoding (non ASCII)"); + } + pbeg = p = path; if (path[0] == '#') { rb_raise(rb_eArgError, "can't retrieve anonymous class %s", path); } - pbeg = p = path; while (*p) { while (*p && *p != ':') p++; - id = rb_intern2(pbeg, p-pbeg); + id = rb_intern3(pbeg, p-pbeg, enc); if (p[0] == ':') { if (p[1] != ':') goto undefined_class; p += 2; @@ -284,6 +289,12 @@ rb_path2class(const char *path) return c; } +VALUE +rb_path2class(const char *path) +{ + return rb_path_to_class(rb_usascii_str_new_cstr(path)); +} + void rb_name_class(VALUE klass, ID id) { diff --git a/version.h b/version.h index c861e3e8d5..b13bace722 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #define RUBY_VERSION "1.9.2" -#define RUBY_RELEASE_DATE "2009-08-09" +#define RUBY_RELEASE_DATE "2009-08-10" #define RUBY_PATCHLEVEL -1 #define RUBY_BRANCH_NAME "trunk" @@ -8,7 +8,7 @@ #define RUBY_VERSION_TEENY 1 #define RUBY_RELEASE_YEAR 2009 #define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 9 +#define RUBY_RELEASE_DAY 10 #include "ruby/version.h" -- cgit v1.2.3