mirror of
https://github.com/neovim/neovim.git
synced 2025-09-28 05:58:33 +00:00
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:
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user