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

quazip don't extract file as symlink on linux #48

Open
xlazom00 opened this issue Nov 20, 2019 · 13 comments
Open

quazip don't extract file as symlink on linux #48

xlazom00 opened this issue Nov 20, 2019 · 13 comments

Comments

@xlazom00
Copy link

xlazom00 commented Nov 20, 2019

I have a zip file with symlinks
but when I extracted files with quazip symlinked files looks like file with text to symlinked file
so this
0e5c7ad
don't work on linux

@stachenov
Copy link
Owner

I had no idea ZIP even supported symlinks. I'll look into it.

@xlazom00
Copy link
Author

xlazom00 commented Nov 20, 2019

@stachenov zip -y
btw so I don't get that commit :) what was the purpose ? :)

@stachenov
Copy link
Owner

No, wait. Is that my commit? Change “haad no idea” to “totally forgot” and say again, what's your problem? Show me the shortest code that doesn't work.

@xlazom00
Copy link
Author

xlazom00 commented Nov 20, 2019

@stachenov
Ou sorry It is my fault :)
I will need to check it one more time

@xlazom00
Copy link
Author

xlazom00 commented Nov 20, 2019

@stachenov
My code look like this:

QuaZip zip( filename );
QuaZipFile zipFile( &zip );
for( bool hasMore = zip.goToFirstFile(); hasMore; hasMore = zip.goToNextFile() )
{
   zipFile.open( QIODevice::ReadOnly );
   while( ( len = zipFile.read( buf, BUF_SIZE ) ) > 0 )
   {
     outputFile.write( buf, len );
   }
}

Ok so how can I detect if file in zip is symlink ?

@xlazom00
Copy link
Author

it looks like minizip continue in development here https://github.com/nmoinvaz/minizip
They also have 1.2 branch

@stachenov
Copy link
Owner

Yes, I know, but QuaZIP needs some extra modifications in minizip. It can't be used as-is.

@xlazom00
Copy link
Author

xlazom00 commented Nov 20, 2019

I found that all information is in externalAttr
So I have one method

void UpdateDownloader::getFileInfo( quint32 val, bool & isDir, bool & isSymlink ) const
{
    quint32 unixData = val >> 16;
    isDir = ( unixData & 0170000 ) == 0040000;
    isSymlink = ( unixData & 0170000 ) == 0120000;
}

QuaZipFileInfo64 info;
zip.getCurrentFileInfo( &info );

bool isDir, isSymlink;
getFileInfo( info.externalAttr, isDir, isSymlink );

ispiration is from
https://github.com/nmoinvaz/minizip/blob/master/mz_zip.c#L2559
so you can detect directory and symlink with this

@stachenov
Copy link
Owner

Right, it's the same bits that are used in QuaZipNewInfo (the commit you linked from your first post). Well, almost the same. I don't know whether it's unixData & 0170000 or unixData & 0120000. But that's not too important right now. What's important is that it turned out that QuaZIP currently supports symlink creation in the archives, but not extraction. You can do it manually for now, and I'll add a convenience method into QuaZipFileInfo64 later.

@Wzshun
Copy link

Wzshun commented May 26, 2020

Could you tell me if it's been fixed? or How can i to fix it.
It seems that the quazip extract file by copy data, but doesn't handle file attributes?

@stachenov
Copy link
Owner

QuaZip is now stuck between 0.9.x and 1.0, thanks to CMake... There's the v0.9.x branch, however. If you figure out how to do it, feel free to send a PR to that branch, and I'll make it 0.10 or something. Or wait until I get to it myself, but I can't make any promises how soon it will be done. Thanks for reminding me about it, though.

@stachenov
Copy link
Owner

I sort of fixed this now with e226541, but I'm not sure what happens if someone tries to extract an archive containing symbolic links on Windows. Qt will probably end up creating shortcuts instead, which will probably won't be what the user expect because they won't be named *.lnk and therefore won't be recognized by the OS.

@stachenov
Copy link
Owner

Added a Windows test in 54fd26e. Looks like it works as expected, except that links are broken, but they are useless anyway. At least extraction works in general.

The only part I'm unsure of now is this:

static void QuaZipNewInfo_setPermissions(QuaZipNewInfo *info,
        QFile::Permissions perm, bool isDir, bool isSymLink = false)
{
    quint32 uPerm = isDir ? 0040000 : 0100000;

    if ( isSymLink ) {
#ifdef Q_OS_WIN
        uPerm = 0200000;
#else
        uPerm = 0120000;
#endif
    }

I couldn't find what that Windows mask means for Unix permissions. Currently this code is executed for both symbolic links and shortcuts on Qt versions up to 5.13.x, and since 5.14 it is only executed for symbolic links, which are a rare beast on Windows. This code is sort of harmless too because the worst it can do is create ZIP archives with broken links inside. But I'll keep this open for a while in case someone has an idea how to do it right.

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