diff options
Diffstat (limited to 'src/corelib/io')
28 files changed, 315 insertions, 227 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 62dae3577c..fae935fc24 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -153,7 +153,7 @@ QDirPrivate::QDirPrivate(const QDirPrivate ©) bool QDirPrivate::exists() const { - if (fileEngine.isNull()) { + if (!fileEngine) { QFileSystemEngine::fillMetaData(dirEntry, metaData, QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); // always stat return metaData.exists() && metaData.isDirectory(); @@ -226,7 +226,7 @@ inline void QDirPrivate::resolveAbsoluteEntry() const return; QString absoluteName; - if (fileEngine.isNull()) { + if (!fileEngine) { if (!dirEntry.isRelative() && dirEntry.isClean()) { absoluteDirEntry = dirEntry; return; @@ -693,7 +693,7 @@ QString QDir::absolutePath() const QString QDir::canonicalPath() const { const QDirPrivate* d = d_ptr.constData(); - if (d->fileEngine.isNull()) { + if (!d->fileEngine) { QFileSystemEntry answer = QFileSystemEngine::canonicalName(d->dirEntry, d->metaData); return answer.filePath(); } @@ -947,6 +947,12 @@ QString QDir::fromNativeSeparators(const QString &pathName) int i = pathName.indexOf(QLatin1Char('\\')); if (i != -1) { QString n(pathName); + if (n.startsWith(QLatin1String("\\\\?\\"))) { + n.remove(0, 4); + i = n.indexOf(QLatin1Char('\\')); + if (i == -1) + return n; + } QChar * const data = n.data(); data[i++] = QLatin1Char('/'); @@ -1496,7 +1502,7 @@ bool QDir::mkdir(const QString &dirName) const } QString fn = filePath(dirName); - if (d->fileEngine.isNull()) + if (!d->fileEngine) return QFileSystemEngine::createDirectory(QFileSystemEntry(fn), false); return d->fileEngine->mkdir(fn, false); } @@ -1520,7 +1526,7 @@ bool QDir::rmdir(const QString &dirName) const } QString fn = filePath(dirName); - if (d->fileEngine.isNull()) + if (!d->fileEngine) return QFileSystemEngine::removeDirectory(QFileSystemEntry(fn), false); return d->fileEngine->rmdir(fn, false); @@ -1548,7 +1554,7 @@ bool QDir::mkpath(const QString &dirPath) const } QString fn = filePath(dirPath); - if (d->fileEngine.isNull()) + if (!d->fileEngine) return QFileSystemEngine::createDirectory(QFileSystemEntry(fn), true); return d->fileEngine->mkdir(fn, true); } @@ -1574,7 +1580,7 @@ bool QDir::rmpath(const QString &dirPath) const } QString fn = filePath(dirPath); - if (d->fileEngine.isNull()) + if (!d->fileEngine) return QFileSystemEngine::removeDirectory(QFileSystemEntry(fn), true); return d->fileEngine->rmdir(fn, true); } @@ -1647,7 +1653,7 @@ bool QDir::isReadable() const { const QDirPrivate* d = d_ptr.constData(); - if (d->fileEngine.isNull()) { + if (!d->fileEngine) { if (!d->metaData.hasFlags(QFileSystemMetaData::UserReadPermission)) QFileSystemEngine::fillMetaData(d->dirEntry, d->metaData, QFileSystemMetaData::UserReadPermission); @@ -1692,7 +1698,7 @@ bool QDir::exists() const */ bool QDir::isRoot() const { - if (d_ptr->fileEngine.isNull()) + if (!d_ptr->fileEngine) return d_ptr->dirEntry.isRoot(); return d_ptr->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag; } @@ -1724,7 +1730,7 @@ bool QDir::isRoot() const */ bool QDir::isRelative() const { - if (d_ptr->fileEngine.isNull()) + if (!d_ptr->fileEngine) return d_ptr->dirEntry.isRelative(); return d_ptr->fileEngine->isRelativePath(); } @@ -1741,7 +1747,7 @@ bool QDir::makeAbsolute() { const QDirPrivate *d = d_ptr.constData(); QScopedPointer<QDirPrivate> dir; - if (!d->fileEngine.isNull()) { + if (!!d->fileEngine) { QString absolutePath = d->fileEngine->fileName(QAbstractFileEngine::AbsoluteName); if (QDir::isRelativePath(absolutePath)) return false; @@ -1774,8 +1780,8 @@ bool QDir::operator==(const QDir &dir) const if (d == other) return true; Qt::CaseSensitivity sensitive; - if (d->fileEngine.isNull() || other->fileEngine.isNull()) { - if (d->fileEngine.data() != other->fileEngine.data()) // one is native, the other is a custom file-engine + if (!d->fileEngine || !other->fileEngine) { + if (d->fileEngine.get() != other->fileEngine.get()) // one is native, the other is a custom file-engine return false; sensitive = QFileSystemEngine::isCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive; @@ -2339,6 +2345,11 @@ static QString qt_cleanPath(const QString &path, bool *ok) if (path.isEmpty()) return path; QString name = path; +#if defined (Q_OS_WIN) + if (name.startsWith(QLatin1String("\\\\?\\"))) + name.remove(0, 4); +#endif + QChar dir_separator = QDir::separator(); if (dir_separator != QLatin1Char('/')) name.replace(dir_separator, QLatin1Char('/')); diff --git a/src/corelib/io/qdir_p.h b/src/corelib/io/qdir_p.h index 0f3ab7f899..af105de8db 100644 --- a/src/corelib/io/qdir_p.h +++ b/src/corelib/io/qdir_p.h @@ -54,6 +54,8 @@ #include "qfilesystementry_p.h" #include "qfilesystemmetadata_p.h" +#include <memory> + QT_BEGIN_NAMESPACE class QDirPrivate : public QSharedData @@ -82,7 +84,7 @@ public: static inline QChar getFilterSepChar(const QString &nameFilter); - static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0); + static inline QStringList splitFilters(const QString &nameFilter, QChar sep = {}); void setPath(const QString &path); @@ -98,7 +100,7 @@ public: QDir::SortFlags sort; QDir::Filters filters; - QScopedPointer<QAbstractFileEngine> fileEngine; + std::unique_ptr<QAbstractFileEngine> fileEngine; QFileSystemEntry dirEntry; mutable QFileSystemEntry absoluteDirEntry; diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 303caf29a4..ce436b06e3 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -107,6 +107,8 @@ #include <QtCore/private/qfilesystemengine_p.h> #include <QtCore/private/qfileinfo_p.h> +#include <memory> + QT_BEGIN_NAMESPACE template <class Iterator> @@ -132,7 +134,7 @@ public: void checkAndPushDirectory(const QFileInfo &); bool matchesFilters(const QString &fileName, const QFileInfo &fi) const; - QScopedPointer<QAbstractFileEngine> engine; + std::unique_ptr<QAbstractFileEngine> engine; QFileSystemEntry dirEntry; const QStringList nameFilters; @@ -435,7 +437,7 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags) { const QDirPrivate *other = dir.d_ptr.constData(); - d.reset(new QDirIteratorPrivate(other->dirEntry, other->nameFilters, other->filters, flags, !other->fileEngine.isNull())); + d.reset(new QDirIteratorPrivate(other->dirEntry, other->nameFilters, other->filters, flags, bool(other->fileEngine))); } /*! diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 9f9a9e3040..95f03ef816 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -55,6 +55,8 @@ # include "qcoreapplication.h" #endif +#include <private/qmemory_p.h> + #ifdef QT_NO_QOBJECT #define tr(X) QString::fromLatin1(X) #endif @@ -85,10 +87,9 @@ QFilePrivate::openExternalFile(int flags, int fd, QFile::FileHandleFlags handleF Q_UNUSED(fd); return false; #else - delete fileEngine; - fileEngine = nullptr; - QFSFileEngine *fe = new QFSFileEngine; - fileEngine = fe; + auto fs = qt_make_unique<QFSFileEngine>(); + auto fe = fs.get(); + fileEngine = std::move(fs); return fe->open(QIODevice::OpenMode(flags), fd, handleFlags); #endif } @@ -101,10 +102,9 @@ QFilePrivate::openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handl Q_UNUSED(fh); return false; #else - delete fileEngine; - fileEngine = nullptr; - QFSFileEngine *fe = new QFSFileEngine; - fileEngine = fe; + auto fs = qt_make_unique<QFSFileEngine>(); + auto fe = fs.get(); + fileEngine = std::move(fs); return fe->open(QIODevice::OpenMode(flags), fh, handleFlags); #endif } @@ -112,8 +112,8 @@ QFilePrivate::openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handl QAbstractFileEngine *QFilePrivate::engine() const { if (!fileEngine) - fileEngine = QAbstractFileEngine::create(fileName); - return fileEngine; + fileEngine.reset(QAbstractFileEngine::create(fileName)); + return fileEngine.get(); } //************* QFile @@ -334,10 +334,7 @@ QFile::setFileName(const QString &name) file_already_open(*this, "setFileName"); close(); } - if(d->fileEngine) { //get a new file engine later - delete d->fileEngine; - d->fileEngine = nullptr; - } + d->fileEngine.reset(); //get a new file engine later d->fileName = name; } diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp index 2f74547054..ee619d99cc 100644 --- a/src/corelib/io/qfiledevice.cpp +++ b/src/corelib/io/qfiledevice.cpp @@ -42,6 +42,8 @@ #include "qfiledevice_p.h" #include "qfsfileengine_p.h" +#include <private/qmemory_p.h> + #ifdef QT_NO_QOBJECT #define tr(X) QString::fromLatin1(X) #endif @@ -53,24 +55,20 @@ QT_BEGIN_NAMESPACE #endif QFileDevicePrivate::QFileDevicePrivate() - : fileEngine(nullptr), - cachedSize(0), + : cachedSize(0), error(QFile::NoError), lastWasWrite(false) { writeBufferChunkSize = QFILE_WRITEBUFFER_SIZE; } QFileDevicePrivate::~QFileDevicePrivate() -{ - delete fileEngine; - fileEngine = nullptr; -} + = default; QAbstractFileEngine * QFileDevicePrivate::engine() const { if (!fileEngine) - fileEngine = new QFSFileEngine; - return fileEngine; + fileEngine = qt_make_unique<QFSFileEngine>(); + return fileEngine.get(); } void QFileDevicePrivate::setError(QFileDevice::FileError err) diff --git a/src/corelib/io/qfiledevice_p.h b/src/corelib/io/qfiledevice_p.h index 47053d01b7..aef3fca811 100644 --- a/src/corelib/io/qfiledevice_p.h +++ b/src/corelib/io/qfiledevice_p.h @@ -53,6 +53,8 @@ #include "private/qiodevice_p.h" +#include <memory> + QT_BEGIN_NAMESPACE class QAbstractFileEngine; @@ -75,7 +77,7 @@ protected: void setError(QFileDevice::FileError err, const QString &errorString); void setError(QFileDevice::FileError err, int errNum); - mutable QAbstractFileEngine *fileEngine; + mutable std::unique_ptr<QAbstractFileEngine> fileEngine; mutable qint64 cachedSize; QFileDevice::FileHandleFlags handleFlags; diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index f5b398feae..a5a3bc8b3e 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -707,11 +707,11 @@ bool QFileInfo::exists(const QString &file) return false; QFileSystemEntry entry(file); QFileSystemMetaData data; - QAbstractFileEngine *engine = - QFileSystemEngine::resolveEntryAndCreateLegacyEngine(entry, data); + std::unique_ptr<QAbstractFileEngine> engine + {QFileSystemEngine::resolveEntryAndCreateLegacyEngine(entry, data)}; // Expensive fallback to non-QFileSystemEngine implementation if (engine) - return QFileInfo(new QFileInfoPrivate(entry, data, engine)).exists(); + return QFileInfo(new QFileInfoPrivate(entry, data, std::move(engine))).exists(); QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute); return data.exists(); diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index 36f440812f..333ea70adc 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -61,6 +61,8 @@ #include <QtCore/private/qfilesystementry_p.h> #include <QtCore/private/qfilesystemmetadata_p.h> +#include <memory> + QT_BEGIN_NAMESPACE class QFileInfoPrivate : public QSharedData @@ -126,10 +128,10 @@ public: metaData = QFileSystemMetaData(); } - inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, QAbstractFileEngine *engine) + inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, std::unique_ptr<QAbstractFileEngine> engine) : fileEntry(file), metaData(data), - fileEngine(engine), + fileEngine{std::move(engine)}, cachedFlags(0), #ifndef QT_NO_FSFILEENGINE isDefaultConstructed(false), @@ -163,7 +165,7 @@ public: QFileSystemEntry fileEntry; mutable QFileSystemMetaData metaData; - QScopedPointer<QAbstractFileEngine> const fileEngine; + std::unique_ptr<QAbstractFileEngine> const fileEngine; mutable QString fileNames[QAbstractFileEngine::NFileNames]; mutable QString fileOwners[2]; // QAbstractFileEngine::FileOwner: OwnerUser and OwnerGroup diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 066a7c3f01..74865fe31f 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -822,6 +822,8 @@ QString QFileSystemEngine::resolveUserName(uint userId) #endif if (pw) return QFile::decodeName(QByteArray(pw->pw_name)); +#else // Integrity || WASM + Q_UNUSED(userId); #endif return QString(); } @@ -859,6 +861,8 @@ QString QFileSystemEngine::resolveGroupName(uint groupId) #endif if (gr) return QFile::decodeName(QByteArray(gr->gr_name)); +#else // Integrity || WASM + Q_UNUSED(groupId); #endif return QString(); } diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp index 5ac7e13a2e..2d09c277eb 100644 --- a/src/corelib/io/qfilesystemiterator_unix.cpp +++ b/src/corelib/io/qfilesystemiterator_unix.cpp @@ -40,13 +40,54 @@ #include "qplatformdefs.h" #include "qfilesystemiterator_p.h" +#if QT_CONFIG(textcodec) +# include <qtextcodec.h> +# include <private/qutfcodec_p.h> +#endif + #ifndef QT_NO_FILESYSTEMITERATOR +#include <memory> + #include <stdlib.h> #include <errno.h> QT_BEGIN_NAMESPACE +static bool checkNameDecodable(const char *d_name, qsizetype len) +{ + // This function is called in a loop from advance() below, but the loop is + // usually run only once. + +#if QT_CONFIG(textcodec) + // We identify the codecs by their RFC 2978 MIBenum values. In this + // function: + // 3 US-ASCII (ANSI X3.4-1986) + // 4 Latin1 (ISO-8859-1) + // 106 UTF-8 + QTextCodec *codec = QTextCodec::codecForLocale(); +# ifdef QT_LOCALE_IS_UTF8 + int mibEnum = 106; +# else + int mibEnum = codec->mibEnum(); +# endif + if (Q_LIKELY(mibEnum == 106)) // UTF-8 + return QUtf8::isValidUtf8(d_name, len).isValidUtf8; + if (mibEnum == 3) // US-ASCII + return QtPrivate::isAscii(QLatin1String(d_name, len)); + if (mibEnum == 4) // Latin 1 + return true; + + // fall back to generic QTextCodec + QTextCodec::ConverterState cs(QTextCodec::IgnoreHeader); + codec->toUnicode(d_name, len, &cs); + return cs.invalidChars == 0 && cs.remainingChars == 0; +#else + // if we have no text codecs, then QString::fromLocal8Bit is fromLatin1 + return true; +#endif +} + QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters, QDirIterator::IteratorFlags flags) : nativePath(entry.nativeFilePath()) @@ -81,9 +122,9 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa dirEntry = QT_READDIR(dir); if (dirEntry) { - // process entries with correct UTF-8 names only - if (QFile::encodeName(QFile::decodeName(dirEntry->d_name)) == dirEntry->d_name) { - fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name), QFileSystemEntry::FromNativePath()); + qsizetype len = strlen(dirEntry->d_name); + if (checkNameDecodable(dirEntry->d_name, len)) { + fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name, len), QFileSystemEntry::FromNativePath()); metaData.fillFromDirEnt(*dirEntry); return true; } diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp index 5fb5685f42..ca1f6cc359 100644 --- a/src/corelib/io/qfilesystemwatcher_inotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp @@ -422,16 +422,27 @@ void QInotifyFileSystemWatcherEngine::readFromInotify() } } -QString QInotifyFileSystemWatcherEngine::getPathFromID(int id) const +template <typename Hash, typename Key> +typename Hash::const_iterator +find_last_in_equal_range(const Hash &c, const Key &key) { - QHash<int, QString>::const_iterator i = idToPath.find(id); - while (i != idToPath.constEnd() && i.key() == id) { - if ((i + 1) == idToPath.constEnd() || (i + 1).key() != id) { - return i.value(); - } + // find c.equal_range(key).second - 1 without backwards iteration: + auto i = c.find(key); + const auto end = c.cend(); + if (i == end) + return end; + decltype(i) prev; + do { + prev = i; ++i; - } - return QString(); + } while (i != end && i.key() == key); + return prev; +} + +QString QInotifyFileSystemWatcherEngine::getPathFromID(int id) const +{ + auto i = find_last_in_equal_range(idToPath, id); + return i == idToPath.cend() ? QString() : i.value() ; } QT_END_NAMESPACE diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 0db27f3e25..0d73839f8d 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -167,19 +167,21 @@ QFSFileEngine::QFSFileEngine(QFSFileEnginePrivate &dd) /*! \internal */ -bool QFSFileEngine::processOpenModeFlags(QIODevice::OpenMode *mode) +ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode openMode) { - QIODevice::OpenMode &openMode = *mode; + ProcessOpenModeResult result; + result.ok = false; if ((openMode & QFile::NewOnly) && (openMode & QFile::ExistingOnly)) { qWarning("NewOnly and ExistingOnly are mutually exclusive"); - setError(QFile::OpenError, QLatin1String("NewOnly and ExistingOnly are mutually exclusive")); - return false; + result.error = QLatin1String("NewOnly and ExistingOnly are mutually exclusive"); + return result; } if ((openMode & QFile::ExistingOnly) && !(openMode & (QFile::ReadOnly | QFile::WriteOnly))) { qWarning("ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite"); - setError(QFile::OpenError, QLatin1String("ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite")); - return false; + result.error = QLatin1String( + "ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite"); + return result; } // Either Append or NewOnly implies WriteOnly @@ -190,7 +192,9 @@ bool QFSFileEngine::processOpenModeFlags(QIODevice::OpenMode *mode) if ((openMode & QFile::WriteOnly) && !(openMode & (QFile::ReadOnly | QFile::Append | QFile::NewOnly))) openMode |= QFile::Truncate; - return true; + result.ok = true; + result.openMode = openMode; + return result; } /*! @@ -234,16 +238,19 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode) return false; } - if (!processOpenModeFlags(&openMode)) + const ProcessOpenModeResult res = processOpenModeFlags(openMode); + if (!res.ok) { + setError(QFileDevice::OpenError, res.error); return false; + } - d->openMode = openMode; + d->openMode = res.openMode; d->lastFlushFailed = false; d->tried_stat = 0; d->fh = nullptr; d->fd = -1; - return d->nativeOpen(openMode); + return d->nativeOpen(d->openMode); } /*! @@ -262,17 +269,20 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, FILE *fh, QFile::FileHand Q_D(QFSFileEngine); - if (!processOpenModeFlags(&openMode)) + const ProcessOpenModeResult res = processOpenModeFlags(openMode); + if (!res.ok) { + setError(QFileDevice::OpenError, res.error); return false; + } - d->openMode = openMode; + d->openMode = res.openMode; d->lastFlushFailed = false; d->closeFileHandle = (handleFlags & QFile::AutoCloseHandle); d->fileEntry.clear(); d->tried_stat = 0; d->fd = -1; - return d->openFh(openMode, fh); + return d->openFh(d->openMode, fh); } /*! @@ -321,10 +331,13 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd, QFile::FileHandle { Q_D(QFSFileEngine); - if (!processOpenModeFlags(&openMode)) + const ProcessOpenModeResult res = processOpenModeFlags(openMode); + if (!res.ok) { + setError(QFileDevice::OpenError, res.error); return false; + } - d->openMode = openMode; + d->openMode = res.openMode; d->lastFlushFailed = false; d->closeFileHandle = (handleFlags & QFile::AutoCloseHandle); d->fileEntry.clear(); @@ -332,7 +345,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd, QFile::FileHandle d->fd = -1; d->tried_stat = 0; - return d->openFd(openMode, fd); + return d->openFd(d->openMode, fd); } diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 0f416f4886..639c01571a 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -61,6 +61,13 @@ QT_BEGIN_NAMESPACE +struct ProcessOpenModeResult { + bool ok; + QIODevice::OpenMode openMode; + QString error; +}; +Q_CORE_EXPORT ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode mode); + class QFSFileEnginePrivate; class Q_CORE_EXPORT QFSFileEngine : public QAbstractFileEngine @@ -131,9 +138,6 @@ public: protected: QFSFileEngine(QFSFileEnginePrivate &dd); - -private: - inline bool processOpenModeFlags(QIODevice::OpenMode *mode); }; class Q_AUTOTEST_EXPORT QFSFileEnginePrivate : public QAbstractFileEnginePrivate diff --git a/src/corelib/io/qipaddress.cpp b/src/corelib/io/qipaddress.cpp index b3421fca8f..ddc5b6607f 100644 --- a/src/corelib/io/qipaddress.cpp +++ b/src/corelib/io/qipaddress.cpp @@ -312,7 +312,7 @@ void toString(QString &appendTo, const IPv6Address address) } } - const QChar colon = ushort(':'); + const QChar colon = u':'; if (zeroRunLength < 4) zeroRunOffset = -1; else if (zeroRunOffset == 0) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 0b964e6a21..35ca2542f7 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -202,6 +202,7 @@ void QProcessEnvironmentPrivate::insert(const QProcessEnvironmentPrivate &other) vars.insert(it.key(), it.value()); #ifdef Q_OS_UNIX + const OrderedNameMapMutexLocker locker(this, &other); auto nit = other.nameMap.constBegin(); const auto nend = other.nameMap.constEnd(); for ( ; nit != nend; ++nit) @@ -275,7 +276,6 @@ bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const return true; if (d) { if (other.d) { - QProcessEnvironmentPrivate::OrderedMutexLocker locker(d, other.d); return d->vars == other.d->vars; } else { return isEmpty(); @@ -322,7 +322,6 @@ bool QProcessEnvironment::contains(const QString &name) const { if (!d) return false; - QProcessEnvironmentPrivate::MutexLocker locker(d); return d->vars.contains(d->prepareName(name)); } @@ -373,7 +372,6 @@ QString QProcessEnvironment::value(const QString &name, const QString &defaultVa if (!d) return defaultValue; - QProcessEnvironmentPrivate::MutexLocker locker(d); const auto it = d->vars.constFind(d->prepareName(name)); if (it == d->vars.constEnd()) return defaultValue; @@ -398,7 +396,6 @@ QStringList QProcessEnvironment::toStringList() const { if (!d) return QStringList(); - QProcessEnvironmentPrivate::MutexLocker locker(d); return d->toList(); } @@ -412,7 +409,6 @@ QStringList QProcessEnvironment::keys() const { if (!d) return QStringList(); - QProcessEnvironmentPrivate::MutexLocker locker(d); return d->keys(); } @@ -429,7 +425,6 @@ void QProcessEnvironment::insert(const QProcessEnvironment &e) return; // our re-impl of detach() detaches from null - QProcessEnvironmentPrivate::MutexLocker locker(e.d); d->insert(*e.d); } diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index d02e87837c..2587530c09 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -146,16 +146,22 @@ public: inline QString nameToString(const Key &name) const { return name; } inline Value prepareValue(const QString &value) const { return value; } inline QString valueToString(const Value &value) const { return value; } - struct MutexLocker { - MutexLocker(const QProcessEnvironmentPrivate *) {} +#else + struct NameMapMutexLocker : public QMutexLocker + { + NameMapMutexLocker(const QProcessEnvironmentPrivate *d) : QMutexLocker(&d->nameMapMutex) {} }; - struct OrderedMutexLocker { - OrderedMutexLocker(const QProcessEnvironmentPrivate *, - const QProcessEnvironmentPrivate *) {} + struct OrderedNameMapMutexLocker : public QOrderedMutexLocker + { + OrderedNameMapMutexLocker(const QProcessEnvironmentPrivate *d1, + const QProcessEnvironmentPrivate *d2) + : QOrderedMutexLocker(&d1->nameMapMutex, &d2->nameMapMutex) + {} }; -#else + inline Key prepareName(const QString &name) const { + const NameMapMutexLocker locker(this); Key &ent = nameMap[name]; if (ent.isEmpty()) ent = name.toLocal8Bit(); @@ -164,40 +170,27 @@ public: inline QString nameToString(const Key &name) const { const QString sname = QString::fromLocal8Bit(name); - nameMap[sname] = name; + { + const NameMapMutexLocker locker(this); + nameMap[sname] = name; + } return sname; } inline Value prepareValue(const QString &value) const { return Value(value); } inline QString valueToString(const Value &value) const { return value.string(); } - struct MutexLocker : public QMutexLocker - { - MutexLocker(const QProcessEnvironmentPrivate *d) : QMutexLocker(&d->mutex) {} - }; - struct OrderedMutexLocker : public QOrderedMutexLocker - { - OrderedMutexLocker(const QProcessEnvironmentPrivate *d1, - const QProcessEnvironmentPrivate *d2) : - QOrderedMutexLocker(&d1->mutex, &d2->mutex) - {} - }; - QProcessEnvironmentPrivate() : QSharedData() {} QProcessEnvironmentPrivate(const QProcessEnvironmentPrivate &other) : - QSharedData() + QSharedData(), vars(other.vars) { - // This being locked ensures that the functions that only assign - // d pointers don't need explicit locking. // We don't need to lock our own mutex, as this object is new and // consequently not shared. For the same reason, non-const methods // do not need a lock, as they detach objects (however, we need to // ensure that they really detach before using prepareName()). - MutexLocker locker(&other); - vars = other.vars; + NameMapMutexLocker locker(&other); nameMap = other.nameMap; - // We need to detach our members, so that our mutex can protect them. - // As we are being detached, they likely would be detached a moment later anyway. - vars.detach(); + // We need to detach our nameMap, so that our mutex can protect it. + // As we are being detached, it likely would be detached a moment later anyway. nameMap.detach(); } #endif @@ -208,8 +201,7 @@ public: #ifdef Q_OS_UNIX typedef QHash<QString, Key> NameHash; mutable NameHash nameMap; - - mutable QMutex mutex; + mutable QMutex nameMapMutex; #endif static QProcessEnvironment fromList(const QStringList &list); diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 1d5b76a8a4..951fc4ccaa 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -438,7 +438,6 @@ void QProcessPrivate::startProcess() int envc = 0; char **envp = 0; if (environment.d.constData()) { - QProcessEnvironmentPrivate::MutexLocker locker(environment.d); envp = _q_dupEnvironment(environment.d.constData()->vars, &envc); } @@ -970,7 +969,6 @@ bool QProcessPrivate::startDetached(qint64 *pid) int envc = 0; char **envp = nullptr; if (environment.d.constData()) { - QProcessEnvironmentPrivate::MutexLocker locker(environment.d); envp = _q_dupEnvironment(environment.d.constData()->vars, &envc); } diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index fcc5b69179..52b746d04a 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2018 The Qt Company Ltd. -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2019 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -279,14 +279,14 @@ static inline QStringList *resourceSearchPaths() This enum is used by compressionAlgorithm() to indicate which algorithm the RCC tool used to compress the payload. - \value NoCompression Contents are not compressed (isCompressed() is false). + \value NoCompression Contents are not compressed \value ZlibCompression Contents are compressed using \l{zlib}{https://zlib.net} and can be decompressed using the qUncompress() function. \value ZstdCompression Contents are compressed using \l{zstd}{https://zstd.net}. To decompress, use the \c{ZSTD_decompress} function from the zstd library. - \sa compressionAlgorithm(), isCompressed() + \sa compressionAlgorithm() */ class QResourcePrivate { @@ -551,13 +551,20 @@ bool QResource::isValid() const \sa isDir() */ - +#if QT_DEPRECATED_SINCE(5, 13) /*! + \obsolete + Returns \c true if the resource represents a file and the data backing it is in a compressed format, false otherwise. If the data is compressed, check compressionAlgorithm() to verify what algorithm to use to decompress the data. + \note This function is deprecated and can be replaced with + \code + compressionAlgorithm() != NoCompression + \endcode + \sa data(), compressionAlgorithm(), isFile() */ @@ -565,6 +572,7 @@ bool QResource::isCompressed() const { return compressionAlgorithm() != NoCompression; } +#endif /*! \since 5.13 @@ -582,7 +590,7 @@ bool QResource::isCompressed() const See \l{http://facebook.github.io/zstd/zstd_manual.html}{Zstandard manual}. - \sa isCompressed(), data(), isFile() + \sa data(), isFile() */ QResource::Compression QResource::compressionAlgorithm() const { @@ -606,11 +614,11 @@ qint64 QResource::size() const /*! Returns direct access to a read only segment of data that this resource - represents. If the resource is compressed the data returns is - compressed and qUncompress() must be used to access the data. If the - resource is a directory \nullptr is returned. + represents. If the resource is compressed the data returned is compressed + and the appropriate library functions must be used to access the data. If + the resource is a directory \nullptr is returned. - \sa size(), isCompressed(), isFile() + \sa size(), compressionAlgorithm(), isFile() */ const uchar *QResource::data() const @@ -940,12 +948,15 @@ bool QResourceRoot::mappingRootSubdir(const QString &path, QString *match) const Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree, const unsigned char *name, const unsigned char *data) { + if (resourceGlobalData.isDestroyed()) + return false; QMutexLocker lock(resourceMutex()); - if (version >= 0x01 && version <= 0x3 && resourceList()) { + ResourceList *list = resourceList(); + if (version >= 0x01 && version <= 0x3) { bool found = false; QResourceRoot res(version, tree, name, data); - for(int i = 0; i < resourceList()->size(); ++i) { - if(*resourceList()->at(i) == res) { + for (int i = 0; i < list->size(); ++i) { + if (*list->at(i) == res) { found = true; break; } @@ -953,7 +964,7 @@ Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree, if(!found) { QResourceRoot *root = new QResourceRoot(version, tree, name, data); root->ref.ref(); - resourceList()->append(root); + list->append(root); } return true; } @@ -967,11 +978,12 @@ Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tre return false; QMutexLocker lock(resourceMutex()); - if (version >= 0x01 && version <= 0x3 && resourceList()) { + if (version >= 0x01 && version <= 0x3) { QResourceRoot res(version, tree, name, data); - for(int i = 0; i < resourceList()->size(); ) { - if(*resourceList()->at(i) == res) { - QResourceRoot *root = resourceList()->takeAt(i); + ResourceList *list = resourceList(); + for (int i = 0; i < list->size(); ) { + if (*list->at(i) == res) { + QResourceRoot *root = list->takeAt(i); if(!root->ref.deref()) delete root; } else { @@ -1217,7 +1229,7 @@ QResource::unregisterResource(const QString &rccFilename, const QString &resourc if(res->type() == QResourceRoot::Resource_File) { QDynamicFileResourceRoot *root = reinterpret_cast<QDynamicFileResourceRoot*>(res); if (root->mappingFile() == rccFilename && root->mappingRoot() == r) { - resourceList()->removeAt(i); + list->removeAt(i); if(!root->ref.deref()) { delete root; return true; @@ -1288,7 +1300,7 @@ QResource::unregisterResource(const uchar *rccData, const QString &resourceRoot) if(res->type() == QResourceRoot::Resource_Buffer) { QDynamicBufferResourceRoot *root = reinterpret_cast<QDynamicBufferResourceRoot*>(res); if (root->mappingBuffer() == rccData && root->mappingRoot() == r) { - resourceList()->removeAt(i); + list->removeAt(i); if(!root->ref.deref()) { delete root; return true; @@ -1366,9 +1378,15 @@ bool QResourceFileEngine::open(QIODevice::OpenMode flags) qWarning("QResourceFileEngine::open: Missing file name"); return false; } - if(flags & QIODevice::WriteOnly) + if (flags & QIODevice::WriteOnly) return false; - d->uncompress(); + if (d->resource.compressionAlgorithm() != QResource::NoCompression) { + d->uncompress(); + if (d->uncompressed.isNull()) { + d->errorString = QSystemError::stdString(EIO); + return false; + } + } if (!d->resource.isValid()) { d->errorString = QSystemError::stdString(ENOENT); return false; @@ -1395,7 +1413,7 @@ qint64 QResourceFileEngine::read(char *data, qint64 len) len = size()-d->offset; if(len <= 0) return 0; - if(d->resource.isCompressed()) + if (!d->uncompressed.isNull()) memcpy(data, d->uncompressed.constData()+d->offset, len); else memcpy(data, d->resource.data()+d->offset, len); @@ -1431,9 +1449,9 @@ bool QResourceFileEngine::link(const QString &) qint64 QResourceFileEngine::size() const { Q_D(const QResourceFileEngine); - if(!d->resource.isValid()) + if (!d->resource.isValid()) return 0; - if (d->resource.isCompressed()) { + if (d->resource.compressionAlgorithm() != QResource::NoCompression) { d->uncompress(); return d->uncompressed.size(); } @@ -1596,7 +1614,7 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory Q_UNUSED(flags); qint64 max = resource.size(); - if (resource.isCompressed()) { + if (resource.compressionAlgorithm() != QResource::NoCompression) { uncompress(); max = uncompressed.size(); } @@ -1609,7 +1627,7 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory } const uchar *address = resource.data(); - if (resource.isCompressed()) + if (resource.compressionAlgorithm() != QResource::NoCompression) address = reinterpret_cast<const uchar *>(uncompressed.constData()); return const_cast<uchar *>(address) + offset; diff --git a/src/corelib/io/qresource.h b/src/corelib/io/qresource.h index 5e798de436..5ee8d5d266 100644 --- a/src/corelib/io/qresource.h +++ b/src/corelib/io/qresource.h @@ -72,7 +72,6 @@ public: bool isValid() const; - bool isCompressed() const; Compression compressionAlgorithm() const; qint64 size() const; const uchar *data() const; @@ -84,6 +83,10 @@ public: QT_DEPRECATED_X("Use QDir::searchPaths() instead") static QStringList searchPaths(); #endif +#if QT_DEPRECATED_SINCE(5, 15) + QT_DEPRECATED_VERSION_X_5_15("Use QResource::compressionAlgorithm() instead") + bool isCompressed() const; +#endif static bool registerResource(const QString &rccFilename, const QString &resourceRoot=QString()); static bool unregisterResource(const QString &rccFilename, const QString &resourceRoot=QString()); diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp index 915d0a0a00..f41e6302a2 100644 --- a/src/corelib/io/qsavefile.cpp +++ b/src/corelib/io/qsavefile.cpp @@ -150,8 +150,7 @@ QSaveFile::~QSaveFile() QFileDevice::close(); if (d->fileEngine) { d->fileEngine->remove(); - delete d->fileEngine; - d->fileEngine = nullptr; + d->fileEngine.reset(); } } @@ -197,6 +196,7 @@ bool QSaveFile::open(OpenMode mode) return false; } unsetError(); + d->writeError = QFileDevice::NoError; if ((mode & (ReadOnly | WriteOnly)) == 0) { qWarning("QSaveFile::open: Open mode not specified"); return false; @@ -234,7 +234,7 @@ bool QSaveFile::open(OpenMode mode) } auto openDirectly = [&]() { - d->fileEngine = QAbstractFileEngine::create(d->finalFileName); + d->fileEngine.reset(QAbstractFileEngine::create(d->finalFileName)); if (d->fileEngine->open(mode | QIODevice::Unbuffered)) { d->useTemporaryFile = false; QFileDevice::open(mode); @@ -251,8 +251,7 @@ bool QSaveFile::open(OpenMode mode) if (openDirectly()) return true; d->setError(d->fileEngine->error(), d->fileEngine->errorString()); - delete d->fileEngine; - d->fileEngine = nullptr; + d->fileEngine.reset(); } else { QString msg = QSaveFile::tr("QSaveFile cannot open '%1' without direct write fallback " @@ -264,18 +263,17 @@ bool QSaveFile::open(OpenMode mode) } #endif - d->fileEngine = new QTemporaryFileEngine(&d->finalFileName, QTemporaryFileEngine::Win32NonShared); + d->fileEngine.reset(new QTemporaryFileEngine(&d->finalFileName, QTemporaryFileEngine::Win32NonShared)); // if the target file exists, we'll copy its permissions below, // but until then, let's ensure the temporary file is not accessible // to a third party int perm = (existingFile.exists() ? 0600 : 0666); - static_cast<QTemporaryFileEngine *>(d->fileEngine)->initialize(d->finalFileName, perm); + static_cast<QTemporaryFileEngine *>(d->fileEngine.get())->initialize(d->finalFileName, perm); // Same as in QFile: QIODevice provides the buffering, so there's no need to request it from the file engine. if (!d->fileEngine->open(mode | QIODevice::Unbuffered)) { QFileDevice::FileError err = d->fileEngine->error(); #ifdef Q_OS_UNIX if (d->directWriteFallback && err == QFileDevice::OpenError && errno == EACCES) { - delete d->fileEngine; if (openDirectly()) return true; err = d->fileEngine->error(); @@ -284,8 +282,7 @@ bool QSaveFile::open(OpenMode mode) if (err == QFileDevice::UnspecifiedError) err = QFileDevice::OpenError; d->setError(err, d->fileEngine->errorString()); - delete d->fileEngine; - d->fileEngine = nullptr; + d->fileEngine.reset(); return false; } @@ -331,30 +328,26 @@ bool QSaveFile::commit() } QFileDevice::close(); // calls flush() + const auto fe = std::move(d->fileEngine); + // Sync to disk if possible. Ignore errors (e.g. not supported). - d->fileEngine->syncToDisk(); + fe->syncToDisk(); if (d->useTemporaryFile) { if (d->writeError != QFileDevice::NoError) { - d->fileEngine->remove(); + fe->remove(); d->writeError = QFileDevice::NoError; - delete d->fileEngine; - d->fileEngine = nullptr; return false; } // atomically replace old file with new file // Can't use QFile::rename for that, must use the file engine directly - Q_ASSERT(d->fileEngine); - if (!d->fileEngine->renameOverwrite(d->finalFileName)) { - d->setError(d->fileEngine->error(), d->fileEngine->errorString()); - d->fileEngine->remove(); - delete d->fileEngine; - d->fileEngine = nullptr; + Q_ASSERT(fe); + if (!fe->renameOverwrite(d->finalFileName)) { + d->setError(fe->error(), fe->errorString()); + fe->remove(); return false; } } - delete d->fileEngine; - d->fileEngine = nullptr; return true; } diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp index dbf650d5f6..f56fef7f8e 100644 --- a/src/corelib/io/qstandardpaths.cpp +++ b/src/corelib/io/qstandardpaths.cpp @@ -297,7 +297,7 @@ QT_BEGIN_NAMESPACE \li "<APPROOT>/tmp" \row \li HomeLocation \li "<APPROOT>/files" - \li "<APPROOT>" (not writable) + \li system defined \row \li DataLocation \li "<APPROOT>/files", "<USER>/<APPNAME>/files" \li "<APPROOT>/Library/Application Support" diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp index f4f8787968..6425890e3f 100644 --- a/src/corelib/io/qstandardpaths_unix.cpp +++ b/src/corelib/io/qstandardpaths_unix.cpp @@ -71,6 +71,28 @@ static void appendOrganizationAndApp(QString &path) #endif } +#if QT_CONFIG(regularexpression) +static QLatin1String xdg_key_name(QStandardPaths::StandardLocation type) +{ + switch (type) { + case QStandardPaths::DesktopLocation: + return QLatin1String("DESKTOP"); + case QStandardPaths::DocumentsLocation: + return QLatin1String("DOCUMENTS"); + case QStandardPaths::PicturesLocation: + return QLatin1String("PICTURES"); + case QStandardPaths::MusicLocation: + return QLatin1String("MUSIC"); + case QStandardPaths::MoviesLocation: + return QLatin1String("VIDEOS"); + case QStandardPaths::DownloadLocation: + return QLatin1String("DOWNLOAD"); + default: + return QLatin1String(); + } +} +#endif + QString QStandardPaths::writableLocation(StandardLocation type) { switch (type) { @@ -182,61 +204,32 @@ QString QStandardPaths::writableLocation(StandardLocation type) if (xdgConfigHome.isEmpty()) xdgConfigHome = QDir::homePath() + QLatin1String("/.config"); QFile file(xdgConfigHome + QLatin1String("/user-dirs.dirs")); - if (!isTestModeEnabled() && file.open(QIODevice::ReadOnly)) { - QHash<QString, QString> lines; + const QLatin1String key = xdg_key_name(type); + if (!key.isEmpty() && !isTestModeEnabled() && file.open(QIODevice::ReadOnly)) { QTextStream stream(&file); // Only look for lines like: XDG_DESKTOP_DIR="$HOME/Desktop" QRegularExpression exp(QLatin1String("^XDG_(.*)_DIR=(.*)$")); + QString result; while (!stream.atEnd()) { const QString &line = stream.readLine(); QRegularExpressionMatch match = exp.match(line); - if (match.hasMatch()) { - const QStringList lst = match.capturedTexts(); - const QString key = lst.at(1); - QString value = lst.at(2); + if (match.hasMatch() && match.capturedView(1) == key) { + QStringView value = match.capturedView(2); if (value.length() > 2 && value.startsWith(QLatin1Char('\"')) && value.endsWith(QLatin1Char('\"'))) value = value.mid(1, value.length() - 2); - // Store the key and value: "DESKTOP", "$HOME/Desktop" - lines[key] = value; - } - } - - QString key; - switch (type) { - case DesktopLocation: - key = QLatin1String("DESKTOP"); - break; - case DocumentsLocation: - key = QLatin1String("DOCUMENTS"); - break; - case PicturesLocation: - key = QLatin1String("PICTURES"); - break; - case MusicLocation: - key = QLatin1String("MUSIC"); - break; - case MoviesLocation: - key = QLatin1String("VIDEOS"); - break; - case DownloadLocation: - key = QLatin1String("DOWNLOAD"); - break; - default: - break; - } - if (!key.isEmpty()) { - QString value = lines.value(key); - if (!value.isEmpty()) { // value can start with $HOME if (value.startsWith(QLatin1String("$HOME"))) - value = QDir::homePath() + value.midRef(5); - if (value.length() > 1 && value.endsWith(QLatin1Char('/'))) - value.chop(1); - return value; + result = QDir::homePath() + value.mid(5); + else + result = value.toString(); + if (result.length() > 1 && result.endsWith(QLatin1Char('/'))) + result.chop(1); } } + if (!result.isNull()) + return result; } #endif // QT_CONFIG(regularexpression) diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 4669c20711..1e72241e68 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -468,8 +468,18 @@ inline bool QStorageIterator::next() size_t len = strlen(buffer.data()); if (len == 0) return false; - if (ptr[len - 1] == '\n') - ptr[len - 1] = '\0'; + while (Q_UNLIKELY(ptr[len - 1] != '\n' && !feof(fp))) { + // buffer wasn't large enough. Enlarge and try again. + // (we're readidng from the kernel, so OOM is unlikely) + buffer.resize((buffer.size() + 4096) & ~4095); + ptr = buffer.data(); + if (fgets(ptr + len, buffer.size() - len, fp) == nullptr) + return false; + + len += strlen(ptr + len); + Q_ASSERT(len < size_t(buffer.size())); + } + ptr[len - 1] = '\0'; // parse the line bool ok; diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index c89ad06a1f..acd31f4d84 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -544,10 +544,10 @@ QTemporaryFilePrivate::~QTemporaryFilePrivate() QAbstractFileEngine *QTemporaryFilePrivate::engine() const { if (!fileEngine) { - fileEngine = new QTemporaryFileEngine(&templateName); + fileEngine.reset(new QTemporaryFileEngine(&templateName)); resetFileEngine(); } - return fileEngine; + return fileEngine.get(); } void QTemporaryFilePrivate::resetFileEngine() const @@ -555,7 +555,7 @@ void QTemporaryFilePrivate::resetFileEngine() const if (!fileEngine) return; - QTemporaryFileEngine *tef = static_cast<QTemporaryFileEngine *>(fileEngine); + QTemporaryFileEngine *tef = static_cast<QTemporaryFileEngine *>(fileEngine.get()); if (fileName.isEmpty()) tef->initialize(templateName, 0600); else @@ -568,7 +568,7 @@ void QTemporaryFilePrivate::materializeUnnamedFile() if (!fileName.isEmpty() || !fileEngine) return; - auto *tef = static_cast<QTemporaryFileEngine *>(fileEngine); + auto *tef = static_cast<QTemporaryFileEngine *>(fileEngine.get()); fileName = tef->fileName(QAbstractFileEngine::DefaultName); #endif } @@ -792,7 +792,7 @@ void QTemporaryFile::setAutoRemove(bool b) QString QTemporaryFile::fileName() const { Q_D(const QTemporaryFile); - auto tef = static_cast<QTemporaryFileEngine *>(d->fileEngine); + auto tef = static_cast<QTemporaryFileEngine *>(d->fileEngine.get()); if (tef && tef->isReallyOpen()) const_cast<QTemporaryFilePrivate *>(d)->materializeUnnamedFile(); @@ -841,7 +841,7 @@ void QTemporaryFile::setFileTemplate(const QString &name) bool QTemporaryFile::rename(const QString &newName) { Q_D(QTemporaryFile); - auto tef = static_cast<QTemporaryFileEngine *>(d->fileEngine); + auto tef = static_cast<QTemporaryFileEngine *>(d->fileEngine.get()); if (!tef || !tef->isReallyOpen() || !tef->filePathWasTemplate) return QFile::rename(newName); @@ -947,7 +947,7 @@ QTemporaryFile *QTemporaryFile::createNativeFile(QFile &file) bool QTemporaryFile::open(OpenMode flags) { Q_D(QTemporaryFile); - auto tef = static_cast<QTemporaryFileEngine *>(d->fileEngine); + auto tef = static_cast<QTemporaryFileEngine *>(d->fileEngine.get()); if (tef && tef->isReallyOpen()) { setOpenMode(flags); return true; @@ -961,7 +961,7 @@ bool QTemporaryFile::open(OpenMode flags) d->resetFileEngine(); if (QFile::open(flags)) { - tef = static_cast<QTemporaryFileEngine *>(d->fileEngine); + tef = static_cast<QTemporaryFileEngine *>(d->fileEngine.get()); if (tef->isUnnamedFile()) d->fileName.clear(); else diff --git a/src/corelib/io/qtldurl.cpp b/src/corelib/io/qtldurl.cpp index a934d19fa2..912609ec91 100644 --- a/src/corelib/io/qtldurl.cpp +++ b/src/corelib/io/qtldurl.cpp @@ -59,9 +59,9 @@ enum TLDMatchType { static bool containsTLDEntry(QStringView entry, TLDMatchType match) { const QStringView matchSymbols[] = { - QStringViewLiteral(""), - QStringViewLiteral("*"), - QStringViewLiteral("!"), + u"", + u"*", + u"!", }; const auto symbol = matchSymbols[match]; int index = qt_hash(entry, qt_hash(symbol)) % tldCount; diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index d9ebc6c750..878e007fb0 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -1010,7 +1010,7 @@ inline bool QUrlPrivate::setScheme(const QString &value, int len, bool doSetErro for (int i = needsLowercasing; i >= 0; --i) { ushort c = schemeData[i].unicode(); if (c >= 'A' && c <= 'Z') - schemeData[i] = c + 0x20; + schemeData[i] = QChar(c + 0x20); } } diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp index 2f89d22660..a2f0caa606 100644 --- a/src/corelib/io/qurlidna.cpp +++ b/src/corelib/io/qurlidna.cpp @@ -2220,9 +2220,8 @@ Q_AUTOTEST_EXPORT void qt_punycodeEncoder(const QChar *s, int ucLength, QString bool skipped = false; // copy all basic code points verbatim to output. for (uint j = 0; j < (uint) ucLength; ++j) { - ushort js = s[j].unicode(); - if (js < 0x80) - *d++ = js; + if (s[j].unicode() < 0x80) + *d++ = s[j]; else skipped = true; } diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp index 36a2880bf1..8d80a2d8bd 100644 --- a/src/corelib/io/qurlquery.cpp +++ b/src/corelib/io/qurlquery.cpp @@ -146,7 +146,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QUrlQuery(std::initializer_list<QPair<QString, QString>> list) + \fn QUrlQuery::QUrlQuery(std::initializer_list<QPair<QString, QString>> list) \since 5.13 @@ -293,9 +293,9 @@ void QUrlQueryPrivate::setQuery(const QString &query) const QChar *delimiter = nullptr; while (pos != end) { // scan for the component parts of this pair - if (!delimiter && pos->unicode() == valueDelimiter) + if (!delimiter && *pos == valueDelimiter) delimiter = pos; - if (pos->unicode() == pairDelimiter) + if (*pos == pairDelimiter) break; ++pos; } @@ -584,8 +584,8 @@ QString QUrlQuery::query(QUrl::ComponentFormattingOptions encoding) const */ void QUrlQuery::setQueryDelimiters(QChar valueDelimiter, QChar pairDelimiter) { - d->valueDelimiter = valueDelimiter.unicode(); - d->pairDelimiter = pairDelimiter.unicode(); + d->valueDelimiter = valueDelimiter; + d->pairDelimiter = pairDelimiter; } /*! |