summaryrefslogtreecommitdiff
path: root/libavutil/avstring.c
diff options
context:
space:
mode:
authorStefano Sabatini <stefasab@gmail.com>2014-08-28 17:37:27 +0200
committerStefano Sabatini <stefasab@gmail.com>2014-09-01 10:47:24 +0200
commitd4ec07dfe7dbc86e8f6403781c511b9463a526d2 (patch)
tree007bae339ff7567a6f330ac0b6edcadb155cc74b /libavutil/avstring.c
parent36952786a5cca8784f582a071c0d73ab1e3252a1 (diff)
downloadffmpeg-d4ec07dfe7dbc86e8f6403781c511b9463a526d2.tar.gz
lavu/avstring: check for overlong encodings in av_utf8_decode()
Fix reopened trac ticket #1163.
Diffstat (limited to 'libavutil/avstring.c')
-rw-r--r--libavutil/avstring.c15
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;