diff -ur mythplugins-0.18/mythmusic/mythmusic/maddecoder.cpp mythplugins-0.18-r1/mythmusic/mythmusic/maddecoder.cpp --- mythplugins-0.18/mythmusic/mythmusic/maddecoder.cpp 2005-02-23 21:41:08.000000000 +0100 +++ mythplugins-0.18-r1/mythmusic/mythmusic/maddecoder.cpp 2005-05-08 16:39:08.000000000 +0200 @@ -19,6 +19,7 @@ #include #define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g') +#define ID3V2_MAGIC (('I' << 16) | ('D' << 8) | '3') MadDecoder::MadDecoder(const QString &file, DecoderFactory *d, QIODevice *i, AudioOutput *o) @@ -147,6 +148,62 @@ output_at = 0; } +unsigned long MadDecoder::skipNotUnsynchronizedTag(struct mad_bitptr ptr, unsigned int bitlen) +{ + unsigned long offset = 0; + unsigned char t = 0; + unsigned long version = 0; + unsigned char test = 0; + + if(bitlen < 80 || mad_bit_read(&ptr, 24) != ID3V2_MAGIC) // Not ID3v2 + goto fail; + + version = mad_bit_read(&ptr, 8); + switch(version) + { + case 2: + test = 0xbf; // flags = ab000000 + break; + case 3: + test = 0x9f; // flags = abc00000 + break; + case 4: + test = 0x8f; // flags = abcd0000 + break; + default: + goto fail; // Unknown id3v2 revision + } + if(mad_bit_read(&ptr, 8) != 0x0) // remainder + goto fail; + if(mad_bit_read(&ptr, 8) & test != 0x0) // Either tag is unsynchronized or flags byte contains garbage (tbt) + goto fail; + + // building offset concatenating the 7 first bits of the 4 next bytes + // if any byte has its 8th bit set, that's an error + t = mad_bit_read(&ptr, 8); + if(t > 0x7f) + goto fail; + offset |= t << 21; + t = mad_bit_read(&ptr, 8); + if(t > 0x7f) + goto fail; + offset |= t << 14; + t = mad_bit_read(&ptr, 8); + if(t > 0x7f) + goto fail; + offset |= t << 7; + t = mad_bit_read(&ptr, 8); + if(t > 0x7f) + goto fail; + offset |= t; + offset += 10; // Tag header is not in length + + return offset; + + fail: + return 0; +} + bool MadDecoder::findXingHeader(struct mad_bitptr ptr, unsigned int bitlen) { if (bitlen < 64 || mad_bit_read(&ptr, 32) != XING_MAGIC) @@ -220,6 +277,10 @@ mad_stream_buffer(&stream, (unsigned char *) input_buf, input_bytes); + stream.anc_ptr = stream.ptr; + stream.anc_bitlen = CHAR_BIT * input_bytes; + stream.skiplen = skipNotUnsynchronizedTag(stream.anc_ptr, stream.anc_bitlen); + bool done = false; while (! done) { if (mad_frame_decode(&frame, &stream) != -1) @@ -406,7 +467,7 @@ flush(TRUE); if (output()) { - output()->Drain(); + output()->Drain(); } done = TRUE; diff -ur mythplugins-0.18/mythmusic/mythmusic/maddecoder.h mythplugins-0.18-r1/mythmusic/mythmusic/maddecoder.h --- mythplugins-0.18/mythmusic/mythmusic/maddecoder.h 2005-02-23 21:41:08.000000000 +0100 +++ mythplugins-0.18-r1/mythmusic/mythmusic/maddecoder.h 2005-05-03 10:09:40.000000000 +0200 @@ -36,6 +36,7 @@ void flush(bool = FALSE); void deinit(); bool findHeader(); + unsigned long skipNotUnsynchronizedTag(struct mad_bitptr, unsigned int); bool findXingHeader(struct mad_bitptr, unsigned int); void calcLength(struct mad_header *);