- Revision
- 164819
- Author
- [email protected]
- Date
- 2014-02-27 11:39:42 -0800 (Thu, 27 Feb 2014)
Log Message
Math.{max, min}() must not return after first NaN value
https://bugs.webkit.org/show_bug.cgi?id=104147
Patch by Tibor Meszaros <[email protected]> on 2014-02-27
Reviewed by Oliver Hunt.
Source/_javascript_Core:
According to the spec, ToNumber going to be called on each argument
even if a `NaN` value was already found
* runtime/MathObject.cpp:
(JSC::mathProtoFuncMax):
(JSC::mathProtoFuncMin):
LayoutTests:
Extended the Math.{max, min}() tests, to check that these methods are return after first NaN value or not.
* js/math-expected.txt:
* js/script-tests/math.js:
Modified Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (164818 => 164819)
--- trunk/LayoutTests/ChangeLog 2014-02-27 19:20:08 UTC (rev 164818)
+++ trunk/LayoutTests/ChangeLog 2014-02-27 19:39:42 UTC (rev 164819)
@@ -1,3 +1,15 @@
+2014-02-27 Tibor Meszaros <[email protected]>
+
+ Math.{max, min}() must not return after first NaN value
+ https://bugs.webkit.org/show_bug.cgi?id=104147
+
+ Reviewed by Oliver Hunt.
+
+ Extended the Math.{max, min}() tests, to check that these methods are return after first NaN value or not.
+
+ * js/math-expected.txt:
+ * js/script-tests/math.js:
+
2014-02-27 Chris Fleizach <[email protected]>
speechSynthesis.speak of a zero length utterance kills future speech
Modified: trunk/LayoutTests/js/math-expected.txt (164818 => 164819)
--- trunk/LayoutTests/js/math-expected.txt 2014-02-27 19:20:08 UTC (rev 164818)
+++ trunk/LayoutTests/js/math-expected.txt 2014-02-27 19:39:42 UTC (rev 164819)
@@ -97,12 +97,24 @@
PASS Math.max(0) is 0
PASS Math.max(-0) is -0
PASS Math.max(-0, 0) is 0
+PASS Math.max(NaN, {valueOf:function(){throw "err"}}) threw exception err.
+PASS Math.max(NaN, NaN, {valueOf:function(){throw "err"}}) threw exception err.
+PASS Math.max(-0, NaN, 0) is NaN
+PASS Math.max(-0, NaN, 0, NaN) is NaN
+PASS Math.max({valueOf:function(){throw "error1"}}, {valueOf:function(){sideEffect = 1}}) threw exception error1.
+PASS sideEffect is 0
PASS Math.min() is Infinity
PASS Math.min(NaN) is NaN
PASS Math.min(NaN,1) is NaN
PASS Math.min(0) is 0
PASS Math.min(-0) is -0
PASS Math.min(-0, 0) is -0
+PASS Math.min(NaN, {valueOf:function(){throw "err"}}) threw exception err.
+PASS Math.min(NaN, NaN, {valueOf:function(){throw "err"}}) threw exception err.
+PASS Math.min(-0, NaN, 0) is NaN
+PASS Math.min(-0, NaN, 0, NaN) is NaN
+PASS Math.min({valueOf:function(){throw "error1"}}, {valueOf:function(){sideEffect = 1}}) threw exception error1.
+PASS sideEffect is 0
PASS Math.pow(NaN, NaN) is NaN
PASS Math.pow(NaN, 0) is 1
PASS Math.pow(NaN, -0) is 1
Modified: trunk/LayoutTests/js/script-tests/math.js (164818 => 164819)
--- trunk/LayoutTests/js/script-tests/math.js 2014-02-27 19:20:08 UTC (rev 164818)
+++ trunk/LayoutTests/js/script-tests/math.js 2014-02-27 19:39:42 UTC (rev 164819)
@@ -139,6 +139,13 @@
shouldBe("Math.max(0)", "0");
shouldBe("Math.max(-0)", "-0");
shouldBe("Math.max(-0, 0)", "0");
+shouldThrow("Math.max(NaN, {valueOf:function(){throw \"err\"}})","'err'");
+shouldThrow("Math.max(NaN, NaN, {valueOf:function(){throw \"err\"}})","'err'");
+shouldBe("Math.max(-0, NaN, 0)", "NaN");
+shouldBe("Math.max(-0, NaN, 0, NaN)", "NaN");
+sideEffect = 0;
+shouldThrow("Math.max({valueOf:function(){throw \"error1\"}}, {valueOf:function(){sideEffect = 1}})", "'error1'")
+shouldBe('sideEffect', '0');
shouldBe("Math.min()", "Infinity");
shouldBe("Math.min(NaN)", "NaN");
@@ -146,6 +153,13 @@
shouldBe("Math.min(0)", "0");
shouldBe("Math.min(-0)", "-0");
shouldBe("Math.min(-0, 0)", "-0");
+shouldThrow("Math.min(NaN, {valueOf:function(){throw \"err\"}})","'err'");
+shouldThrow("Math.min(NaN, NaN, {valueOf:function(){throw \"err\"}})","'err'");
+shouldBe("Math.min(-0, NaN, 0)", "NaN");
+shouldBe("Math.min(-0, NaN, 0, NaN)", "NaN");
+sideEffect = 0;
+shouldThrow("Math.min({valueOf:function(){throw \"error1\"}}, {valueOf:function(){sideEffect = 1}})", "'error1'")
+shouldBe('sideEffect', '0');
shouldBe("Math.pow(NaN, NaN)", "NaN");
shouldBe("Math.pow(NaN, 0)", "1");
Modified: trunk/Source/_javascript_Core/ChangeLog (164818 => 164819)
--- trunk/Source/_javascript_Core/ChangeLog 2014-02-27 19:20:08 UTC (rev 164818)
+++ trunk/Source/_javascript_Core/ChangeLog 2014-02-27 19:39:42 UTC (rev 164819)
@@ -1,3 +1,17 @@
+2014-02-27 Tibor Meszaros <[email protected]>
+
+ Math.{max, min}() must not return after first NaN value
+ https://bugs.webkit.org/show_bug.cgi?id=104147
+
+ Reviewed by Oliver Hunt.
+
+ According to the spec, ToNumber going to be called on each argument
+ even if a `NaN` value was already found
+
+ * runtime/MathObject.cpp:
+ (JSC::mathProtoFuncMax):
+ (JSC::mathProtoFuncMin):
+
2014-02-27 Gergo Balogh <[email protected]>
JSType upper limit (0xff) assertion can be removed.
Modified: trunk/Source/_javascript_Core/runtime/MathObject.cpp (164818 => 164819)
--- trunk/Source/_javascript_Core/runtime/MathObject.cpp 2014-02-27 19:20:08 UTC (rev 164818)
+++ trunk/Source/_javascript_Core/runtime/MathObject.cpp 2014-02-27 19:39:42 UTC (rev 164819)
@@ -188,9 +188,7 @@
double val = exec->uncheckedArgument(k).toNumber(exec);
if (std::isnan(val)) {
result = QNaN;
- break;
- }
- if (val > result || (!val && !result && !std::signbit(val)))
+ } else if (val > result || (!val && !result && !std::signbit(val)))
result = val;
}
return JSValue::encode(jsNumber(result));
@@ -204,9 +202,7 @@
double val = exec->uncheckedArgument(k).toNumber(exec);
if (std::isnan(val)) {
result = QNaN;
- break;
- }
- if (val < result || (!val && !result && std::signbit(val)))
+ } else if (val < result || (!val && !result && std::signbit(val)))
result = val;
}
return JSValue::encode(jsNumber(result));