mbyte.c: Fix invalid memory access in utfc_ptr2char_len

To get an UTF-8 character, utf_ptr2char() is used.
But this function can read more than maxlen bytes, if an incomplete
byte sequence is used(first byte specifies a length > maxlen).
This commit is contained in:
oni-link
2016-04-13 12:26:10 +02:00
parent 4eb58273cd
commit 11e8ec0cac

View File

@@ -1304,35 +1304,38 @@ int utfc_ptr2char(const char_u *p, int *pcc)
*/ */
int utfc_ptr2char_len(const char_u *p, int *pcc, int maxlen) int utfc_ptr2char_len(const char_u *p, int *pcc, int maxlen)
{ {
int len; #define IS_COMPOSING(s1, s2, s3) \
int c; (i == 0 ? UTF_COMPOSINGLIKE((s1), (s2)) : utf_iscomposing((s3)))
int cc;
assert(maxlen > 0);
int i = 0; int i = 0;
c = utf_ptr2char(p); int len = utf_ptr2len_len(p, maxlen);
len = utf_ptr2len_len(p, maxlen); // Is it safe to use utf_ptr2char()?
/* Only accept a composing char when the first char isn't illegal. */ bool safe = len > 1 && len <= maxlen;
if ((len > 1 || *p < 0x80) int c = safe ? utf_ptr2char(p) : *p;
&& len < maxlen
&& p[len] >= 0x80 // Only accept a composing char when the first char isn't illegal.
&& UTF_COMPOSINGLIKE(p, p + len)) { if ((safe || c < 0x80) && len < maxlen && p[len] >= 0x80) {
cc = utf_ptr2char(p + len); for (; i < MAX_MCO; i++) {
for (;; ) { int len_cc = utf_ptr2len_len(p + len, maxlen - len);
pcc[i++] = cc; safe = len_cc > 1 && len_cc <= maxlen - len;
if (i == MAX_MCO) if (!safe || (pcc[i] = utf_ptr2char(p + len)) < 0x80
break; || !IS_COMPOSING(p, p + len, pcc[i])) {
len += utf_ptr2len_len(p + len, maxlen - len);
if (len >= maxlen
|| p[len] < 0x80
|| !utf_iscomposing(cc = utf_ptr2char(p + len)))
break; break;
}
len += len_cc;
} }
} }
if (i < MAX_MCO) /* last composing char must be 0 */ if (i < MAX_MCO) {
// last composing char must be 0
pcc[i] = 0; pcc[i] = 0;
}
return c; return c;
#undef ISCOMPOSING
} }
/* /*