Skip to content

The encrypted zip file generated with QuaZip on Ubuntu cannot be decrypted on Windows. #201

@xiqixi

Description

@xiqixi

quazip-0.7.1 + qt-5.12.12
quazip-1.5 + qt-5.12.12

I generated a password-protected zip file (password is "a") using Qt + QuaZip on Ubuntu.
After copying the file to Windows, I tried to extract it using Qt + QuaZip (with the same password "a"), but the extraction failed.
Moreover, I couldn't extract the file using unzip on Ubuntu, nor using 7-Zip on Windows.
The only way to successfully extract it is by using Qt + QuaZip on Ubuntu.
Below is the code I used.
How can I make it extract successfully on Windows?
Looking forward to your answer.
Thank you!

bool ZipHandler::compressFile(QuaZip* zip, const QString& fileName, const QString& fileDest, const QString& password)
{
    if (!zip)
    {
        return false;
    }
    if (zip->getMode()!=QuaZip::mdCreate &&
            zip->getMode()!=QuaZip::mdAppend &&
            zip->getMode()!=QuaZip::mdAdd)
    {
        return false;
    }

    QFile inFile;
    inFile.setFileName(fileName);
    if (!inFile.open(QIODevice::ReadOnly))
    {
        return false;
    }

    QuaZipFile outFile(zip);
    if (!password.isEmpty())
    {
        if (!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, inFile.fileName()), password.toUtf8().constData()))
        {
            return false;
        }
    } else
    {
        if (!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, inFile.fileName())))
        {
            return false;
        }
    }

    if (!copyData(inFile, outFile) || outFile.getZipError()!=UNZ_OK)
    {
        return false;
    }

    outFile.close();
    if (outFile.getZipError()!=UNZ_OK)
    {
        return false;
    }
    inFile.close();

    return true;
}

ZipError ZipHandler::extractFile(QuaZip* zip, const QString& fileName, const QString& fileDest, const QString& password)
{
    QuaZipFile inFile(zip);
    QuaZipFileInfo64 info;
    QFile::Permissions srcPerm;
    ZipError ret = NoError;

    if (!fileName.isEmpty())
    {
        zip->setCurrentFile(fileName);
    }

    if (!zip->getCurrentFileInfo(&info))
    {
        ret = OtherError;
    }

    if (ret == NoError)
    {
        if (info.isEncrypted())
        {
            if (!inFile.open(QIODevice::ReadOnly, password.toUtf8().constData()) || inFile.getZipError()!=UNZ_OK)
            {
                ret = OtherError;
            }
        } else
        {
            if (!inFile.open(QIODevice::ReadOnly) || inFile.getZipError()!=UNZ_OK)
            {
                ret = OtherError;
            }
        }
    }

    if (ret == NoError)
    {
        ret = makepath(fileDest);
    }

    if (ret == NoError)
    {
        srcPerm = info.getPermissions();
        if (fileDest.endsWith(FILEPATH_SEP) && QFileInfo(fileDest).isDir()) {
            if (srcPerm != 0)
            {
                QFile(fileDest).setPermissions(srcPerm);
            }
        } else
        {
            ret = extractData(srcPerm, inFile, fileDest);
        }
    }

    return ret;
}

ZipError ZipHandler::makepath(const QString& fileDest)
{
    QDir curDir;
    ZipError ret = NoError;


    if (fileDest.endsWith(FILEPATH_SEP))
    {
        if (!curDir.mkpath(fileDest))
        {
            ret = NoPermission;
        }
    } else
    {
        if (!curDir.mkpath(QFileInfo(fileDest).absolutePath()))
        {
            ret = NoPermission;
        }
    }

    return ret;
}

ZipError ZipHandler::extractData(const QFile::Permissions& srcPerm, QuaZipFile& inFile, const QString& fileDest)
{
    QFile outFile;
    ZipError ret = NoError;

    outFile.setFileName(fileDest);
    if (!outFile.open(QIODevice::WriteOnly))
    {
        ret = NoPermission;
    }

    if (ret == NoError)
    {
        if (!copyData(inFile, outFile) || inFile.getZipError()!=UNZ_OK)
        {
            outFile.close();
            removeFile(QStringList(fileDest));
            ret = NoSpace;
        }
    }

    if (ret == NoError)
    {
        outFile.close();
        inFile.close();

        if (inFile.getZipError() != UNZ_OK)
        {
            removeFile(QStringList(fileDest));
            ret = OtherError;
        }
    }

    if (ret == NoError)
    {
        if (srcPerm != 0) {
            outFile.setPermissions(srcPerm);
        }
    }

    return ret;
}

bool ZipHandler::copyData(QIODevice &inFile, QIODevice &outFile)
{
    char buf[writeBuff];
    qint64 readLen = 0;
    bool ret = true;
    qint64 writeBuffNum = 4096;

    while (!inFile.atEnd())
    {
        readLen = inFile.read(buf, writeBuffNum);
        if (readLen <= 0)
        {
            ret = false;
            break;
        }
        if (outFile.write(buf, readLen) != readLen)
        {
            ret = false;
            break;
        }
    }
    return ret;
}

bool ZipHandler::removeFile(const QStringList& listFile)
{
    bool ret = true;

    for (int i=0; i<listFile.count(); ++i)
    {
        ret = ret && QFile::remove(listFile.at(i));
    }
    return ret;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions