summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/io/qfilesystemengine.cpp4
-rw-r--r--src/corelib/io/qfilesystemiterator_p.h8
-rw-r--r--src/corelib/io/qfilesystemiterator_unix.cpp38
-rw-r--r--src/corelib/json/qjsonparser.cpp79
-rw-r--r--src/corelib/json/qjsonparser_p.h4
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp6
-rw-r--r--src/corelib/plugin/qpluginloader.cpp5
-rw-r--r--src/corelib/tools/qalgorithms.h4
-rw-r--r--src/corelib/tools/qstring.cpp33
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