Loading media/libstagefright/id3/ID3.cpp +84 −4 Original line number Diff line number Diff line Loading @@ -142,11 +142,22 @@ struct id3_header { mSize = size; if (source->readAt(sizeof(header), mData, mSize) != (ssize_t)mSize) { free(mData); mData = NULL; return false; } if (header.flags & 0x80) { if (header.version_major == 4) { if (!removeUnsynchronizationV2_4()) { free(mData); mData = NULL; return false; } } else if (header.flags & 0x80) { LOGV("removing unsynchronization"); removeUnsynchronization(); } Loading Loading @@ -243,6 +254,74 @@ void ID3::removeUnsynchronization() { } } static void WriteSyncsafeInteger(uint8_t *dst, size_t x) { for (size_t i = 0; i < 4; ++i) { dst[3 - i] = (x & 0x7f); x >>= 7; } } bool ID3::removeUnsynchronizationV2_4() { size_t oldSize = mSize; size_t offset = 0; while (offset + 10 <= mSize) { if (!memcmp(&mData[offset], "\0\0\0\0", 4)) { break; } size_t dataSize; if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) { return false; } if (offset + dataSize + 10 > mSize) { return false; } uint16_t flags = U16_AT(&mData[offset + 8]); uint16_t prevFlags = flags; if (flags & 1) { // Strip data length indicator memmove(&mData[offset + 10], &mData[offset + 14], mSize - offset - 14); mSize -= 4; dataSize -= 4; flags &= ~1; } if (flags & 2) { // Unsynchronization added. for (size_t i = 0; i + 1 < dataSize; ++i) { if (mData[offset + 10 + i] == 0xff && mData[offset + 11 + i] == 0x00) { memmove(&mData[offset + 11 + i], &mData[offset + 12 + i], mSize - offset - 12 - i); --mSize; --dataSize; } } flags &= ~2; } if (flags != prevFlags) { WriteSyncsafeInteger(&mData[offset + 4], dataSize); mData[offset + 8] = flags >> 8; mData[offset + 9] = flags & 0xff; } offset += 10 + dataSize; } memset(&mData[mSize], 0, oldSize - mSize); return true; } ID3::Iterator::Iterator(const ID3 &parent, const char *id) : mParent(parent), mID(NULL), Loading Loading @@ -529,10 +608,11 @@ void ID3::Iterator::findFrame() { uint16_t flags = U16_AT(&mParent.mData[mOffset + 8]); if ((mParent.mVersion == ID3_V2_4 && (flags & 0x000e)) if ((mParent.mVersion == ID3_V2_4 && (flags & 0x000c)) || (mParent.mVersion == ID3_V2_3 && (flags & 0x00c0))) { // Compression, Encryption or per-Frame unsynchronization // are not supported at this time. // Compression or encryption are not supported at this time. // Per-frame unsynchronization and data-length indicator // have already been taken care of. LOGV("Skipping unsupported frame (compression, encryption " "or per-frame unsynchronization flagged"); Loading media/libstagefright/include/ID3.h +1 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ private: bool parseV1(const sp<DataSource> &source); bool parseV2(const sp<DataSource> &source); void removeUnsynchronization(); bool removeUnsynchronizationV2_4(); static bool ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x); Loading Loading
media/libstagefright/id3/ID3.cpp +84 −4 Original line number Diff line number Diff line Loading @@ -142,11 +142,22 @@ struct id3_header { mSize = size; if (source->readAt(sizeof(header), mData, mSize) != (ssize_t)mSize) { free(mData); mData = NULL; return false; } if (header.flags & 0x80) { if (header.version_major == 4) { if (!removeUnsynchronizationV2_4()) { free(mData); mData = NULL; return false; } } else if (header.flags & 0x80) { LOGV("removing unsynchronization"); removeUnsynchronization(); } Loading Loading @@ -243,6 +254,74 @@ void ID3::removeUnsynchronization() { } } static void WriteSyncsafeInteger(uint8_t *dst, size_t x) { for (size_t i = 0; i < 4; ++i) { dst[3 - i] = (x & 0x7f); x >>= 7; } } bool ID3::removeUnsynchronizationV2_4() { size_t oldSize = mSize; size_t offset = 0; while (offset + 10 <= mSize) { if (!memcmp(&mData[offset], "\0\0\0\0", 4)) { break; } size_t dataSize; if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) { return false; } if (offset + dataSize + 10 > mSize) { return false; } uint16_t flags = U16_AT(&mData[offset + 8]); uint16_t prevFlags = flags; if (flags & 1) { // Strip data length indicator memmove(&mData[offset + 10], &mData[offset + 14], mSize - offset - 14); mSize -= 4; dataSize -= 4; flags &= ~1; } if (flags & 2) { // Unsynchronization added. for (size_t i = 0; i + 1 < dataSize; ++i) { if (mData[offset + 10 + i] == 0xff && mData[offset + 11 + i] == 0x00) { memmove(&mData[offset + 11 + i], &mData[offset + 12 + i], mSize - offset - 12 - i); --mSize; --dataSize; } } flags &= ~2; } if (flags != prevFlags) { WriteSyncsafeInteger(&mData[offset + 4], dataSize); mData[offset + 8] = flags >> 8; mData[offset + 9] = flags & 0xff; } offset += 10 + dataSize; } memset(&mData[mSize], 0, oldSize - mSize); return true; } ID3::Iterator::Iterator(const ID3 &parent, const char *id) : mParent(parent), mID(NULL), Loading Loading @@ -529,10 +608,11 @@ void ID3::Iterator::findFrame() { uint16_t flags = U16_AT(&mParent.mData[mOffset + 8]); if ((mParent.mVersion == ID3_V2_4 && (flags & 0x000e)) if ((mParent.mVersion == ID3_V2_4 && (flags & 0x000c)) || (mParent.mVersion == ID3_V2_3 && (flags & 0x00c0))) { // Compression, Encryption or per-Frame unsynchronization // are not supported at this time. // Compression or encryption are not supported at this time. // Per-frame unsynchronization and data-length indicator // have already been taken care of. LOGV("Skipping unsupported frame (compression, encryption " "or per-frame unsynchronization flagged"); Loading
media/libstagefright/include/ID3.h +1 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ private: bool parseV1(const sp<DataSource> &source); bool parseV2(const sp<DataSource> &source); void removeUnsynchronization(); bool removeUnsynchronizationV2_4(); static bool ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x); Loading