Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zip with entries containing complete paths will mount but cannot stat or enumerate #68

Open
jm-seabery opened this issue Sep 12, 2023 · 1 comment
Assignees

Comments

@jm-seabery
Copy link

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)

not-working-integrity

Zipping the files directly in Ubuntu gives a working file but looks like this...

working-test-integrity

Here are the two files and some example code to hopefully show the error...

not-working.zip
working.zip

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 :)

@icculus icculus self-assigned this Sep 12, 2023
@undernorthernsky
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants