physfs
physfs copied to clipboard
Zip with entries containing complete paths will mount but cannot stat or enumerate
Hi,
Had a strange issue that has occurred regarding a zip created through an external library that mounts without error in physfs but any attempt to enumerate or stat on the files inside returns the 'not found' error.
I've tested in the integrity of the zip (through Ubuntu) and there are no issues (plus the files can be extracted in other tools without error), the only guess I can make on the problem is that the entries inside the zip are not separated as two parts directory and then the file (also probably perhaps something related to the leading slash in the filenames?).
E.g. (the problem zip shows this for the integrity check)
Zipping the files directly in Ubuntu gives a working file but looks like this...
Here are the two files and some example code to hopefully show the error...
int main( int argc, char* argv[] )
{
if ( PHYSFS_init( NULL ) )
{
// This zip mounts fine (created by Ubuntu compress)
if ( PHYSFS_mount( "working.zip", "root-good", 0 ) != 0 )
{
PHYSFS_Stat fileInfo0;
if ( PHYSFS_stat( "root-good/0/test_file_0.txt", &fileInfo0 ) == 0 )
{
PHYSFS_ErrorCode errorCode = PHYSFS_getLastErrorCode();
std::cout << PHYSFS_getErrorByCode( errorCode ) << std::endl;
}
else
{
std::cout << fileInfo0.filesize << std::endl;
}
PHYSFS_Stat fileInfo1;
if ( PHYSFS_stat( "root-good/1/test_file_1.txt", &fileInfo1 ) == 0 )
{
PHYSFS_ErrorCode errorCode = PHYSFS_getLastErrorCode();
std::cout << PHYSFS_getErrorByCode( errorCode ) << std::endl;
}
else
{
std::cout << fileInfo1.filesize << std::endl;
}
PHYSFS_unmount( "root-good" );
}
// This zip mounts but cannot find the files
if ( PHYSFS_mount( "not-working.zip", "root-bad", 0 ) != 0 )
{
PHYSFS_Stat fileInfo0;
if ( PHYSFS_stat( "root-bad/0/test_file_0.txt", &fileInfo0 ) == 0 )
{
PHYSFS_ErrorCode errorCode = PHYSFS_getLastErrorCode();
std::cout << PHYSFS_getErrorByCode( errorCode ) << std::endl;
}
else
{
std::cout << fileInfo0.filesize << std::endl;
}
PHYSFS_Stat fileInfo1;
if ( PHYSFS_stat( "root-bad/1/test_file_1.txt", &fileInfo1 ) == 0 )
{
PHYSFS_ErrorCode errorCode = PHYSFS_getLastErrorCode();
std::cout << PHYSFS_getErrorByCode( errorCode ) << std::endl;
}
else
{
std::cout << fileInfo1.filesize << std::endl;
}
PHYSFS_unmount( "root-bad" );
}
PHYSFS_deinit();
}
}
Thanks in advance for any enlightenment on this :)
According to https://pkwaredownloads.blob.core.windows.net/pem/APPNOTE.txt
4.4.17.1 The name of the file, with optional relative path. The path stored MUST NOT contain a drive or device letter, or a leading slash.
Probably confuses DirTree lookup but not detected/handled when parsing the central archive during mount.