diff options
author | wm4 <wm4@nowhere> | 2015-09-21 10:36:19 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-09-21 10:36:19 +0200 |
commit | 60d6f067dd104eaf595072f35c1d45ac6a66aaa2 (patch) | |
tree | a3f5432fe0c2383c024c3c2815363963617d8b66 | |
parent | 0347901140f5a0ca5566b03d49895134549b9019 (diff) | |
download | libass-60d6f067dd104eaf595072f35c1d45ac6a66aaa2.tar.bz2 libass-60d6f067dd104eaf595072f35c1d45ac6a66aaa2.tar.xz |
fix error cases
- do not go into an endless loop on odd byte count
- check for valid surrogate pairs (somewhat)
-rw-r--r-- | libass/ass_utils.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/libass/ass_utils.c b/libass/ass_utils.c index 44f76cf..fef8030 100644 --- a/libass/ass_utils.c +++ b/libass/ass_utils.c @@ -426,20 +426,30 @@ unsigned ass_utf8_put_char(char *dest, uint32_t ch) static uint32_t ass_read_utf16be(uint8_t **src, size_t bytes) { if (bytes < 2) - return 0; + goto too_short; uint32_t cp = ((*src)[0] << 8) | (*src)[1]; *src += 2; bytes -= 2; - if (cp >= 0xD800 && cp <= 0xDBFF && bytes >= 2) { + if (cp >= 0xD800 && cp <= 0xDBFF) { + if (bytes < 2) + goto too_short; + uint32_t cp2 = ((*src)[0] << 8) | (*src)[1]; *src += 2; + if (cp2 < 0xDC00 || cp2 > 0xDFFF) + return 0xFFFD; + cp = 0x10000 + ((cp - 0xD800) << 10) + (cp2 - 0xDC00); } return cp; + +too_short: + *src += bytes; + return 0xFFFD; } void ass_utf16be_to_utf8(char *dst, size_t dst_size, uint8_t *src, size_t src_size) |