summaryrefslogtreecommitdiffstats
path: root/rbutil/rbutilqt/quazip/quazipfileinfo.cpp
diff options
context:
space:
mode:
authorDominik Riebeling <Dominik.Riebeling@gmail.com>2020-06-08 20:25:36 +0200
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2020-08-07 22:18:41 +0200
commitb0f22620a2dbfb991b10a8e1e8b0c8db5e3ee117 (patch)
tree2695997733229be38ec71c36753b19ba2e98aa61 /rbutil/rbutilqt/quazip/quazipfileinfo.cpp
parentb3a0187416e48d80275af6be0178cef155aa03dc (diff)
downloadrockbox-b0f22620a2.tar.gz
rockbox-b0f22620a2.tar.bz2
rockbox-b0f22620a2.zip
rbutil: Update quazip to release 0.9.1.
Update to latest quazip release. Change-Id: I03189ceeadbe3110a9420153d84bd5d33d5b663f
Diffstat (limited to 'rbutil/rbutilqt/quazip/quazipfileinfo.cpp')
-rw-r--r--rbutil/rbutilqt/quazip/quazipfileinfo.cpp146
1 files changed, 83 insertions, 63 deletions
diff --git a/rbutil/rbutilqt/quazip/quazipfileinfo.cpp b/rbutil/rbutilqt/quazip/quazipfileinfo.cpp
index 1961f116b3..d5798ea771 100644
--- a/rbutil/rbutilqt/quazip/quazipfileinfo.cpp
+++ b/rbutil/rbutilqt/quazip/quazipfileinfo.cpp
@@ -24,6 +24,8 @@ see quazip/(un)zip.h files for details. Basically it's the zlib license.
#include "quazipfileinfo.h"
+#include <QtCore/QDataStream>
+
static QFile::Permissions permissionsFromExternalAttr(quint32 externalAttr) {
quint32 uPerm = (externalAttr & 0xFFFF0000u) >> 16;
QFile::Permissions perm = QFile::Permissions();
@@ -93,69 +95,30 @@ static QDateTime getNTFSTime(const QByteArray &extra, int position,
int *fineTicks)
{
QDateTime dateTime;
- for (int i = 0; i <= extra.size() - 4; ) {
- unsigned type = static_cast<unsigned>(static_cast<unsigned char>(
- extra.at(i)))
- | (static_cast<unsigned>(static_cast<unsigned char>(
- extra.at(i + 1))) << 8);
- i += 2;
- unsigned length = static_cast<unsigned>(static_cast<unsigned char>(
- extra.at(i)))
- | (static_cast<unsigned>(static_cast<unsigned char>(
- extra.at(i + 1))) << 8);
- i += 2;
- if (type == QUAZIP_EXTRA_NTFS_MAGIC && length >= 32) {
- i += 4; // reserved
- while (i <= extra.size() - 4) {
- unsigned tag = static_cast<unsigned>(
- static_cast<unsigned char>(extra.at(i)))
- | (static_cast<unsigned>(
- static_cast<unsigned char>(extra.at(i + 1)))
- << 8);
- i += 2;
- int tagsize = static_cast<unsigned>(
- static_cast<unsigned char>(extra.at(i)))
- | (static_cast<unsigned>(
- static_cast<unsigned char>(extra.at(i + 1)))
- << 8);
- i += 2;
- if (tag == QUAZIP_EXTRA_NTFS_TIME_MAGIC
- && tagsize >= position + 8) {
- i += position;
- quint64 mtime = static_cast<quint64>(
- static_cast<unsigned char>(extra.at(i)))
- | (static_cast<quint64>(static_cast<unsigned char>(
- extra.at(i + 1))) << 8)
- | (static_cast<quint64>(static_cast<unsigned char>(
- extra.at(i + 2))) << 16)
- | (static_cast<quint64>(static_cast<unsigned char>(
- extra.at(i + 3))) << 24)
- | (static_cast<quint64>(static_cast<unsigned char>(
- extra.at(i + 4))) << 32)
- | (static_cast<quint64>(static_cast<unsigned char>(
- extra.at(i + 5))) << 40)
- | (static_cast<quint64>(static_cast<unsigned char>(
- extra.at(i + 6))) << 48)
- | (static_cast<quint64>(static_cast<unsigned char>(
- extra.at(i + 7))) << 56);
- // the NTFS time is measured from 1601 for whatever reason
- QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
- dateTime = base.addMSecs(mtime / 10000);
- if (fineTicks != NULL) {
- *fineTicks = static_cast<int>(mtime % 10000);
- }
- i += tagsize - position;
- } else {
- i += tagsize;
- }
-
- }
- } else {
- i += length;
- }
- }
- if (fineTicks != NULL && dateTime.isNull()) {
- *fineTicks = 0;
+ QuaExtraFieldHash extraHash = QuaZipFileInfo64::parseExtraField(extra);
+ QList<QByteArray> ntfsExtraFields = extraHash[QUAZIP_EXTRA_NTFS_MAGIC];
+ if (ntfsExtraFields.isEmpty())
+ return dateTime;
+ QByteArray ntfsExtraField = ntfsExtraFields.at(0);
+ if (ntfsExtraField.length() <= 4)
+ return dateTime;
+ QByteArray ntfsAttributes = ntfsExtraField.mid(4);
+ QuaExtraFieldHash ntfsHash = QuaZipFileInfo64::parseExtraField(ntfsAttributes);
+ QList<QByteArray> ntfsTimeAttributes = ntfsHash[QUAZIP_EXTRA_NTFS_TIME_MAGIC];
+ if (ntfsTimeAttributes.isEmpty())
+ return dateTime;
+ QByteArray ntfsTimes = ntfsTimeAttributes.at(0);
+ if (ntfsTimes.size() < 24)
+ return dateTime;
+ QDataStream timeReader(ntfsTimes);
+ timeReader.setByteOrder(QDataStream::LittleEndian);
+ timeReader.device()->seek(position);
+ quint64 time;
+ timeReader >> time;
+ QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
+ dateTime = base.addMSecs(time / 10000);
+ if (fineTicks != NULL) {
+ *fineTicks = static_cast<int>(time % 10000);
}
return dateTime;
}
@@ -174,3 +137,60 @@ QDateTime QuaZipFileInfo64::getNTFScTime(int *fineTicks) const
{
return getNTFSTime(extra, 16, fineTicks);
}
+
+QDateTime QuaZipFileInfo64::getExtTime(const QByteArray &extra, int flag)
+{
+ QDateTime dateTime;
+ QuaExtraFieldHash extraHash = QuaZipFileInfo64::parseExtraField(extra);
+ QList<QByteArray> extTimeFields = extraHash[QUAZIP_EXTRA_EXT_TIME_MAGIC];
+ if (extTimeFields.isEmpty())
+ return dateTime;
+ QByteArray extTimeField = extTimeFields.at(0);
+ if (extTimeField.length() < 1)
+ return dateTime;
+ QDataStream input(extTimeField);
+ input.setByteOrder(QDataStream::LittleEndian);
+ quint8 flags;
+ input >> flags;
+ int flagsRemaining = flags;
+ while (!input.atEnd()) {
+ int nextFlag = flagsRemaining & -flagsRemaining;
+ flagsRemaining &= flagsRemaining - 1;
+ qint32 time;
+ input >> time;
+ if (nextFlag == flag) {
+ QDateTime base(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC);
+ dateTime = base.addSecs(time);
+ return dateTime;
+ }
+ }
+ return dateTime;
+}
+
+QDateTime QuaZipFileInfo64::getExtModTime() const
+{
+ return getExtTime(extra, 1);
+}
+
+QuaExtraFieldHash QuaZipFileInfo64::parseExtraField(const QByteArray &extraField)
+{
+ QDataStream input(extraField);
+ input.setByteOrder(QDataStream::LittleEndian);
+ QHash<quint16, QList<QByteArray> > result;
+ while (!input.atEnd()) {
+ quint16 id, size;
+ input >> id;
+ if (input.status() == QDataStream::ReadPastEnd)
+ return result;
+ input >> size;
+ if (input.status() == QDataStream::ReadPastEnd)
+ return result;
+ QByteArray data;
+ data.resize(size);
+ int read = input.readRawData(data.data(), data.size());
+ if (read < data.size())
+ return result;
+ result[id] << data;
+ }
+ return result;
+}