diff --git a/string.c b/string.c index 5eda835f4b..4c0fe87635 100644 --- a/string.c +++ b/string.c @@ -7987,7 +7987,14 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag) while (s < send) { int may_modify = 0; - c0 = c = rb_enc_codepoint_len((char *)s, (char *)send, &clen, e1); + int r = rb_enc_precise_mbclen((char *)s, (char *)send, e1); + if (!MBCLEN_CHARFOUND_P(r)) { + xfree(buf); + rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(e1)); + } + clen = MBCLEN_CHARFOUND_LEN(r); + c0 = c = rb_enc_mbc_to_codepoint((char *)s, (char *)send, e1); + tlen = enc == e1 ? clen : rb_enc_codelen(c, enc); s += clen; @@ -8067,7 +8074,15 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag) while (s < send) { int may_modify = 0; - c0 = c = rb_enc_codepoint_len((char *)s, (char *)send, &clen, e1); + + int r = rb_enc_precise_mbclen((char *)s, (char *)send, e1); + if (!MBCLEN_CHARFOUND_P(r)) { + xfree(buf); + rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(e1)); + } + clen = MBCLEN_CHARFOUND_LEN(r); + c0 = c = rb_enc_mbc_to_codepoint((char *)s, (char *)send, e1); + tlen = enc == e1 ? clen : rb_enc_codelen(c, enc); if (c < 256) {