Skip to content

Commit

Permalink
Merge pull request #2134 from svaarala/fix-plus-minus-number-coercion…
Browse files Browse the repository at this point in the history
…-gh2019

Fix +'+' and +'-' coercion to NaN instead of 0
  • Loading branch information
svaarala committed Jun 30, 2019
2 parents d22c5cd + b30c1d2 commit 4ca1b3b
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 2 deletions.
2 changes: 2 additions & 0 deletions RELEASES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3472,6 +3472,8 @@ Planned
caused an error and Duktape.errCreate returned a callable value (such
as Float64Array); this caused an assertion failure (GH-2061, GH-2087)

* Fix coercion of +'+' and +'-' to NaN instead of 0 (GH-2019, GH-2134)

* Fix possible out-of-memory in call stack unwind by preallocating the
environment property table on creation (GH-476, GH-2021, GH-2106)

Expand Down
3 changes: 2 additions & 1 deletion src-input/duk_js_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ DUK_INTERNAL duk_bool_t duk_js_toboolean(duk_tval *tv) {
* ("0x123") and infinities
*
* - Unlike source code literals, ToNumber() coerces empty strings
* and strings with only whitespace to zero (not NaN).
* and strings with only whitespace to zero (not NaN). However,
* while '' coerces to 0, '+' and '-' coerce to NaN.
*/

/* E5 Section 9.3.1 */
Expand Down
9 changes: 8 additions & 1 deletion src-input/duk_numconv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2090,10 +2090,17 @@ DUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk
goto parse_fail;
}
} else {
/* empty ("") is allowed in some formats (e.g. Number(''), as zero */
/* Empty ("") is allowed in some formats (e.g. Number(''), as zero,
* but it must not have a leading +/- sign (GH-2019). Note that
* for Number(), h_str is already trimmed so we can check for zero
* length and still get Number(' + ') == NaN.
*/
if ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO) == 0) {
DUK_DDD(DUK_DDDPRINT("parse failed: empty string not allowed (as zero)"));
goto parse_fail;
} else if (DUK_HSTRING_GET_BYTELEN(h_str) != 0) {
DUK_DDD(DUK_DDDPRINT("parse failed: no digits, but not empty (had a +/- sign)"));
goto parse_fail;
}
}
} else {
Expand Down
73 changes: 73 additions & 0 deletions tests/ecmascript/test-bug-plus-coercion-gh2019.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* https://github.com/svaarala/duktape/issues/2019
*/

/*===
NaN
NaN
0
Infinity
0
-Infinity
0
NaN
NaN
0
Infinity
0
-Infinity
0
NaN
NaN
0
-Infinity
0
Infinity
0
NaN
NaN
0
-Infinity
0
Infinity
0
done
===*/

try {
print(+'+');
print(+'-');
print(+'+0');
print(1 / +'+0');
print(+'-0');
print(1 / +'-0');
print(+'');

print(+' + ');
print(+' - ');
print(+' +0 ');
print(1 / +' +0 ');
print(+' -0 ');
print(1 / +' -0 ');
print(+' ');

print(-'+');
print(-'-');
print(-'+0');
print(1 / -'+0');
print(-'-0');
print(1 / -'-0');
print(-'');

print(-' + ');
print(-' - ');
print(-' +0 ');
print(1 / -' +0 ');
print(-' -0 ');
print(1 / -' -0 ');
print(-' ');
} catch (e) {
print(e.stack || e);
}

print('done');

0 comments on commit 4ca1b3b

Please sign in to comment.