diff options
author | Stefano Sabatini <stefasab@gmail.com> | 2014-08-28 17:37:27 +0200 |
---|---|---|
committer | Stefano Sabatini <stefasab@gmail.com> | 2014-09-01 10:47:24 +0200 |
commit | d4ec07dfe7dbc86e8f6403781c511b9463a526d2 (patch) | |
tree | 007bae339ff7567a6f330ac0b6edcadb155cc74b /libavutil | |
parent | 36952786a5cca8784f582a071c0d73ab1e3252a1 (diff) | |
download | ffmpeg-d4ec07dfe7dbc86e8f6403781c511b9463a526d2.tar.gz |
lavu/avstring: check for overlong encodings in av_utf8_decode()
Fix reopened trac ticket #1163.
Diffstat (limited to 'libavutil')
-rw-r--r-- | libavutil/avstring.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/libavutil/avstring.c b/libavutil/avstring.c index a63fb84bcf..fd010e407c 100644 --- a/libavutil/avstring.c +++ b/libavutil/avstring.c @@ -27,6 +27,7 @@ #include "config.h" #include "common.h" #include "mem.h" +#include "avassert.h" #include "avstring.h" #include "bprint.h" @@ -331,7 +332,10 @@ int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end, const uint8_t *p = *bufp; uint32_t top; uint64_t code; - int ret = 0; + int ret = 0, tail_len; + uint32_t overlong_encoding_mins[6] = { + 0x00000000, 0x00000080, 0x00000800, 0x00010000, 0x00200000, 0x04000000, + }; if (p >= buf_end) return 0; @@ -346,8 +350,10 @@ int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end, } top = (code & 128) >> 1; + tail_len = 0; while (code & top) { int tmp; + tail_len++; if (p >= buf_end) { (*bufp) ++; return AVERROR(EILSEQ); /* incomplete sequence */ @@ -364,6 +370,13 @@ int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end, } code &= (top << 1) - 1; + /* check for overlong encodings */ + av_assert0(tail_len <= 5); + if (code < overlong_encoding_mins[tail_len]) { + ret = AVERROR(EILSEQ); + goto end; + } + if (code >= 1<<31) { ret = AVERROR(EILSEQ); /* out-of-range value */ goto end; |