Game Development Community

ZipArchive tests fail.

by Stefan Lundmark · in Torque Game Engine Advanced · 07/10/2009 (11:33 pm) · 6 replies

ZipArchive::addFile () does a buffer overrun somewhere and corrupts the callstack state so I can't examine it. It's after createNewFile () is called in openFile (). To test this without running the UnitTest, do this:

Zip::ZipArchive *zip = new Zip::ZipArchive;

if(!zip->openArchive("testArchive.zip", Zip::ZipArchive::ReadWrite))
{
     delete zip;
     return;
}

zip->addFile ("shaders/baseInteriorP.hlsl", "shaders/baseInteriorP.hlsl");
zip->closeArchive ();

I was under the impression these unit tests were there to be tested on each release to detect bugs and to avoid breaking functionallity, but whatever. I'm posting this so others don't go insane trying the same stuff.

#1
07/11/2009 (6:37 pm)
This is confusing.

osGetTemporaryDirectory () is where the buffer overrun seems to happen. Because if I remove the code and return "" (so the temporary file gets created in the app root) it works just fine so the zip code isn't broken.

Rene, any ideas? You seem to be the only soul still watching. Any advice is greatly appreciated.

#2
07/11/2009 (8:35 pm)

Oh yeah, I remember this came up in the TGB section. The modifications I made to TGEA and TGB were the same and osGetTemporaryDirectory() was faulty. Wait, I post the corrected function in a sec.... :)
#3
07/11/2009 (8:39 pm)

Replace the function with this:

StringTableEntry osGetTemporaryDirectory()
{
   TCHAR buf[ 1024 ];
   const U32 bufSize = sizeof( buf ) / sizeof( buf[ 0 ] );
   DWORD len = GetTempPath( sizeof( buf ) / sizeof( buf[ 0 ] ), buf );

   TempAlloc< TCHAR > temp;
   TCHAR* buffer = buf;
   if( len > bufSize - 1 )
   {
      temp = TempAlloc< TCHAR >( len + 1 );
      buffer = temp;
      GetTempPath( len + 1, buffer );
   }

   // Remove the trailing slash
   buffer[len-1] = 0;

#ifdef UNICODE
   TempAlloc< char > dirBuffer( len * 3 + 1 );
   char* dir = dirBuffer;
   convertUTF16toUTF8( buffer, dir, dirBuffer.size );
#else
   char* dir = buf;
#endif

   forwardslash(dir);
   return StringTable->insert(dir);
}

This should solve the problem.
#4
07/11/2009 (8:55 pm)

Hmm, this should really have been in the known issues list. I'm sorry about that, Stefan. I fixed it in the TGEA repo but for some reason never informed Alex. Will shoot him an email now.
#5
07/12/2009 (12:50 am)
Quote:
'TempAlloc<T>' : no appropriate default constructor available

This is what I ended up with:

StringTableEntry osGetTemporaryDirectory()
{
   TCHAR buf[ 1024 ];
   const U32 bufSize = sizeof( buf ) / sizeof( buf[ 0 ] );
   DWORD len = GetTempPath( sizeof( buf ) / sizeof( buf[ 0 ] ), buf );

   TCHAR* buffer = buf;
   TempAlloc< TCHAR > temp = TempAlloc< TCHAR >( len + 1 );
   if( len > bufSize - 1 )
   {  
      buffer = temp;
      GetTempPath( len + 1, buffer );
   }

   // Remove the trailing slash
   buffer[len-1] = 0;

#ifdef UNICODE
   TempAlloc< char > dirBuffer( len * 3 + 1 );
   char* dir = dirBuffer;
   convertUTF16toUTF8( buffer, dir, dirBuffer.size );
#else
   char* dir = buf;
#endif

   forwardslash(dir);
   return StringTable->insert(dir);
}

Thank you so much!
#6
07/12/2009 (12:55 am)

You're welcome.

Forgot that I had added that constructor for this one.

Great things are working for you now.