diff --git a/dom/base/DOMQuad.cpp b/dom/base/DOMQuad.cpp index 258bfc1bfd..dac3b370f7 100644 --- a/dom/base/DOMQuad.cpp +++ b/dom/base/DOMQuad.cpp @@ -8,7 +8,7 @@ #include "mozilla/dom/DOMQuadBinding.h" #include "mozilla/dom/DOMPoint.h" #include "mozilla/dom/DOMRect.h" -#include +#include "mozilla/FloatingPoint.h" using namespace mozilla; using namespace mozilla::dom; @@ -106,8 +106,8 @@ DOMQuad::GetHorizontalMinMax(double* aX1, double* aX2) const x1 = x2 = Point(0)->X(); for (uint32_t i = 1; i < 4; ++i) { double x = Point(i)->X(); - x1 = std::min(x1, x); - x2 = std::max(x2, x); + x1 = NaNSafeMin(x1, x); + x2 = NaNSafeMax(x2, x); } *aX1 = x1; *aX2 = x2; @@ -120,8 +120,8 @@ DOMQuad::GetVerticalMinMax(double* aY1, double* aY2) const y1 = y2 = Point(0)->Y(); for (uint32_t i = 1; i < 4; ++i) { double y = Point(i)->Y(); - y1 = std::min(y1, y); - y2 = std::max(y2, y); + y1 = NaNSafeMin(y1, y); + y2 = NaNSafeMax(y2, y); } *aY1 = y1; *aY2 = y2; diff --git a/dom/base/DOMRect.h b/dom/base/DOMRect.h index 541ff02539..58792c8590 100644 --- a/dom/base/DOMRect.h +++ b/dom/base/DOMRect.h @@ -16,7 +16,7 @@ #include "mozilla/Attributes.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/ErrorResult.h" -#include +#include "mozilla/FloatingPoint.h" struct nsRect; @@ -79,22 +79,22 @@ public: double Left() const { double x = X(), w = Width(); - return std::min(x, x + w); + return NaNSafeMin(x, x + w); } double Top() const { double y = Y(), h = Height(); - return std::min(y, y + h); + return NaNSafeMin(y, y + h); } double Right() const { double x = X(), w = Width(); - return std::max(x, x + w); + return NaNSafeMax(x, x + w); } double Bottom() const { double y = Y(), h = Height(); - return std::max(y, y + h); + return NaNSafeMax(y, y + h); } bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const; diff --git a/mfbt/FloatingPoint.h b/mfbt/FloatingPoint.h index a2846ce298..5fc449b49d 100644 --- a/mfbt/FloatingPoint.h +++ b/mfbt/FloatingPoint.h @@ -14,6 +14,7 @@ #include "mozilla/MathAlgorithms.h" #include "mozilla/Types.h" +#include #include namespace mozilla { @@ -450,6 +451,30 @@ EqualOrBothNaN(T aValue1, T aValue2) return aValue1 == aValue2; } +/** + * Return NaN if either |aValue1| or |aValue2| is NaN, or the minimum of + * |aValue1| and |aValue2| otherwise. + */ +template +static inline T NaNSafeMin(T aValue1, T aValue2) { + if (IsNaN(aValue1) || IsNaN(aValue2)) { + return UnspecifiedNaN(); + } + return std::min(aValue1, aValue2); +} + +/** + * Return NaN if either |aValue1| or |aValue2| is NaN, or the maximum of + * |aValue1| and |aValue2| otherwise. + */ +template +static inline T NaNSafeMax(T aValue1, T aValue2) { + if (IsNaN(aValue1) || IsNaN(aValue2)) { + return UnspecifiedNaN(); + } + return std::max(aValue1, aValue2); +} + namespace detail { template