summaryrefslogtreecommitdiff
path: root/libavformat/id3v2.c
diff options
context:
space:
mode:
authorPeter Ross <pross@xvid.org>2014-04-18 14:49:40 +1000
committerMichael Niedermayer <michaelni@gmx.at>2014-04-19 04:25:01 +0200
commit5331773cc33ba26b9e26ace643d926219e46a17b (patch)
tree9b66a00bf0b540d8bfd5b69ab5b36ddf220579f4 /libavformat/id3v2.c
parentc94305ae23318c8956a30485cd5642829f4f16a9 (diff)
ff_id3v2_read: add option to limit ID3 magic number search
Several chunked formats (AIFF, IFF,DSF) store ID3 metadata within an 'ID3 ' chunk tag. If such chunks are stored sequentially, it is possible for the ID3v2 parser to confuse the chunk tag for the ID3 magic number. e.g. [1st chunk tag ('ID3 ') | chunk size] [ID3 magic number | metadata ...] [2nd chunk tag ('ID3 ') | chunk size] [ID3 magic number | metadata ...] Fixes ticket #3530. Signed-off-by: Peter Ross <pross@xvid.org> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/id3v2.c')
-rw-r--r--libavformat/id3v2.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 15b58d7cf2..4cf8e9bcea 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -880,16 +880,25 @@ error:
static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata,
AVFormatContext *s, const char *magic,
- ID3v2ExtraMeta **extra_meta)
+ ID3v2ExtraMeta **extra_meta, int64_t max_search_size)
{
int len, ret;
uint8_t buf[ID3v2_HEADER_SIZE];
int found_header;
- int64_t off;
+ int64_t start, off;
+ if (max_search_size && max_search_size < ID3v2_HEADER_SIZE)
+ return;
+
+ start = avio_tell(pb);
do {
/* save the current offset in case there's nothing to read/skip */
off = avio_tell(pb);
+ if (max_search_size && off - start >= max_search_size - ID3v2_HEADER_SIZE) {
+ avio_seek(pb, off, SEEK_SET);
+ break;
+ }
+
ret = avio_read(pb, buf, ID3v2_HEADER_SIZE);
if (ret != ID3v2_HEADER_SIZE) {
avio_seek(pb, off, SEEK_SET);
@@ -916,13 +925,13 @@ static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata,
void ff_id3v2_read_dict(AVIOContext *pb, AVDictionary **metadata,
const char *magic, ID3v2ExtraMeta **extra_meta)
{
- id3v2_read_internal(pb, metadata, NULL, magic, extra_meta);
+ id3v2_read_internal(pb, metadata, NULL, magic, extra_meta, 0);
}
void ff_id3v2_read(AVFormatContext *s, const char *magic,
- ID3v2ExtraMeta **extra_meta)
+ ID3v2ExtraMeta **extra_meta, unsigned int max_search_size)
{
- id3v2_read_internal(s->pb, &s->metadata, s, magic, extra_meta);
+ id3v2_read_internal(s->pb, &s->metadata, s, magic, extra_meta, max_search_size);
}
void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)