[FFmpeg-cvslog] ff_id3v2_read: add option to limit ID3 magic number search
Peter Ross
git at videolan.org
Sat Apr 19 13:40:56 CEST 2014
ffmpeg | branch: release/2.1 | Peter Ross <pross at xvid.org> | Fri Apr 18 14:49:40 2014 +1000| [7269ab10c5179baa6928164b1bb932a62398d365] | committer: Carl Eugen Hoyos
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 at xvid.org>
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
(cherry picked from commit 5331773cc33ba26b9e26ace643d926219e46a17b)
Conflicts:
libavformat/dsfdec.c
libavformat/id3v2.c
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7269ab10c5179baa6928164b1bb932a62398d365
---
libavformat/aiffdec.c | 2 +-
libavformat/asfdec.c | 2 +-
libavformat/id3v2.c | 13 +++++++++++--
libavformat/id3v2.h | 4 +++-
libavformat/omadec.c | 2 +-
libavformat/utils.c | 2 +-
6 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c
index 6f82d93..a0b6e71 100644
--- a/libavformat/aiffdec.c
+++ b/libavformat/aiffdec.c
@@ -237,7 +237,7 @@ static int aiff_read_header(AVFormatContext *s)
break;
case MKTAG('I', 'D', '3', ' '):
position = avio_tell(pb);
- ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
+ ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size);
if (id3v2_extra_meta)
if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) {
ff_id3v2_free_extra_meta(&id3v2_extra_meta);
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index 528bcbd..d6378e9 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -266,7 +266,7 @@ static void get_id3_tag(AVFormatContext *s, int len)
{
ID3v2ExtraMeta *id3v2_extra_meta = NULL;
- ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
+ ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, len);
if (id3v2_extra_meta)
ff_id3v2_parse_apic(s, &id3v2_extra_meta);
ff_id3v2_free_extra_meta(&id3v2_extra_meta);
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 86c5cb3..a3434c9 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -815,16 +815,25 @@ error:
}
void ff_id3v2_read(AVFormatContext *s, const char *magic,
- ID3v2ExtraMeta **extra_meta)
+ ID3v2ExtraMeta **extra_meta, unsigned int 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(s->pb);
do {
/* save the current offset in case there's nothing to read/skip */
off = avio_tell(s->pb);
+ if (max_search_size && off - start >= max_search_size - ID3v2_HEADER_SIZE) {
+ avio_seek(s->pb, off, SEEK_SET);
+ break;
+ }
+
ret = avio_read(s->pb, buf, ID3v2_HEADER_SIZE);
if (ret != ID3v2_HEADER_SIZE) {
avio_seek(s->pb, off, SEEK_SET);
diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h
index e893922..25d37f3 100644
--- a/libavformat/id3v2.h
+++ b/libavformat/id3v2.h
@@ -92,8 +92,10 @@ int ff_id3v2_tag_len(const uint8_t *buf);
* Read an ID3v2 tag, including supported extra metadata
* @param extra_meta If not NULL, extra metadata is parsed into a list of
* ID3v2ExtraMeta structs and *extra_meta points to the head of the list
+ * @param[opt] max_search_search restrict ID3 magic number search (bytes from start)
*/
-void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta);
+void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta,
+ unsigned int max_search_size);
/**
* Initialize an ID3v2 tag.
diff --git a/libavformat/omadec.c b/libavformat/omadec.c
index 4017db3..8453aa7 100644
--- a/libavformat/omadec.c
+++ b/libavformat/omadec.c
@@ -293,7 +293,7 @@ static int oma_read_header(AVFormatContext *s)
ID3v2ExtraMeta *extra_meta = NULL;
OMAContext *oc = s->priv_data;
- ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta);
+ ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta, 0);
ret = avio_read(s->pb, buf, EA3_HEADER_SIZE);
if (ret < EA3_HEADER_SIZE)
return -1;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index fd5c0dd..aaf4f98 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -538,7 +538,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
/* e.g. AVFMT_NOFILE formats will not have a AVIOContext */
if (s->pb)
- ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
+ ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, 0);
if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header)
if ((ret = s->iformat->read_header(s)) < 0)
More information about the ffmpeg-cvslog
mailing list