diff options
-rw-r--r-- | src/corelib/time/qdatetime.cpp | 125 | ||||
-rw-r--r-- | src/corelib/time/qdatetimeparser.cpp | 12 | ||||
-rw-r--r-- | src/corelib/time/qtimezoneprivate.cpp | 31 | ||||
-rw-r--r-- | src/gui/painting/qicc.cpp | 10 | ||||
-rw-r--r-- | src/gui/text/qcssparser.cpp | 4 |
5 files changed, 98 insertions, 84 deletions
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 3b1b9e754f..26e25afd38 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -76,13 +76,14 @@ QT_BEGIN_NAMESPACE Date/Time Constants *****************************************************************************/ -enum { +enum : qint64 { SECS_PER_DAY = 86400, MSECS_PER_DAY = 86400000, SECS_PER_HOUR = 3600, MSECS_PER_HOUR = 3600000, SECS_PER_MIN = 60, MSECS_PER_MIN = 60000, + MSECS_PER_SEC = 1000, TIME_T_MAX = 2145916799, // int maximum 2037-12-31T23:59:59 UTC JULIAN_DAY_FOR_EPOCH = 2440588 // result of julianDayFromDate(1970, 1, 1) }; @@ -279,7 +280,7 @@ static QString toOffsetString(Qt::DateFormat format, int offset) { return QString::asprintf("%c%02d%s%02d", offset >= 0 ? '+' : '-', - qAbs(offset) / SECS_PER_HOUR, + qAbs(offset) / int(SECS_PER_HOUR), // Qt::ISODate puts : between the hours and minutes, but Qt:TextDate does not: format == Qt::TextDate ? "" : ":", (qAbs(offset) / 60) % 60); @@ -1792,7 +1793,7 @@ int QTime::second() const if (!isValid()) return -1; - return (ds() / 1000)%SECS_PER_MIN; + return (ds() / MSECS_PER_SEC) % SECS_PER_MIN; } /*! @@ -1808,7 +1809,7 @@ int QTime::msec() const if (!isValid()) return -1; - return ds() % 1000; + return ds() % MSECS_PER_SEC; } #if QT_CONFIG(datestring) // depends on, so implies, textdate @@ -1939,7 +1940,7 @@ bool QTime::setHMS(int h, int m, int s, int ms) mds = NullTime; // make this invalid return false; } - mds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms; + mds = (h * SECS_PER_HOUR + m * SECS_PER_MIN + s) * MSECS_PER_SEC + ms; return true; } @@ -1961,7 +1962,7 @@ bool QTime::setHMS(int h, int m, int s, int ms) QTime QTime::addSecs(int s) const { s %= SECS_PER_DAY; - return addMSecs(s * 1000); + return addMSecs(s * MSECS_PER_SEC); } /*! @@ -1985,8 +1986,8 @@ int QTime::secsTo(QTime t) const return 0; // Truncate milliseconds as we do not want to consider them. - int ourSeconds = ds() / 1000; - int theirSeconds = t.ds() / 1000; + int ourSeconds = ds() / MSECS_PER_SEC; + int theirSeconds = t.ds() / MSECS_PER_SEC; return theirSeconds - ourSeconds; } @@ -2183,9 +2184,9 @@ static QTime fromIsoTimeString(QStringView string, Qt::DateFormat format, bool * Q_ASSERT(!(fraction < 0.0) && fraction < 1.0); // Round millis to nearest (unlike minutes and seconds, rounded down): - int msec = frac.ok ? qRound(1000 * fraction) : 0; + int msec = frac.ok ? qRound(MSECS_PER_SEC * fraction) : 0; // But handle overflow gracefully: - if (msec == 1000) { + if (msec == MSECS_PER_SEC) { // If we can (when data were otherwise valid) validly propagate overflow // into other fields, do so: if (isMidnight24 || hour.value < 23 || minute.value < 59 || second.value < 59) { @@ -2201,7 +2202,7 @@ static QTime fromIsoTimeString(QStringView string, Qt::DateFormat format, bool * } else { // QTime::fromString() or Qt::TextDate: rounding up would cause // 23:59:59.999... to become invalid; clip to 999 ms instead: - msec = 999; + msec = MSECS_PER_SEC - 1; } } @@ -2350,7 +2351,7 @@ QTime QTime::fromString(const QString &string, QStringView format) bool QTime::isValid(int h, int m, int s, int ms) { - return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000; + return uint(h) < 24 && uint(m) < 60 && uint(s) < SECS_PER_MIN && uint(ms) < MSECS_PER_SEC; } /***************************************************************************** @@ -2456,6 +2457,12 @@ static qint64 qt_mktime(QDate *date, QTime *time, QDateTimePrivate::DaylightStat int hh = local.tm_hour; #endif // Q_OS_WIN time_t secsSinceEpoch = qMkTime(&local); + // That can fail if we thought we knew DST-ness, but were wrong: + if (secsSinceEpoch == time_t(-1) && local.tm_isdst >= 0) { + local.tm_isdst = -1; + secsSinceEpoch = qMkTime(&local); + } + if (secsSinceEpoch != time_t(-1)) { *date = QDate(local.tm_year + 1900, local.tm_mon + 1, local.tm_mday); *time = QTime(local.tm_hour, local.tm_min, local.tm_sec, msec); @@ -2505,7 +2512,7 @@ static qint64 qt_mktime(QDate *date, QTime *time, QDateTimePrivate::DaylightStat if (ok) *ok = true; - return qint64(secsSinceEpoch) * 1000 + msec; + return qint64(secsSinceEpoch) * MSECS_PER_SEC + msec; } // Calls the platform variant of localtime for the given msecs, and updates @@ -2513,8 +2520,8 @@ static qint64 qt_mktime(QDate *date, QTime *time, QDateTimePrivate::DaylightStat static bool qt_localtime(qint64 msecsSinceEpoch, QDate *localDate, QTime *localTime, QDateTimePrivate::DaylightStatus *daylightStatus) { - const time_t secsSinceEpoch = msecsSinceEpoch / 1000; - const int msec = msecsSinceEpoch % 1000; + const time_t secsSinceEpoch = msecsSinceEpoch / MSECS_PER_SEC; + const int msec = msecsSinceEpoch % MSECS_PER_SEC; tm local; bool valid = false; @@ -2603,11 +2610,11 @@ static bool epochMSecsToLocalTime(qint64 msecs, QDate *localDate, QTime *localTi // Docs state any LocalTime before 1970-01-01 will *not* have any Daylight Time applied // Instead just use the standard offset from UTC to convert to UTC time qTzSet(); - msecsToTime(msecs - qt_timezone() * 1000, localDate, localTime); + msecsToTime(msecs - qt_timezone() * MSECS_PER_SEC, localDate, localTime); if (daylightStatus) *daylightStatus = QDateTimePrivate::StandardTime; return true; - } else if (msecs > (qint64(TIME_T_MAX) * 1000)) { + } else if (msecs > TIME_T_MAX * MSECS_PER_SEC) { // Docs state any LocalTime after 2037-12-31 *will* have any DST applied // but this may fall outside the supported time_t range, so need to fake it. // Use existing method to fake the conversion, but this is deeply flawed as it may @@ -2644,15 +2651,15 @@ static qint64 localMSecsToEpochMSecs(qint64 localMsecs, QTime tm; msecsToTime(localMsecs, &dt, &tm); - const qint64 msecsMax = qint64(TIME_T_MAX) * 1000; + const qint64 msecsMax = TIME_T_MAX * MSECS_PER_SEC; - if (localMsecs <= qint64(MSECS_PER_DAY)) { + if (localMsecs <= MSECS_PER_DAY) { // Docs state any LocalTime before 1970-01-01 will *not* have any DST applied // First, if localMsecs is within +/- 1 day of minimum time_t try mktime in case it does // fall after minimum and needs proper DST conversion - if (localMsecs >= -qint64(MSECS_PER_DAY)) { + if (localMsecs >= -MSECS_PER_DAY) { bool valid; qint64 utcMsecs = qt_mktime(&dt, &tm, daylightStatus, abbreviation, &valid); if (valid && utcMsecs >= 0) { @@ -2668,7 +2675,7 @@ static qint64 localMSecsToEpochMSecs(qint64 localMsecs, qTzSet(); } // Time is clearly before 1970-01-01 so just use standard offset to convert - qint64 utcMsecs = localMsecs + qt_timezone() * 1000; + qint64 utcMsecs = localMsecs + qt_timezone() * MSECS_PER_SEC; if (localDate || localTime) msecsToTime(localMsecs, localDate, localTime); if (daylightStatus) @@ -2867,10 +2874,14 @@ static void refreshZonedDateTime(QDateTimeData &d, Qt::TimeSpec spec) msecs, d->m_timeZone, dstStatus, &testDate, &testTime); #endif // timezone } // else: testDate, testTime haven't been set, so are invalid. - // Cache the offset to use in offsetFromUtc() &c. - offsetFromUtc = (msecs - epochMSecs) / 1000; - if (testDate.isValid() && testTime.isValid() - && timeToMSecs(testDate, testTime) == msecs) { + const bool ok = testDate.isValid() && testTime.isValid(); + // Cache the offset to use in offsetFromUtc() &c., even if the next + // check marks invalid; this lets fromMSecsSinceEpoch() give a useful + // fallback for times in spring-forward gaps. + if (ok) + offsetFromUtc = (msecs - epochMSecs) / MSECS_PER_SEC; + Q_ASSERT(offsetFromUtc >= -SECS_PER_DAY && offsetFromUtc <= SECS_PER_DAY); + if (ok && timeToMSecs(testDate, testTime) == msecs) { status = mergeDaylightStatus(status, dstStatus); status |= QDateTimePrivate::ValidDateTime; } else { @@ -3202,21 +3213,23 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT // Get the effective data from QTimeZone QTimeZonePrivate::Data data = zone.d->dataForLocalTime(zoneMSecs, int(hint)); Q_ASSERT(zone.d->offsetFromUtc(data.atMSecsSinceEpoch) == data.offsetFromUtc); - Q_ASSERT((zoneMSecs - data.atMSecsSinceEpoch) / 1000 == data.offsetFromUtc - // If zoneMSecs fell in a spring-forward's gap, we get this instead: - || (zoneMSecs - data.atMSecsSinceEpoch) / 1000 == data.standardTimeOffset - // If we have a second DST, like in Europe/Berlin 1947 (mid-summer time). - // If zoneMSecs fell in a gap at beginning of mid-summer time, we get this instead: - || (zoneMSecs - data.atMSecsSinceEpoch) / 1000 == 2 * data.standardTimeOffset - // If it fell in a skipped day (Pacific date-line crossings), this happens: - || (data.offsetFromUtc - (zoneMSecs - data.atMSecsSinceEpoch) / 1000) % 86400 == 0); + Q_ASSERT(([data](qint64 offset) { + return offset == data.offsetFromUtc + // When zoneMSecs falls in a spring-forward's gap: + || offset == data.standardTimeOffset + // When it falls in the gap leading into double-DST: + || offset == 2 * data.standardTimeOffset + // When it falls in a skipped day (Pacific date-line crossings): + || (data.offsetFromUtc - offset) % SECS_PER_DAY == 0; + })((zoneMSecs - data.atMSecsSinceEpoch) / MSECS_PER_SEC)); // Docs state any time before 1970-01-01 will *not* have any DST applied // but all affected times afterwards will have DST applied. if (data.atMSecsSinceEpoch < 0) { msecsToTime(zoneMSecs, zoneDate, zoneTime); - return zoneMSecs - data.standardTimeOffset * 1000; + return zoneMSecs - data.standardTimeOffset * MSECS_PER_SEC; } else { - msecsToTime(data.atMSecsSinceEpoch + data.offsetFromUtc * 1000, zoneDate, zoneTime); + msecsToTime(data.atMSecsSinceEpoch + data.offsetFromUtc * MSECS_PER_SEC, + zoneDate, zoneTime); return data.atMSecsSinceEpoch; } } @@ -3610,7 +3623,7 @@ int QDateTime::offsetFromUtc() const if (spec == Qt::LocalTime) { // we didn't cache the value, so we need to calculate it now... qint64 msecs = getMSecs(d); - return (msecs - toMSecsSinceEpoch()) / 1000; + return (msecs - toMSecsSinceEpoch()) / MSECS_PER_SEC; } Q_ASSERT(spec == Qt::UTC); @@ -3829,14 +3842,14 @@ qint64 QDateTime::toMSecsSinceEpoch() const case Qt::OffsetFromUTC: Q_ASSERT(!d.isShort()); - return d->m_msecs - (d->m_offsetFromUtc * 1000); + return d->m_msecs - d->m_offsetFromUtc * MSECS_PER_SEC; case Qt::LocalTime: { // recalculate the local timezone auto status = extractDaylightStatus(getStatus(d)); // If short, use offset saved by refreshZonedDateTime() on creation: if (!d.isShort()) - return d->m_msecs - d->m_offsetFromUtc * 1000; + return d->m_msecs - d->m_offsetFromUtc * MSECS_PER_SEC; // Offset from UTC not recorded: need to recompute. return localMSecsToEpochMSecs(getMSecs(d), &status); } @@ -3846,7 +3859,7 @@ qint64 QDateTime::toMSecsSinceEpoch() const #if QT_CONFIG(timezone) // Use offset refreshZonedDateTime() saved on creation: if (d->m_timeZone.isValid()) - return d->m_msecs - d->m_offsetFromUtc * 1000; + return d->m_msecs - d->m_offsetFromUtc * MSECS_PER_SEC; #endif return 0; } @@ -3871,7 +3884,7 @@ qint64 QDateTime::toMSecsSinceEpoch() const */ qint64 QDateTime::toSecsSinceEpoch() const { - return toMSecsSinceEpoch() / 1000; + return toMSecsSinceEpoch() / MSECS_PER_SEC; } /*! @@ -3899,7 +3912,7 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs) status |= QDateTimePrivate::ValidWhenMask; break; case Qt::OffsetFromUTC: - msecs += d->m_offsetFromUtc * 1000; + msecs += d->m_offsetFromUtc * MSECS_PER_SEC; status |= QDateTimePrivate::ValidWhenMask; break; case Qt::TimeZone: @@ -3920,7 +3933,7 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs) status = mergeDaylightStatus(status, QDateTimePrivate::StandardTime); d->m_offsetFromUtc = d->m_timeZone.d->standardTimeOffset(msecs); } - if (!add_overflow(msecs, qint64(d->m_offsetFromUtc * 1000), &msecs)) + if (!add_overflow(msecs, d->m_offsetFromUtc * MSECS_PER_SEC, &msecs)) status |= QDateTimePrivate::ValidWhenMask; #endif // timezone break; @@ -3966,7 +3979,7 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs) void QDateTime::setSecsSinceEpoch(qint64 secs) { qint64 msecs; - if (!mul_overflow(secs, std::integral_constant<qint64, 1000>(), &msecs)) { + if (!mul_overflow(secs, std::integral_constant<qint64, MSECS_PER_SEC>(), &msecs)) { setMSecsSinceEpoch(msecs); } else if (d.isShort()) { d.data.status &= ~QDateTimePrivate::ValidWhenMask; @@ -4237,7 +4250,7 @@ QDateTime QDateTime::addYears(int nyears) const QDateTime QDateTime::addSecs(qint64 s) const { qint64 msecs; - if (mul_overflow(s, std::integral_constant<qint64, 1000>(), &msecs)) + if (mul_overflow(s, std::integral_constant<qint64, MSECS_PER_SEC>(), &msecs)) return QDateTime(); return addMSecs(msecs); } @@ -4337,7 +4350,7 @@ qint64 QDateTime::daysTo(const QDateTime &other) const qint64 QDateTime::secsTo(const QDateTime &other) const { - return msecsTo(other) / 1000; + return msecsTo(other) / MSECS_PER_SEC; } /*! @@ -4589,7 +4602,7 @@ bool QDateTime::precedes(const QDateTime &other) const #if defined(Q_OS_WIN) static inline uint msecsFromDecomposed(int hour, int minute, int sec, int msec = 0) { - return MSECS_PER_HOUR * hour + MSECS_PER_MIN * minute + 1000 * sec + msec; + return MSECS_PER_HOUR * hour + MSECS_PER_MIN * minute + MSECS_PER_SEC * sec + msec; } QDate QDate::currentDate() @@ -4640,7 +4653,7 @@ qint64 QDateTime::currentMSecsSinceEpoch() noexcept const qint64 daysAfterEpoch = QDate(1970, 1, 1).daysTo(QDate(st.wYear, st.wMonth, st.wDay)); return msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds) + - daysAfterEpoch * Q_INT64_C(86400000); + daysAfterEpoch * MSECS_PER_DAY; } qint64 QDateTime::currentSecsSinceEpoch() noexcept @@ -4651,7 +4664,7 @@ qint64 QDateTime::currentSecsSinceEpoch() noexcept const qint64 daysAfterEpoch = QDate(1970, 1, 1).daysTo(QDate(st.wYear, st.wMonth, st.wDay)); return st.wHour * SECS_PER_HOUR + st.wMinute * SECS_PER_MIN + st.wSecond + - daysAfterEpoch * Q_INT64_C(86400); + daysAfterEpoch * SECS_PER_DAY; } #elif defined(Q_OS_UNIX) @@ -4681,14 +4694,14 @@ qint64 QDateTime::currentMSecsSinceEpoch() noexcept // we have milliseconds struct timeval tv; gettimeofday(&tv, nullptr); - return qint64(tv.tv_sec) * Q_INT64_C(1000) + tv.tv_usec / 1000; + return tv.tv_sec * MSECS_PER_SEC + tv.tv_usec / 1000; } qint64 QDateTime::currentSecsSinceEpoch() noexcept { struct timeval tv; gettimeofday(&tv, nullptr); - return qint64(tv.tv_sec); + return tv.tv_sec; } #else #error "What system is this?" @@ -4742,11 +4755,11 @@ QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int of */ QDateTime QDateTime::fromSecsSinceEpoch(qint64 secs, Qt::TimeSpec spec, int offsetSeconds) { - constexpr qint64 maxSeconds = std::numeric_limits<qint64>::max() / 1000; - constexpr qint64 minSeconds = std::numeric_limits<qint64>::min() / 1000; + constexpr qint64 maxSeconds = std::numeric_limits<qint64>::max() / MSECS_PER_SEC; + constexpr qint64 minSeconds = std::numeric_limits<qint64>::min() / MSECS_PER_SEC; if (secs > maxSeconds || secs < minSeconds) return QDateTime(); // Would {und,ov}erflow - return fromMSecsSinceEpoch(secs * 1000, spec, offsetSeconds); + return fromMSecsSinceEpoch(secs * MSECS_PER_SEC, spec, offsetSeconds); } #if QT_CONFIG(timezone) @@ -4779,11 +4792,11 @@ QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone */ QDateTime QDateTime::fromSecsSinceEpoch(qint64 secs, const QTimeZone &timeZone) { - constexpr qint64 maxSeconds = std::numeric_limits<qint64>::max() / 1000; - constexpr qint64 minSeconds = std::numeric_limits<qint64>::min() / 1000; + constexpr qint64 maxSeconds = std::numeric_limits<qint64>::max() / MSECS_PER_SEC; + constexpr qint64 minSeconds = std::numeric_limits<qint64>::min() / MSECS_PER_SEC; if (secs > maxSeconds || secs < minSeconds) return QDateTime(); // Would {und,ov}erflow - return fromMSecsSinceEpoch(secs * 1000, timeZone); + return fromMSecsSinceEpoch(secs * MSECS_PER_SEC, timeZone); } #endif diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp index b17135ef36..d85a904450 100644 --- a/src/corelib/time/qdatetimeparser.cpp +++ b/src/corelib/time/qdatetimeparser.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -2132,15 +2132,9 @@ bool QDateTimeParser::fromString(const QString &t, QDateTime* datetime) const { QDateTime val(QDate(1900, 1, 1).startOfDay()); const StateNode tmp = parse(t, -1, val, false); - if (tmp.state != Acceptable || tmp.conflicts) - return false; - if (datetime) { - if (!tmp.value.isValid()) - return false; + if (datetime) *datetime = tmp.value; - } - - return true; + return tmp.state == Acceptable && !tmp.conflicts && tmp.value.isValid(); } QDateTime QDateTimeParser::getMinimum() const diff --git a/src/corelib/time/qtimezoneprivate.cpp b/src/corelib/time/qtimezoneprivate.cpp index 8b37c78241..5588cf8cce 100644 --- a/src/corelib/time/qtimezoneprivate.cpp +++ b/src/corelib/time/qtimezoneprivate.cpp @@ -43,6 +43,7 @@ #include "qtimezoneprivate_p.h" #include "qtimezoneprivate_data_p.h" +#include <private/qnumeric_p.h> #include <qdatastream.h> #include <qdebug.h> @@ -274,11 +275,19 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs, offset sixteen hours each side gives us information we can be sure brackets the correct time and at most one DST transition. */ - const qint64 sixteenHoursInMSecs(16 * 3600 * 1000); + std::integral_constant<qint64, 16 * 3600 * 1000> sixteenHoursInMSecs; static_assert(-sixteenHoursInMSecs / 1000 < QTimeZone::MinUtcOffsetSecs && sixteenHoursInMSecs / 1000 > QTimeZone::MaxUtcOffsetSecs); - const qint64 recent = forLocalMSecs - sixteenHoursInMSecs; - const qint64 imminent = forLocalMSecs + sixteenHoursInMSecs; + using Bound = std::numeric_limits<qint64>; + qint64 millis; + const qint64 recent = + sub_overflow(forLocalMSecs, sixteenHoursInMSecs, &millis) + ? Bound::min() : millis; + const qint64 imminent = + add_overflow(forLocalMSecs, sixteenHoursInMSecs, &millis) + ? Bound::max() : millis; + // At most one of those took the boundary value: + Q_ASSERT(recent < imminent && sixteenHoursInMSecs < imminent - recent); /* Offsets are Local - UTC, positive to the east of Greenwich, negative to the west; DST offset always exceeds standard offset, when DST applies. @@ -374,11 +383,13 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs, if (tran.atMSecsSinceEpoch != invalidMSecs()) { /* - So now tran is definitely before and nextTran is either after or only - slightly before. One is standard time; we interpret the other as DST - (although the transition might in fact by a change in standard offset). Our - hint tells us which of those to use (defaulting to standard if no hint): try - it first; if that fails, try the other; if both fail, life's tricky. + So now tran is definitely before and nextTran is either after or + only slightly before. We're going to interpret one as standard + time, the other as DST (although the transition might in fact by a + change in standard offset, or a chance in DST offset, e.g. to/from + double-DST). Our hint tells us which of those to use (defaulting + to standard if no hint): try it first; if that fails, try the + other; if both fail, life's tricky. */ Q_ASSERT(forLocalMSecs < 0 || forLocalMSecs - tran.offsetFromUtc * 1000 > tran.atMSecsSinceEpoch); @@ -425,8 +436,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs, nextTran.atMSecsSinceEpoch += dstStep; return nextTran; } - // System has transitions but not for this zone. - // Try falling back to offsetFromUtc + // Before first transition, or system has transitions but not for this zone. + // Try falling back to offsetFromUtc (works for before first transition, at least). } /* Bracket and refine to discover offset. */ diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp index 09ac40b50e..4be339b299 100644 --- a/src/gui/painting/qicc.cpp +++ b/src/gui/painting/qicc.cpp @@ -176,7 +176,7 @@ struct ParaTagData : GenericTagData { struct DescTagData : GenericTagData { quint32_be asciiDescriptionLength; - char asciiDescription[1]; + // followed by ascii description: char[] // .. we ignore the rest }; @@ -599,18 +599,14 @@ bool parseDesc(const QByteArray &data, const TagEntry &tagEntry, QString &descNa // Either 'desc' (ICCv2) or 'mluc' (ICCv4) if (tag.type == quint32(Tag::desc)) { - if (tagEntry.size < sizeof(DescTagData)) - return false; + Q_STATIC_ASSERT(sizeof(DescTagData) == 12); const DescTagData desc = qFromUnaligned<DescTagData>(data.constData() + tagEntry.offset); const quint32 len = desc.asciiDescriptionLength; if (len < 1) return false; if (tagEntry.size - 12 < len) return false; - static_assert(sizeof(GenericTagData) == 2 * sizeof(quint32_be), - "GenericTagData has padding. The following code is a subject to UB."); - const char *asciiDescription = data.constData() + tagEntry.offset + sizeof(GenericTagData) - + sizeof(quint32_be); + const char *asciiDescription = data.constData() + tagEntry.offset + sizeof(DescTagData); if (asciiDescription[len - 1] != '\0') return false; descName = QString::fromLatin1(asciiDescription, len - 1); diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 05a5ec4420..46ed67ea7d 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -1143,14 +1143,14 @@ static bool setFontSizeFromValue(QCss::Value value, QFont *font, int *fontSizeAd s.chop(2); value.variant = s; if (value.variant.convert(QMetaType::fromType<qreal>())) { - font->setPointSizeF(value.variant.toReal()); + font->setPointSizeF(qBound(qreal(0), value.variant.toReal(), qreal(1 << 24) - 1)); valid = true; } } else if (s.endsWith(QLatin1String("px"), Qt::CaseInsensitive)) { s.chop(2); value.variant = s; if (value.variant.convert(QMetaType::fromType<int>())) { - font->setPixelSize(value.variant.toInt()); + font->setPixelSize(qBound(0, value.variant.toInt(), (1 << 24) - 1)); valid = true; } } |