diff --git a/string.c b/string.c index c9db5d35c5..b970c5c6f5 100644 --- a/string.c +++ b/string.c @@ -3076,7 +3076,8 @@ rb_str_subpos(VALUE str, long beg, long *lenp) } if (beg < 0) { if (len > -beg) len = -beg; - if (-beg * rb_enc_mbmaxlen(enc) < blen / 8) { + if ((ENC_CODERANGE(str) == ENC_CODERANGE_VALID) && + (-beg * rb_enc_mbmaxlen(enc) < blen / 8)) { beg = -beg; while (beg-- > len && (e = rb_enc_prev_char(s, e, e, enc)) != 0); p = e; diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index c8b9aeb597..d2099607fd 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -169,6 +169,10 @@ CODE assert_equal(nil, S("\u{3042 3044 3046}")[RbConfig::LIMITS["LONG_MIN"], 1]) end + def test_AREF_invalid_encoding + assert_equal(S("\x80"), S("A"*39+"\x80")[-1, 1]) + end + def test_ASET # '[]=' s = S("FooBar") s[0] = S('A')