diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/io/qfilesystemengine.cpp | 4 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemiterator_p.h | 8 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemiterator_unix.cpp | 38 | ||||
-rw-r--r-- | src/corelib/json/qjsonparser.cpp | 79 | ||||
-rw-r--r-- | src/corelib/json/qjsonparser_p.h | 4 | ||||
-rw-r--r-- | src/corelib/plugin/qfactoryloader.cpp | 6 | ||||
-rw-r--r-- | src/corelib/plugin/qpluginloader.cpp | 5 | ||||
-rw-r--r-- | src/corelib/tools/qalgorithms.h | 4 | ||||
-rw-r--r-- | src/corelib/tools/qstring.cpp | 33 |
9 files changed, 122 insertions, 59 deletions
diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index fd8f251ccb..c93c42bc60 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -222,7 +222,7 @@ bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data) return false; } -#if defined(QT_EXT_QNX_READDIR_R) +#if defined(_DEXTRA_FIRST) static void fillStat64fromStat32(struct stat64 *statBuf64, const struct stat &statBuf32) { statBuf64->st_mode = statBuf32.st_mode; @@ -287,7 +287,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry) { -#if defined(QT_EXT_QNX_READDIR_R) +#if defined(_DEXTRA_FIRST) knownFlagsMask = 0; entryFlags = 0; for (dirent_extra *extra = _DEXTRA_FIRST(&entry); _DEXTRA_VALID(extra, &entry); diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h index 16830257e1..081487e66e 100644 --- a/src/corelib/io/qfilesystemiterator_p.h +++ b/src/corelib/io/qfilesystemiterator_p.h @@ -93,14 +93,6 @@ private: #else QT_DIR *dir; QT_DIRENT *dirEntry; -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) || defined(QT_EXT_QNX_READDIR_R) - // for readdir_r - QScopedPointer<QT_DIRENT, QScopedPointerPodDeleter> mt_file; -#if defined(QT_EXT_QNX_READDIR_R) - // for _readdir_r - size_t direntSize; -#endif -#endif int lastError; #endif diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp index d7b21fac32..0d1438f137 100644 --- a/src/corelib/io/qfilesystemiterator_unix.cpp +++ b/src/corelib/io/qfilesystemiterator_unix.cpp @@ -52,9 +52,6 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi : nativePath(entry.nativeFilePath()) , dir(0) , dirEntry(0) -#if defined(Q_OS_QNX) && defined(__EXT_QNX__READDIR_R) - , direntSize(0) -#endif , lastError(0) { Q_UNUSED(filters) @@ -64,32 +61,8 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi if ((dir = QT_OPENDIR(nativePath.constData())) == 0) { lastError = errno; } else { - if (!nativePath.endsWith('/')) nativePath.append('/'); - -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) || defined(QT_EXT_QNX_READDIR_R) - // ### Race condition; we should use fpathconf and dirfd(). - size_t maxPathName = ::pathconf(nativePath.constData(), _PC_NAME_MAX); - if (maxPathName == size_t(-1)) - maxPathName = FILENAME_MAX; - maxPathName += sizeof(QT_DIRENT) + 1; - - QT_DIRENT *p = reinterpret_cast<QT_DIRENT*>(::malloc(maxPathName)); - Q_CHECK_PTR(p); - - mt_file.reset(p); -#if defined(QT_EXT_QNX_READDIR_R) - direntSize = maxPathName; - - // Include extra stat information in the readdir() call (d_stat member of - // dirent_extra_stat). This is used in QFileSystemMetaData::fillFromDirEnt() to - // avoid extra stat() calls when iterating over directories - int flags = dircntl(dir, D_GETFLAG) | D_FLAG_STAT | D_FLAG_FILTER; - if (dircntl(dir, D_SETFLAG, flags) == -1) - lastError = errno; -#endif -#endif } } @@ -104,18 +77,7 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa if (!dir) return false; -#if defined(QT_EXT_QNX_READDIR_R) - lastError = QT_EXT_QNX_READDIR_R(dir, mt_file.data(), &dirEntry, direntSize); - if (lastError) - return false; -#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) - lastError = QT_READDIR_R(dir, mt_file.data(), &dirEntry); - if (lastError) - return false; -#else - // ### add local lock to prevent breaking reentrancy dirEntry = QT_READDIR(dir); -#endif // _POSIX_THREAD_SAFE_FUNCTIONS if (dirEntry) { fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name), QFileSystemEntry::FromNativePath()); diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp index 6a3d1de99a..094cb7a76b 100644 --- a/src/corelib/json/qjsonparser.cpp +++ b/src/corelib/json/qjsonparser.cpp @@ -391,6 +391,8 @@ bool Parser::parseObject() } int objectOffset = reserveSpace(sizeof(QJsonPrivate::Object)); + if (objectOffset < 0) + return false; BEGIN << "parseObject pos=" << objectOffset << current << json; ParsedObject parsedObject(this, objectOffset); @@ -423,6 +425,9 @@ bool Parser::parseObject() if (parsedObject.offsets.size()) { int tableSize = parsedObject.offsets.size()*sizeof(uint); table = reserveSpace(tableSize); + if (table < 0) + return false; + #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN memcpy(data + table, parsedObject.offsets.constData(), tableSize); #else @@ -452,6 +457,8 @@ bool Parser::parseObject() bool Parser::parseMember(int baseOffset) { int entryOffset = reserveSpace(sizeof(QJsonPrivate::Entry)); + if (entryOffset < 0) + return false; BEGIN << "parseMember pos=" << entryOffset; bool latin1; @@ -475,6 +482,42 @@ bool Parser::parseMember(int baseOffset) return true; } +namespace { + struct ValueArray { + static const int prealloc = 128; + ValueArray() : data(stackValues), alloc(prealloc), size(0) {} + ~ValueArray() { if (data != stackValues) free(data); } + + inline bool grow() { + alloc *= 2; + if (data == stackValues) { + QJsonPrivate::Value *newValues = static_cast<QJsonPrivate::Value *>(malloc(alloc*sizeof(QJsonPrivate::Value))); + if (!newValues) + return false; + memcpy(newValues, data, size*sizeof(QJsonPrivate::Value)); + data = newValues; + } else { + data = static_cast<QJsonPrivate::Value *>(realloc(data, alloc*sizeof(QJsonPrivate::Value))); + if (!data) + return false; + } + return true; + } + bool append(const QJsonPrivate::Value &v) { + if (alloc == size && !grow()) + return false; + data[size] = v; + ++size; + return true; + } + + QJsonPrivate::Value stackValues[prealloc]; + QJsonPrivate::Value *data; + int alloc; + int size; + }; +} + /* array = begin-array [ value *( value-separator value ) ] end-array */ @@ -488,8 +531,10 @@ bool Parser::parseArray() } int arrayOffset = reserveSpace(sizeof(QJsonPrivate::Array)); + if (arrayOffset < 0) + return false; - QVarLengthArray<QJsonPrivate::Value, 64> values; + ValueArray values; if (!eatSpace()) { lastError = QJsonParseError::UnterminatedArray; @@ -502,7 +547,10 @@ bool Parser::parseArray() QJsonPrivate::Value val; if (!parseValue(&val, arrayOffset)) return false; - values.append(val); + if (!values.append(val)) { + lastError = QJsonParseError::DocumentTooLarge; + return false; + } char token = nextToken(); if (token == EndArray) break; @@ -516,20 +564,22 @@ bool Parser::parseArray() } } - DEBUG << "size =" << values.size(); + DEBUG << "size =" << values.size; int table = arrayOffset; // finalize the object - if (values.size()) { - int tableSize = values.size()*sizeof(QJsonPrivate::Value); + if (values.size) { + int tableSize = values.size*sizeof(QJsonPrivate::Value); table = reserveSpace(tableSize); - memcpy(data + table, values.constData(), tableSize); + if (table < 0) + return false; + memcpy(data + table, values.data, tableSize); } QJsonPrivate::Array *a = (QJsonPrivate::Array *)(data + arrayOffset); a->tableOffset = table - arrayOffset; a->size = current - arrayOffset; a->is_object = false; - a->length = values.size(); + a->length = values.size; DEBUG << "current=" << current; END; @@ -738,6 +788,8 @@ bool Parser::parseNumber(QJsonPrivate::Value *val, int baseOffset) } int pos = reserveSpace(sizeof(double)); + if (pos < 0) + return false; qToLittleEndian(ui, data + pos); if (current - baseOffset >= Value::MaxSize) { lastError = QJsonParseError::DocumentTooLarge; @@ -856,6 +908,9 @@ bool Parser::parseString(bool *latin1) // try to write out a latin1 string int stringPos = reserveSpace(2); + if (stringPos < 0) + return false; + BEGIN << "parse string stringPos=" << stringPos << json; while (json < end) { uint ch = 0; @@ -878,6 +933,8 @@ bool Parser::parseString(bool *latin1) break; } int pos = reserveSpace(1); + if (pos < 0) + return false; DEBUG << " " << ch << (char)ch; data[pos] = (uchar)ch; } @@ -893,6 +950,8 @@ bool Parser::parseString(bool *latin1) // write string length *(QJsonPrivate::qle_ushort *)(data + stringPos) = ushort(current - outStart - sizeof(ushort)); int pos = reserveSpace((4 - current) & 3); + if (pos < 0) + return false; while (pos & 3) data[pos++] = 0; END; @@ -922,10 +981,14 @@ bool Parser::parseString(bool *latin1) } if (QChar::requiresSurrogates(ch)) { int pos = reserveSpace(4); + if (pos < 0) + return false; *(QJsonPrivate::qle_ushort *)(data + pos) = QChar::highSurrogate(ch); *(QJsonPrivate::qle_ushort *)(data + pos + 2) = QChar::lowSurrogate(ch); } else { int pos = reserveSpace(2); + if (pos < 0) + return false; *(QJsonPrivate::qle_ushort *)(data + pos) = (ushort)ch; } } @@ -939,6 +1002,8 @@ bool Parser::parseString(bool *latin1) // write string length *(QJsonPrivate::qle_int *)(data + stringPos) = (current - outStart - sizeof(int))/2; int pos = reserveSpace((4 - current) & 3); + if (pos < 0) + return false; while (pos & 3) data[pos++] = 0; END; diff --git a/src/corelib/json/qjsonparser_p.h b/src/corelib/json/qjsonparser_p.h index ceb366b0f8..920f265ca3 100644 --- a/src/corelib/json/qjsonparser_p.h +++ b/src/corelib/json/qjsonparser_p.h @@ -108,6 +108,10 @@ private: if (current + space >= dataLength) { dataLength = 2*dataLength + space; data = (char *)realloc(data, dataLength); + if (!data) { + lastError = QJsonParseError::DocumentTooLarge; + return -1; + } } int pos = current; current += space; diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index 6cd02e3a3f..13f7b89e2d 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -187,10 +187,12 @@ void QFactoryLoader::update() ++keyUsageCount; } } - if (keyUsageCount || keys.isEmpty()) + if (keyUsageCount || keys.isEmpty()) { + library->setLoadHints(QLibrary::PreventUnloadHint); // once loaded, don't unload d->libraryList += library; - else + } else { library->release(); + } } } #else diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index 094280e3b4..4ec4e43952 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -154,6 +154,7 @@ QPluginLoader::QPluginLoader(const QString &fileName, QObject *parent) : QObject(parent), d(0), did_load(false) { setFileName(fileName); + setLoadHints(QLibrary::PreventUnloadHint); } /*! @@ -348,7 +349,7 @@ static QString locatePlugin(const QString& fileName) void QPluginLoader::setFileName(const QString &fileName) { #if defined(QT_SHARED) - QLibrary::LoadHints lh; + QLibrary::LoadHints lh = QLibrary::PreventUnloadHint; if (d) { lh = d->loadHints(); d->release(); @@ -394,7 +395,7 @@ QString QPluginLoader::errorString() const \brief Give the load() function some hints on how it should behave. You can give hints on how the symbols in the plugin are - resolved. By default, none of the hints are set. + resolved. By default since Qt 5.7, QLibrary::PreventUnloadHint is set. See the documentation of QLibrary::loadHints for a complete description of how this property works. diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h index 4f704d6764..e7caa5c312 100644 --- a/src/corelib/tools/qalgorithms.h +++ b/src/corelib/tools/qalgorithms.h @@ -42,6 +42,10 @@ #include <QtCore/qglobal.h> +#if defined(Q_CC_MSVC) && _MSC_VER > 1500 +#include <intrin.h> +#endif + QT_BEGIN_NAMESPACE QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations") diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 5ea4a0077b..ad44228039 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -4848,6 +4848,39 @@ QString QString::fromUtf16(const ushort *unicode, int size) return QUtf16::convertToUnicode((const char *)unicode, size*2, 0); } +/*! + \fn QString QString::fromUtf16(const char16_t *str, int size) + \since 5.3 + + Returns a QString initialized with the first \a size characters + of the Unicode string \a str (ISO-10646-UTF-16 encoded). + + If \a size is -1 (default), \a str must be terminated + with a 0. + + This function checks for a Byte Order Mark (BOM). If it is missing, + host byte order is assumed. + + This function is slow compared to the other Unicode conversions. + Use QString(const QChar *, int) or QString(const QChar *) if possible. + + QString makes a deep copy of the Unicode data. + + \sa utf16(), setUtf16(), fromStdU16String() +*/ + +/*! + \fn QString QString::fromUcs4(const char32_t *str, int size) + \since 5.3 + + Returns a QString initialized with the first \a size characters + of the Unicode string \a str (ISO-10646-UCS-4 encoded). + + If \a size is -1 (default), \a str must be terminated + with a 0. + + \sa toUcs4(), fromUtf16(), utf16(), setUtf16(), fromWCharArray(), fromStdU32String() +*/ /*! \since 4.2 |