mirror of
https://github.com/taglib/taglib.git
synced 2026-07-12 14:21:10 -04:00
Fix data length indicator check for compressed ID3v2 frames (#1371)
This commit is contained in:
@@ -295,7 +295,8 @@ ByteVector Frame::fieldData(const ByteVector &frameData) const
|
||||
frameDataLength = SynchData::toUInt(frameData.mid(headerSize, 4));
|
||||
frameDataOffset += 4;
|
||||
}
|
||||
if(frameData.size() >= headerSize &&
|
||||
if(!d->header->compression() &&
|
||||
frameData.size() >= headerSize &&
|
||||
frameDataOffset + frameDataLength > frameData.size()) {
|
||||
// The first check is needed because some "dual purpose" frame constructors
|
||||
// call this method with only the frame ID, i.e. without a complete header.
|
||||
@@ -309,7 +310,8 @@ ByteVector Frame::fieldData(const ByteVector &frameData) const
|
||||
return ByteVector();
|
||||
}
|
||||
|
||||
const ByteVector outData = zlib::decompress(frameData.mid(frameDataOffset));
|
||||
const ByteVector outData = zlib::decompress(frameData.mid(frameDataOffset),
|
||||
frameDataLength);
|
||||
if(!outData.isEmpty() && frameDataLength != outData.size()) {
|
||||
debug("frameDataLength does not match the data length returned by zlib");
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "tzlib.h"
|
||||
#include <climits>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
@@ -50,7 +51,8 @@ bool zlib::isAvailable()
|
||||
#endif
|
||||
}
|
||||
|
||||
ByteVector zlib::decompress([[maybe_unused]] const ByteVector &data)
|
||||
ByteVector zlib::decompress([[maybe_unused]] const ByteVector &data,
|
||||
unsigned int maxLength)
|
||||
{
|
||||
#ifdef HAVE_ZLIB
|
||||
|
||||
@@ -90,6 +92,12 @@ ByteVector zlib::decompress([[maybe_unused]] const ByteVector &data)
|
||||
}
|
||||
|
||||
outData.resize(outData.size() - stream.avail_out);
|
||||
|
||||
if(outData.size() > maxLength && maxLength != UINT_MAX) {
|
||||
debug("zlib::decompress() - Too long compressed stream.");
|
||||
outData.resize(maxLength);
|
||||
break;
|
||||
}
|
||||
} while(stream.avail_out == 0);
|
||||
|
||||
inflateEnd(&stream);
|
||||
@@ -102,3 +110,8 @@ ByteVector zlib::decompress([[maybe_unused]] const ByteVector &data)
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
ByteVector zlib::decompress([[maybe_unused]] const ByteVector &data)
|
||||
{
|
||||
return decompress(data, UINT_MAX);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,11 @@ namespace TagLib {
|
||||
*/
|
||||
ByteVector decompress(const ByteVector &data);
|
||||
|
||||
/*!
|
||||
* Decompress \a data by zlib, at most \a maxLength bytes.
|
||||
*/
|
||||
ByteVector decompress(const ByteVector &data, unsigned int maxLength);
|
||||
|
||||
} // namespace zlib
|
||||
} // namespace TagLib
|
||||
|
||||
|
||||
Binary file not shown.
BIN
tests/data/compressed_id3_frame_invalid.mp3
Normal file
BIN
tests/data/compressed_id3_frame_invalid.mp3
Normal file
Binary file not shown.
@@ -1121,7 +1121,7 @@ public:
|
||||
|
||||
void testCompressedFrameWithBrokenLength()
|
||||
{
|
||||
MPEG::File f(TEST_FILE_PATH_C("compressed_id3_frame.mp3"), false);
|
||||
MPEG::File f(TEST_FILE_PATH_C("compressed_id3_frame_invalid.mp3"), false);
|
||||
CPPUNIT_ASSERT(f.ID3v2Tag()->frameListMap().contains("APIC"));
|
||||
|
||||
if(zlib::isAvailable()) {
|
||||
@@ -1132,7 +1132,7 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(String("image/bmp"), frame->mimeType());
|
||||
CPPUNIT_ASSERT_EQUAL(ID3v2::AttachedPictureFrame::Other, frame->type());
|
||||
CPPUNIT_ASSERT_EQUAL(String(""), frame->description());
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(86414), frame->picture().size());
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(142), frame->picture().size());
|
||||
}
|
||||
else {
|
||||
// Skip the test if ZLIB is not installed.
|
||||
|
||||
Reference in New Issue
Block a user