summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qresource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qresource.cpp')
-rw-r--r--src/corelib/io/qresource.cpp150
1 files changed, 56 insertions, 94 deletions
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index af0b9429af..b76d2b6478 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Copyright (C) 2020 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// Copyright (C) 2020 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qresource.h"
#include "qresource_p.h"
@@ -69,7 +33,7 @@
# include <zstd.h>
#endif
-#if defined(Q_OS_UNIX) && !defined(Q_OS_NACL) && !defined(Q_OS_INTEGRITY)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
# define QT_USE_MMAP
# include <sys/mman.h>
#endif
@@ -78,6 +42,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
// Symbols used by code generated by RCC.
// They cause compilation errors if the RCC content couldn't
// be interpreted by this QtCore version.
@@ -116,7 +82,7 @@ public:
inline QStringView next()
{
- int start = m_pos;
+ const qsizetype start = m_pos;
while (m_pos < m_len && m_data[m_pos] != m_splitChar)
++m_pos;
return QStringView(m_data + start, m_pos - start);
@@ -125,7 +91,7 @@ public:
const QChar *m_data;
qsizetype m_len;
qsizetype m_pos = 0;
- QChar m_splitChar = QLatin1Char('/');
+ QChar m_splitChar = u'/';
};
// resource glue
@@ -189,7 +155,7 @@ static QString cleanPath(const QString &_path)
QString path = QDir::cleanPath(_path);
// QDir::cleanPath does not remove two trailing slashes under _Windows_
// due to support for UNC paths. Remove those manually.
- if (path.startsWith(QLatin1String("//")))
+ if (path.startsWith("//"_L1))
path.remove(0, 1);
return path;
}
@@ -201,7 +167,6 @@ struct QResourceGlobalData
{
QRecursiveMutex resourceMutex;
ResourceList resourceList;
- QStringList resourceSearchPaths;
};
Q_GLOBAL_STATIC(QResourceGlobalData, resourceGlobalData)
@@ -211,9 +176,6 @@ static inline QRecursiveMutex &resourceMutex()
static inline ResourceList *resourceList()
{ return &resourceGlobalData->resourceList; }
-static inline QStringList *resourceSearchPaths()
-{ return &resourceGlobalData->resourceSearchPaths; }
-
/*!
\class QResource
\inmodule QtCore
@@ -271,6 +233,19 @@ static inline QStringList *resourceSearchPaths()
itself will be unmapped from memory when the last QResource that points
to it is destroyed.
+ \section2 Corruption and Security
+
+ The QResource class performs some checks on the file passed to determine
+ whether it is supported by the current version of Qt. Those tests are only
+ to check the file header does not request features (such as Zstandard
+ decompression) that have not been compiled in or that the file is not of a
+ future version of Qt. They do not confirm the validity of the entire file.
+
+ QResource should not be used on files whose provenance cannot be trusted.
+ Applications should be designed to attempt to load only resource files
+ whose provenance is at least as trustworthy as that of the application
+ itself or its plugins.
+
\sa {The Qt Resource System}, QFile, QDir, QFileInfo
*/
@@ -381,29 +356,23 @@ void QResourcePrivate::ensureInitialized() const
if (!related.isEmpty())
return;
QResourcePrivate *that = const_cast<QResourcePrivate *>(this);
- if (fileName == QLatin1String(":"))
- that->fileName += QLatin1Char('/');
+ if (fileName == ":"_L1)
+ that->fileName += u'/';
that->absoluteFilePath = fileName;
- if (!that->absoluteFilePath.startsWith(QLatin1Char(':')))
- that->absoluteFilePath.prepend(QLatin1Char(':'));
+ if (!that->absoluteFilePath.startsWith(u':'))
+ that->absoluteFilePath.prepend(u':');
QStringView path(fileName);
- if (path.startsWith(QLatin1Char(':')))
+ if (path.startsWith(u':'))
path = path.mid(1);
- if (path.startsWith(QLatin1Char('/'))) {
+ if (path.startsWith(u'/')) {
that->load(path.toString());
} else {
- const auto locker = qt_scoped_lock(resourceMutex());
- QStringList searchPaths = *resourceSearchPaths();
- searchPaths << QLatin1String("");
- for (int i = 0; i < searchPaths.size(); ++i) {
- const QString searchPath(searchPaths.at(i) + QLatin1Char('/') + path);
- if (that->load(searchPath)) {
- that->absoluteFilePath = QLatin1Char(':') + searchPath;
- break;
- }
- }
+ // Should we search QDir::searchPath() before falling back to root ?
+ const QString searchPath(u'/' + path);
+ if (that->load(searchPath))
+ that->absoluteFilePath = u':' + searchPath;
}
}
@@ -414,7 +383,7 @@ void QResourcePrivate::ensureChildren() const
return;
QString path = absoluteFilePath, k;
- if (path.startsWith(QLatin1Char(':')))
+ if (path.startsWith(u':'))
path = path.mid(1);
QDuplicateTracker<QString> kids(related.size());
QString cleaned = cleanPath(path);
@@ -797,7 +766,7 @@ inline QString QResourceRoot::name(int node) const
ret.resize(name_length);
QChar *strData = ret.data();
- qFromBigEndian<ushort>(names + name_offset, name_length, strData);
+ qFromBigEndian<char16_t>(names + name_offset, name_length, strData);
return ret;
}
@@ -808,14 +777,14 @@ int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const
QString root = mappingRoot();
if (!root.isEmpty()) {
if (root == path) {
- path = QLatin1Char('/');
+ path = u'/';
} else {
- if (!root.endsWith(QLatin1Char('/')))
- root += QLatin1Char('/');
+ if (!root.endsWith(u'/'))
+ root += u'/';
if (path.size() >= root.size() && path.startsWith(root))
- path = path.mid(root.length() - 1);
+ path = path.mid(root.size() - 1);
if (path.isEmpty())
- path = QLatin1Char('/');
+ path = u'/';
}
}
}
@@ -823,7 +792,7 @@ int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const
qDebug() << "!!!!" << "START" << path << locale.territory() << locale.language();
#endif
- if (path == QLatin1String("/"))
+ if (path == "/"_L1)
return 0;
// the root node is always first
@@ -1228,7 +1197,7 @@ bool QDynamicFileResourceRoot::registerSelf(const QString &f)
static QString qt_resource_fixResourceRoot(QString r)
{
if (!r.isEmpty()) {
- if (r.startsWith(QLatin1Char(':')))
+ if (r.startsWith(u':'))
r = r.mid(1);
if (!r.isEmpty())
r = QDir::cleanPath(r);
@@ -1249,7 +1218,7 @@ static QString qt_resource_fixResourceRoot(QString r)
bool QResource::registerResource(const QString &rccFilename, const QString &resourceRoot)
{
QString r = qt_resource_fixResourceRoot(resourceRoot);
- if (!r.isEmpty() && r[0] != QLatin1Char('/')) {
+ if (!r.isEmpty() && r[0] != u'/') {
qWarning("QDir::registerResource: Registering a resource [%ls] must be rooted in an "
"absolute path (start with /) [%ls]",
qUtf16Printable(rccFilename), qUtf16Printable(resourceRoot));
@@ -1318,7 +1287,7 @@ bool QResource::unregisterResource(const QString &rccFilename, const QString &re
bool QResource::registerResource(const uchar *rccData, const QString &resourceRoot)
{
QString r = qt_resource_fixResourceRoot(resourceRoot);
- if (!r.isEmpty() && r[0] != QLatin1Char('/')) {
+ if (!r.isEmpty() && r[0] != u'/') {
qWarning("QDir::registerResource: Registering a resource [%p] must be rooted in an "
"absolute path (start with /) [%ls]",
rccData, qUtf16Printable(resourceRoot));
@@ -1512,7 +1481,7 @@ QAbstractFileEngine::FileFlags QResourceFileEngine::fileFlags(QAbstractFileEngin
}
if (type & FlagsMask) {
ret |= ExistsFlag;
- if (d->resource.absoluteFilePath() == QLatin1String(":/"))
+ if (d->resource.absoluteFilePath() == ":/"_L1)
ret |= RootFlag;
}
return ret;
@@ -1522,24 +1491,24 @@ QString QResourceFileEngine::fileName(FileName file) const
{
Q_D(const QResourceFileEngine);
if (file == BaseName) {
- int slash = d->resource.fileName().lastIndexOf(QLatin1Char('/'));
+ const qsizetype slash = d->resource.fileName().lastIndexOf(u'/');
if (slash == -1)
return d->resource.fileName();
return d->resource.fileName().mid(slash + 1);
} else if (file == PathName || file == AbsolutePathName) {
const QString path = (file == AbsolutePathName) ? d->resource.absoluteFilePath()
: d->resource.fileName();
- const int slash = path.lastIndexOf(QLatin1Char('/'));
+ const qsizetype slash = path.lastIndexOf(u'/');
if (slash == -1)
- return QLatin1String(":");
+ return ":"_L1;
else if (slash <= 1)
- return QLatin1String(":/");
+ return ":/"_L1;
return path.left(slash);
} else if (file == CanonicalName || file == CanonicalPathName) {
const QString absoluteFilePath = d->resource.absoluteFilePath();
if (file == CanonicalPathName) {
- const int slash = absoluteFilePath.lastIndexOf(QLatin1Char('/'));
+ const qsizetype slash = absoluteFilePath.lastIndexOf(u'/');
if (slash != -1)
return absoluteFilePath.left(slash);
}
@@ -1554,10 +1523,10 @@ uint QResourceFileEngine::ownerId(FileOwner) const
return nobodyID;
}
-QDateTime QResourceFileEngine::fileTime(FileTime time) const
+QDateTime QResourceFileEngine::fileTime(QFile::FileTime time) const
{
Q_D(const QResourceFileEngine);
- if (time == ModificationTime)
+ if (time == QFile::FileModificationTime)
return d->resource.lastModified();
return QDateTime();
}
@@ -1565,18 +1534,11 @@ QDateTime QResourceFileEngine::fileTime(FileTime time) const
/*!
\internal
*/
-QAbstractFileEngine::Iterator *QResourceFileEngine::beginEntryList(QDir::Filters filters,
- const QStringList &filterNames)
-{
- return new QResourceFileEngineIterator(filters, filterNames);
-}
-
-/*!
- \internal
-*/
-QAbstractFileEngine::Iterator *QResourceFileEngine::endEntryList()
+QAbstractFileEngine::IteratorUniquePtr
+QResourceFileEngine::beginEntryList(const QString &path, QDir::Filters filters,
+ const QStringList &filterNames)
{
- return nullptr;
+ return std::make_unique<QResourceFileEngineIterator>(path, filters, filterNames);
}
bool QResourceFileEngine::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output)
@@ -1608,7 +1570,7 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory
qint64 max = resource.uncompressedSize();
qint64 end;
if (offset < 0 || size <= 0 || !resource.isValid() ||
- add_overflow(offset, size, &end) || end > max) {
+ qAddOverflow(offset, size, &end) || end > max) {
q->setError(QFile::UnspecifiedError, QString());
return nullptr;
}