diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2021-12-17 11:38:34 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-12-19 20:11:13 +0000 |
commit | a656f684f2c996e3d0bcc7f58369e0d8c24d815b (patch) | |
tree | 94f5010fca7bb784de6100f912d359a7404e2f1d /src/gui/text | |
parent | a6550abcb685e0f7d2a5f413d218aaff2cb15612 (diff) |
QZipReader: update to unzip partly broken archives
The problem was discovered while providing a fix for the linked issue.
The original zip archive is very old, and it does not contain separate
entries for directories, only for files.
As a result, QZipReader algorithm was failing to create all the
necessary subdirectory structures, and unzipping failed.
This patch detects such case, and creates a directory hierarchy based
on the file paths.
Task-number: QTBUG-81503
Change-Id: I204f9b620853b3ffcbb9cbf6fe08fb5958776ea0
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
(cherry picked from commit 5cc75108012251bef96c56a71cb3f92274990064)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qzip.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp index 711482af8a..1fe7a6d042 100644 --- a/src/gui/text/qzip.cpp +++ b/src/gui/text/qzip.cpp @@ -1024,13 +1024,33 @@ bool QZipReader::extractAll(const QString &destinationDir) const // create directories first const QList<FileInfo> allFiles = fileInfoList(); + bool foundDirs = false; + bool hasDirs = false; for (const FileInfo &fi : allFiles) { const QString absPath = destinationDir + QDir::separator() + fi.filePath; if (fi.isDir) { + foundDirs = true; if (!baseDir.mkpath(fi.filePath)) return false; if (!QFile::setPermissions(absPath, fi.permissions)) return false; + } else if (!hasDirs && fi.filePath.contains(u"/")) { + // filePath does not have leading or trailing '/', so if we find + // one, than the file path contains directories. + hasDirs = true; + } + } + + // Some zip archives can be broken in the sense that they do not report + // separate entries for directories, only for files. In this case we + // need to recreate directory structure based on the file paths. + if (hasDirs && !foundDirs) { + for (const FileInfo &fi : allFiles) { + const auto dirPath = fi.filePath.left(fi.filePath.lastIndexOf(u"/")); + if (!baseDir.mkpath(dirPath)) + return false; + // We will leave the directory permissions default in this case, + // because setting dir permissions based on file is incorrect } } |