diff --git a/dom/base/ResponsiveImageSelector.cpp b/dom/base/ResponsiveImageSelector.cpp index 75ff1a499c29..ee8333300a40 100644 --- a/dom/base/ResponsiveImageSelector.cpp +++ b/dom/base/ResponsiveImageSelector.cpp @@ -43,6 +43,66 @@ ParseInteger(const nsAString& aString, int32_t& aInt) nsContentUtils::eParseHTMLInteger_NonStandard )); } +static bool +ParseFloat(const nsAString& aString, double& aDouble) +{ + // Check if it is a valid floating-point number first since the result of + // nsString.ToDouble() is more lenient than the spec, + // https://html.spec.whatwg.org/#valid-floating-point-number + nsAString::const_iterator iter, end; + aString.BeginReading(iter); + aString.EndReading(end); + + if (iter == end) { + return false; + } + + if (*iter == char16_t('-') && ++iter == end) { + return false; + } + + if (nsCRT::IsAsciiDigit(*iter)) { + for (; iter != end && nsCRT::IsAsciiDigit(*iter) ; ++iter); + } else if (*iter == char16_t('.')) { + // Do nothing, jumps to fraction part + } else { + return false; + } + + // Fraction + if (*iter == char16_t('.')) { + ++iter; + if (iter == end || !nsCRT::IsAsciiDigit(*iter)) { + // U+002E FULL STOP character (.) must be followed by one or more ASCII digits + return false; + } + + for (; iter != end && nsCRT::IsAsciiDigit(*iter) ; ++iter); + } + + if (iter != end && (*iter == char16_t('e') || *iter == char16_t('E'))) { + ++iter; + if (*iter == char16_t('-') || *iter == char16_t('+')) { + ++iter; + } + + if (iter == end || !nsCRT::IsAsciiDigit(*iter)) { + // Should have one or more ASCII digits + return false; + } + + for (; iter != end && nsCRT::IsAsciiDigit(*iter) ; ++iter); + } + + if (iter != end) { + return false; + } + + nsresult rv; + aDouble = PromiseFlatString(aString).ToDouble(&rv); + return NS_SUCCEEDED(rv); +} + ResponsiveImageSelector::ResponsiveImageSelector(nsIContent *aContent) : mOwnerNode(aContent), mSelectedCandidateIndex(-1) @@ -533,9 +593,8 @@ ResponsiveImageDescriptors::AddDescriptor(const nsAString& aDescriptor) } else if (*descType == char16_t('x')) { // If the value is not a valid floating point number, it doesn't match this // descriptor, fall through. - nsresult rv; - double possibleDensity = PromiseFlatString(valueStr).ToDouble(&rv); - if (NS_SUCCEEDED(rv)) { + double possibleDensity = 0.0; + if (ParseFloat(valueStr, possibleDensity)) { if (possibleDensity >= 0.0 && mWidth.isNothing() && mDensity.isNothing() && diff --git a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini deleted file mode 100644 index d2816f941813..000000000000 --- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini +++ /dev/null @@ -1,20 +0,0 @@ -[parse-a-srcset-attribute.html] - type: testharness - ["data:,a 1.x"] - expected: FAIL - - ["data:,a +1x"] - expected: FAIL - - ["data:,a  1x" (leading U+2009)] - expected: FAIL - - ["data:,a  1x" (leading U+200A)] - expected: FAIL - - ["data:,a ‌1x" (leading U+200C)] - expected: FAIL - - ["data:,a ‍1x" (leading U+200D)] - expected: FAIL -