From b655cfefafd565590bfc5976b9ce8dd141b3c41c Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Wed, 14 Nov 2012 03:25:41 -0500 Subject: [PATCH 1/3] apetag: fix error handling in ff_ape_parse_tag() The following error handling is broken due to signedness. int file_size; uint32_t tag_bytes; int64_t tag_start; ... tag_start = file_size - tag_bytes - APE_TAG_FOOTER_BYTES; if (tag_start < 0) { ... } Note that tag_bytes is unsigned, which makes the right-hand side of `tag_start = ...' unsigned, too. The 32-bit unsigned value is then zero-extended to 64 bits. Therefore, tag_start must be non-negative, and the check (tag_start < 0) is always false, which breaks the error handling. This patch fixes the check. Signed-off-by: Xi Wang Signed-off-by: Anton Khirnov --- libavformat/apetag.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/apetag.c b/libavformat/apetag.c index 28a3ff7753..0d2cb973fb 100644 --- a/libavformat/apetag.c +++ b/libavformat/apetag.c @@ -144,11 +144,11 @@ int64_t ff_ape_parse_tag(AVFormatContext *s) return 0; } - tag_start = file_size - tag_bytes - APE_TAG_FOOTER_BYTES; - if (tag_start < 0) { + if (tag_bytes > file_size - APE_TAG_FOOTER_BYTES) { av_log(s, AV_LOG_ERROR, "Invalid tag size %u.\n", tag_bytes); return 0; } + tag_start = file_size - tag_bytes - APE_TAG_FOOTER_BYTES; fields = avio_rl32(pb); /* number of fields */ if (fields > 65536) { From 0d3123666a42ed6c74d0a052342175261304b8ca Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Wed, 14 Nov 2012 03:42:37 -0500 Subject: [PATCH 2/3] cdgraphics: fix incorrect vertical offset mask in cdg_scroll() The vertical offset mask 0x07 is suspicious. v_off = FFMIN(data[2] & 0x07, CDG_BORDER_HEIGHT - 1); Note that v_off is up to 11 (CDG_BORDER_HEIGHT - 1), the correct mask should be 0x0F. Signed-off-by: Xi Wang Signed-off-by: Anton Khirnov --- libavcodec/cdgraphics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c index 21de07effb..631c415124 100644 --- a/libavcodec/cdgraphics.c +++ b/libavcodec/cdgraphics.c @@ -218,7 +218,7 @@ static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data, vscmd = (data[2] & 0x30) >> 4; h_off = FFMIN(data[1] & 0x07, CDG_BORDER_WIDTH - 1); - v_off = FFMIN(data[2] & 0x07, CDG_BORDER_HEIGHT - 1); + v_off = FFMIN(data[2] & 0x0F, CDG_BORDER_HEIGHT - 1); /// find the difference and save the offset for cdg_tile_block usage hinc = h_off - cc->hscroll; From 9ae80e6a9cefcab61e867256ba19ef78a4bfe0cb Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 21 Nov 2012 08:48:47 +0100 Subject: [PATCH 3/3] id3v2: fix reading unsynchronized frames. Current code would incorrectly process e.g. 'ff 00 ff 00 ff' to 'ff ff ff', while it should be 'ff ff 00 ff'. Fixes Bug 395. CC: libav-stable@libav.org --- libavformat/id3v2.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 012d7933a8..4516ac74ef 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -617,21 +617,23 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t /* check for text tag or supported special meta tag */ } else if (tag[0] == 'T' || (extra_meta && (extra_func = get_extra_meta_func(tag, isv34)))) { if (unsync || tunsync) { - int i, j; + int64_t end = avio_tell(s->pb) + tlen; + uint8_t *b; av_fast_malloc(&buffer, &buffer_size, tlen); if (!buffer) { av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", tlen); goto seek; } - for (i = 0, j = 0; i < tlen; i++, j++) { - buffer[j] = avio_r8(s->pb); - if (j > 0 && !buffer[j] && buffer[j - 1] == 0xff) { - /* Unsynchronised byte, skip it */ - j--; + b = buffer; + while (avio_tell(s->pb) < end) { + *b++ = avio_r8(s->pb); + if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1) { + uint8_t val = avio_r8(s->pb); + *b++ = val ? val : avio_r8(s->pb); } } - ffio_init_context(&pb, buffer, j, 0, NULL, NULL, NULL, NULL); - tlen = j; + ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL, NULL); + tlen = b - buffer; pbx = &pb; // read from sync buffer } else { pbx = s->pb; // read straight from input