aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-07 06:44:46 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-07 06:44:46 +0000
commitcfa0035962f7c373ca612be5bee749803368fd5b (patch)
tree3b040a18394f2e81079d356f76c5a136b6986fcd
parentf4ca906d5c3267c0f84db4c5780829783c71a8b6 (diff)
downloadruby-cfa0035962f7c373ca612be5bee749803368fd5b.tar.gz
* encoding.c (rb_enc_set_index, rb_enc_associate_index): should
check if frozen. * parse.y (rb_intern3), ruby.c (process_options, ruby_script): defer freezing after associating encodings. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32435 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog8
-rw-r--r--encoding.c15
-rw-r--r--ext/-test-/string/enc_associate.c13
-rw-r--r--parse.y3
-rw-r--r--ruby.c5
-rw-r--r--test/-ext-/string/test_enc_associate.rb12
6 files changed, 49 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 7b2a5298ba..4cb879ee30 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Thu Jul 7 15:44:42 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * encoding.c (rb_enc_set_index, rb_enc_associate_index): should
+ check if frozen.
+
+ * parse.y (rb_intern3), ruby.c (process_options, ruby_script):
+ defer freezing after associating encodings.
+
Thu Jul 7 15:16:51 2011 NARUSE, Yui <naruse@ruby-lang.org>
* numeric.c (rb_num2ull): use own switch sentense.
diff --git a/encoding.c b/encoding.c
index 95b2767911..0b6bf96bc5 100644
--- a/encoding.c
+++ b/encoding.c
@@ -685,8 +685,8 @@ rb_enc_get_index(VALUE obj)
return i;
}
-void
-rb_enc_set_index(VALUE obj, int idx)
+static void
+enc_set_index(VALUE obj, int idx)
{
if (idx < ENCODING_INLINE_MAX) {
ENCODING_SET_INLINED(obj, idx);
@@ -694,13 +694,20 @@ rb_enc_set_index(VALUE obj, int idx)
}
ENCODING_SET_INLINED(obj, ENCODING_INLINE_MAX);
rb_ivar_set(obj, rb_id_encoding(), INT2NUM(idx));
- return;
+}
+
+void
+rb_enc_set_index(VALUE obj, int idx)
+{
+ rb_check_frozen(obj);
+ enc_set_index(obj, idx);
}
VALUE
rb_enc_associate_index(VALUE obj, int idx)
{
/* enc_check_capable(obj);*/
+ rb_check_frozen(obj);
if (rb_enc_get_index(obj) == idx)
return obj;
if (SPECIAL_CONST_P(obj)) {
@@ -710,7 +717,7 @@ rb_enc_associate_index(VALUE obj, int idx)
!rb_enc_asciicompat(rb_enc_from_index(idx))) {
ENC_CODERANGE_CLEAR(obj);
}
- rb_enc_set_index(obj, idx);
+ enc_set_index(obj, idx);
return obj;
}
diff --git a/ext/-test-/string/enc_associate.c b/ext/-test-/string/enc_associate.c
new file mode 100644
index 0000000000..2ecc9c0227
--- /dev/null
+++ b/ext/-test-/string/enc_associate.c
@@ -0,0 +1,13 @@
+#include "ruby.h"
+
+VALUE
+bug_str_enc_associate(VALUE str, VALUE enc)
+{
+ return rb_enc_associate(str, rb_to_encoding(enc));
+}
+
+void
+Init_enc_associate(VALUE klass)
+{
+ rb_define_method(klass, "associate_encoding!", bug_str_enc_associate, 1);
+}
diff --git a/parse.y b/parse.y
index 015ad51531..9769bb9887 100644
--- a/parse.y
+++ b/parse.y
@@ -9723,13 +9723,14 @@ rb_intern3(const char *name, long len, rb_encoding *enc)
int mb;
st_data_t data;
struct RString fake_str;
- fake_str.basic.flags = T_STRING|RSTRING_NOEMBED|FL_FREEZE;
+ fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
fake_str.basic.klass = rb_cString;
fake_str.as.heap.len = len;
fake_str.as.heap.ptr = (char *)name;
fake_str.as.heap.aux.capa = len;
str = (VALUE)&fake_str;
rb_enc_associate(str, enc);
+ OBJ_FREEZE(str);
if (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) {
rb_raise(rb_eEncodingError, "invalid encoding symbol");
diff --git a/ruby.c b/ruby.c
index 86cb0b08a5..93b12d87bf 100644
--- a/ruby.c
+++ b/ruby.c
@@ -1309,12 +1309,12 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
#if defined DOSISH || defined __CYGWIN__
translit_char(RSTRING_PTR(opt->script_name), '\\', '/');
#endif
- rb_obj_freeze(opt->script_name);
ruby_init_loadpath_safe(opt->safe_level);
rb_enc_find_index("encdb");
lenc = rb_locale_encoding();
rb_enc_associate(rb_progname, lenc);
+ rb_obj_freeze(rb_progname);
parser = rb_parser_new();
if (opt->dump & DUMP_BIT(yydebug)) {
rb_parser_set_yydebug(parser, Qtrue);
@@ -1342,6 +1342,7 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
opt->intern.enc.index = -1;
}
rb_enc_associate(opt->script_name, lenc);
+ rb_obj_freeze(opt->script_name);
{
long i;
VALUE load_path = GET_VM()->load_path;
@@ -1694,7 +1695,7 @@ void
ruby_script(const char *name)
{
if (name) {
- rb_progname = rb_obj_freeze(rb_external_str_new(name, strlen(name)));
+ rb_progname = rb_external_str_new(name, strlen(name));
rb_vm_set_progname(rb_progname);
}
}
diff --git a/test/-ext-/string/test_enc_associate.rb b/test/-ext-/string/test_enc_associate.rb
new file mode 100644
index 0000000000..edddfb4316
--- /dev/null
+++ b/test/-ext-/string/test_enc_associate.rb
@@ -0,0 +1,12 @@
+require 'test/unit'
+require "-test-/string/string"
+
+class Test_StrEncAssociate < Test::Unit::TestCase
+ def test_frozen
+ s = Bug::String.new("abc")
+ s.force_encoding(Encoding::US_ASCII)
+ s.freeze
+ assert_raise(RuntimeError) {s.associate_encoding!(Encoding::US_ASCII)}
+ assert_raise(RuntimeError) {s.associate_encoding!(Encoding::UTF_8)}
+ end
+end