aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--encoding.c19
-rw-r--r--include/ruby/encoding.h1
-rw-r--r--io.c26
-rw-r--r--test/ruby/test_io_m17n.rb11
5 files changed, 59 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index ee27a15ec5..5ae88b34f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Mon Mar 12 19:23:13 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * encoding.c (rb_find_encoding): new function find encoding from
+ arbitrary object as a pointer to rb_encoding, and return NULL if
+ not found.
+
+ * io.c (io_encoding_set): just warn unsupported encodings, but not
+ exception. [ruby-core:40726] [Bug #5567]
+
Mon Mar 12 19:03:32 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* vm_method.c (Init_eval_method): respond_to? and
diff --git a/encoding.c b/encoding.c
index dd20477906..1d82d4d3c4 100644
--- a/encoding.c
+++ b/encoding.c
@@ -161,7 +161,7 @@ rb_to_encoding_index(VALUE enc)
/* Returns encoding index or UNSPECIFIED_ENCODING */
static int
-str_to_encindex(VALUE enc)
+str_find_encindex(VALUE enc)
{
int idx;
@@ -170,6 +170,13 @@ str_to_encindex(VALUE enc)
rb_raise(rb_eArgError, "invalid name encoding (non ASCII)");
}
idx = rb_enc_find_index(StringValueCStr(enc));
+ return idx;
+}
+
+static int
+str_to_encindex(VALUE enc)
+{
+ int idx = str_find_encindex(enc);
if (idx < 0) {
rb_raise(rb_eArgError, "unknown encoding name - %s", RSTRING_PTR(enc));
}
@@ -189,6 +196,16 @@ rb_to_encoding(VALUE enc)
return str_to_encoding(enc);
}
+rb_encoding *
+rb_find_encoding(VALUE enc)
+{
+ int idx;
+ if (enc_check_encoding(enc) >= 0) return RDATA(enc)->data;
+ idx = str_find_encindex(enc);
+ if (idx < 0) return NULL;
+ return rb_enc_from_index(idx);
+}
+
void
rb_gc_mark_encodings(void)
{
diff --git a/include/ruby/encoding.h b/include/ruby/encoding.h
index cced3d2688..ad2b614cd2 100644
--- a/include/ruby/encoding.h
+++ b/include/ruby/encoding.h
@@ -89,6 +89,7 @@ void rb_enc_set_index(VALUE obj, int encindex);
int rb_enc_find_index(const char *name);
int rb_to_encoding_index(VALUE);
rb_encoding* rb_to_encoding(VALUE);
+rb_encoding* rb_find_encoding(VALUE);
rb_encoding* rb_enc_get(VALUE);
rb_encoding* rb_enc_compatible(VALUE,VALUE);
rb_encoding* rb_enc_check(VALUE,VALUE);
diff --git a/io.c b/io.c
index d53633c937..169a5897a5 100644
--- a/io.c
+++ b/io.c
@@ -4604,6 +4604,12 @@ rb_io_ext_int_to_encs(rb_encoding *ext, rb_encoding *intern, rb_encoding **enc,
}
static void
+unsupported_encoding(const char *name)
+{
+ rb_warn("Unsupported encoding %s ignored", name);
+}
+
+static void
parse_mode_enc(const char *estr, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
{
const char *p;
@@ -4647,7 +4653,7 @@ parse_mode_enc(const char *estr, rb_encoding **enc_p, rb_encoding **enc2_p, int
ext_enc = rb_enc_from_index(idx);
else {
if (idx != -2)
- rb_warn("Unsupported encoding %s ignored", estr);
+ unsupported_encoding(estr);
ext_enc = NULL;
}
@@ -4660,7 +4666,7 @@ parse_mode_enc(const char *estr, rb_encoding **enc_p, rb_encoding **enc2_p, int
else {
idx2 = rb_enc_find_index(p);
if (idx2 < 0)
- rb_warn("Unsupported encoding %s ignored", p);
+ unsupported_encoding(p);
else if (idx2 == idx) {
rb_warn("Ignoring internal encoding %s: it is identical to external encoding %s", p, estr);
int_enc = (rb_encoding *)Qnil;
@@ -8709,6 +8715,14 @@ io_new_instance(VALUE args)
return rb_class_new_instance(2, (VALUE*)args+1, *(VALUE*)args);
}
+static rb_encoding *
+find_encoding(VALUE v)
+{
+ rb_encoding *enc = rb_find_encoding(v);
+ if (!enc) unsupported_encoding(StringValueCStr(v));
+ return enc;
+}
+
static void
io_encoding_set(rb_io_t *fptr, VALUE v1, VALUE v2, VALUE opt)
{
@@ -8717,7 +8731,7 @@ io_encoding_set(rb_io_t *fptr, VALUE v1, VALUE v2, VALUE opt)
VALUE ecopts, tmp;
if (!NIL_P(v2)) {
- enc2 = rb_to_encoding(v1);
+ enc2 = find_encoding(v1);
tmp = rb_check_string_type(v2);
if (!NIL_P(tmp)) {
if (RSTRING_LEN(tmp) == 1 && RSTRING_PTR(tmp)[0] == '-') {
@@ -8726,14 +8740,14 @@ io_encoding_set(rb_io_t *fptr, VALUE v1, VALUE v2, VALUE opt)
enc2 = NULL;
}
else
- enc = rb_to_encoding(v2);
+ enc = find_encoding(v2);
if (enc == enc2) {
/* Special case - "-" => no transcoding */
enc2 = NULL;
}
}
else
- enc = rb_to_encoding(v2);
+ enc = find_encoding(v2);
SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags);
ecflags = rb_econv_prepare_options(opt, &ecopts, ecflags);
}
@@ -8752,7 +8766,7 @@ io_encoding_set(rb_io_t *fptr, VALUE v1, VALUE v2, VALUE opt)
ecflags = rb_econv_prepare_options(opt, &ecopts, ecflags);
}
else {
- rb_io_ext_int_to_encs(rb_to_encoding(v1), NULL, &enc, &enc2);
+ rb_io_ext_int_to_encs(find_encoding(v1), NULL, &enc, &enc2);
SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(enc2, ecflags);
ecopts = Qnil;
}
diff --git a/test/ruby/test_io_m17n.rb b/test/ruby/test_io_m17n.rb
index d8916433ad..eccc27ac97 100644
--- a/test/ruby/test_io_m17n.rb
+++ b/test/ruby/test_io_m17n.rb
@@ -1060,6 +1060,17 @@ EOT
}
end
+ def test_set_encoding_unsupported
+ bug5567 = '[ruby-core:40726]'
+ IO.pipe do |r, w|
+ assert_nothing_raised(bug5567) do
+ assert_warn(/Unsupported/, bug5567) {r.set_encoding("fffffffffffxx")}
+ assert_warn(/Unsupported/, bug5567) {r.set_encoding("fffffffffffxx", "us-ascii")}
+ assert_warn(/Unsupported/, bug5567) {r.set_encoding("us-ascii", "fffffffffffxx")}
+ end
+ end
+ end
+
def test_textmode_twice
assert_raise(ArgumentError) {
open(__FILE__, "rt", textmode: true) {|f|