[vm] Handle errors from RegExp engine

Bug: b/72146178
Change-Id: I2d05a004690b4d3e0b3e79786a967e27fddaacb5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166582
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov 2020-10-07 22:34:24 +00:00 committed by commit-bot@chromium.org
parent 6c31582031
commit 5c19b4abcd
4 changed files with 53 additions and 0 deletions

View file

@ -0,0 +1,23 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Verifies that RegExp compilation doesn't crash on a huge source string.
import 'package:expect/expect.dart';
void testBigRegExp(String source) {
try {
var re = new RegExp(source);
Expect.isTrue(re.hasMatch(source));
} catch (e) {
// May throw a compile-time error, but shouldn't crash.
Expect.isTrue(e.toString().contains('RegExp too big'));
}
}
main() {
testBigRegExp("a" * (0x10000 - 128));
testBigRegExp(
String.fromCharCodes(List.generate(0x10000 - 128, (x) => x + 128)));
}

View file

@ -0,0 +1,23 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Verifies that RegExp compilation doesn't crash on a huge source string.
import 'package:expect/expect.dart';
void testBigRegExp(String source) {
try {
var re = new RegExp(source);
Expect.isTrue(re.hasMatch(source));
} catch (e) {
// May throw an error containing
Expect.isTrue(e.toString().contains('RegExp too big'));
}
}
main() {
testBigRegExp("a" * (0x10000 - 128));
testBigRegExp(
String.fromCharCodes(List.generate(0x10000 - 128, (x) => x + 128)));
}

View file

@ -179,6 +179,10 @@ FlowGraph* IrregexpCompilationPipeline::BuildFlowGraph(
RegExpEngine::CompilationResult result =
RegExpEngine::CompileIR(parsed_function->regexp_compile_data(),
parsed_function, *ic_data_array, osr_id);
if (result.error_message != nullptr) {
Report::LongJump(LanguageError::Handle(
LanguageError::New(String::Handle(String::New(result.error_message)))));
}
backtrack_goto_ = result.backtrack_goto;
// Allocate variables now that we know the number of locals.

View file

@ -452,6 +452,9 @@ static intptr_t Prepare(const RegExp& regexp,
RegExpEngine::CompilationResult result = RegExpEngine::CompileBytecode(
compile_data, regexp, is_one_byte, sticky, zone);
if (result.error_message != nullptr) {
Exceptions::ThrowUnsupportedError(result.error_message);
}
ASSERT(result.bytecode != NULL);
ASSERT(regexp.num_registers(is_one_byte) == -1 ||
regexp.num_registers(is_one_byte) == result.num_registers);