Commit 75ee205a authored by Tomaz  Canabrava's avatar Tomaz Canabrava Committed by Elvis Angelaccio
Browse files

Block extraction if there's no space left

This works only on the BatchExtract, that's triggered by the
right click menu in dolphin. If the final size of the file
to be uncompressed is bigger than the free space on a folder
or device, quit with an error.

FEATURE: 393959
parent d02e8a1c
Pipeline #188226 passed with stage
in 1 minute and 59 seconds
......@@ -30,6 +30,11 @@ Archive::Entry::~Entry()
{
}
qulonglong Archive::Entry::size() const
{
return m_size;
}
void Archive::Entry::copyMetaData(const Archive::Entry *sourceEntry)
{
setProperty("fullPath", sourceEntry->property("fullPath"));
......
......@@ -77,6 +77,7 @@ public:
Entry *find(QStringView name) const;
Entry *findByPath(const QStringList & pieces, int index = 0) const;
QIcon icon() const;
qulonglong size() const;
/**
* Fills @p dirs and @p files with the number of directories and files
......
......@@ -16,14 +16,15 @@
namespace Kerfuffle
{
ReadOnlyArchiveInterface::ReadOnlyArchiveInterface(QObject *parent, const QVariantList & args)
: QObject(parent)
, m_numberOfVolumes(0)
, m_numberOfEntries(0)
, m_waitForFinishedSignal(false)
, m_isHeaderEncryptionEnabled(false)
, m_isCorrupt(false)
, m_isMultiVolume(false)
ReadOnlyArchiveInterface::ReadOnlyArchiveInterface(QObject *parent, const QVariantList &args)
: QObject(parent)
, m_numberOfVolumes(0)
, m_numberOfEntries(0)
, m_waitForFinishedSignal(false)
, m_isHeaderEncryptionEnabled(false)
, m_isCorrupt(false)
, m_isMultiVolume(false)
, m_unpackedSize(0)
{
Q_ASSERT(args.size() >= 2);
......@@ -40,8 +41,9 @@ ReadOnlyArchiveInterface::~ReadOnlyArchiveInterface()
void ReadOnlyArchiveInterface::onEntry(Archive::Entry *archiveEntry)
{
Q_UNUSED(archiveEntry)
m_numberOfEntries++;
Q_ASSERT(archiveEntry);
m_numberOfEntries += 1;
m_unpackedSize += archiveEntry->size();
}
QString ReadOnlyArchiveInterface::filename() const
......@@ -146,6 +148,11 @@ void ReadOnlyArchiveInterface::setWaitForFinishedSignal(bool value)
m_waitForFinishedSignal = value;
}
qulonglong ReadOnlyArchiveInterface::unpackedSize() const
{
return m_unpackedSize;
}
QStringList ReadOnlyArchiveInterface::entryFullPaths(const QVector<Archive::Entry*> &entries, PathFormat format)
{
QStringList filesList;
......
......@@ -162,6 +162,11 @@ public:
*/
virtual bool isLocked() const;
/**
* Returns the size of the unpacked archive
*/
qulonglong unpackedSize() const;
Q_SIGNALS:
/**
......@@ -207,6 +212,7 @@ private:
bool m_isHeaderEncryptionEnabled;
bool m_isCorrupt;
bool m_isMultiVolume;
qulonglong m_unpackedSize;
private Q_SLOTS:
void onEntry(Archive::Entry *archiveEntry);
......
......@@ -13,6 +13,7 @@
#include <QDir>
#include <QDirIterator>
#include <QFileInfo>
#include <QStorageInfo>
#include <QThread>
#include <QTimer>
#include <QUrl>
......@@ -396,6 +397,16 @@ void BatchExtractJob::slotLoadingFinished(KJob *job)
return;
}
// Block extraction if there's no space on the device.
// Probably we need to take into account a small delta too,
// so, free space + 1% just for the sake of it.
QStorageInfo destinationStorage(m_destination);
if (m_loadJob->extractedFilesSize() * 1.01 > destinationStorage.bytesAvailable()) {
onError(xi18n("No space available on device <filename>%1</filename>", m_destination), QString(), Kerfuffle::DestinationNotWritableError);
onFinished(false);
return;
}
// Now we can start extraction.
setupDestination();
......@@ -542,6 +553,19 @@ void ExtractJob::doWork()
<< "Destination dir:" << m_destinationDir
<< "Options:" << m_options;
qulonglong totalUncompressedSize = 0;
for (Archive::Entry *entry : m_entries) {
totalUncompressedSize += entry->size();
}
QStorageInfo destinationStorage(m_destinationDir);
if (totalUncompressedSize > destinationStorage.bytesAvailable()) {
onError(xi18n("No space available on device <filename>%1</filename>", m_destinationDir), QString(), Kerfuffle::DestinationNotWritableError);
onFinished(false);
return;
}
bool ret = archiveInterface()->extractFiles(m_entries, m_destinationDir, m_options);
if (!archiveInterface()->waitForFinishedSignal()) {
......
......@@ -17,8 +17,6 @@ class ReadOnlyLibarchivePlugin : public LibarchivePlugin
public:
explicit ReadOnlyLibarchivePlugin(QObject *parent, const QVariantList& args);
~ReadOnlyLibarchivePlugin() override;
};
#endif // READONLYLIBARCHIVEPLUGIN_H
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment