summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-02 08:22:19 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-02 08:22:19 +0000
commitaa1acf1d4282d44ddfa677d24b7c3c1e951467d6 (patch)
tree24f9cbcf9aa83bd8a13279706c46d7977769f4c6
parent263ce88f9f2f713273e628bcef64e5f13cdbc2ff (diff)
encoding.c: validate index
* encoding.c (rb_enc_set_index, rb_enc_associate_index): validate argument encoding index. * include/ruby/encoding.h (ENCODING_SET): use rb_enc_set_index() instead of setting inlined bits directly. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41739 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog8
-rw-r--r--encoding.c25
-rw-r--r--include/ruby/encoding.h9
3 files changed, 32 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 8a60d2ee99..cee683f80b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,10 @@
-Tue Jul 2 17:22:12 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+Tue Jul 2 17:22:16 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * encoding.c (rb_enc_set_index, rb_enc_associate_index): validate
+ argument encoding index.
+
+ * include/ruby/encoding.h (ENCODING_SET): use rb_enc_set_index()
+ instead of setting inlined bits directly.
* encoding.c (rb_enc_init): register preserved indexes.
diff --git a/encoding.c b/encoding.c
index cc6ce0768a..f3db8e3b3f 100644
--- a/encoding.c
+++ b/encoding.c
@@ -142,6 +142,25 @@ must_encoding(VALUE enc)
return index;
}
+static rb_encoding *
+must_encindex(int index)
+{
+ rb_encoding *enc = rb_enc_from_index(index);
+ if (!enc) {
+ rb_raise(rb_eEncodingError, "encoding index out of bound: %d",
+ index);
+ }
+ if (ENC_TO_ENCINDEX(enc) != index) {
+ rb_raise(rb_eEncodingError, "wrong encoding index %d for %s (expected %d)",
+ index, rb_enc_name(enc), ENC_TO_ENCINDEX(enc));
+ }
+ if (enc_autoload_p(enc) && enc_autoload(enc) == -1) {
+ rb_loaderror("failed to load encoding (%s)",
+ rb_enc_name(enc));
+ }
+ return enc;
+}
+
int
rb_to_encoding_index(VALUE enc)
{
@@ -736,12 +755,15 @@ void
rb_enc_set_index(VALUE obj, int idx)
{
rb_check_frozen(obj);
+ must_encindex(idx);
enc_set_index(obj, idx);
}
VALUE
rb_enc_associate_index(VALUE obj, int idx)
{
+ rb_encoding *enc;
+
/* enc_check_capable(obj);*/
rb_check_frozen(obj);
if (rb_enc_get_index(obj) == idx)
@@ -749,8 +771,9 @@ rb_enc_associate_index(VALUE obj, int idx)
if (SPECIAL_CONST_P(obj)) {
rb_raise(rb_eArgError, "cannot set encoding");
}
+ enc = must_encindex(idx);
if (!ENC_CODERANGE_ASCIIONLY(obj) ||
- !rb_enc_asciicompat(rb_enc_from_index(idx))) {
+ !rb_enc_asciicompat(enc)) {
ENC_CODERANGE_CLEAR(obj);
}
enc_set_index(obj, idx);
diff --git a/include/ruby/encoding.h b/include/ruby/encoding.h
index 1233053063..2cd44eafe1 100644
--- a/include/ruby/encoding.h
+++ b/include/ruby/encoding.h
@@ -32,14 +32,7 @@ RUBY_SYMBOL_EXPORT_BEGIN
RBASIC(obj)->flags &= ~ENCODING_MASK;\
RBASIC(obj)->flags |= (VALUE)(i) << ENCODING_SHIFT;\
} while (0)
-#define ENCODING_SET(obj,i) do {\
- VALUE rb_encoding_set_obj = (obj); \
- int encoding_set_enc_index = (i); \
- if (encoding_set_enc_index < ENCODING_INLINE_MAX) \
- ENCODING_SET_INLINED(rb_encoding_set_obj, encoding_set_enc_index); \
- else \
- rb_enc_set_index(rb_encoding_set_obj, encoding_set_enc_index); \
-} while (0)
+#define ENCODING_SET(obj,i) rb_enc_set_index((obj), (i))
#define ENCODING_GET_INLINED(obj) (int)((RBASIC(obj)->flags & ENCODING_MASK)>>ENCODING_SHIFT)
#define ENCODING_GET(obj) \