Skip to content

Commit

Permalink
fix: crash in v8 due to regexp reentrancy (#31142)
Browse files Browse the repository at this point in the history
* fix: crash in v8 due to regexp reentrancy

Check failed: !regexp_stack_->is_in_use()

Refs https://bugs.chromium.org/p/chromium/issues/detail?id=1250646
Refs https://bugs.chromium.org/p/v8/issues/detail?id=11382

* chore: update patches

* chore: update patches

Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
  • Loading branch information
3 people committed Sep 28, 2021
1 parent d936293 commit d70c5d1
Show file tree
Hide file tree
Showing 4 changed files with 2,243 additions and 0 deletions.
3 changes: 3 additions & 0 deletions patches/v8/.patches
Expand Up @@ -13,3 +13,6 @@ cherry-pick-1228036.patch
cherry-pick-1234764.patch
cherry-pick-fbfd2557c2ab.patch
cherry-pick-034c2003be31.patch
regexp_add_a_currently_failing_cctest_for_irregexp_reentrancy.patch
regexp_allow_reentrant_irregexp_execution.patch
regexp_remove_the_stack_parameter_from_regexp_matchers.patch
@@ -0,0 +1,109 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jakob Gruber <jgruber@chromium.org>
Date: Mon, 6 Sep 2021 08:29:33 +0200
Subject: Add a (currently failing) cctest for irregexp reentrancy

The test should be enabled once reentrancy is supported.

Bug: v8:11382
Change-Id: Ifb90d8a6fd8bf9f05e9ca2405d4e04e013ce7ee3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3138201
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Patrick Thier <pthier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76667}

diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 7b1bf8caa5e3f3975a457e061d966fd60c5ef441..d6691b5e861d29100d0f1c15c887dd824f3929cb 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -126,6 +126,9 @@
'test-strings/StringOOM*': [PASS, ['mode == debug', SKIP]],
'test-serialize/CustomSnapshotDataBlobImmortalImmovableRoots': [PASS, ['mode == debug', SKIP]],
'test-parsing/ObjectRestNegativeTestSlow': [PASS, ['mode == debug', SKIP]],
+
+ # TODO(v8:11382): Reenable once irregexp is reentrant.
+ 'test-regexp/RegExpInterruptReentrantExecution': [FAIL],
}], # ALWAYS

##############################################################################
@@ -606,6 +609,9 @@

# Instruction cache flushing is disabled in jitless mode.
'test-icache/*': [SKIP],
+
+ # Tests generated irregexp code.
+ 'test-regexp/RegExpInterruptReentrantExecution': [SKIP],
}], # lite_mode or variant == jitless

##############################################################################
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 5eafa420bc21f40a2eb0caaa76ad2ffd4bd8db85..db0fb3c965c66e7d5a173559c52deca36bc47ebd 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -21581,10 +21581,6 @@ TEST(RegExpInterruptAndMakeSubjectTwoByteExternal) {
// experimental engine.
i::FLAG_enable_experimental_regexp_engine_on_excessive_backtracks = false;
RegExpInterruptTest test;
- // We want to be stuck regexp execution, so no fallback to linear-time
- // engine.
- // TODO(mbid,v8:10765): Find a way to test interrupt support of the
- // experimental engine.
test.RunTest(RegExpInterruptTest::MakeSubjectTwoByteExternal);
}

diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 63495194d4fbce61abbe9a7e83a446341f6f3dd6..fa02c23c47dcefb4ee77c9fc4c8222f52653e576 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -2340,6 +2340,50 @@ TEST(UnicodePropertyEscapeCodeSize) {
}
}

+namespace {
+
+struct RegExpExecData {
+ i::Isolate* isolate;
+ i::Handle<i::JSRegExp> regexp;
+ i::Handle<i::String> subject;
+};
+
+i::Handle<i::Object> RegExpExec(const RegExpExecData* d) {
+ return i::RegExp::Exec(d->isolate, d->regexp, d->subject, 0,
+ d->isolate->regexp_last_match_info())
+ .ToHandleChecked();
+}
+
+void ReenterRegExp(v8::Isolate* isolate, void* data) {
+ RegExpExecData* d = static_cast<RegExpExecData*>(data);
+ i::Handle<i::Object> result = RegExpExec(d);
+ CHECK(result->IsNull());
+}
+
+} // namespace
+
+// Tests reentrant irregexp calls.
+TEST(RegExpInterruptReentrantExecution) {
+ CHECK(!i::FLAG_jitless);
+ i::FLAG_regexp_tier_up = false; // Enter irregexp, not the interpreter.
+
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ RegExpExecData d;
+ d.isolate = reinterpret_cast<i::Isolate*>(isolate);
+ d.regexp = v8::Utils::OpenHandle(
+ *v8::RegExp::New(context.local(), v8_str("(a*)*x"), v8::RegExp::kNone)
+ .ToLocalChecked());
+ d.subject = v8::Utils::OpenHandle(*v8_str("aaaa"));
+
+ isolate->RequestInterrupt(&ReenterRegExp, &d);
+
+ i::Handle<i::Object> result = RegExpExec(&d);
+ CHECK(result->IsNull());
+}
+
#undef CHECK_PARSE_ERROR
#undef CHECK_SIMPLE
#undef CHECK_MIN_MAX

0 comments on commit d70c5d1

Please sign in to comment.