@ -107,20 +107,6 @@ ID3::ID3(DataSourceHelper *sourcehelper, bool ignoreV1, off64_t offset)
}
}
ID3 : : ID3 ( DataSourceBase * source , bool ignoreV1 , off64_t offset )
: mIsValid ( false ) ,
mData ( NULL ) ,
mSize ( 0 ) ,
mFirstFrameOffset ( 0 ) ,
mVersion ( ID3_UNKNOWN ) ,
mRawSize ( 0 ) {
mIsValid = parseV2 ( source , offset ) ;
if ( ! mIsValid & & ! ignoreV1 ) {
mIsValid = parseV1 ( source ) ;
}
}
ID3 : : ID3 ( const uint8_t * data , size_t size , bool ignoreV1 )
: mIsValid ( false ) ,
mData ( NULL ) ,
@ -247,44 +233,14 @@ struct id3_header {
return false ;
}
if ( header . version_major = = 4 ) {
void * copy = malloc ( size ) ;
if ( copy = = NULL ) {
free ( mData ) ;
mData = NULL ;
ALOGE ( " b/24623447, no more memory " ) ;
return false ;
}
memcpy ( copy , mData , size ) ;
bool success = removeUnsynchronizationV2_4 ( false /* iTunesHack */ ) ;
if ( ! success ) {
memcpy ( mData , copy , size ) ;
mSize = size ;
success = removeUnsynchronizationV2_4 ( true /* iTunesHack */ ) ;
if ( success ) {
ALOGV ( " Had to apply the iTunes hack to parse this ID3 tag " ) ;
}
}
free ( copy ) ;
copy = NULL ;
if ( ! success ) {
free ( mData ) ;
mData = NULL ;
return false ;
}
} else if ( header . flags & 0x80 ) {
// first handle global unsynchronization
if ( header . flags & 0x80 ) {
ALOGV ( " removing unsynchronization " ) ;
removeUnsynchronization ( ) ;
}
// handle extended header, if present
mFirstFrameOffset = 0 ;
if ( header . version_major = = 3 & & ( header . flags & 0x40 ) ) {
// Version 2.3 has an optional extended header.
@ -296,6 +252,7 @@ struct id3_header {
return false ;
}
// v2.3 does not have syncsafe integers
size_t extendedHeaderSize = U32_AT ( & mData [ 0 ] ) ;
if ( extendedHeaderSize > SIZE_MAX - 4 ) {
free ( mData ) ;
@ -367,6 +324,48 @@ struct id3_header {
mFirstFrameOffset = ext_size ;
}
// Handle any v2.4 per-frame unsynchronization
// The id3 spec isn't clear about what should happen if the global
// unsynchronization flag is combined with per-frame unsynchronization,
// or whether that's even allowed, so this code assumes id3 writing
// tools do the right thing and not apply double-unsynchronization,
// but will honor the flags if they are set.
if ( header . version_major = = 4 ) {
void * copy = malloc ( size ) ;
if ( copy = = NULL ) {
free ( mData ) ;
mData = NULL ;
ALOGE ( " b/24623447, no more memory " ) ;
return false ;
}
memcpy ( copy , mData , size ) ;
bool success = removeUnsynchronizationV2_4 ( false /* iTunesHack */ ) ;
if ( ! success ) {
memcpy ( mData , copy , size ) ;
mSize = size ;
success = removeUnsynchronizationV2_4 ( true /* iTunesHack */ ) ;
if ( success ) {
ALOGV ( " Had to apply the iTunes hack to parse this ID3 tag " ) ;
}
}
free ( copy ) ;
copy = NULL ;
if ( ! success ) {
free ( mData ) ;
mData = NULL ;
return false ;
}
}
if ( header . version_major = = 2 ) {
mVersion = ID3_V2_2 ;
} else if ( header . version_major = = 3 ) {
@ -411,7 +410,7 @@ static void WriteSyncsafeInteger(uint8_t *dst, size_t x) {
bool ID3 : : removeUnsynchronizationV2_4 ( bool iTunesHack ) {
size_t oldSize = mSize ;
size_t offset = 0 ;
size_t offset = mFirstFrameOffset ;
while ( mSize > = 10 & & offset < = mSize - 10 ) {
if ( ! memcmp ( & mData [ offset ] , " \0 \0 \0 \0 " , 4 ) ) {
break ;
@ -445,7 +444,7 @@ bool ID3::removeUnsynchronizationV2_4(bool iTunesHack) {
}
if ( ( flags & 2 ) & & ( dataSize > = 2 ) ) {
// This f il e has "unsynchronization", so we have to replace occurrences
// This f ram e has "unsynchronization", so we have to replace occurrences
// of 0xff 0x00 with just 0xff in order to get the real data.
size_t readOffset = offset + 11 ;