diff --git a/common.gypi b/common.gypi index 7eaad1e5ea1..3e37e440b86 100644 --- a/common.gypi +++ b/common.gypi @@ -43,7 +43,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.35', + 'v8_embedder_string': '-node.36', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index cf468f85950..404f8901990 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -124,6 +124,7 @@ Douglas Crosher Dusan Milosavljevic Eden Wang Edoardo Marangoni +Eliau Elkouby Elisha Hollander Eric Rannaud Erich Ocean diff --git a/deps/v8/src/execution/isolate.cc b/deps/v8/src/execution/isolate.cc index 74762de5a9a..e94255333ac 100644 --- a/deps/v8/src/execution/isolate.cc +++ b/deps/v8/src/execution/isolate.cc @@ -1645,12 +1645,15 @@ MaybeDirectHandle Isolate::CaptureAndSetErrorStack( static_cast( stack_trace_for_uncaught_exceptions_frame_limit_)); DCHECK_GE(stack_trace_limit, 0); - if (static_cast(stack_trace_limit) * - CallSiteInfo::Fields::kCount < - raw_data_for_call_site_infos->length()) { + // Compare in frames rather than raw slots to avoid overflowing for + // large Error.stackTraceLimit values. + uint32_t frame_count = raw_data_for_call_site_infos->ulength() / + CallSiteInfo::Fields::kCount; + if (static_cast(stack_trace_limit) < frame_count) { call_site_infos_or_formatted_stack = FixedArray::RightTrimOrEmpty( this, raw_data_for_call_site_infos, - stack_trace_limit * CallSiteInfo::Fields::kCount); + static_cast(stack_trace_limit) * + CallSiteInfo::Fields::kCount); } // Notify the debugger. OnStackTraceCaptured(stack_trace); diff --git a/deps/v8/test/cctest/test-api-stack-traces.cc b/deps/v8/test/cctest/test-api-stack-traces.cc index 22626a5e11f..4e8de23db42 100644 --- a/deps/v8/test/cctest/test-api-stack-traces.cc +++ b/deps/v8/test/cctest/test-api-stack-traces.cc @@ -438,6 +438,34 @@ TEST(CaptureStackTraceForUncaughtException) { CHECK_EQ(1, report_count); } +TEST(CaptureStackTraceForUncaughtExceptionHugeStackTraceLimit) { + LocalContext env; + v8::Isolate* isolate = env.isolate(); + v8::HandleScope scope(isolate); + isolate->SetCaptureStackTraceForUncaughtExceptions(true); + + CompileRun( + "function foo() { return new Error().stack; }\n" + "function bar() { return foo(); }\n" + "function stackWithLimit(limit) {\n" + " Error.stackTraceLimit = limit;\n" + " return bar();\n" + "}\n"); + Local expected = CompileRun("stackWithLimit(10)"); + CHECK(expected->IsString()); + + // For these limits, limit * CallSiteInfo::Fields::kCount overflows. + for (const char* limit : {"858993460", "858993461", "Infinity"}) { + std::string source = std::string("stackWithLimit(") + limit + ")"; + CHECK(CompileRun(source.c_str())->StrictEquals(expected)); + } + + // Small limits must still trim the stack trace. + CHECK(CompileRun("stackWithLimit(1).split('\\n').length === 2")->IsTrue()); + + isolate->SetCaptureStackTraceForUncaughtExceptions(false); +} + // Test uncaught exception in a setter const char uncaught_setter_exception_source[] = "var setters = ['column', 'lineNumber', 'scriptName',\n"