Browse Source

Fixing crash at Importer::IsExtensionSupported().

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@411 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
aramis_acg 16 years ago
parent
commit
afcfdf27ea
3 changed files with 34 additions and 18 deletions
  1. 16 13
      code/BaseImporter.cpp
  2. 13 4
      code/Importer.cpp
  3. 5 1
      test/unit/utImporter.cpp

+ 16 - 13
code/BaseImporter.cpp

@@ -108,11 +108,12 @@ void BaseImporter::SetupProperties(const Importer* pImp)
 	unsigned int		numTokens,
 	unsigned int		searchBytes /* = 200 */)
 {
-	ai_assert(NULL != tokens && 0 != numTokens && NULL != pIOHandler && 0 != searchBytes);
+	ai_assert(NULL != tokens && 0 != numTokens && 0 != searchBytes);
+	if (!pIOHandler)
+		return false;
 
 	boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
-	if (pStream.get() )
-	{
+	if (pStream.get() )	{
 		// read 200 characters from the file
 		boost::scoped_array<char> _buffer (new char[searchBytes+1 /* for the '\0' */]);
 		char* buffer = _buffer.get();
@@ -126,18 +127,17 @@ void BaseImporter::SetupProperties(const Importer* pImp)
 		// It is not a proper handling of unicode files here ...
 		// ehm ... but it works in most cases.
 		char* cur = buffer,*cur2 = buffer,*end = &buffer[read];
-		while (cur != end)
-		{
-			if (*cur)*cur2++ = *cur;
+		while (cur != end)	{
+			if (*cur)
+				*cur2++ = *cur;
 			++cur;
 		}
 		*cur2 = '\0';
 
-		for (unsigned int i = 0; i < numTokens;++i)
-		{
+		for (unsigned int i = 0; i < numTokens;++i)	{
 			ai_assert(NULL != tokens[i]);
-			if (::strstr(buffer,tokens[i]))
-			{
+
+			if (::strstr(buffer,tokens[i]))	{
 				DefaultLogger::get()->debug(std::string("Found positive match for header keyword: ") + tokens[i]);
 				return true;
 			}
@@ -193,12 +193,15 @@ void BaseImporter::SetupProperties(const Importer* pImp)
 /* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile, 
 	const void* _magic, unsigned int num, unsigned int offset, unsigned int size)
 {
-	ai_assert(size <= 16 && _magic && num && pIOHandler);
+	ai_assert(size <= 16 && _magic);
+
+	if (!pIOHandler)
+		return false;
 
 	const char* magic = (const char*)_magic;
 	boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
-	if (pStream.get() )
-	{
+	if (pStream.get() )	{
+
 		// skip to offset
 		pStream->Seek(offset,aiOrigin_SET);
 

+ 13 - 4
code/Importer.cpp

@@ -845,13 +845,22 @@ bool Importer::IsExtensionSupported(const char* szExtension)
 }
 
 // ------------------------------------------------------------------------------------------------
+// Find a loader plugin for a given file extension
 BaseImporter* Importer::FindLoader (const char* _szExtension)
 {
-	const std::string szExtension(_szExtension);
-	for (std::vector<BaseImporter*>::const_iterator i =  pimpl->mImporter.begin();i != pimpl->mImporter.end();++i)
-	{
+	std::string ext(_szExtension);
+	if (ext.length() <= 1)
+		return NULL;
+
+	if (ext[0] != '.') {
+		// trailing dot is explicitly requested in the doc but we don't care for now ..
+		ext.erase(0,1);
+	}
+
+	for (std::vector<BaseImporter*>::const_iterator i =  pimpl->mImporter.begin();i != pimpl->mImporter.end();++i)	{
+
 		// pass the file extension to the CanRead(..,NULL)-method
-		if ((*i)->CanRead(szExtension,NULL,false))
+		if ((*i)->CanRead(ext,NULL,false))
 			return *i;
 	}
 	return NULL;

+ 5 - 1
test/unit/utImporter.cpp

@@ -13,7 +13,8 @@ bool TestPlugin :: CanRead( const std::string& pFile,
 {
 	std::string::size_type pos = pFile.find_last_of('.');
 	// no file extension - can't read
-	if( pos == std::string::npos)return false;
+	if( pos == std::string::npos)
+		return false;
 	std::string extension = pFile.substr( pos);
 
 	// todo ... make case-insensitive
@@ -80,6 +81,9 @@ void ImporterTest :: testPluginInterface (void)
 	CPPUNIT_ASSERT(pImp->IsExtensionSupported(".mac"));
 	CPPUNIT_ASSERT(pImp->IsExtensionSupported(".linux"));
 	CPPUNIT_ASSERT(pImp->IsExtensionSupported(".windows"));
+	CPPUNIT_ASSERT(pImp->IsExtensionSupported(".x")); /* x and 3ds must be available of course */
+	CPPUNIT_ASSERT(pImp->IsExtensionSupported(".3ds"));
+	CPPUNIT_ASSERT(!pImp->IsExtensionSupported("."));
 
 	TestPlugin* p = (TestPlugin*) pImp->FindLoader(".windows");
 	CPPUNIT_ASSERT(NULL != p);