firefox-97.0.1 qt5-base rebuild

This commit is contained in:
Rmys
2022-02-18 14:10:45 +03:00
parent b7de342288
commit 8b7086e8f1
3 changed files with 726 additions and 24 deletions
+711 -23
View File
@@ -20849,6 +20849,19 @@ index 7411eab68b..c58dde8bfd 100644
, iteratorFlags(flags)
{
#if defined(QT_BOOTSTRAPPED)
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 231e5cb0ea..f32bb5248b 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -312,7 +312,7 @@ mtime(const T &statBuffer, int)
static int qt_real_statx(int fd, const char *pathname, int flags, struct statx *statxBuffer)
{
unsigned mask = STATX_BASIC_STATS | STATX_BTIME;
- int ret = statx(fd, pathname, flags, mask, statxBuffer);
+ int ret = statx(fd, pathname, flags | AT_NO_AUTOMOUNT, mask, statxBuffer);
return ret == -1 ? -errno : 0;
}
diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp
index 94d9d06bcb..27e0b13b0b 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify.cpp
@@ -62410,7 +62423,7 @@ index 9de22cef33..ff868a3268 100644
}
diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp
index 1016884437..3ab5bd4cb4 100644
index 1016884437..fa8f4c545d 100644
--- a/src/corelib/mimetypes/qmimeglobpattern.cpp
+++ b/src/corelib/mimetypes/qmimeglobpattern.cpp
@@ -83,11 +83,48 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q
@@ -62432,7 +62445,7 @@ index 1016884437..3ab5bd4cb4 100644
+ if (!patternLength)
+ return OtherPattern;
+
+ const bool starCount = pattern.count(QLatin1Char('*')) == 1;
+ const int starCount = pattern.count(QLatin1Char('*'));
+ const bool hasSquareBracket = pattern.indexOf(QLatin1Char('[')) != -1;
+ const bool hasQuestionMark = pattern.indexOf(QLatin1Char('?')) != -1;
+
@@ -62444,10 +62457,10 @@ index 1016884437..3ab5bd4cb4 100644
+ // Patterns like "README*" (well this is currently the only one like that...)
+ if (pattern.at(patternLength - 1) == QLatin1Char('*'))
+ return PrefixPattern;
+ }
+ // Names without any wildcards like "README"
+ if (starCount == 0)
+ } else if (starCount == 0) {
+ // Names without any wildcards like "README"
+ return LiteralPattern;
+ }
+ }
+
+ if (pattern == QLatin1String("[0-9][0-9][0-9].vdr"))
@@ -68823,6 +68836,148 @@ index d4fb756b94..1d01fc1b28 100644
}
return;
}
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index b2d1628e6e..f32f6f0460 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -174,7 +174,7 @@ public:
int returnCode;
uint stackSize;
- QThread::Priority priority;
+ std::underlying_type<QThread::Priority>::type priority;
static QThread *threadForId(int id);
@@ -213,6 +213,13 @@ public:
QCoreApplication::instance()->postEvent(q_ptr, new QEvent(QEvent::Quit));
}
}
+
+#ifndef Q_OS_INTEGRITY
+private:
+ // Used in QThread(Private)::start to avoid racy access to QObject::objectName,
+ // unset afterwards. On INTEGRITY we set the thread name before starting it.
+ QString objectName;
+#endif
};
#else // QT_CONFIG(thread)
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 659d5fb03c..cbeb870395 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -296,11 +296,13 @@ void *QThreadPrivate::start(void *arg)
QMutexLocker locker(&thr->d_func()->mutex);
// do we need to reset the thread priority?
- if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) {
+ if (thr->d_func()->priority & ThreadPriorityResetFlag) {
thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
}
- data->threadId.storeRelaxed(to_HANDLE(pthread_self()));
+ // threadId is set in QThread::start()
+ Q_ASSERT(pthread_equal(from_HANDLE<pthread_t>(data->threadId.loadRelaxed()),
+ pthread_self()));
set_thread_data(data);
data->ref();
@@ -314,10 +316,10 @@ void *QThreadPrivate::start(void *arg)
// Sets the name of the current thread. We can only do this
// when the thread is starting, as we don't have a cross
// platform way of setting the name of an arbitrary thread.
- if (Q_LIKELY(thr->objectName().isEmpty()))
+ if (Q_LIKELY(thr->d_func()->objectName.isEmpty()))
setCurrentThreadName(thr->metaObject()->className());
else
- setCurrentThreadName(thr->objectName().toLocal8Bit());
+ setCurrentThreadName(std::exchange(thr->d_func()->objectName, {}).toLocal8Bit());
}
#endif
@@ -384,6 +386,8 @@ void QThreadPrivate::finish(void *arg)
d->interruptionRequested = false;
d->isInFinish = false;
+ d->data->threadId.storeRelaxed(nullptr);
+
d->thread_done.wakeAll();
}
#ifndef QT_NO_EXCEPTIONS
@@ -667,7 +671,7 @@ void QThread::start(Priority priority)
// could not set scheduling hints, fallback to inheriting them
// we'll try again from inside the thread
pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
- d->priority = Priority(priority | ThreadPriorityResetFlag);
+ d->priority = static_cast<std::underlying_type<QThread::Priority>::type>(priority) | ThreadPriorityResetFlag;
}
break;
}
@@ -698,7 +702,10 @@ void QThread::start(Priority priority)
pthread_attr_setthreadname(&attr, metaObject()->className());
else
pthread_attr_setthreadname(&attr, objectName().toLocal8Bit());
+#else
+ d->objectName = objectName();
#endif
+
pthread_t threadId;
int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
if (code == EPERM) {
@@ -755,6 +762,8 @@ bool QThread::wait(QDeadlineTimer deadline)
if (!d->thread_done.wait(locker.mutex(), deadline))
return false;
}
+ Q_ASSERT(d->data->threadId.loadRelaxed() == nullptr);
+
return true;
}
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index bc70e3178a..4e76972498 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -394,10 +394,9 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT)
// sets the name of the current thread.
- QByteArray objectName = thr->objectName().toLocal8Bit();
- qt_set_thread_name(HANDLE(-1),
- objectName.isEmpty() ?
- thr->metaObject()->className() : objectName.constData());
+ qt_set_thread_name(HANDLE(-1), thr->d_func()->objectName.isEmpty()
+ ? thr->metaObject()->className()
+ : std::exchange(thr->d_func()->objectName, {}).toLocal8Bit().constData());
#endif
emit thr->started(QThread::QPrivateSignal());
@@ -503,6 +502,7 @@ void QThread::start(Priority priority)
if (d->running)
return;
+ d->objectName = objectName();
d->running = true;
d->finished = false;
d->exited = false;
@@ -548,7 +548,7 @@ void QThread::start(Priority priority)
int prio;
d->priority = priority;
- switch (d->priority) {
+ switch (priority) {
case IdlePriority:
prio = THREAD_PRIORITY_IDLE;
break;
@@ -686,7 +686,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
int prio;
priority = threadPriority;
- switch (priority) {
+ switch (threadPriority) {
case QThread::IdlePriority:
prio = THREAD_PRIORITY_IDLE;
break;
diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp
index 88b058f410..0f1da4dc9b 100644
--- a/src/corelib/thread/qwaitcondition_unix.cpp
@@ -75636,10 +75791,29 @@ index 6d2bbc83c1..ccf2234540 100644
0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x65, 0x72, 0x6d, 0x6f, 0x73, 0x69, 0x6c, 0x6c, 0x6f, 0x0,
0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x68, 0x6f, 0x65, 0x6e, 0x69, 0x78, 0x0, 0x45, 0x74, 0x63, 0x2f,
diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp
index b816b4ecff..48d1803455 100644
index b816b4ecff..9ec8ee7857 100644
--- a/src/corelib/time/qtimezoneprivate_tz.cpp
+++ b/src/corelib/time/qtimezoneprivate_tz.cpp
@@ -371,8 +371,8 @@ static QDate calculatePosixDate(const QByteArray &dateRule, int year)
@@ -42,6 +42,7 @@
#include "qtimezone.h"
#include "qtimezoneprivate_p.h"
#include "private/qlocale_tools_p.h"
+#include "private/qlocking_p.h"
#include <QtCore/QDataStream>
#include <QtCore/QDateTime>
@@ -62,6 +63,10 @@
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(icu)
+static QBasicMutex s_icu_mutex;
+#endif
+
/*
Private
@@ -371,8 +376,8 @@ static QDate calculatePosixDate(const QByteArray &dateRule, int year)
int month = dateParts.at(0).mid(1).toInt();
int week = dateParts.at(1).toInt();
int dow = dateParts.at(2).toInt();
@@ -75650,7 +75824,7 @@ index b816b4ecff..48d1803455 100644
return calculateDowDate(year, month, dow, week);
} else if (dateRule.at(0) == 'J') {
// Day of Year ignores Feb 29
@@ -394,29 +394,34 @@ static int parsePosixTime(const char *begin, const char *end)
@@ -394,29 +399,34 @@ static int parsePosixTime(const char *begin, const char *end)
// Format "hh[:mm[:ss]]"
int hour, min = 0, sec = 0;
@@ -75696,6 +75870,121 @@ index b816b4ecff..48d1803455 100644
}
}
@@ -650,6 +660,9 @@ QTzTimeZonePrivate::~QTzTimeZonePrivate()
QTzTimeZonePrivate *QTzTimeZonePrivate::clone() const
{
+#if QT_CONFIG(icu)
+ const auto lock = qt_scoped_lock(s_icu_mutex);
+#endif
return new QTzTimeZonePrivate(*this);
}
@@ -862,13 +875,19 @@ void QTzTimeZonePrivate::init(const QByteArray &ianaId)
cached_data = std::move(entry);
m_id = ianaId;
// Avoid empty ID, if we have an abbreviation to use instead
- if (m_id.isEmpty()) { // We've read /etc/localtime's contents
- for (const auto &abbr : cached_data.m_abbreviations) {
- if (!abbr.isEmpty()) {
- m_id = abbr;
- break;
- }
- }
+ if (m_id.isEmpty()) {
+ // This can only happen for the system zone, when we've read the
+ // contents of /etc/localtime because it wasn't a symlink.
+#if QT_CONFIG(icu)
+ // Use ICU's system zone, if only to avoid using the abbreviation as ID
+ // (ICU might mis-recognize it) in displayName().
+ m_icu = new QIcuTimeZonePrivate();
+ // Use its ID, as an alternate source of data:
+ m_id = m_icu->id();
+ if (!m_id.isEmpty())
+ return;
+#endif
+ m_id = abbreviation(QDateTime::currentMSecsSinceEpoch()).toUtf8();
}
}
@@ -887,12 +906,14 @@ QString QTzTimeZonePrivate::displayName(qint64 atMSecsSinceEpoch,
const QLocale &locale) const
{
#if QT_CONFIG(icu)
+ auto lock = qt_unique_lock(s_icu_mutex);
if (!m_icu)
m_icu = new QIcuTimeZonePrivate(m_id);
// TODO small risk may not match if tran times differ due to outdated files
// TODO Some valid TZ names are not valid ICU names, use translation table?
if (m_icu->isValid())
return m_icu->displayName(atMSecsSinceEpoch, nameType, locale);
+ lock.unlock();
#else
Q_UNUSED(nameType)
Q_UNUSED(locale)
@@ -905,12 +926,14 @@ QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
const QLocale &locale) const
{
#if QT_CONFIG(icu)
+ auto lock = qt_unique_lock(s_icu_mutex);
if (!m_icu)
m_icu = new QIcuTimeZonePrivate(m_id);
// TODO small risk may not match if tran times differ due to outdated files
// TODO Some valid TZ names are not valid ICU names, use translation table?
if (m_icu->isValid())
return m_icu->displayName(timeType, nameType, locale);
+ lock.unlock();
#else
Q_UNUSED(timeType)
Q_UNUSED(nameType)
@@ -1157,8 +1180,11 @@ public:
*/
const StatIdent local = identify("/etc/localtime");
const StatIdent tz = identify("/etc/TZ");
- if (!m_name.isEmpty() && m_last.isValid() && (m_last == local || m_last == tz))
+ const StatIdent timezone = identify("/etc/timezone");
+ if (!m_name.isEmpty() && m_last.isValid()
+ && (m_last == local || m_last == tz || m_last == timezone)) {
return m_name;
+ }
m_name = etcLocalTime();
if (!m_name.isEmpty()) {
@@ -1166,12 +1192,19 @@ public:
return m_name;
}
- m_name = etcTZ();
- m_last = m_name.isEmpty() ? StatIdent() : tz;
+ // Some systems (e.g. uClibc) have a default value for $TZ in /etc/TZ:
+ m_name = etcContent(QStringLiteral("/etc/TZ"));
+ if (!m_name.isEmpty()) {
+ m_last = tz;
+ return m_name;
+ }
+
+ // Gentoo still (2020, QTBUG-87326) uses this:
+ m_name = etcContent(QStringLiteral("/etc/timezone"));
+ m_last = m_name.isEmpty() ? StatIdent() : timezone;
return m_name;
}
-
private:
QByteArray m_name;
struct StatIdent
@@ -1212,10 +1245,8 @@ private:
return QByteArray();
}
- static QByteArray etcTZ()
+ static QByteArray etcContent(const QString &path)
{
- // Some systems (e.g. uClibc) have a default value for $TZ in /etc/TZ:
- const QString path = QStringLiteral("/etc/TZ");
QFile zone(path);
if (zone.open(QIODevice::ReadOnly))
return zone.readAll().trimmed();
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index 8e19525f07..0b967a84f7 100644
--- a/src/corelib/tools/qarraydataops.h
@@ -75834,43 +76123,53 @@ index 790c187cb9..8abb57586b 100644
return std::shared_ptr<X>();
}
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 6be695e317..f9003c31a2 100644
index 6be695e317..2b30da0d2c 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -153,18 +153,10 @@ public:
@@ -152,30 +152,18 @@ public:
if (s == a) { // i.e. s != 0
T copy(t);
realloc(s, s<<1);
const int idx = s++;
- const int idx = s++;
- if (QTypeInfo<T>::isComplex) {
- new (ptr + idx) T(std::move(copy));
- } else {
- ptr[idx] = std::move(copy);
- }
+ new (ptr + idx) T(std::move(copy));
+ new (end()) T(std::move(copy));
} else {
const int idx = s++;
- const int idx = s++;
- if (QTypeInfo<T>::isComplex) {
- new (ptr + idx) T(t);
- } else {
- ptr[idx] = t;
- }
+ new (ptr + idx) T(t);
+ new (end()) T(t);
}
+ ++s;
}
@@ -172,10 +164,7 @@ public:
void append(T &&t) {
if (s == a)
realloc(s, s << 1);
const int idx = s++;
- const int idx = s++;
- if (QTypeInfo<T>::isComplex)
- new (ptr + idx) T(std::move(t));
- else
- ptr[idx] = std::move(t);
+ new (ptr + idx) T(std::move(t));
+ new (end()) T(std::move(t));
+ ++s;
}
void append(const T *buf, int size);
@@ -518,8 +507,8 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
@@ -512,14 +500,14 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
}
template <class T, int Prealloc>
-Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, size_type n, const T &t)
+Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, int n, const T &t)
{
Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
int offset = int(before - ptr);
if (n != 0) {
@@ -75880,12 +76179,15 @@ index 6be695e317..f9003c31a2 100644
if (!QTypeInfoQuery<T>::isRelocatable) {
T *b = ptr + offset;
T *j = ptr + s;
@@ -549,6 +538,8 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
@@ -549,6 +537,11 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
int f = int(abegin - ptr);
int l = int(aend - ptr);
int n = l - f;
+ if (n == 0) // avoid UB in std::copy() below
+ return ptr + f;
+
+ Q_ASSERT(n > 0); // aend must be reachable from abegin
+
if (QTypeInfo<T>::isComplex) {
std::copy(ptr + l, ptr + s, QT_MAKE_CHECKED_ARRAY_ITERATOR(ptr + f, s - f));
T *i = ptr + s;
@@ -75934,6 +76236,24 @@ index 8d1b15b507..d61c26dc2e 100644
}
}
} QT_CATCH (...) {
diff --git a/src/corelib/tools/qversionnumber.h b/src/corelib/tools/qversionnumber.h
index d43b86ba51..2843f2b043 100644
--- a/src/corelib/tools/qversionnumber.h
+++ b/src/corelib/tools/qversionnumber.h
@@ -273,10 +273,10 @@ public:
Q_REQUIRED_RESULT Q_CORE_EXPORT QString toString() const;
#if QT_STRINGVIEW_LEVEL < 2
- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
+ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
#endif
- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
+ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
+ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
private:
#ifndef QT_NO_DATASTREAM
diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp
index 5265568f42..7e9f0f1acc 100644
--- a/src/dbus/qdbusmetaobject.cpp
@@ -76254,6 +76574,106 @@ index 3920a10467..9e7d2861fd 100644
}
/*!
diff --git a/src/gui/painting/qblendfunctions_p.h b/src/gui/painting/qblendfunctions_p.h
index 080da98ec4..6997d62b3c 100644
--- a/src/gui/painting/qblendfunctions_p.h
+++ b/src/gui/painting/qblendfunctions_p.h
@@ -246,25 +246,32 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
int dudx, int dvdx, int dudy, int dvdy, int u0, int v0,
Blender blender)
{
- int fromY = qMax(qRound(topY), clip.top());
- int toY = qMin(qRound(bottomY), clip.top() + clip.height());
+ qint64 fromY = qMax(qRound(topY), clip.top());
+ qint64 toY = qMin(qRound(bottomY), clip.top() + clip.height());
if (fromY >= toY)
return;
qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y);
qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y);
- int dx_l = int(leftSlope * 0x10000);
- int dx_r = int(rightSlope * 0x10000);
- int x_l = int((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
- int x_r = int((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
-
- int fromX, toX, x1, x2, u, v, i, ii;
+ qint64 dx_l = qint64(leftSlope * 0x10000);
+ qint64 dx_r = qint64(rightSlope * 0x10000);
+ qint64 x_l = qint64((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
+ qint64 x_r = qint64((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
+
+ qint64 sourceRectTop = qint64(sourceRect.top());
+ qint64 sourceRectLeft = qint64(sourceRect.left());
+ qint64 sourceRectWidth = qint64(sourceRect.width());
+ qint64 sourceRectHeight = qint64(sourceRect.height());
+ qint64 clipLeft = qint64(clip.left());
+ qint64 clipWidth = qint64(clip.width());
+
+ qint64 fromX, toX, x1, x2, u, v, i, ii;
DestT *line;
- for (int y = fromY; y < toY; ++y) {
+ for (qint64 y = fromY; y < toY; ++y) {
line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl);
- fromX = qMax(x_l >> 16, clip.left());
- toX = qMin(x_r >> 16, clip.left() + clip.width());
+ fromX = qMax(x_l >> 16, clipLeft);
+ toX = qMin(x_r >> 16, clipLeft + clipWidth);
if (fromX < toX) {
// Because of rounding, we can get source coordinates outside the source image.
// Clamp these coordinates to the source rect to avoid segmentation fault and
@@ -275,10 +282,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
u = x1 * dudx + y * dudy + u0;
v = x1 * dvdx + y * dvdy + v0;
for (; x1 < toX; ++x1) {
- int uu = u >> 16;
- int vv = v >> 16;
- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
+ qint64 uu = u >> 16;
+ qint64 vv = v >> 16;
+ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
+ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
break;
}
u += dudx;
@@ -290,10 +297,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
u = (x2 - 1) * dudx + y * dudy + u0;
v = (x2 - 1) * dvdx + y * dvdy + v0;
for (; x2 > x1; --x2) {
- int uu = u >> 16;
- int vv = v >> 16;
- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
+ qint64 uu = u >> 16;
+ qint64 vv = v >> 16;
+ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
+ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
break;
}
u -= dudx;
@@ -308,8 +315,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
// Beginning of the scan line, with per-pixel checks.
i = x1 - fromX;
while (i) {
- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
+ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
+ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
u += dudx;
v += dvdx;
@@ -348,8 +355,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
// End of the scan line, with per-pixel checks.
i = toX - x2;
while (i) {
- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
+ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
+ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
u += dudx;
v += dvdx;
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index 89f3374ea1..9e5605dd48 100644
--- a/src/gui/painting/qbrush.cpp
@@ -76677,6 +77097,30 @@ index ab60afd9cd..e5c6879251 100644
Q_ASSERT(fe);
fe->addOutlineToPath(x, y, glyphs, this,
si.analysis.bidiLevel % 2
diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h
index 9444a87b71..18f64c5e8c 100644
--- a/src/gui/painting/qpathclipper_p.h
+++ b/src/gui/painting/qpathclipper_p.h
@@ -156,7 +156,7 @@ public:
int vertex(Direction direction) const;
private:
- int m_next[2][2];
+ int m_next[2][2] = { { -1, -1 }, { -1, -1 } };
};
class QPathSegments
@@ -296,10 +296,6 @@ inline QPathEdge::QPathEdge(int a, int b)
, angle(0)
, invAngle(0)
{
- m_next[0][0] = -1;
- m_next[1][0] = -1;
- m_next[0][0] = -1;
- m_next[1][0] = -1;
}
inline int QPathEdge::next(Traversal traversal, Direction direction) const
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index de9fc13331..2c8d3c3b53 100644
--- a/src/gui/painting/qpdf.cpp
@@ -76840,6 +77284,27 @@ index 01e581d2ed..254abf88c0 100644
return;
}
if (qAbs(d->width - width) < 0.00000001f)
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index 22302f9790..07fd1ac105 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -1179,6 +1179,7 @@ void QDashStroker::processCurrentSubpath()
bool done = pos >= estop;
+ int maxDashes = dashCount;
if (clipping) {
// Check if the entire line can be clipped away.
if (!lineIntersectsRect(prev, e, clip_tl, clip_br)) {
@@ -1196,7 +1197,7 @@ void QDashStroker::processCurrentSubpath()
done = true;
} else { // Dash is on this line
pos = dpos + estart;
- done = pos >= estop;
+ done = --maxDashes > 0 ? pos >= estop : estop;
if (++idash >= dashCount)
idash = 0;
doffset = 0; // full segment so no offset on next.
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 9d8bb0c3e2..0952bd22fb 100644
--- a/src/gui/painting/qtransform.cpp
@@ -76936,7 +77401,7 @@ index f1fd755e91..d9c0239940 100644
Q_ASSERT(at < m_engines.size());
if (!m_engines.at(at)) {
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index a2b3c8dc76..322f494e5d 100644
index a2b3c8dc76..28610711ef 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -105,14 +105,13 @@ public:
@@ -76955,6 +77420,15 @@ index a2b3c8dc76..322f494e5d 100644
{
}
@@ -2124,7 +2123,7 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
{
Q_Q(const QTextDocumentLayout);
const QTextBlockFormat blockFormat = bl.blockFormat();
- const QTextCharFormat charFormat = QTextCursor(bl).charFormat();
+ const QTextCharFormat charFormat = bl.charFormat();
QFont font(charFormat.font());
if (q->paintDevice())
font = QFont(font, q->paintDevice());
@@ -2358,9 +2357,10 @@ QTextLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QT
floatMinWidth = qMax(floatMinWidth, cd->minimumWidth);
}
@@ -78631,6 +79105,19 @@ index 213df4eba7..8dc4050e24 100644
auto *nsimage = [NSImage imageFromQImage:fullHeightPixmap.toImage()];
[nsimage setTemplate:icon.isMask()];
diff --git a/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h b/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h
index e070ba977d..0896917334 100644
--- a/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h
+++ b/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h
@@ -43,6 +43,8 @@
#include <qpa/qplatformgraphicsbuffer.h>
#include <private/qcore_mac_p.h>
+#include <CoreGraphics/CGColorSpace.h>
+
QT_BEGIN_NAMESPACE
class QIOSurfaceGraphicsBuffer : public QPlatformGraphicsBuffer
diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm
index 2fd63fad67..537ea2aef4 100644
--- a/src/plugins/platforms/cocoa/qnsview_drawing.mm
@@ -79145,7 +79632,7 @@ index fe9ddfece7..dabdfcb6c5 100644
// timed out ... create a new requestor window, otherwise the requestor
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index c557109bd1..9abdae6a7c 100644
index c557109bd1..8477e28df1 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -763,7 +763,10 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
@@ -79175,6 +79662,40 @@ index c557109bd1..9abdae6a7c 100644
xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
xcb_timestamp_t timestamp = pn->time;
free(event);
@@ -784,7 +795,13 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
xcb_window_t QXcbConnection::getSelectionOwner(xcb_atom_t atom) const
{
- return Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom)->owner;
+ auto reply = Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom);
+ if (!reply) {
+ qCDebug(lcQpaXcb) << "failed to query selection owner";
+ return XCB_NONE;
+ }
+
+ return reply->owner;
}
xcb_window_t QXcbConnection::getQtSelectionOwner()
diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
index 18dee89adb..9dd608cdc0 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
@@ -179,7 +179,13 @@ xcb_atom_t QXcbBasicConnection::internAtom(const char *name)
if (!name || *name == 0)
return XCB_NONE;
- return Q_XCB_REPLY(xcb_intern_atom, m_xcbConnection, false, strlen(name), name)->atom;
+ auto reply = Q_XCB_REPLY(xcb_intern_atom, m_xcbConnection, false, strlen(name), name);
+ if (!reply) {
+ qCDebug(lcQpaXcb) << "failed to query intern atom: " << name;
+ return XCB_NONE;
+ }
+
+ return reply->atom;
}
QByteArray QXcbBasicConnection::atomName(xcb_atom_t atom)
diff --git a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp
index 9ba71ada37..ec099101f5 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp
@@ -79199,6 +79720,20 @@ index 9ba71ada37..ec099101f5 100644
if (!resources) {
qWarning("failed to get the screen resources");
} else {
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index 42c7a52bd4..a032085f0b 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -668,7 +668,8 @@ void QXcbCursor::setPos(const QPoint &pos)
{
QXcbVirtualDesktop *virtualDesktop = nullptr;
queryPointer(connection(), &virtualDesktop, nullptr);
- xcb_warp_pointer(xcb_connection(), XCB_NONE, virtualDesktop->root(), 0, 0, 0, 0, pos.x(), pos.y());
+ if (virtualDesktop)
+ xcb_warp_pointer(xcb_connection(), XCB_NONE, virtualDesktop->root(), 0, 0, 0, 0, pos.x(), pos.y());
xcb_flush(xcb_connection());
}
diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp
index 759ee3cc95..9f3c381216 100644
--- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp
@@ -80812,6 +81347,28 @@ index 7df2b59710..e0df5b5158 100644
return QDateTimeParser::getMaximum();
}
QLocale locale() const override { return q_func()->locale(); }
diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index a5f81d6542..c34d0ec8fc 100644
--- a/src/widgets/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
@@ -395,7 +395,7 @@ ControlLabel::ControlLabel(QMdiSubWindow *subWindow, QWidget *parent)
Q_UNUSED(subWindow);
setFocusPolicy(Qt::NoFocus);
updateWindowIcon();
- setFixedSize(label.size());
+ setFixedSize(label.size() / label.devicePixelRatio());
}
/*
@@ -403,7 +403,7 @@ ControlLabel::ControlLabel(QMdiSubWindow *subWindow, QWidget *parent)
*/
QSize ControlLabel::sizeHint() const
{
- return label.size();
+ return label.size() / label.devicePixelRatio();
}
/*
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index ab933c987f..a23d8b790d 100644
--- a/src/widgets/widgets/qmenu.cpp
@@ -81758,6 +82315,76 @@ index e8e578ac25..4c4a8f0416 100644
}
void tst_QString::replace_string()
diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp
index 7be2f48758..ad8556de81 100644
--- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp
+++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp
@@ -106,6 +106,7 @@ private slots:
void quitLock();
void create();
+ void threadIdReuse();
};
enum { one_minute = 60 * 1000, five_minutes = 5 * one_minute };
@@ -1631,5 +1632,57 @@ void tst_QThread::requestTermination()
QVERIFY(!thread.isInterruptionRequested());
}
+/*
+ This is a regression test for QTBUG-96846.
+
+ Incorrect system thread ID cleanup can cause QThread::wait() to report that
+ a thread is trying to wait for itself.
+*/
+void tst_QThread::threadIdReuse()
+{
+ // It's important that those thread ID's are not accessed concurrently
+ Qt::HANDLE threadId1;
+
+ auto thread1Fn = [&threadId1]() -> void { threadId1 = QThread::currentThreadId(); };
+ QScopedPointer<QThread> thread1(QThread::create(thread1Fn));
+ thread1->start();
+ QVERIFY(thread1->wait());
+
+ // If the system thread allocated for thread1 is destroyed before thread2 is started,
+ // at least on some versions of Linux the system thread ID for thread2 would be the
+ // same as one that was used for thread1.
+
+ // The system thread may be alive for some time after returning from QThread::wait()
+ // because the implementation is using detachable threads, so some additional time is
+ // required for the system thread to terminate. Not waiting long enough here would result
+ // in a new system thread ID being allocated for thread2 and this test passing even without
+ // a fix for QTBUG-96846.
+ bool threadIdReused = false;
+
+ for (int i = 0; i < 42; i++) {
+ QThread::msleep(1);
+
+ Qt::HANDLE threadId2;
+ auto waitForThread1 = [&thread1, &threadId2]() -> void {
+ threadId2 = QThread::currentThreadId();
+ QVERIFY(thread1->wait());
+ };
+
+ QScopedPointer<QThread> thread2(QThread::create(waitForThread1));
+ thread2->start();
+ QVERIFY(thread2->wait());
+
+ if (threadId1 == threadId2) {
+ qDebug("Thread ID reused at iteration %d", i);
+ threadIdReused = true;
+ break;
+ }
+ }
+
+ if (!threadIdReused) {
+ QSKIP("Thread ID was not reused");
+ }
+}
+
QTEST_MAIN(tst_QThread)
#include "tst_qthread.moc"
diff --git a/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp b/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp
index 5da69e76a5..55027530ec 100644
--- a/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp
@@ -82046,10 +82673,10 @@ index 332a00efb5..ed31704cbb 100644
QCOMPARE(dat.standardTimeOffset, 3600);
QCOMPARE(dat.daylightTimeOffset, 0);
diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
index a1d0100f96..5443cf120b 100644
index a1d0100f96..625da129c4 100644
--- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
+++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
@@ -26,7 +26,7 @@
@@ -26,9 +26,10 @@
**
****************************************************************************/
@@ -82057,7 +82684,68 @@ index a1d0100f96..5443cf120b 100644
+#include <QtTest/QTest>
#include <qvarlengtharray.h>
#include <qvariant.h>
+#include <qscopedvaluerollback.h>
#include <memory>
@@ -40,6 +41,7 @@ private slots:
void removeLast();
void oldTests();
void appendCausingRealloc();
+ void appendIsStronglyExceptionSafe();
void resize();
void realloc();
void reverseIterators();
@@ -245,6 +247,49 @@ void tst_QVarLengthArray::appendCausingRealloc()
d.append(i);
}
+void tst_QVarLengthArray::appendIsStronglyExceptionSafe()
+{
+#ifdef QT_NO_EXCEPTIONS
+ QSKIP("This test requires exception support enabled in the compiler.");
+#else
+ static bool throwOnCopyNow = false;
+ static bool throwOnMoveNow = false;
+ struct Thrower {
+ Thrower() = default;
+ Thrower(const Thrower &)
+ {
+ if (throwOnCopyNow)
+ throw 1;
+ }
+ Thrower &operator=(const Thrower &) = default;
+ Thrower(Thrower &&)
+ {
+ if (throwOnMoveNow)
+ throw 1;
+ }
+ Thrower &operator=(Thrower &&) = default;
+ ~Thrower() = default;
+ };
+
+ {
+ // ### TODO: QVLA isn't exception-safe when throwing during reallocation,
+ // ### so check with size() < capacity() for now
+ QVarLengthArray<Thrower, 2> vla(1);
+ {
+ Thrower t;
+ const QScopedValueRollback rb(throwOnCopyNow, true);
+ QVERIFY_EXCEPTION_THROWN(vla.push_back(t), int);
+ QCOMPARE(vla.size(), 1);
+ }
+ {
+ const QScopedValueRollback rb(throwOnMoveNow, true);
+ QVERIFY_EXCEPTION_THROWN(vla.push_back({}), int);
+ QCOMPARE(vla.size(), 1);
+ }
+ }
+#endif
+}
+
void tst_QVarLengthArray::resize()
{
//MOVABLE
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index d5c5752f95..2f20559258 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+7
View File
@@ -280,6 +280,13 @@
</Package>-->
<History>
<Update release="37">
<Date>2022-02-18</Date>
<Version>5.15.2</Version>
<Comment>Rebuild kde patch.</Comment>
<Name>Mustafa Cinasal</Name>
<Email>muscnsl@gmail.com</Email>
</Update>
<Update release="36">
<Date>2022-01-06</Date>
<Version>5.15.2</Version>
+8 -1
View File
@@ -15,7 +15,7 @@
<IsA>app:gui</IsA>
<Summary>Firefox Web Browser</Summary>
<Description>It is more secure and faster to browse the web with Firefox web browser. You can personalize your web browser with many specifications that is not enough to explain in two sentences.</Description>
<Archive sha1sum="1b8e6a4d0559ecea27516901f48cf36ba7d5faa1" type="tarxz">https://ftp.mozilla.org/pub/firefox/releases/97.0/source/firefox-97.0.source.tar.xz</Archive>
<Archive sha1sum="371139ec4737f3d65772242b7f970be0e2ddf141" type="tarxz">https://ftp.mozilla.org/pub/firefox/releases/97.0.1/source/firefox-97.0.1.source.tar.xz</Archive>
<AdditionalFiles>
<!--Our main configure script. Configure paramters are stored here.-->
<!-- <AdditionalFile target=".mozconfig" permission="0644">mozconfig</AdditionalFile> -->
@@ -558,6 +558,13 @@
</Package>
<History>
<Update release="72">
<Date>2022-02-18</Date>
<Version>97.0.1</Version>
<Comment>Version bump.</Comment>
<Name>Mustafa Cinasal</Name>
<Email>muscnsl@gmail.com</Email>
</Update>
<Update release="71">
<Date>2022-02-14</Date>
<Version>97.0</Version>