tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 7fef2786530c578c948cf0f90487ff6eb6a83672
parent cf779e134b734420732099f0c0953365a6c5eee5
Author: serge-sans-paille <sguelton@mozilla.com>
Date:   Wed, 22 Oct 2025 08:52:18 +0000

Bug 1993171 - Cleanup mfbt/MathAlgorithms.h r=emilio,win-reviewers,layout-reviewers,gstoll

- Remove DeprecatedAbs, replacing its usage by Abs or std::abs + explicit
  MOZ_ASSERT where it makes sense

- Use std::numeric_limits<...> instead of equivalent C headers

Differential Revision: https://phabricator.services.mozilla.com/D267914

Diffstat:
Mdocshell/shistory/nsSHistory.cpp | 14++++++++------
Mdom/events/EventStateManager.cpp | 31+++++++++++++++++--------------
Meditor/libeditor/HTMLEditorObjectResizer.cpp | 6++++--
Mlayout/tables/nsTableFrame.cpp | 8++++----
Mmemory/build/Utils.h | 2+-
Mmfbt/MathAlgorithms.h | 70+++++++++++++++++++++++-----------------------------------------------
Mmfbt/tests/TestCeilingFloor.cpp | 7++++++-
Mmozglue/misc/TimeStamp_windows.cpp | 11+++++++----
Mwidget/windows/nsWindow.cpp | 26++++++++++++++++----------
Mxpcom/io/nsMultiplexInputStream.cpp | 5++---
10 files changed, 88 insertions(+), 92 deletions(-)

diff --git a/docshell/shistory/nsSHistory.cpp b/docshell/shistory/nsSHistory.cpp @@ -1880,6 +1880,9 @@ void nsSHistory::GloballyEvictDocumentViewers() { nsCOMPtr<nsISHEntry> entry = shist->mEntries[i]; nsCOMPtr<nsIDocumentViewer> viewer = entry->GetDocumentViewer(); + MOZ_ASSERT(mozilla::IsValidAbsArgument(i - shist->mIndex)); + const int32_t idiff = std::abs(i - shist->mIndex); + bool found = false; bool hasDocumentViewerOrFrameLoader = false; if (viewer) { @@ -1891,8 +1894,7 @@ void nsSHistory::GloballyEvictDocumentViewers() { for (uint32_t j = 0; j < shEntries.Length(); j++) { EntryAndDistance& container = shEntries[j]; if (container.mViewer == viewer) { - container.mDistance = - std::min(container.mDistance, DeprecatedAbs(i - shist->mIndex)); + container.mDistance = std::min(container.mDistance, idiff); found = true; break; } @@ -1904,8 +1906,8 @@ void nsSHistory::GloballyEvictDocumentViewers() { for (uint32_t j = 0; j < shEntries.Length(); j++) { EntryAndDistance& container = shEntries[j]; if (container.mFrameLoader == frameLoader) { - container.mDistance = std::min(container.mDistance, - DeprecatedAbs(i - shist->mIndex)); + container.mDistance = std::min(container.mDistance, idiff); + ; found = true; break; } @@ -1916,8 +1918,8 @@ void nsSHistory::GloballyEvictDocumentViewers() { // If we didn't find a EntryAndDistance for this content viewer / // frameloader, make a new one. if (hasDocumentViewerOrFrameLoader && !found) { - EntryAndDistance container(shist, entry, - DeprecatedAbs(i - shist->mIndex)); + MOZ_ASSERT(mozilla::IsValidAbsArgument(i - shist->mIndex)); + EntryAndDistance container(shist, entry, std::abs(i - shist->mIndex)); shEntries.AppendElement(container); } } diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp @@ -3647,20 +3647,23 @@ void EventStateManager::DoScrollText( nsSize pageSize = aScrollContainerFrame->GetPageScrollAmount(); nsIntSize devPixelPageSize(pc->AppUnitsToDevPixels(pageSize.width), pc->AppUnitsToDevPixels(pageSize.height)); - if (!WheelPrefs::GetInstance()->IsOverOnePageScrollAllowedX(aEvent) && - DeprecatedAbs(actualDevPixelScrollAmount.x.value) > - devPixelPageSize.width) { - actualDevPixelScrollAmount.x = (actualDevPixelScrollAmount.x >= 0) - ? devPixelPageSize.width - : -devPixelPageSize.width; - } - - if (!WheelPrefs::GetInstance()->IsOverOnePageScrollAllowedY(aEvent) && - DeprecatedAbs(actualDevPixelScrollAmount.y.value) > - devPixelPageSize.height) { - actualDevPixelScrollAmount.y = (actualDevPixelScrollAmount.y >= 0) - ? devPixelPageSize.height - : -devPixelPageSize.height; + if (!WheelPrefs::GetInstance()->IsOverOnePageScrollAllowedX(aEvent)) { + MOZ_ASSERT(mozilla::IsValidAbsArgument(actualDevPixelScrollAmount.x.value)); + if (std::abs(actualDevPixelScrollAmount.x.value) > devPixelPageSize.width) { + actualDevPixelScrollAmount.x = (actualDevPixelScrollAmount.x >= 0) + ? devPixelPageSize.width + : -devPixelPageSize.width; + } + } + + if (!WheelPrefs::GetInstance()->IsOverOnePageScrollAllowedY(aEvent)) { + MOZ_ASSERT(mozilla::IsValidAbsArgument(actualDevPixelScrollAmount.y.value)); + if (std::abs(actualDevPixelScrollAmount.y.value) > + devPixelPageSize.height) { + actualDevPixelScrollAmount.y = (actualDevPixelScrollAmount.y >= 0) + ? devPixelPageSize.height + : -devPixelPageSize.height; + } } bool isDeltaModePixel = diff --git a/editor/libeditor/HTMLEditorObjectResizer.cpp b/editor/libeditor/HTMLEditorObjectResizer.cpp @@ -1163,8 +1163,10 @@ nsresult HTMLEditor::UpdateResizerOrGrabberPositionTo( int32_t yThreshold = LookAndFeel::GetInt(LookAndFeel::IntID::DragThresholdY, 1); - if (DeprecatedAbs(aClientPoint.x - mOriginalX) * 2 >= xThreshold || - DeprecatedAbs(aClientPoint.y - mOriginalY) * 2 >= yThreshold) { + MOZ_ASSERT(mozilla::IsValidAbsArgument(aClientPoint.x - mOriginalX)); + MOZ_ASSERT(mozilla::IsValidAbsArgument(aClientPoint.y - mOriginalY)); + if (std::abs(aClientPoint.x - mOriginalX) * 2 >= xThreshold || + std::abs(aClientPoint.y - mOriginalY) * 2 >= yThreshold) { mGrabberClicked = false; DebugOnly<nsresult> rvIgnored = StartMoving(); NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored), diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp @@ -6132,10 +6132,10 @@ bool BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) { if (!haveIntersect) { return false; } - mDamageArea = - TableArea(startColIndex, startRowIndex, - 1 + DeprecatedAbs<int32_t>(endColIndex - startColIndex), - 1 + endRowIndex - startRowIndex); + MOZ_ASSERT(mozilla::IsValidAbsArgument(int32_t(endColIndex - startColIndex))); + mDamageArea = TableArea(startColIndex, startRowIndex, + 1 + std::abs(int32_t(endColIndex - startColIndex)), + 1 + endRowIndex - startRowIndex); Reset(); mBlockDirInfo = MakeUnique<BCBlockDirSeg[]>(mDamageArea.ColCount() + 1); diff --git a/memory/build/Utils.h b/memory/build/Utils.h @@ -161,7 +161,7 @@ class FastDivisor { unsigned m_ = ((1U << p) + div - 1 - (((1U << p) - 1) % div)) / div; // Make sure that max * m does not overflow. - MOZ_DIAGNOSTIC_ASSERT(max < UINT_MAX / m_); + MOZ_DIAGNOSTIC_ASSERT(max < std::numeric_limits<unsigned int>::max() / m_); MOZ_ASSERT(m_ <= std::numeric_limits<T>::max()); m = static_cast<T>(m_); diff --git a/mfbt/MathAlgorithms.h b/mfbt/MathAlgorithms.h @@ -13,7 +13,7 @@ #include <algorithm> #include <cmath> -#include <climits> +#include <limits> #include <cstdint> #include <type_traits> @@ -21,46 +21,6 @@ namespace mozilla { namespace detail { -template <typename T> -struct AllowDeprecatedAbsFixed : std::false_type {}; - -template <> -struct AllowDeprecatedAbsFixed<int32_t> : std::true_type {}; -template <> -struct AllowDeprecatedAbsFixed<int64_t> : std::true_type {}; - -template <typename T> -struct AllowDeprecatedAbs : AllowDeprecatedAbsFixed<T> {}; - -template <> -struct AllowDeprecatedAbs<int> : std::true_type {}; -template <> -struct AllowDeprecatedAbs<long> : std::true_type {}; - -} // namespace detail - -// DO NOT USE DeprecatedAbs. It exists only until its callers can be converted -// to Abs below, and it will be removed when all callers have been changed. -template <typename T> -inline std::enable_if_t<detail::AllowDeprecatedAbs<T>::value, T> DeprecatedAbs( - const T aValue) { - // The absolute value of the smallest possible value of a signed-integer type - // won't fit in that type (on twos-complement systems -- and we're blithely - // assuming we're on such systems, for the non-<stdint.h> types listed above), - // so assert that the input isn't that value. - // - // This is the case if: the value is non-negative; or if adding one (giving a - // value in the range [-maxvalue, 0]), then negating (giving a value in the - // range [0, maxvalue]), doesn't produce maxvalue (because in twos-complement, - // (minvalue + 1) == -maxvalue). - MOZ_ASSERT(aValue >= 0 || - -(aValue + 1) != T((1ULL << (CHAR_BIT * sizeof(T) - 1)) - 1), - "You can't negate the smallest possible negative integer!"); - return aValue >= 0 ? aValue : -aValue; -} - -namespace detail { - template <typename T, typename = void> struct AbsReturnType; @@ -77,6 +37,13 @@ struct AbsReturnType<T, std::enable_if_t<std::is_floating_point_v<T>>> { } // namespace detail +template <class T> +constexpr bool IsValidAbsArgument(T val) { + static_assert(std::is_integral_v<T> && std::is_signed_v<T>, + "no need to validate unsigned or floating point type"); + return val != std::numeric_limits<T>::min(); +} + template <typename T> inline constexpr typename detail::AbsReturnType<T>::Type Abs(const T aValue) { using ReturnType = typename detail::AbsReturnType<T>::Type; @@ -294,8 +261,11 @@ constexpr uint_fast8_t FloorLog2Size(size_t aValue) { * be so great that the computed value would overflow |size_t|. */ constexpr size_t RoundUpPow2(size_t aValue) { - MOZ_ASSERT(aValue <= (size_t(1) << (sizeof(size_t) * CHAR_BIT - 1)), - "can't round up -- will overflow!"); + MOZ_ASSERT( + aValue <= (size_t(1) << (sizeof(size_t) * + std::numeric_limits<unsigned char>::digits - + 1)), + "can't round up -- will overflow!"); return size_t(1) << CeilingLog2(aValue); } @@ -307,14 +277,17 @@ MOZ_NO_SANITIZE_UNSIGNED_OVERFLOW constexpr T RotateLeft(const T aValue, uint_fast8_t aShift) { static_assert(std::is_unsigned_v<T>, "Rotates require unsigned values"); - MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!"); + MOZ_ASSERT(aShift < sizeof(T) * std::numeric_limits<unsigned char>::digits, + "Shift value is too large!"); MOZ_ASSERT(aShift > 0, "Rotation by value length is undefined behavior, but compilers " "do not currently fold a test into the rotate instruction. " "Please remove this restriction when compilers optimize the " "zero case (http://blog.regehr.org/archives/1063)."); - return (aValue << aShift) | (aValue >> (sizeof(T) * CHAR_BIT - aShift)); + return (aValue << aShift) | + (aValue >> + (sizeof(T) * std::numeric_limits<unsigned char>::digits - aShift)); } /** @@ -325,14 +298,17 @@ MOZ_NO_SANITIZE_UNSIGNED_OVERFLOW constexpr T RotateRight(const T aValue, uint_fast8_t aShift) { static_assert(std::is_unsigned_v<T>, "Rotates require unsigned values"); - MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!"); + MOZ_ASSERT(aShift < sizeof(T) * std::numeric_limits<unsigned char>::digits, + "Shift value is too large!"); MOZ_ASSERT(aShift > 0, "Rotation by value length is undefined behavior, but compilers " "do not currently fold a test into the rotate instruction. " "Please remove this restriction when compilers optimize the " "zero case (http://blog.regehr.org/archives/1063)."); - return (aValue >> aShift) | (aValue << (sizeof(T) * CHAR_BIT - aShift)); + return (aValue >> aShift) | + (aValue << (sizeof(T) * std::numeric_limits<unsigned char>::digits - + aShift)); } /** diff --git a/mfbt/tests/TestCeilingFloor.cpp b/mfbt/tests/TestCeilingFloor.cpp @@ -6,6 +6,8 @@ #include "mozilla/MathAlgorithms.h" +#include <limits> + using mozilla::CeilingLog2; using mozilla::FloorLog2; using mozilla::RoundUpPow2; @@ -66,7 +68,10 @@ static void TestRoundUpPow2() { MOZ_RELEASE_ASSERT(RoundUpPow2(32) == 32); MOZ_RELEASE_ASSERT(RoundUpPow2(33) == 64); - size_t MaxPow2 = size_t(1) << (sizeof(size_t) * CHAR_BIT - 1); + size_t MaxPow2 = size_t(1) + << (sizeof(size_t) * + std::numeric_limits<unsigned char>::digits - + 1); MOZ_RELEASE_ASSERT(RoundUpPow2(MaxPow2 - 1) == MaxPow2); MOZ_RELEASE_ASSERT(RoundUpPow2(MaxPow2) == MaxPow2); // not valid to round up when past the max power of two diff --git a/mozglue/misc/TimeStamp_windows.cpp b/mozglue/misc/TimeStamp_windows.cpp @@ -101,7 +101,7 @@ static LONGLONG sGTCResolutionThreshold; // Value is in [ms]. static const uint32_t kHardFailureLimit = 2000; // Conversion to [mt] -static LONGLONG sHardFailureLimit; +static uint64_t sHardFailureLimit; // Conversion of kFailureFreeInterval and kFailureThreshold to [mt] static LONGLONG sFailureFreeInterval; @@ -268,6 +268,7 @@ MFBT_API TimeStampValue& TimeStampValue::operator-=(const int64_t aOther) { // If the duration is less then two seconds, perform check of QPC stability // by comparing both GTC and QPC calculated durations of this and aOther. MFBT_API uint64_t TimeStampValue::CheckQPC(const TimeStampValue& aOther) const { + MOZ_ASSERT(mGTC >= aOther.mGTC); uint64_t deltaGTC = mGTC - aOther.mGTC; if (!mHasQPC || !aOther.mHasQPC) { // Both not holding QPC @@ -281,13 +282,15 @@ MFBT_API uint64_t TimeStampValue::CheckQPC(const TimeStampValue& aOther) const { } // Check QPC is sane before using it. - int64_t diff = DeprecatedAbs(int64_t(deltaQPC) - int64_t(deltaGTC)); - if (diff <= sGTCResolutionThreshold) { + uint64_t diff = + deltaQPC > deltaGTC ? deltaQPC - deltaGTC : deltaGTC - deltaQPC; + MOZ_ASSERT(sGTCResolutionThreshold >= 0); + if (diff <= (uint64_t)sGTCResolutionThreshold) { return deltaQPC; } // Treat absolutely for calibration purposes - int64_t duration = DeprecatedAbs(int64_t(deltaGTC)); + uint64_t duration = deltaGTC; int64_t overflow = diff - sGTCResolutionThreshold; LOG(("TimeStamp: QPC check after %llums with overflow %1.4fms", diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp @@ -4281,11 +4281,15 @@ bool nsWindow::DispatchMouseEvent(EventMessage aEventMessage, WPARAM wParam, static LONG sLastClickCount = 0L; static BYTE sLastMouseButton = 0; + // By definition, those should be non-negative. + MOZ_ASSERT(::GetSystemMetrics(SM_CXDOUBLECLK) >= 0); + MOZ_ASSERT(::GetSystemMetrics(SM_CYDOUBLECLK) >= 0); + bool insideMovementThreshold = - (DeprecatedAbs(sLastMousePoint.x - eventPoint.x.value) < - (short)::GetSystemMetrics(SM_CXDOUBLECLK)) && - (DeprecatedAbs(sLastMousePoint.y - eventPoint.y.value) < - (short)::GetSystemMetrics(SM_CYDOUBLECLK)); + (Abs(sLastMousePoint.x - eventPoint.x.value) < + (unsigned)::GetSystemMetrics(SM_CXDOUBLECLK)) && + (Abs(sLastMousePoint.y - eventPoint.y.value) < + (unsigned)::GetSystemMetrics(SM_CYDOUBLECLK)); BYTE eventButton; switch (aButton) { @@ -6830,12 +6834,14 @@ bool nsWindow::OnGesture(WPARAM wParam, LPARAM lParam) { } if (mDisplayPanFeedback) { - mGesture.UpdatePanFeedbackX( - mWnd, DeprecatedAbs(RoundDown(wheelEvent.mOverflowDeltaX)), - endFeedback); - mGesture.UpdatePanFeedbackY( - mWnd, DeprecatedAbs(RoundDown(wheelEvent.mOverflowDeltaY)), - endFeedback); + const auto RoundedDeltaX = RoundDown(wheelEvent.mOverflowDeltaX); + MOZ_ASSERT(mozilla::IsValidAbsArgument(RoundedDeltaX)); + mGesture.UpdatePanFeedbackX(mWnd, std::abs(RoundedDeltaX), endFeedback); + + const auto RoundedDeltaY = RoundDown(wheelEvent.mOverflowDeltaY); + MOZ_ASSERT(mozilla::IsValidAbsArgument(RoundedDeltaY)); + mGesture.UpdatePanFeedbackY(mWnd, std::abs(RoundedDeltaY), endFeedback); + mGesture.PanFeedbackFinalize(mWnd, endFeedback); } diff --git a/xpcom/io/nsMultiplexInputStream.cpp b/xpcom/io/nsMultiplexInputStream.cpp @@ -34,8 +34,6 @@ using namespace mozilla; using namespace mozilla::ipc; -using mozilla::DeprecatedAbs; - NS_IMPL_ADDREF(nsMultiplexInputStream) NS_IMPL_RELEASE(nsMultiplexInputStream) @@ -559,9 +557,10 @@ nsMultiplexInputStream::Seek(int32_t aWhence, int64_t aOffset) { } int64_t streamLength = avail + mStreams[i].mCurrentPos; + MOZ_ASSERT(mozilla::IsValidAbsArgument(remaining)); // The seek(END) can be completed in the current stream. - if (streamLength >= DeprecatedAbs(remaining)) { + if (streamLength >= std::abs(remaining)) { rv = stream->Seek(NS_SEEK_END, remaining); if (NS_WARN_IF(NS_FAILED(rv))) { return rv;