mirror of
https://github.com/taglib/taglib.git
synced 2026-11-05 22:18:50 -05:00
FileRef: Rewind the stream before detecting the type by content (#1487)
A parser tried for the file extension may leave the stream anywhere, and Matroska::File::read() starts at the current position, so a Matroska file under an extension whose parser rejects it gave a null FileRef.
This commit is contained in:
@@ -579,7 +579,9 @@ void FileRef::parse(FileName fileName, bool readAudioProperties,
|
||||
return;
|
||||
|
||||
// At last, try to resolve file types based on the actual content.
|
||||
// A parser tried for the extension may have left the stream anywhere.
|
||||
|
||||
d->stream->seek(0);
|
||||
d->file = detectByContent(d->stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(d->file)
|
||||
return;
|
||||
@@ -612,7 +614,9 @@ void FileRef::parse(IOStream *stream, bool readAudioProperties,
|
||||
return;
|
||||
|
||||
// At last, try to resolve file types based on the actual content of the file.
|
||||
// A parser tried for the extension may have left the stream anywhere.
|
||||
|
||||
stream->seek(0);
|
||||
d->file = detectByContent(stream, readAudioProperties, audioPropertiesStyle);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,9 @@
|
||||
#ifdef TAGLIB_WITH_MOD
|
||||
#include "xmfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MATROSKA
|
||||
#include "matroskafile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
#include "dsffile.h"
|
||||
#include "dsdifffile.h"
|
||||
@@ -141,6 +144,9 @@ class TestFileRef : public CppUnit::TestFixture
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
CPPUNIT_TEST(testDSF);
|
||||
CPPUNIT_TEST(testDSDIFF);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MATROSKA
|
||||
CPPUNIT_TEST(testMatroskaWithOtherExtension);
|
||||
#endif
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
@@ -403,6 +409,31 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_MATROSKA
|
||||
void testMatroskaWithOtherExtension()
|
||||
{
|
||||
// The parsers for these extensions reject Matroska, so the file is found
|
||||
// by content detection after a failed parse.
|
||||
for(const char *ext : { ".flac", ".m4a" }) {
|
||||
ScopedFileCopy copy("no-tags", ".mka");
|
||||
const string newname = copy.fileName() + ext;
|
||||
CPPUNIT_ASSERT_EQUAL(0, std::rename(copy.fileName().c_str(), newname.c_str()));
|
||||
{
|
||||
FileRef f(newname.c_str());
|
||||
CPPUNIT_ASSERT(dynamic_cast<Matroska::File *>(f.file()));
|
||||
CPPUNIT_ASSERT(!f.isNull());
|
||||
}
|
||||
{
|
||||
FileStream s(newname.c_str());
|
||||
FileRef f(&s);
|
||||
CPPUNIT_ASSERT(dynamic_cast<Matroska::File *>(f.file()));
|
||||
CPPUNIT_ASSERT(!f.isNull());
|
||||
}
|
||||
deleteFile(newname);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void testUnsupported()
|
||||
{
|
||||
FileRef f1(TEST_FILE_PATH_C("no-extension"));
|
||||
|
||||
Reference in New Issue
Block a user