diff --git a/src/string.c b/src/string.c index 63aa48371..a26bad4a3 100644 --- a/src/string.c +++ b/src/string.c @@ -264,6 +264,18 @@ mrb_gc_free_str(mrb_state *mrb, struct RString *str) } #ifdef MRB_UTF8_STRING + +#define NOASCII(c) ((c) & 0x80) + +static const char* +search_nonascii(const char* p, const char *e) +{ + for (; p < e; ++p) { + if (NOASCII(*p)) return p; + } + return e; +} + #define utf8_islead(c) ((unsigned char)((c)&0xc0) != 0x80) extern const char mrb_utf8len_table[]; @@ -279,7 +291,6 @@ mrb_utf8len(const char* p, const char* e) if (len > e - p) return 1; switch (len) { case 0: - case 1: return 1; case 4: if (utf8_islead(p[3])) return 1; @@ -333,14 +344,29 @@ chars2bytes(mrb_value s, mrb_int off, mrb_int idx) const char *p0 = RSTRING_PTR(s) + off; const char *p = p0; const char *e = RSTRING_END(s); + mrb_int i = 0; - while (p < e && idx--) { - if ((*p & 0x80) == 0) p++; - else p += mrb_utf8len(p, e); + while (p 0) len++; + if (i