Fix VM accepting too many overlarge hex numbers in int.parse.

Fixes #32858

BUG= http://dartbug.com/32858

Change-Id: I362e51ef0fb8b55a0ca1a7ed75a77a13c9d94893
Reviewed-on: https://dart-review.googlesource.com/60243
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
This commit is contained in:
Lasse R.H. Nielsen 2018-06-18 10:04:07 +00:00 committed by commit-bot@chromium.org
parent c84a9f46b2
commit dfeaf79cef
5 changed files with 34 additions and 7 deletions

View file

@ -40,6 +40,11 @@ allowed when `exp` has type `void`.
### Core library changes
* `dart:core`
* `int.parse` on the VM no longer accepts unsigned hexadecimal numbers
greater than or equal to 2**63 when not prefixed by `0x`.
(SDK issue [32858](https://github.com/dart-lang/sdk/issues/32858))
## 2.0.0-dev.63.0
### Tool Changes

View file

@ -4637,7 +4637,7 @@ class Parser {
Token token = getAndAdvance();
int value = null;
try {
value = int.parse(token.lexeme.substring(2), radix: 16);
value = int.parse(token.lexeme);
} on FormatException {
// The invalid format should have been reported by the scanner.
}

View file

@ -90,7 +90,7 @@ class int {
if (index == end) {
return _throwFormatException(onError, source, index, null);
}
int result = _parseRadix(source, 16, index, end, sign);
int result = _parseRadix(source, 16, index, end, sign, sign > 0);
if (result == null) {
return _throwFormatException(onError, source, null, null);
}
@ -99,7 +99,7 @@ class int {
}
radix = 10;
}
int result = _parseRadix(source, radix, start, end, sign);
int result = _parseRadix(source, radix, start, end, sign, false);
if (result == null) {
return _throwFormatException(onError, source, null, radix);
}
@ -131,7 +131,7 @@ class int {
}
static int _parseRadix(
String source, int radix, int start, int end, int sign) {
String source, int radix, int start, int end, int sign, bool allowU64) {
int tableIndex = (radix - 2) * 4 + (is64Bit ? 2 : 0);
int blockSize = _PARSE_LIMITS[tableIndex];
int length = end - start;
@ -174,7 +174,7 @@ class int {
// platform, the multiplier and block size, which are used to
// compute it, do.
int X = is64Bit ? 1 : 0;
if (radix == 16 &&
if (allowU64 &&
!(result >= _int64UnsignedOverflowLimits[X] &&
(result > _int64UnsignedOverflowLimits[X] ||
smi > _int64UnsignedSmiOverflowLimits[X])) &&

View file

@ -16,6 +16,7 @@ unicode_test: RuntimeError
bigint_from_test: CompileTimeError # Issue 32585
compare_to2_test: CompileTimeError # invalid test
int_parse_radix_bad_handler_test: MissingCompileTimeError
int_try_parse_test: CompileTimeError # Issue 32585
iterable_element_at_test/static: Pass
num_sign_test: Crash, Pass # Issue 31768
@ -33,6 +34,7 @@ bigint_from_test: RuntimeError # Issue 32589
bool_from_environment2_test/03: Crash
int_modulo_arith_test/modPow: RuntimeError
int_modulo_arith_test/none: RuntimeError
int_try_parse_test: RuntimeError # Issue 33351
string_from_environment3_test/03: Crash
[ $compiler == precompiler ]
@ -292,6 +294,7 @@ string_from_environment3_test/03: MissingCompileTimeError
[ $compiler == dartdevc && $runtime != none ]
bigint_from_test: CompileTimeError # Issue 32585
compare_to2_test: CompileTimeError # invalid test
int_try_parse_test: CompileTimeError # Issue 32585
symbol_operator_test: RuntimeError # Issue 29921
[ $compiler != dartdevc && $compiler != dartdevk && $checked && !$strong ]

View file

@ -99,8 +99,8 @@ void main() {
Expect.equals(1, int.tryParse("\n1\n", radix: 2));
Expect.equals(1, int.tryParse("+1", radix: 2));
void testFails(String source, int radix) {
Expect.isNull(int.tryParse(source, radix: radix));
void testFails(String source, int radix, [String message]) {
Expect.isNull(int.tryParse(source, radix: radix), message);
}
for (int i = 2; i < 36; i++) {
@ -117,6 +117,7 @@ void main() {
// At radix 34 and above, "x" is a valid digit.
testFails("0x10", i);
}
int digitX = 33;
Expect.equals(((digitX * 34) + 1) * 34, int.tryParse("0x10", radix: 34));
Expect.equals(((digitX * 35) + 1) * 35, int.tryParse("0x10", radix: 35));
@ -126,4 +127,22 @@ void main() {
Expect.throwsArgumentError(() => int.tryParse("0", radix: 0));
Expect.throwsArgumentError(() => int.tryParse("0", radix: -1));
Expect.throwsArgumentError(() => int.tryParse("0", radix: 37));
// Regression test for http://dartbug.com/32858
Expect.equals(
-0x8000000000000000, int.tryParse("-0x8000000000000000"), "-minint");
// Tests run only with 64-bit integers.
if (0x8000000000000000 < 0) {
// `int` is 64-bit signed integers.
Expect.equals(
-0x8000000000000000, int.tryParse("0x8000000000000000"), "0xUnsigned");
Expect.equals(-1, int.tryParse("0xFFFFFFFFFFFFFFFF"), "0xUnsigned2");
Expect.equals(
0x8000000000000000 - 1, int.tryParse("0x7FFFFFFFFFFFFFFF"), "maxint");
testFails("8000000000000000", 16, "2^63 radix: 16");
testFails("FFFFFFFFFFFFFFFF", 16, "maxuint64 radix: 16");
testFails("-0xC000000000000000", null, "signed uint64");
}
}