mirror of
https://github.com/dart-lang/sdk
synced 2024-10-04 16:54:55 +00:00
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:
parent
c84a9f46b2
commit
dfeaf79cef
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
|
|
@ -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])) &&
|
||||
|
|
|
@ -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 ]
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue