diff --git a/internal/string.h b/internal/string.h index cfaf628e02..abb0a536ad 100644 --- a/internal/string.h +++ b/internal/string.h @@ -125,6 +125,15 @@ at_char_boundary(const char *s, const char *p, const char *e, rb_encoding *enc) return rb_enc_left_char_head(s, p, e, enc) == p; } +static inline bool +at_char_right_boundary(const char *s, const char *p, const char *e, rb_encoding *enc) +{ + RUBY_ASSERT(s <= p); + RUBY_ASSERT(p <= e); + + return rb_enc_right_char_head(s, p, e, enc) == p; +} + /* expect tail call optimization */ // YJIT needs this function to never allocate and never raise static inline VALUE diff --git a/string.c b/string.c index 5af5fc4a40..deeed4a12a 100644 --- a/string.c +++ b/string.c @@ -10472,7 +10472,7 @@ rb_str_start_with(int argc, VALUE *argv, VALUE str) p = RSTRING_PTR(str); e = p + slen; s = p + tlen; - if (!at_char_boundary(p, s, e, enc)) + if (!at_char_right_boundary(p, s, e, enc)) continue; if (memcmp(p, RSTRING_PTR(tmp), tlen) == 0) return Qtrue; @@ -10554,7 +10554,7 @@ deleted_prefix_length(VALUE str, VALUE prefix) } const char *strend = strptr + olen; const char *after_prefix = strptr + prefixlen; - if (!at_char_boundary(strptr, after_prefix, strend, enc)) { + if (!at_char_right_boundary(strptr, after_prefix, strend, enc)) { /* prefix does not end at char-boundary */ return 0; }