From cc6bf884a35b7787813399b2a128694e24fbb39a Mon Sep 17 00:00:00 2001 From: Scott Wheeler Date: Mon, 2 Aug 2004 19:35:47 +0000 Subject: [PATCH] Ignore compressed and encrypted ID3v2 frames rather than just blindly giving back the compressed/encrypted data as a string. git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@335256 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- mpeg/id3v2/id3v2frame.cpp | 71 +++++++++++++++++++++++++------- mpeg/id3v2/id3v2frame.h | 9 +++- mpeg/id3v2/id3v2framefactory.cpp | 12 ++++++ mpeg/id3v2/id3v2tag.cpp | 4 +- 4 files changed, 78 insertions(+), 18 deletions(-) diff --git a/mpeg/id3v2/id3v2frame.cpp b/mpeg/id3v2/id3v2frame.cpp index 243ee321..84b3f8d3 100644 --- a/mpeg/id3v2/id3v2frame.cpp +++ b/mpeg/id3v2/id3v2frame.cpp @@ -175,7 +175,7 @@ public: frameSize(0), version(4), tagAlterPreservation(false), - frameAlterPreservation(false), + fileAlterPreservation(false), readOnly(false), groupingIdentity(false), compression(false), @@ -191,7 +191,7 @@ public: // flags bool tagAlterPreservation; - bool frameAlterPreservation; + bool fileAlterPreservation; bool readOnly; bool groupingIdentity; bool compression; @@ -258,7 +258,6 @@ void Frame::Header::setData(const ByteVector &data, uint version) case 1: case 2: { - // ID3v2.2 if(data.size() < 3) { @@ -283,10 +282,8 @@ void Frame::Header::setData(const ByteVector &data, uint version) break; } case 3: - case 4: - default: { - // ID3v2.3 / ID3v2.4 + // ID3v2.3 if(data.size() < 4) { debug("You must at least specify a frame ID."); @@ -308,16 +305,55 @@ void Frame::Header::setData(const ByteVector &data, uint version) // Set the size -- the frame size is the four bytes starting at byte four in // the frame header (structure 4) - if(version >= 4) - d->frameSize = SynchData::toUInt(data.mid(4, 4)); - else - d->frameSize = data.mid(4, 4).toUInt(); + d->frameSize = data.mid(4, 4).toUInt(); { // read the first byte of flags std::bitset<8> flags(data[8]); - d->tagAlterPreservation = flags[6]; // (structure 4.1.1.a) - d->frameAlterPreservation = flags[5]; // (structure 4.1.1.b) - d->readOnly = flags[4]; // (structure 4.1.1.c) + d->tagAlterPreservation = flags[7]; // (structure 3.3.1.a) + d->fileAlterPreservation = flags[6]; // (structure 3.3.1.b) + d->readOnly = flags[5]; // (structure 3.3.1.c) + } + + { // read the second byte of flags + std::bitset<8> flags(data[9]); + d->compression = flags[7]; // (structure 3.3.1.i) + d->encryption = flags[6]; // (structure 3.3.1.j) + d->groupingIdentity = flags[5]; // (structure 3.3.1.k) + } + break; + } + case 4: + default: + { + // ID3v2.4 + + if(data.size() < 4) { + debug("You must at least specify a frame ID."); + return; + } + + // Set the frame ID -- the first four bytes + + d->frameID = data.mid(0, 4); + + // If the full header information was not passed in, do not continue to the + // steps to parse the frame size and flags. + + if(data.size() < 10) { + d->frameSize = 0; + return; + } + + // Set the size -- the frame size is the four bytes starting at byte four in + // the frame header (structure 4) + + d->frameSize = SynchData::toUInt(data.mid(4, 4)); + + { // read the first byte of flags + std::bitset<8> flags(data[8]); + d->tagAlterPreservation = flags[6]; // (structure 4.1.1.a) + d->fileAlterPreservation = flags[5]; // (structure 4.1.1.b) + d->readOnly = flags[4]; // (structure 4.1.1.c) } { // read the second byte of flags @@ -363,9 +399,9 @@ bool Frame::Header::tagAlterPreservation() const return d->tagAlterPreservation; } -bool Frame::Header::frameAlterPreservation() const +bool Frame::Header::fileAlterPreservation() const { - return d->frameAlterPreservation; + return d->fileAlterPreservation; } bool Frame::Header::readOnly() const @@ -406,3 +442,8 @@ ByteVector Frame::Header::render() const return v; } + +bool Frame::Header::frameAlterPreservation() const // deprecated +{ + return fileAlterPreservation(); +} diff --git a/mpeg/id3v2/id3v2frame.h b/mpeg/id3v2/id3v2frame.h index cdcc76d5..4e12dc21 100644 --- a/mpeg/id3v2/id3v2frame.h +++ b/mpeg/id3v2/id3v2frame.h @@ -299,11 +299,11 @@ namespace TagLib { bool tagAlterPreservation() const; /*! - * Returns true if the flag for frame alter preservation is set. + * Returns true if the flag for file alter preservation is set. * * \note This flag is currently ignored internally in TagLib. */ - bool frameAlterPreservation() const; + bool fileAlterPreservation() const; /*! * Returns true if the frame is meant to be read only. @@ -350,6 +350,11 @@ namespace TagLib { */ ByteVector render() const; + /*! + * @deprecated + */ + bool frameAlterPreservation() const; + private: Header(const Header &); Header &operator=(const Header &); diff --git a/mpeg/id3v2/id3v2framefactory.cpp b/mpeg/id3v2/id3v2framefactory.cpp index 3df55372..f98b8855 100644 --- a/mpeg/id3v2/id3v2framefactory.cpp +++ b/mpeg/id3v2/id3v2framefactory.cpp @@ -65,6 +65,18 @@ Frame *FrameFactory::createFrame(const ByteVector &data, uint version) const { Frame::Header *header = new Frame::Header(data, version); + // TagLib doesn't mess with encrypted or compressed frames, so just treat them + // as unknown frames. + + if(header->compression()) { + debug("Compressed frames are currently not supported."); + return new UnknownFrame(data, header); + } + if(header->encryption()) { + debug("Entrypted frames are currently not supported."); + return new UnknownFrame(data, header); + } + TagLib::ByteVector frameID = header->frameID(); // A quick sanity check -- make sure that the frameID is 4 uppercase Latin1 diff --git a/mpeg/id3v2/id3v2tag.cpp b/mpeg/id3v2/id3v2tag.cpp index 7324a3f9..00249b81 100644 --- a/mpeg/id3v2/id3v2tag.cpp +++ b/mpeg/id3v2/id3v2tag.cpp @@ -124,7 +124,9 @@ String ID3v2::Tag::genre() const // should be separated by " / " instead of " ". For the moment to keep // the behavior the same as released versions it is being left with " ". - if(!d->frameListMap["TCON"].isEmpty()) { + if(!d->frameListMap["TCON"].isEmpty() && + dynamic_cast(d->frameListMap["TCON"].front())) + { Frame *frame = d->frameListMap["TCON"].front(); // ID3v2.4 lists genres as the fields in its frames field list. If the field