Fix bugs related to setting reflected floating point DOM attributes
https://bugs.webkit.org/show_bug.cgi?id=178061

Reviewed by Sam Weinig.

LayoutTests/imported/w3c:

* web-platform-tests/html/dom/reflection-forms-expected.txt:
Updated to expect meter reflection tests to pass.

Source/WebCore:

* html/HTMLProgressElement.cpp:
(WebCore::HTMLProgressElement::setValue): Changed the semantics to match what
the HTML specification calls for. When a caller passes a negative number or
zero, the value does get set on the element. Negative numbers are not allowed
when you get the current value, but are allowed to be set.
(WebCore::HTMLProgressElement::setMax): Changed the semantics to match what
the HTML specification calls for. When a caller passes a negative number or
zero, this should leave the attribute unchanged.

* html/shadow/MediaControlElementTypes.cpp:
(WebCore::MediaControlVolumeSliderElement::setVolume): Use
String::numberToStringECMAScript instead of String::number since that is what
we want any time we are setting an attribute value from a floating point value.
* html/shadow/MediaControlElements.cpp:
(WebCore::MediaControlTimelineElement::setPosition): Ditto.
(WebCore::MediaControlTimelineElement::setDuration): Removed unneeded check
of std::isfinite since the single caller already checks that.

Source/WTF:

* wtf/dtoa.cpp:
(WTF::formatStringTruncatingTrailingZerosIfNeeded): Fix a bug where
this function would remove trailing zeroes from the exponent if
present instead of from the mantissa. This meant that it would
format 1e10 as "1.00000e+1" instead of "1e+10". Added regression
tests for this to TestWebKitAPI.

* wtf/dtoa/utils.h:
(WTF::double_conversion::StringBuilder::RemoveCharacters): Added.
Used by the fix above.

* wtf/text/AtomicString.cpp:
(WTF::AtomicString::number): Note: This function is used by code
that sets the values of reflected floating point DOM attributes.
Changed the function to use the rules from numberToString rather
ones from numberToFixedPrecisionString. This is analogous to
String::numberToStringECMAScript, and in the future we should change
String and StringBuilder so this "ECMAScript" semantic is the default
way to convert a floating point number to a string, and rename the fixed
precision version that is currently called String::number. I audited
the small number of sites calling AtomicString::number, by temporarily
renaming it, and discovered that this is the correct behavior for all;
none needed fixed precision. Also, fixed a mistake where this explicitly
converted to String. That was defeating the purpose of having these
functions in AtomicString: It would allocate a new String and then
destroy it in the case where an equal string was already in the
AtomicString table.

Tools:

* TestWebKitAPI/Tests/WTF/AtomicString.cpp: Added a test of the
AtomicString::number function, based on the test cases we already
had for String::numberToStringECMAScript, and with some additional
cases with powers of 10 that check handling of trailng zeroes.

* TestWebKitAPI/Tests/WTF/WTFString.cpp: Added test cases to the
existing tests of the String::numberToStringECMAScript function
as above. Also added tests for String::number and for
String::numberToStringFixedWidth. Also changed the tests to all use
EXPECT instead of ASSERT macros since these are all non-fatal.

* WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
(WTR::dumpFrameScrollPosition): Use StringBuilder::appendECMAScriptNumber
instead of String::number.

LayoutTests:

* fast/dom/HTMLProgressElement/set-progress-properties-expected.txt: Updated test to expect
setting HTMLProgressElement.max to 0 to have no effect, rather than setting max to "1".
* fast/dom/HTMLProgressElement/set-progress-properties.html: Ditto.

* platform/ios-wk2/imported/w3c/web-platform-tests/html/dom/reflection-forms-expected.txt:
Updated to expect meter reflection tests to pass.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@223035 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 4fab450..dc3c656 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,17 @@
+2017-10-08  Darin Adler  <darin@apple.com>
+
+        Fix bugs related to setting reflected floating point DOM attributes
+        https://bugs.webkit.org/show_bug.cgi?id=178061
+
+        Reviewed by Sam Weinig.
+
+        * fast/dom/HTMLProgressElement/set-progress-properties-expected.txt: Updated test to expect
+        setting HTMLProgressElement.max to 0 to have no effect, rather than setting max to "1".
+        * fast/dom/HTMLProgressElement/set-progress-properties.html: Ditto.
+
+        * platform/ios-wk2/imported/w3c/web-platform-tests/html/dom/reflection-forms-expected.txt:
+        Updated to expect meter reflection tests to pass.
+
 2017-10-08  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         DataTransfer.items does not contain items for custom types supplied via add or setData
diff --git a/LayoutTests/fast/dom/HTMLProgressElement/set-progress-properties-expected.txt b/LayoutTests/fast/dom/HTMLProgressElement/set-progress-properties-expected.txt
index 59ad3b3..71cfadb 100644
--- a/LayoutTests/fast/dom/HTMLProgressElement/set-progress-properties-expected.txt
+++ b/LayoutTests/fast/dom/HTMLProgressElement/set-progress-properties-expected.txt
@@ -28,7 +28,7 @@
 PASS p.value = NaN; threw exception TypeError: The provided value is non-finite.
 Set value to null and max to 0
 PASS p.value is 0
-PASS p.max is 1
+PASS p.max is 100
 PASS p.position is 0
 Set attributes to valid numbers
 PASS p.value is 5
diff --git a/LayoutTests/fast/dom/HTMLProgressElement/set-progress-properties.html b/LayoutTests/fast/dom/HTMLProgressElement/set-progress-properties.html
index e39f52c..06aa652 100644
--- a/LayoutTests/fast/dom/HTMLProgressElement/set-progress-properties.html
+++ b/LayoutTests/fast/dom/HTMLProgressElement/set-progress-properties.html
@@ -49,7 +49,7 @@
 p.value = null;
 p.max = 0;
 shouldBe("p.value", "0");
-shouldBe("p.max", "1");
+shouldBe("p.max", "100");
 shouldBe("p.position", "0");
 
 debug("Set attributes to valid numbers");
diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog
index 631a41c..c2d2f75 100644
--- a/LayoutTests/imported/w3c/ChangeLog
+++ b/LayoutTests/imported/w3c/ChangeLog
@@ -1,5 +1,15 @@
 2017-10-08  Darin Adler  <darin@apple.com>
 
+        Fix bugs related to setting reflected floating point DOM attributes
+        https://bugs.webkit.org/show_bug.cgi?id=178061
+
+        Reviewed by Sam Weinig.
+
+        * web-platform-tests/html/dom/reflection-forms-expected.txt:
+        Updated to expect meter reflection tests to pass.
+
+2017-10-08  Darin Adler  <darin@apple.com>
+
         CustomElementRegistry.define was throwing a JavaScript syntax error instead of a DOM syntax error
         https://bugs.webkit.org/show_bug.cgi?id=178055
 
diff --git a/LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-forms-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-forms-expected.txt
index c0928a9..68139b7 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-forms-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-forms-expected.txt
@@ -6996,50 +6996,50 @@
 PASS meter.tabIndex: IDL set to -2147483648 
 PASS meter.value: typeof IDL attribute 
 PASS meter.value: IDL get with DOM attribute unset 
-FAIL meter.value: IDL set to -10000000000 assert_equals: getAttribute() expected "-10000000000" but got "-1.00000e+1"
+PASS meter.value: IDL set to -10000000000 
 PASS meter.value: IDL set to -1 
 PASS meter.value: IDL set to -0 
 PASS meter.value: IDL set to 0 
 PASS meter.value: IDL set to 1 
-FAIL meter.value: IDL set to 10000000000 assert_equals: getAttribute() expected "10000000000" but got "1.00000e+1"
+PASS meter.value: IDL set to 10000000000 
 PASS meter.min: typeof IDL attribute 
 PASS meter.min: IDL get with DOM attribute unset 
-FAIL meter.min: IDL set to -10000000000 assert_equals: getAttribute() expected "-10000000000" but got "-1.00000e+1"
+PASS meter.min: IDL set to -10000000000 
 PASS meter.min: IDL set to -1 
 PASS meter.min: IDL set to -0 
 PASS meter.min: IDL set to 0 
 PASS meter.min: IDL set to 1 
-FAIL meter.min: IDL set to 10000000000 assert_equals: getAttribute() expected "10000000000" but got "1.00000e+1"
+PASS meter.min: IDL set to 10000000000 
 PASS meter.max: typeof IDL attribute 
 FAIL meter.max: IDL get with DOM attribute unset assert_equals: expected 0 but got 1
-FAIL meter.max: IDL set to -10000000000 assert_equals: getAttribute() expected "-10000000000" but got "-1.00000e+1"
+PASS meter.max: IDL set to -10000000000 
 PASS meter.max: IDL set to -1 
 PASS meter.max: IDL set to -0 
 PASS meter.max: IDL set to 0 
 PASS meter.max: IDL set to 1 
-FAIL meter.max: IDL set to 10000000000 assert_equals: getAttribute() expected "10000000000" but got "1.00000e+1"
+PASS meter.max: IDL set to 10000000000 
 PASS meter.low: typeof IDL attribute 
 PASS meter.low: IDL get with DOM attribute unset 
-FAIL meter.low: IDL set to -10000000000 assert_equals: getAttribute() expected "-10000000000" but got "-1.00000e+1"
+PASS meter.low: IDL set to -10000000000 
 PASS meter.low: IDL set to -1 
 PASS meter.low: IDL set to -0 
 PASS meter.low: IDL set to 0 
 PASS meter.low: IDL set to 1 
-FAIL meter.low: IDL set to 10000000000 assert_equals: getAttribute() expected "10000000000" but got "1.00000e+1"
+PASS meter.low: IDL set to 10000000000 
 PASS meter.high: typeof IDL attribute 
 FAIL meter.high: IDL get with DOM attribute unset assert_equals: expected 0 but got 1
-FAIL meter.high: IDL set to -10000000000 assert_equals: getAttribute() expected "-10000000000" but got "-1.00000e+1"
+PASS meter.high: IDL set to -10000000000 
 PASS meter.high: IDL set to -1 
 PASS meter.high: IDL set to -0 
 PASS meter.high: IDL set to 0 
 PASS meter.high: IDL set to 1 
-FAIL meter.high: IDL set to 10000000000 assert_equals: getAttribute() expected "10000000000" but got "1.00000e+1"
+PASS meter.high: IDL set to 10000000000 
 PASS meter.optimum: typeof IDL attribute 
 FAIL meter.optimum: IDL get with DOM attribute unset assert_equals: expected 0 but got 0.5
-FAIL meter.optimum: IDL set to -10000000000 assert_equals: getAttribute() expected "-10000000000" but got "-1.00000e+1"
+PASS meter.optimum: IDL set to -10000000000 
 PASS meter.optimum: IDL set to -1 
 PASS meter.optimum: IDL set to -0 
 PASS meter.optimum: IDL set to 0 
 PASS meter.optimum: IDL set to 1 
-FAIL meter.optimum: IDL set to 10000000000 assert_equals: getAttribute() expected "10000000000" but got "1.00000e+1"
+PASS meter.optimum: IDL set to 10000000000 
 (Note: missing tests for types tokenlist, settable tokenlist, limited double.)
diff --git a/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/dom/reflection-forms-expected.txt b/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/dom/reflection-forms-expected.txt
index 0f50486..1f26167 100644
--- a/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/dom/reflection-forms-expected.txt
+++ b/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/dom/reflection-forms-expected.txt
@@ -6996,50 +6996,50 @@
 PASS meter.tabIndex: IDL set to -2147483648 
 PASS meter.value: typeof IDL attribute 
 PASS meter.value: IDL get with DOM attribute unset 
-FAIL meter.value: IDL set to -10000000000 assert_equals: getAttribute() expected "-10000000000" but got "-1.00000e+1"
+PASS meter.value: IDL set to -10000000000 
 PASS meter.value: IDL set to -1 
 PASS meter.value: IDL set to -0 
 PASS meter.value: IDL set to 0 
 PASS meter.value: IDL set to 1 
-FAIL meter.value: IDL set to 10000000000 assert_equals: getAttribute() expected "10000000000" but got "1.00000e+1"
+PASS meter.value: IDL set to 10000000000 
 PASS meter.min: typeof IDL attribute 
 PASS meter.min: IDL get with DOM attribute unset 
-FAIL meter.min: IDL set to -10000000000 assert_equals: getAttribute() expected "-10000000000" but got "-1.00000e+1"
+PASS meter.min: IDL set to -10000000000 
 PASS meter.min: IDL set to -1 
 PASS meter.min: IDL set to -0 
 PASS meter.min: IDL set to 0 
 PASS meter.min: IDL set to 1 
-FAIL meter.min: IDL set to 10000000000 assert_equals: getAttribute() expected "10000000000" but got "1.00000e+1"
+PASS meter.min: IDL set to 10000000000 
 PASS meter.max: typeof IDL attribute 
 FAIL meter.max: IDL get with DOM attribute unset assert_equals: expected 0 but got 1
-FAIL meter.max: IDL set to -10000000000 assert_equals: getAttribute() expected "-10000000000" but got "-1.00000e+1"
+PASS meter.max: IDL set to -10000000000 
 PASS meter.max: IDL set to -1 
 PASS meter.max: IDL set to -0 
 PASS meter.max: IDL set to 0 
 PASS meter.max: IDL set to 1 
-FAIL meter.max: IDL set to 10000000000 assert_equals: getAttribute() expected "10000000000" but got "1.00000e+1"
+PASS meter.max: IDL set to 10000000000 
 PASS meter.low: typeof IDL attribute 
 PASS meter.low: IDL get with DOM attribute unset 
-FAIL meter.low: IDL set to -10000000000 assert_equals: getAttribute() expected "-10000000000" but got "-1.00000e+1"
+PASS meter.low: IDL set to -10000000000 
 PASS meter.low: IDL set to -1 
 PASS meter.low: IDL set to -0 
 PASS meter.low: IDL set to 0 
 PASS meter.low: IDL set to 1 
-FAIL meter.low: IDL set to 10000000000 assert_equals: getAttribute() expected "10000000000" but got "1.00000e+1"
+PASS meter.low: IDL set to 10000000000 
 PASS meter.high: typeof IDL attribute 
 FAIL meter.high: IDL get with DOM attribute unset assert_equals: expected 0 but got 1
-FAIL meter.high: IDL set to -10000000000 assert_equals: getAttribute() expected "-10000000000" but got "-1.00000e+1"
+PASS meter.high: IDL set to -10000000000 
 PASS meter.high: IDL set to -1 
 PASS meter.high: IDL set to -0 
 PASS meter.high: IDL set to 0 
 PASS meter.high: IDL set to 1 
-FAIL meter.high: IDL set to 10000000000 assert_equals: getAttribute() expected "10000000000" but got "1.00000e+1"
+PASS meter.high: IDL set to 10000000000 
 PASS meter.optimum: typeof IDL attribute 
 FAIL meter.optimum: IDL get with DOM attribute unset assert_equals: expected 0 but got 0.5
-FAIL meter.optimum: IDL set to -10000000000 assert_equals: getAttribute() expected "-10000000000" but got "-1.00000e+1"
+PASS meter.optimum: IDL set to -10000000000 
 PASS meter.optimum: IDL set to -1 
 PASS meter.optimum: IDL set to -0 
 PASS meter.optimum: IDL set to 0 
 PASS meter.optimum: IDL set to 1 
-FAIL meter.optimum: IDL set to 10000000000 assert_equals: getAttribute() expected "10000000000" but got "1.00000e+1"
+PASS meter.optimum: IDL set to 10000000000 
 (Note: missing tests for types tokenlist, settable tokenlist, limited double.)
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index 5e2867c..a3871d0 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,3 +1,38 @@
+2017-10-08  Darin Adler  <darin@apple.com>
+
+        Fix bugs related to setting reflected floating point DOM attributes
+        https://bugs.webkit.org/show_bug.cgi?id=178061
+
+        Reviewed by Sam Weinig.
+
+        * wtf/dtoa.cpp:
+        (WTF::formatStringTruncatingTrailingZerosIfNeeded): Fix a bug where
+        this function would remove trailing zeroes from the exponent if
+        present instead of from the mantissa. This meant that it would
+        format 1e10 as "1.00000e+1" instead of "1e+10". Added regression
+        tests for this to TestWebKitAPI.
+
+        * wtf/dtoa/utils.h:
+        (WTF::double_conversion::StringBuilder::RemoveCharacters): Added.
+        Used by the fix above.
+
+        * wtf/text/AtomicString.cpp:
+        (WTF::AtomicString::number): Note: This function is used by code
+        that sets the values of reflected floating point DOM attributes.
+        Changed the function to use the rules from numberToString rather
+        ones from numberToFixedPrecisionString. This is analogous to
+        String::numberToStringECMAScript, and in the future we should change
+        String and StringBuilder so this "ECMAScript" semantic is the default
+        way to convert a floating point number to a string, and rename the fixed
+        precision version that is currently called String::number. I audited
+        the small number of sites calling AtomicString::number, by temporarily
+        renaming it, and discovered that this is the correct behavior for all;
+        none needed fixed precision. Also, fixed a mistake where this explicitly
+        converted to String. That was defeating the purpose of having these
+        functions in AtomicString: It would allocate a new String and then
+        destroy it in the case where an equal string was already in the
+        AtomicString table.
+
 2017-10-06  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r222791 and r222873.
diff --git a/Source/WTF/wtf/dtoa.cpp b/Source/WTF/wtf/dtoa.cpp
index 823b161..972b289 100644
--- a/Source/WTF/wtf/dtoa.cpp
+++ b/Source/WTF/wtf/dtoa.cpp
@@ -3,7 +3,7 @@
  * The author of this software is David M. Gay.
  *
  * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
- * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2010, 2012, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2002-2017 Apple Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose without fee is hereby granted, provided that this entire notice
@@ -1227,7 +1227,7 @@
 const char* numberToString(double d, NumberToStringBuffer buffer)
 {
     double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength);
-    const double_conversion::DoubleToStringConverter& converter = double_conversion::DoubleToStringConverter::EcmaScriptConverter();
+    auto& converter = double_conversion::DoubleToStringConverter::EcmaScriptConverter();
     converter.ToShortest(d, &builder);
     return builder.Finalize();
 }
@@ -1241,28 +1241,32 @@
             break;
     }
 
-    // No decimal seperator found, early exit.
+    // No decimal separator found, early exit.
     if (decimalPointPosition == length)
         return builder.Finalize();
 
-    size_t truncatedLength = length - 1;
-    for (; truncatedLength > decimalPointPosition; --truncatedLength) {
-        if (buffer[truncatedLength] != '0')
+    size_t pastMantissa = decimalPointPosition + 1;
+    for (; pastMantissa < length; ++pastMantissa) {
+        if (buffer[pastMantissa] == 'e')
+            break;
+    }
+
+    size_t truncatedLength = pastMantissa;
+    for (; truncatedLength > decimalPointPosition + 1; --truncatedLength) {
+        if (buffer[truncatedLength - 1] != '0')
             break;
     }
 
     // No trailing zeros found to strip.
-    if (truncatedLength == length - 1)
+    if (truncatedLength == pastMantissa)
         return builder.Finalize();
 
     // If we removed all trailing zeros, remove the decimal point as well.
-    if (truncatedLength == decimalPointPosition) {
-        ASSERT(truncatedLength > 0);
-        --truncatedLength;
-    }
+    if (truncatedLength == decimalPointPosition + 1)
+        truncatedLength = decimalPointPosition;
 
-    // Truncate the StringBuilder, and return the final result.
-    builder.SetPosition(truncatedLength + 1);
+    // Truncate the mantissa, and return the final result.
+    builder.RemoveCharacters(truncatedLength, pastMantissa);
     return builder.Finalize();
 }
 
@@ -1274,7 +1278,7 @@
     // precision argument. Trailing zeros are truncated, and the decimal point appears only if one or more digits follow it.
     // "precision": The precision specifies the maximum number of significant digits printed.
     double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength);
-    const double_conversion::DoubleToStringConverter& converter = double_conversion::DoubleToStringConverter::EcmaScriptConverter();
+    auto& converter = double_conversion::DoubleToStringConverter::EcmaScriptConverter();
     converter.ToPrecision(d, significantFigures, &builder);
     if (!truncateTrailingZeros)
         return builder.Finalize();
@@ -1291,7 +1295,7 @@
     // If a decimal point appears, at least one digit appears before it.
     // The value is rounded to the appropriate number of digits.    
     double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength);
-    const double_conversion::DoubleToStringConverter& converter = double_conversion::DoubleToStringConverter::EcmaScriptConverter();
+    auto& converter = double_conversion::DoubleToStringConverter::EcmaScriptConverter();
     converter.ToFixed(d, decimalPlaces, &builder);
     return builder.Finalize();
 }
diff --git a/Source/WTF/wtf/dtoa/utils.h b/Source/WTF/wtf/dtoa/utils.h
index 889642c..edb171b 100644
--- a/Source/WTF/wtf/dtoa/utils.h
+++ b/Source/WTF/wtf/dtoa/utils.h
@@ -243,6 +243,16 @@
             }
         }
         
+        void RemoveCharacters(int start, int end)
+        {
+            ASSERT(start >= 0);
+            ASSERT(end >= 0);
+            ASSERT(start <= end);
+            ASSERT(end <= position_);
+            std::memmove(&buffer_[start], &buffer_[end], position_ - end);
+            position_ -= end - start;
+        }
+
         // Finalize the string by 0-terminating it and returning the buffer.
         char* Finalize() {
             ASSERT(!is_finalized() && position_ < buffer_.length());
diff --git a/Source/WTF/wtf/text/AtomicString.cpp b/Source/WTF/wtf/text/AtomicString.cpp
index 2a06512..b125742 100644
--- a/Source/WTF/wtf/text/AtomicString.cpp
+++ b/Source/WTF/wtf/text/AtomicString.cpp
@@ -104,7 +104,7 @@
 AtomicString AtomicString::number(double number)
 {
     NumberToStringBuffer buffer;
-    return String(numberToFixedPrecisionString(number, 6, buffer, true));
+    return numberToString(number, buffer);
 }
 
 AtomicString AtomicString::fromUTF8Internal(const char* charactersStart, const char* charactersEnd)
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 1fb4bc3..f99e3bc 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,28 @@
+2017-10-08  Darin Adler  <darin@apple.com>
+
+        Fix bugs related to setting reflected floating point DOM attributes
+        https://bugs.webkit.org/show_bug.cgi?id=178061
+
+        Reviewed by Sam Weinig.
+
+        * html/HTMLProgressElement.cpp:
+        (WebCore::HTMLProgressElement::setValue): Changed the semantics to match what
+        the HTML specification calls for. When a caller passes a negative number or
+        zero, the value does get set on the element. Negative numbers are not allowed
+        when you get the current value, but are allowed to be set.
+        (WebCore::HTMLProgressElement::setMax): Changed the semantics to match what
+        the HTML specification calls for. When a caller passes a negative number or
+        zero, this should leave the attribute unchanged.
+
+        * html/shadow/MediaControlElementTypes.cpp:
+        (WebCore::MediaControlVolumeSliderElement::setVolume): Use
+        String::numberToStringECMAScript instead of String::number since that is what
+        we want any time we are setting an attribute value from a floating point value.
+        * html/shadow/MediaControlElements.cpp:
+        (WebCore::MediaControlTimelineElement::setPosition): Ditto.
+        (WebCore::MediaControlTimelineElement::setDuration): Removed unneeded check
+        of std::isfinite since the single caller already checks that.
+
 2017-10-08  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         DataTransfer.items does not contain items for custom types supplied via add or setData
diff --git a/Source/WebCore/html/HTMLProgressElement.cpp b/Source/WebCore/html/HTMLProgressElement.cpp
index 8b40e1d..6a721d5 100644
--- a/Source/WebCore/html/HTMLProgressElement.cpp
+++ b/Source/WebCore/html/HTMLProgressElement.cpp
@@ -98,7 +98,7 @@
 
 void HTMLProgressElement::setValue(double value)
 {
-    setAttributeWithoutSynchronization(valueAttr, AtomicString::number(value >= 0 ? value : 0));
+    setAttributeWithoutSynchronization(valueAttr, AtomicString::number(value));
 }
 
 double HTMLProgressElement::max() const
@@ -109,7 +109,8 @@
 
 void HTMLProgressElement::setMax(double max)
 {
-    setAttributeWithoutSynchronization(maxAttr, AtomicString::number(max > 0 ? max : 1));
+    if (max > 0)
+        setAttributeWithoutSynchronization(maxAttr, AtomicString::number(max));
 }
 
 double HTMLProgressElement::position() const
diff --git a/Source/WebCore/html/shadow/MediaControlElementTypes.cpp b/Source/WebCore/html/shadow/MediaControlElementTypes.cpp
index a2a62a8..b1c736c 100644
--- a/Source/WebCore/html/shadow/MediaControlElementTypes.cpp
+++ b/Source/WebCore/html/shadow/MediaControlElementTypes.cpp
@@ -234,7 +234,7 @@
 void MediaControlVolumeSliderElement::setVolume(double volume)
 {
     if (value().toDouble() != volume)
-        setValue(String::number(volume));
+        setValue(String::numberToStringECMAScript(volume));
 }
 
 void MediaControlVolumeSliderElement::setClearMutedOnUserInteraction(bool clearMute)
diff --git a/Source/WebCore/html/shadow/MediaControlElements.cpp b/Source/WebCore/html/shadow/MediaControlElements.cpp
index 64f2c1a..8e6229e 100644
--- a/Source/WebCore/html/shadow/MediaControlElements.cpp
+++ b/Source/WebCore/html/shadow/MediaControlElements.cpp
@@ -885,12 +885,12 @@
 
 void MediaControlTimelineElement::setPosition(double currentTime)
 {
-    setValue(String::number(currentTime));
+    setValue(String::numberToStringECMAScript(currentTime));
 }
 
 void MediaControlTimelineElement::setDuration(double duration)
 {
-    setAttribute(maxAttr, AtomicString::number(std::isfinite(duration) ? duration : 0));
+    setAttribute(maxAttr, AtomicString::number(duration));
 }
 
 // ----------------------------
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index 53a207f..67c71e5 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,25 @@
+2017-10-08  Darin Adler  <darin@apple.com>
+
+        Fix bugs related to setting reflected floating point DOM attributes
+        https://bugs.webkit.org/show_bug.cgi?id=178061
+
+        Reviewed by Sam Weinig.
+
+        * TestWebKitAPI/Tests/WTF/AtomicString.cpp: Added a test of the
+        AtomicString::number function, based on the test cases we already
+        had for String::numberToStringECMAScript, and with some additional
+        cases with powers of 10 that check handling of trailng zeroes.
+
+        * TestWebKitAPI/Tests/WTF/WTFString.cpp: Added test cases to the
+        existing tests of the String::numberToStringECMAScript function
+        as above. Also added tests for String::number and for
+        String::numberToStringFixedWidth. Also changed the tests to all use
+        EXPECT instead of ASSERT macros since these are all non-fatal.
+
+        * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+        (WTR::dumpFrameScrollPosition): Use StringBuilder::appendECMAScriptNumber
+        instead of String::number.
+
 2017-10-08  Dean Jackson  <dino@apple.com>
 
         Make sort-Xcode-project file handle UnifiedSources
diff --git a/Tools/TestWebKitAPI/Tests/WTF/AtomicString.cpp b/Tools/TestWebKitAPI/Tests/WTF/AtomicString.cpp
index de962ec..1d4ae4e 100644
--- a/Tools/TestWebKitAPI/Tests/WTF/AtomicString.cpp
+++ b/Tools/TestWebKitAPI/Tests/WTF/AtomicString.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -61,4 +61,53 @@
     ASSERT_EQ(string2.existingHash(), 0u);
 }
 
+static inline const char* testAtomicStringNumber(double number)
+{
+    static char testBuffer[100];
+    std::strncpy(testBuffer, AtomicString::number(number).string().utf8().data(), 100);
+    return testBuffer;
+}
+
+TEST(WTF, AtomicStringNumberDouble)
+{
+    using Limits = std::numeric_limits<double>;
+
+    EXPECT_STREQ("Infinity", testAtomicStringNumber(Limits::infinity()));
+    EXPECT_STREQ("-Infinity", testAtomicStringNumber(-Limits::infinity()));
+
+    EXPECT_STREQ("NaN", testAtomicStringNumber(-Limits::quiet_NaN()));
+
+    EXPECT_STREQ("0", testAtomicStringNumber(0));
+    EXPECT_STREQ("0", testAtomicStringNumber(-0));
+
+    EXPECT_STREQ("2.2250738585072014e-308", testAtomicStringNumber(Limits::min()));
+    EXPECT_STREQ("-1.7976931348623157e+308", testAtomicStringNumber(Limits::lowest()));
+    EXPECT_STREQ("1.7976931348623157e+308", testAtomicStringNumber(Limits::max()));
+
+    EXPECT_STREQ("3.141592653589793", testAtomicStringNumber(piDouble));
+    EXPECT_STREQ("3.1415927410125732", testAtomicStringNumber(piFloat));
+    EXPECT_STREQ("1.5707963267948966", testAtomicStringNumber(piOverTwoDouble));
+    EXPECT_STREQ("1.5707963705062866", testAtomicStringNumber(piOverTwoFloat));
+    EXPECT_STREQ("0.7853981633974483", testAtomicStringNumber(piOverFourDouble));
+    EXPECT_STREQ("0.7853981852531433", testAtomicStringNumber(piOverFourFloat));
+
+    EXPECT_STREQ("2.718281828459045", testAtomicStringNumber(2.71828182845904523536028747135266249775724709369995));
+
+    EXPECT_STREQ("299792458", testAtomicStringNumber(299792458));
+
+    EXPECT_STREQ("1.618033988749895", testAtomicStringNumber(1.6180339887498948482));
+
+    EXPECT_STREQ("1000", testAtomicStringNumber(1e3));
+    EXPECT_STREQ("10000000000", testAtomicStringNumber(1e10));
+    EXPECT_STREQ("100000000000000000000", testAtomicStringNumber(1e20));
+    EXPECT_STREQ("1e+21", testAtomicStringNumber(1e21));
+    EXPECT_STREQ("1e+30", testAtomicStringNumber(1e30));
+
+    EXPECT_STREQ("1100", testAtomicStringNumber(1.1e3));
+    EXPECT_STREQ("11000000000", testAtomicStringNumber(1.1e10));
+    EXPECT_STREQ("110000000000000000000", testAtomicStringNumber(1.1e20));
+    EXPECT_STREQ("1.1e+21", testAtomicStringNumber(1.1e21));
+    EXPECT_STREQ("1.1e+30", testAtomicStringNumber(1.1e30));
+}
+
 } // namespace TestWebKitAPI
diff --git a/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp b/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp
index 6184c62..4ecfe2f 100644
--- a/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp
+++ b/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,16 +36,16 @@
 TEST(WTF, StringCreationFromLiteral)
 {
     String stringFromLiteral(ASCIILiteral("Explicit construction syntax"));
-    ASSERT_EQ(strlen("Explicit construction syntax"), stringFromLiteral.length());
-    ASSERT_TRUE(stringFromLiteral == "Explicit construction syntax");
-    ASSERT_TRUE(stringFromLiteral.is8Bit());
-    ASSERT_TRUE(String("Explicit construction syntax") == stringFromLiteral);
+    EXPECT_EQ(strlen("Explicit construction syntax"), stringFromLiteral.length());
+    EXPECT_EQ("Explicit construction syntax", stringFromLiteral);
+    EXPECT_TRUE(stringFromLiteral.is8Bit());
+    EXPECT_EQ(String("Explicit construction syntax"), stringFromLiteral);
 
     String stringWithTemplate("Template Literal", String::ConstructFromLiteral);
-    ASSERT_EQ(strlen("Template Literal"), stringWithTemplate.length());
-    ASSERT_TRUE(stringWithTemplate == "Template Literal");
-    ASSERT_TRUE(stringWithTemplate.is8Bit());
-    ASSERT_TRUE(String("Template Literal") == stringWithTemplate);
+    EXPECT_EQ(strlen("Template Literal"), stringWithTemplate.length());
+    EXPECT_EQ("Template Literal", stringWithTemplate);
+    EXPECT_TRUE(stringWithTemplate.is8Bit());
+    EXPECT_EQ(String("Template Literal"), stringWithTemplate);
 }
 
 TEST(WTF, StringASCII)
@@ -54,111 +54,209 @@
 
     // Null String.
     output = String().ascii();
-    ASSERT_STREQ("", output.data());
+    EXPECT_STREQ("", output.data());
 
     // Empty String.
     output = emptyString().ascii();
-    ASSERT_STREQ("", output.data());
+    EXPECT_STREQ("", output.data());
 
     // Regular String.
     output = String(ASCIILiteral("foobar")).ascii();
-    ASSERT_STREQ("foobar", output.data());
+    EXPECT_STREQ("foobar", output.data());
 }
 
-static void testNumberToStringECMAScript(double number, const char* reference)
+static inline const char* testStringNumberFixedPrecision(double number)
 {
-    CString numberString = String::numberToStringECMAScript(number).latin1();
-    ASSERT_STREQ(reference, numberString.data());
+    static char testBuffer[100];
+    std::strncpy(testBuffer, String::number(number).utf8().data(), 100);
+    return testBuffer;
 }
 
-TEST(WTF, StringNumberToStringECMAScriptBoundaries)
+TEST(WTF, StringNumberFixedPrecision)
 {
-    typedef std::numeric_limits<double> Limits;
+    using Limits = std::numeric_limits<double>;
 
-    // Infinity.
-    testNumberToStringECMAScript(Limits::infinity(), "Infinity");
-    testNumberToStringECMAScript(-Limits::infinity(), "-Infinity");
+    EXPECT_STREQ("Infinity", testStringNumberFixedPrecision(Limits::infinity()));
+    EXPECT_STREQ("-Infinity", testStringNumberFixedPrecision(-Limits::infinity()));
 
-    // NaN.
-    testNumberToStringECMAScript(-Limits::quiet_NaN(), "NaN");
+    EXPECT_STREQ("NaN", testStringNumberFixedPrecision(-Limits::quiet_NaN()));
 
-    // Zeros.
-    testNumberToStringECMAScript(0, "0");
-    testNumberToStringECMAScript(-0, "0");
+    EXPECT_STREQ("0", testStringNumberFixedPrecision(0));
+    EXPECT_STREQ("0", testStringNumberFixedPrecision(-0));
 
-    // Min-Max.
-    testNumberToStringECMAScript(Limits::min(), "2.2250738585072014e-308");
-    testNumberToStringECMAScript(Limits::max(), "1.7976931348623157e+308");
+    EXPECT_STREQ("2.22507e-308", testStringNumberFixedPrecision(Limits::min()));
+    EXPECT_STREQ("-1.79769e+308", testStringNumberFixedPrecision(Limits::lowest()));
+    EXPECT_STREQ("1.79769e+308", testStringNumberFixedPrecision(Limits::max()));
+
+    EXPECT_STREQ("3.14159", testStringNumberFixedPrecision(piDouble));
+    EXPECT_STREQ("3.14159", testStringNumberFixedPrecision(piFloat));
+    EXPECT_STREQ("1.5708", testStringNumberFixedPrecision(piOverTwoDouble));
+    EXPECT_STREQ("1.5708", testStringNumberFixedPrecision(piOverTwoFloat));
+    EXPECT_STREQ("0.785398", testStringNumberFixedPrecision(piOverFourDouble));
+    EXPECT_STREQ("0.785398", testStringNumberFixedPrecision(piOverFourFloat));
+
+    EXPECT_STREQ("2.71828", testStringNumberFixedPrecision(2.71828182845904523536028747135266249775724709369995));
+
+    EXPECT_STREQ("2.99792e+8", testStringNumberFixedPrecision(299792458));
+
+    EXPECT_STREQ("1.61803", testStringNumberFixedPrecision(1.6180339887498948482));
+
+    EXPECT_STREQ("1000", testStringNumberFixedPrecision(1e3));
+    EXPECT_STREQ("1e+10", testStringNumberFixedPrecision(1e10));
+    EXPECT_STREQ("1e+20", testStringNumberFixedPrecision(1e20));
+    EXPECT_STREQ("1e+21", testStringNumberFixedPrecision(1e21));
+    EXPECT_STREQ("1e+30", testStringNumberFixedPrecision(1e30));
+
+    EXPECT_STREQ("1100", testStringNumberFixedPrecision(1.1e3));
+    EXPECT_STREQ("1.1e+10", testStringNumberFixedPrecision(1.1e10));
+    EXPECT_STREQ("1.1e+20", testStringNumberFixedPrecision(1.1e20));
+    EXPECT_STREQ("1.1e+21", testStringNumberFixedPrecision(1.1e21));
+    EXPECT_STREQ("1.1e+30", testStringNumberFixedPrecision(1.1e30));
 }
 
-TEST(WTF, StringNumberToStringECMAScriptRegularNumbers)
+static inline const char* testStringNumberFixedWidth(double number)
 {
-    // Pi.
-    testNumberToStringECMAScript(piDouble, "3.141592653589793");
-    testNumberToStringECMAScript(piFloat, "3.1415927410125732");
-    testNumberToStringECMAScript(piOverTwoDouble, "1.5707963267948966");
-    testNumberToStringECMAScript(piOverTwoFloat, "1.5707963705062866");
-    testNumberToStringECMAScript(piOverFourDouble, "0.7853981633974483");
-    testNumberToStringECMAScript(piOverFourFloat, "0.7853981852531433");
+    static char testBuffer[100];
+    std::strncpy(testBuffer, String::numberToStringFixedWidth(number, 6).utf8().data(), 100);
+    return testBuffer;
+}
 
-    // e.
-    const double e = 2.71828182845904523536028747135266249775724709369995;
-    testNumberToStringECMAScript(e, "2.718281828459045");
+TEST(WTF, StringNumberFixedWidth)
+{
+    using Limits = std::numeric_limits<double>;
 
-    // c, speed of light in m/s.
-    const double c = 299792458;
-    testNumberToStringECMAScript(c, "299792458");
+    EXPECT_STREQ("Infinity", testStringNumberFixedWidth(Limits::infinity()));
+    EXPECT_STREQ("-Infinity", testStringNumberFixedWidth(-Limits::infinity()));
 
-    // Golen ratio.
-    const double phi = 1.6180339887498948482;
-    testNumberToStringECMAScript(phi, "1.618033988749895");
+    EXPECT_STREQ("NaN", testStringNumberFixedWidth(-Limits::quiet_NaN()));
+
+    EXPECT_STREQ("0.000000", testStringNumberFixedWidth(0));
+    EXPECT_STREQ("0.000000", testStringNumberFixedWidth(-0));
+
+    EXPECT_STREQ("0.000000", testStringNumberFixedWidth(Limits::min()));
+    EXPECT_STREQ("", testStringNumberFixedWidth(Limits::lowest()));
+    EXPECT_STREQ("", testStringNumberFixedWidth(Limits::max()));
+
+    EXPECT_STREQ("3.141593", testStringNumberFixedWidth(piDouble));
+    EXPECT_STREQ("3.141593", testStringNumberFixedWidth(piFloat));
+    EXPECT_STREQ("1.570796", testStringNumberFixedWidth(piOverTwoDouble));
+    EXPECT_STREQ("1.570796", testStringNumberFixedWidth(piOverTwoFloat));
+    EXPECT_STREQ("0.785398", testStringNumberFixedWidth(piOverFourDouble));
+    EXPECT_STREQ("0.785398", testStringNumberFixedWidth(piOverFourFloat));
+
+    EXPECT_STREQ("2.718282", testStringNumberFixedWidth(2.71828182845904523536028747135266249775724709369995));
+
+    EXPECT_STREQ("299792458.000000", testStringNumberFixedWidth(299792458));
+
+    EXPECT_STREQ("1.618034", testStringNumberFixedWidth(1.6180339887498948482));
+
+    EXPECT_STREQ("1000.000000", testStringNumberFixedWidth(1e3));
+    EXPECT_STREQ("10000000000.000000", testStringNumberFixedWidth(1e10));
+    EXPECT_STREQ("100000000000000000000.000000", testStringNumberFixedWidth(1e20));
+    EXPECT_STREQ("1000000000000000000000.000000", testStringNumberFixedWidth(1e21));
+    EXPECT_STREQ("1000000000000000019884624838656.000000", testStringNumberFixedWidth(1e30));
+
+    EXPECT_STREQ("1100.000000", testStringNumberFixedWidth(1.1e3));
+    EXPECT_STREQ("11000000000.000000", testStringNumberFixedWidth(1.1e10));
+    EXPECT_STREQ("110000000000000000000.000000", testStringNumberFixedWidth(1.1e20));
+    EXPECT_STREQ("1100000000000000000000.000000", testStringNumberFixedWidth(1.1e21));
+    EXPECT_STREQ("1099999999999999993725589651456.000000", testStringNumberFixedWidth(1.1e30));
+}
+
+static inline const char* testStringNumber(double number)
+{
+    static char testBuffer[100];
+    std::strncpy(testBuffer, String::numberToStringECMAScript(number).utf8().data(), 100);
+    return testBuffer;
+}
+
+TEST(WTF, StringNumber)
+{
+    using Limits = std::numeric_limits<double>;
+
+    EXPECT_STREQ("Infinity", testStringNumber(Limits::infinity()));
+    EXPECT_STREQ("-Infinity", testStringNumber(-Limits::infinity()));
+
+    EXPECT_STREQ("NaN", testStringNumber(-Limits::quiet_NaN()));
+
+    EXPECT_STREQ("0", testStringNumber(0));
+    EXPECT_STREQ("0", testStringNumber(-0));
+
+    EXPECT_STREQ("2.2250738585072014e-308", testStringNumber(Limits::min()));
+    EXPECT_STREQ("-1.7976931348623157e+308", testStringNumber(Limits::lowest()));
+    EXPECT_STREQ("1.7976931348623157e+308", testStringNumber(Limits::max()));
+
+    EXPECT_STREQ("3.141592653589793", testStringNumber(piDouble));
+    EXPECT_STREQ("3.1415927410125732", testStringNumber(piFloat));
+    EXPECT_STREQ("1.5707963267948966", testStringNumber(piOverTwoDouble));
+    EXPECT_STREQ("1.5707963705062866", testStringNumber(piOverTwoFloat));
+    EXPECT_STREQ("0.7853981633974483", testStringNumber(piOverFourDouble));
+    EXPECT_STREQ("0.7853981852531433", testStringNumber(piOverFourFloat));
+
+    EXPECT_STREQ("2.718281828459045", testStringNumber(2.71828182845904523536028747135266249775724709369995));
+
+    EXPECT_STREQ("299792458", testStringNumber(299792458));
+
+    EXPECT_STREQ("1.618033988749895", testStringNumber(1.6180339887498948482));
+
+    EXPECT_STREQ("1000", testStringNumber(1e3));
+    EXPECT_STREQ("10000000000", testStringNumber(1e10));
+    EXPECT_STREQ("100000000000000000000", testStringNumber(1e20));
+    EXPECT_STREQ("1e+21", testStringNumber(1e21));
+    EXPECT_STREQ("1e+30", testStringNumber(1e30));
+
+    EXPECT_STREQ("1100", testStringNumber(1.1e3));
+    EXPECT_STREQ("11000000000", testStringNumber(1.1e10));
+    EXPECT_STREQ("110000000000000000000", testStringNumber(1.1e20));
+    EXPECT_STREQ("1.1e+21", testStringNumber(1.1e21));
+    EXPECT_STREQ("1.1e+30", testStringNumber(1.1e30));
 }
 
 TEST(WTF, StringReplaceWithLiteral)
 {
     // Cases for 8Bit source.
     String testString = "1224";
-    ASSERT_TRUE(testString.is8Bit());
+    EXPECT_TRUE(testString.is8Bit());
     testString.replaceWithLiteral('2', "");
-    ASSERT_STREQ("14", testString.utf8().data());
+    EXPECT_STREQ("14", testString.utf8().data());
 
     testString = "1224";
-    ASSERT_TRUE(testString.is8Bit());
+    EXPECT_TRUE(testString.is8Bit());
     testString.replaceWithLiteral('2', "3");
-    ASSERT_STREQ("1334", testString.utf8().data());
+    EXPECT_STREQ("1334", testString.utf8().data());
 
     testString = "1224";
-    ASSERT_TRUE(testString.is8Bit());
+    EXPECT_TRUE(testString.is8Bit());
     testString.replaceWithLiteral('2', "555");
-    ASSERT_STREQ("15555554", testString.utf8().data());
+    EXPECT_STREQ("15555554", testString.utf8().data());
 
     testString = "1224";
-    ASSERT_TRUE(testString.is8Bit());
+    EXPECT_TRUE(testString.is8Bit());
     testString.replaceWithLiteral('3', "NotFound");
-    ASSERT_STREQ("1224", testString.utf8().data());
+    EXPECT_STREQ("1224", testString.utf8().data());
 
     // Cases for 16Bit source.
     testString = String::fromUTF8("résumé");
-    ASSERT_FALSE(testString.is8Bit());
+    EXPECT_FALSE(testString.is8Bit());
     testString.replaceWithLiteral(UChar(0x00E9 /*U+00E9 is 'é'*/), "e");
-    ASSERT_STREQ("resume", testString.utf8().data());
+    EXPECT_STREQ("resume", testString.utf8().data());
 
     testString = String::fromUTF8("résumé");
-    ASSERT_FALSE(testString.is8Bit());
+    EXPECT_FALSE(testString.is8Bit());
     testString.replaceWithLiteral(UChar(0x00E9 /*U+00E9 is 'é'*/), "");
-    ASSERT_STREQ("rsum", testString.utf8().data());
+    EXPECT_STREQ("rsum", testString.utf8().data());
 
     testString = String::fromUTF8("résumé");
-    ASSERT_FALSE(testString.is8Bit());
+    EXPECT_FALSE(testString.is8Bit());
     testString.replaceWithLiteral('3', "NotFound");
-    ASSERT_STREQ("résumé", testString.utf8().data());
+    EXPECT_STREQ("résumé", testString.utf8().data());
 }
 
 TEST(WTF, StringIsolatedCopy)
 {
     String original = "1234";
     auto copy = WTFMove(original).isolatedCopy();
-    ASSERT_FALSE(original.impl() == copy.impl());
+    EXPECT_FALSE(original.impl() == copy.impl());
 }
 
 TEST(WTF, StringToInt)
@@ -285,33 +383,33 @@
 TEST(WTF, StringExistingHash)
 {
     String string1("Template Literal");
-    ASSERT_FALSE(string1.isNull());
-    ASSERT_FALSE(string1.impl()->hasHash());
+    EXPECT_FALSE(string1.isNull());
+    EXPECT_FALSE(string1.impl()->hasHash());
     string1.impl()->hash();
-    ASSERT_EQ(string1.existingHash(), string1.impl()->existingHash());
+    EXPECT_EQ(string1.existingHash(), string1.impl()->existingHash());
     String string2;
-    ASSERT_EQ(string2.existingHash(), 0u);
+    EXPECT_EQ(string2.existingHash(), 0u);
 }
 
 TEST(WTF, StringUnicodeEqualUCharArray)
 {
     String string1("abc");
-    ASSERT_FALSE(string1.isNull());
-    ASSERT_TRUE(string1.is8Bit());
+    EXPECT_FALSE(string1.isNull());
+    EXPECT_TRUE(string1.is8Bit());
     UChar ab[] = { 'a', 'b' };
     UChar abc[] = { 'a', 'b', 'c' };
     UChar abcd[] = { 'a', 'b', 'c', 'd' };
     UChar aBc[] = { 'a', 'B', 'c' };
-    ASSERT_FALSE(equal(string1, ab));
-    ASSERT_TRUE(equal(string1, abc));
-    ASSERT_FALSE(equal(string1, abcd));
-    ASSERT_FALSE(equal(string1, aBc));
+    EXPECT_FALSE(equal(string1, ab));
+    EXPECT_TRUE(equal(string1, abc));
+    EXPECT_FALSE(equal(string1, abcd));
+    EXPECT_FALSE(equal(string1, aBc));
 
     String string2(abc, 3);
-    ASSERT_FALSE(equal(string2, ab));
-    ASSERT_TRUE(equal(string2, abc));
-    ASSERT_FALSE(equal(string2, abcd));
-    ASSERT_FALSE(equal(string2, aBc));
+    EXPECT_FALSE(equal(string2, ab));
+    EXPECT_TRUE(equal(string2, abc));
+    EXPECT_FALSE(equal(string2, abcd));
+    EXPECT_FALSE(equal(string2, aBc));
 }
 
 TEST(WTF, StringRightBasic)
diff --git a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
index 17bcfa3..429a2cf 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
@@ -752,9 +752,9 @@
         stringBuilder.appendLiteral("' ");
     }
     stringBuilder.appendLiteral("scrolled to ");
-    stringBuilder.append(WTF::String::number(x));
+    stringBuilder.appendECMAScriptNumber(x);
     stringBuilder.append(',');
-    stringBuilder.append(WTF::String::number(y));
+    stringBuilder.appendECMAScriptNumber(y);
     stringBuilder.append('\n');
 }