summaryrefslogtreecommitdiffhomepage
path: root/src/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/string.c')
-rw-r--r--src/string.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/string.c b/src/string.c
index 6664eabd6..a3f337d4b 100644
--- a/src/string.c
+++ b/src/string.c
@@ -306,17 +306,20 @@ bytes2chars(char *p, mrb_int bi)
mrb_int i, b, n;
for (b=i=0; b<bi; i++) {
- n = utf8len(p, p+bi);
+ n = utf8len_codepage[(unsigned char)*p];
b += n;
p += n;
}
+ if (b != bi) return -1;
return i;
}
+#define BYTES_ALIGN_CHECK(pos) if (pos < 0) return mrb_nil_value();
#else
#define RSTRING_CHAR_LEN(s) RSTRING_LEN(s)
#define chars2bytes(p, off, ci) (ci)
#define bytes2chars(p, bi) (bi)
+#define BYTES_ALIGN_CHECK(pos)
#endif
static inline mrb_int
@@ -352,12 +355,12 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n)
return 0;
}
else if (m == 1) {
- const unsigned char *ys = y, *ye = ys + n;
- for (; y < ye; ++y) {
- if (*x == *y)
- return y - ys;
- }
- return -1;
+ const unsigned char *ys = memchr(y, *x, n);
+
+ if (ys)
+ return ys - y;
+ else
+ return -1;
}
return mrb_memsearch_qs((const unsigned char *)x0, m, (const unsigned char *)y0, n);
}
@@ -1608,6 +1611,7 @@ mrb_str_index(mrb_state *mrb, mrb_value str)
if (pos == -1) return mrb_nil_value();
pos = bytes2chars(RSTRING_PTR(str), pos);
+ BYTES_ALIGN_CHECK(pos);
return mrb_fixnum_value(pos);
}
@@ -1877,6 +1881,7 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str)
pos = str_rindex(mrb, str, sub, pos);
if (pos >= 0) {
pos = bytes2chars(RSTRING_PTR(str), pos);
+ BYTES_ALIGN_CHECK(pos);
return mrb_fixnum_value(pos);
}
break;