From be17e6084a151c901c3946ec7b37afabc3b84f5f Mon Sep 17 00:00:00 2001
From: Francois Cartegnie <fcvlcdev@free.fr>
Date: Tue, 11 Aug 2020 10:53:31 +0200
Subject: [PATCH] Implement ID3v2 readStyle, avoid worst case

---
 taglib/mpeg/mpegfile.cpp | 22 +++++++++++++---------
 taglib/mpeg/mpegfile.h   | 13 ++++++++-----
 taglib/toolkit/taglib.h  |  3 +++
 3 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/taglib/mpeg/mpegfile.cpp b/taglib/mpeg/mpegfile.cpp
index 5f14e49d..30124e0d 100644
--- a/taglib/mpeg/mpegfile.cpp
+++ b/taglib/mpeg/mpegfile.cpp
@@ -132,30 +132,31 @@ bool MPEG::File::isSupported(IOStream *stream)
 // public members
 ////////////////////////////////////////////////////////////////////////////////
 
-MPEG::File::File(FileName file, bool readProperties, Properties::ReadStyle) :
+MPEG::File::File(FileName file,
+                 bool readProperties, Properties::ReadStyle readStyle) :
   TagLib::File(file),
   d(new FilePrivate())
 {
   if(isOpen())
-    read(readProperties);
+    read(readProperties, readStyle);
 }
 
 MPEG::File::File(FileName file, ID3v2::FrameFactory *frameFactory,
-                 bool readProperties, Properties::ReadStyle) :
+                 bool readProperties, Properties::ReadStyle readStyle) :
   TagLib::File(file),
   d(new FilePrivate(frameFactory))
 {
   if(isOpen())
-    read(readProperties);
+    read(readProperties, readStyle);
 }
 
 MPEG::File::File(IOStream *stream, ID3v2::FrameFactory *frameFactory,
-                 bool readProperties, Properties::ReadStyle) :
+                 bool readProperties, Properties::ReadStyle readStyle) :
   TagLib::File(stream),
   d(new FilePrivate(frameFactory))
 {
   if(isOpen())
-    read(readProperties);
+    read(readProperties, readStyle);
 }
 
 MPEG::File::~File()
@@ -498,11 +499,11 @@ bool MPEG::File::hasAPETag() const
 // private members
 ////////////////////////////////////////////////////////////////////////////////
 
-void MPEG::File::read(bool readProperties)
+void MPEG::File::read(bool readProperties, Properties::ReadStyle readStyle)
 {
   // Look for an ID3v2 tag
 
-  d->ID3v2Location = findID3v2();
+  d->ID3v2Location = findID3v2(readStyle);
 
   if(d->ID3v2Location >= 0) {
     d->tag.set(ID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory));
@@ -535,7 +536,7 @@ void MPEG::File::read(bool readProperties)
   ID3v1Tag(true);
 }
 
-long MPEG::File::findID3v2()
+long MPEG::File::findID3v2(Properties::ReadStyle readStyle)
 {
   if(!isValid())
     return -1;
@@ -558,6 +559,9 @@ long MPEG::File::findID3v2()
   ByteVector tagHeaderBytes(3, '\0');
   long position = 0;
 
+  if(readStyle < Properties::Accurate)
+    return -1;
+
   while(true) {
     seek(position);
     const ByteVector buffer = readBlock(bufferSize());
diff --git a/taglib/mpeg/mpegfile.h b/taglib/mpeg/mpegfile.h
index 3fcb7272..22a282d9 100644
--- a/taglib/mpeg/mpegfile.h
+++ b/taglib/mpeg/mpegfile.h
@@ -76,7 +76,8 @@ namespace TagLib {
        * Constructs an MPEG file from \a file.  If \a readProperties is true the
        * file's audio properties will also be read.
        *
-       * \note In the current implementation, \a propertiesStyle is ignored.
+       * If \a propertiesStyle is Accurate, the file will be scanned
+       * completely if no ID3v2 tag or MPEG sync code is found at the start.
        *
        * \deprecated This constructor will be dropped in favor of the one below
        * in a future version.
@@ -91,7 +92,8 @@ namespace TagLib {
        * If this file contains and ID3v2 tag the frames will be created using
        * \a frameFactory.
        *
-       * \note In the current implementation, \a propertiesStyle is ignored.
+       * If \a propertiesStyle is Accurate, the file will be scanned
+       * completely if no ID3v2 tag or MPEG sync code is found at the start.
        */
       // BIC: merge with the above constructor
       File(FileName file, ID3v2::FrameFactory *frameFactory,
@@ -108,7 +110,8 @@ namespace TagLib {
        * If this file contains and ID3v2 tag the frames will be created using
        * \a frameFactory.
        *
-       * \note In the current implementation, \a propertiesStyle is ignored.
+       * If \a propertiesStyle is Accurate, the file will be scanned
+       * completely if no ID3v2 tag or MPEG sync code is found at the start.
        */
       File(IOStream *stream, ID3v2::FrameFactory *frameFactory,
            bool readProperties = true,
@@ -375,8 +378,8 @@ namespace TagLib {
       File(const File &);
       File &operator=(const File &);
 
-      void read(bool readProperties);
-      long findID3v2();
+      void read(bool readProperties, Properties::ReadStyle);
+      long findID3v2(Properties::ReadStyle);
 
       class FilePrivate;
       FilePrivate *d;
diff --git a/taglib/toolkit/taglib.h b/taglib/toolkit/taglib.h
index ffce61f7..38fee5d1 100644
--- a/taglib/toolkit/taglib.h
+++ b/taglib/toolkit/taglib.h
@@ -54,6 +54,9 @@
 #define TAGLIB_DEPRECATED
 #endif
 
+/* VLC Specific patches implementations */
+#define VLC_PATCHED_TAGLIB_ID3V2_READSTYLE
+
 #include <string>
 
 //! A namespace for all TagLib related classes and functions
-- 
2.33.0

