When only 2 bytes can be read from a 4 byte UTF-16 character in a base64
encoded chunk of a UTF-7 string, treat that as an incomplete character and return an error instead of a shift sequence and no error. Also check that the low 2 bytes have a valid value. MFC after: 1 week
This commit is contained in:
parent
36204c3016
commit
f171d54687
@ -62,8 +62,7 @@ typedef struct {
|
||||
unsigned int
|
||||
mode: 1, /* whether base64 mode */
|
||||
bits: 4, /* need to hold 0 - 15 */
|
||||
cache: 22, /* 22 = BASE64_BIT + UTF16_BIT */
|
||||
surrogate: 1; /* whether surrogate pair or not */
|
||||
cache: 22; /* 22 = BASE64_BIT + UTF16_BIT */
|
||||
int chlen;
|
||||
char ch[4]; /* BASE64_IN, 3 * 6 = 18, most closed to UTF16_BIT */
|
||||
} _UTF7State;
|
||||
@ -253,34 +252,31 @@ _citrus_UTF7_mbrtowc_priv(_UTF7EncodingInfo * __restrict ei,
|
||||
*nresult = (size_t)_ENCODING_IS_STATE_DEPENDENT;
|
||||
return (0);
|
||||
}
|
||||
if (psenc->surrogate) {
|
||||
hi = (psenc->cache >> psenc->bits) & UTF16_MAX;
|
||||
if (hi < HISRG_MIN || hi > HISRG_MAX)
|
||||
return (EINVAL);
|
||||
siz = 0;
|
||||
} else {
|
||||
err = _citrus_UTF7_mbtoutf16(ei, &hi, s, n, psenc, &nr);
|
||||
if (nr == (size_t)-1 || nr == (size_t)-2) {
|
||||
*nresult = nr;
|
||||
return (err);
|
||||
}
|
||||
if (err != 0)
|
||||
return (err);
|
||||
n -= nr;
|
||||
siz = nr;
|
||||
if (hi < HISRG_MIN || hi > HISRG_MAX) {
|
||||
u32 = (uint32_t)hi;
|
||||
goto done;
|
||||
}
|
||||
psenc->surrogate = 1;
|
||||
}
|
||||
err = _citrus_UTF7_mbtoutf16(ei, &lo, s, n, psenc, &nr);
|
||||
err = _citrus_UTF7_mbtoutf16(ei, &hi, s, n, psenc, &nr);
|
||||
if (nr == (size_t)-1 || nr == (size_t)-2) {
|
||||
*nresult = nr;
|
||||
return (err);
|
||||
}
|
||||
if (err != 0)
|
||||
return (err);
|
||||
n -= nr;
|
||||
siz = nr;
|
||||
if (hi < HISRG_MIN || hi > HISRG_MAX) {
|
||||
u32 = (uint32_t)hi;
|
||||
goto done;
|
||||
}
|
||||
err = _citrus_UTF7_mbtoutf16(ei, &lo, s, n, psenc, &nr);
|
||||
if (nr == (size_t)-1 || nr == (size_t)-2) {
|
||||
psenc->chlen = 1; /* make get_state_desc return incomplete */
|
||||
*nresult = nr;
|
||||
return (err);
|
||||
}
|
||||
if (err != 0)
|
||||
return (err);
|
||||
if (lo < LOSRG_MIN || lo > LOSRG_MAX) {
|
||||
*nresult = (size_t)-1;
|
||||
return (EILSEQ);
|
||||
}
|
||||
hi -= HISRG_MIN;
|
||||
lo -= LOSRG_MIN;
|
||||
u32 = (hi << 10 | lo) + SRG_BASE;
|
||||
@ -293,7 +289,6 @@ _citrus_UTF7_mbrtowc_priv(_UTF7EncodingInfo * __restrict ei,
|
||||
_citrus_UTF7_init_state(ei, psenc);
|
||||
} else {
|
||||
*nresult = siz;
|
||||
psenc->surrogate = 0;
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
@ -392,7 +387,7 @@ _citrus_UTF7_put_state_reset(_UTF7EncodingInfo * __restrict ei __unused,
|
||||
{
|
||||
int bits, pos;
|
||||
|
||||
if (psenc->chlen != 0 || psenc->bits > BASE64_BIT || psenc->surrogate)
|
||||
if (psenc->chlen != 0 || psenc->bits > BASE64_BIT)
|
||||
return (EINVAL);
|
||||
|
||||
if (psenc->mode) {
|
||||
|
Loading…
Reference in New Issue
Block a user