diff --git a/js/public/Value.h b/js/public/Value.h index 3c686b8172a5..d08442f58080 100644 --- a/js/public/Value.h +++ b/js/public/Value.h @@ -10,6 +10,7 @@ #define js_Value_h #include "mozilla/Attributes.h" +#include "mozilla/Casting.h" #include "mozilla/FloatingPoint.h" #include "mozilla/Likely.h" @@ -340,14 +341,10 @@ class MOZ_NON_PARAM alignas(8) Value } void setDouble(double d) { - setDoubleNoCheck(d); - MOZ_ASSERT(isDouble()); - } - - void setDoubleNoCheck(double d) { // Don't assign to data.asDouble to fix a miscompilation with // GCC 5.2.1 and 5.3.1. See bug 1312488. data = layout(d); + MOZ_ASSERT(isDouble()); } void setNaN() { @@ -1025,6 +1022,17 @@ CanonicalizedDoubleValue(double d) : Value::fromDouble(d); } +static inline bool +IsCanonicalized(double d) +{ + if (mozilla::IsInfinite(d) || mozilla::IsFinite(d)) + return true; + + uint64_t bits; + mozilla::BitwiseCast(d, &bits); + return (bits & ~mozilla::DoubleTypeTraits::kSignBit) == detail::CanonicalizedNaNBits; +} + static inline Value DoubleNaNValue() { diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 2ff50cb4e0cd..7ac6297d913d 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -1617,9 +1617,7 @@ JSStructuredCloneWriter::write(HandleValue v) bool JSStructuredCloneReader::checkDouble(double d) { - JS::Value v; - v.setDoubleNoCheck(d); - if (!v.isDouble()) { + if (!JS::IsCanonicalized(d)) { JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA, "unrecognized NaN"); return false;