RESOLVED FIXED309208
Deeply nested <div> causes hang in parser (realistic example)
https://bugs.webkit.org/show_bug.cgi?id=309208
Summary Deeply nested <div> causes hang in parser (realistic example)
neil
Reported 2026-03-04 16:59:24 PST
Created attachment 478558 [details] HTML that reproduces the issue Steps to reproduce: 1. Try opening the attached HTML file in Safari (on iOS or macOS). Expected result: It renders the page (as Chrome and Firefox do). Actual result: That render process hangs. This HTML is from a real email a user received at Fastmail. I have removed the personal user data but otherwise left it the same. The bigger issue is that we have to analyse and render safely arbitrary HTML. To do this, we first get the browser to parse it like this: `const doc = new DOMParser().parseFromString(html, 'text/html');` With the attached HTML, the above function call hangs and never returns or throws an error (either would be fine), which causes our whole app to hang.
Attachments
HTML that reproduces the issue (33.17 KB, text/html)
2026-03-04 16:59 PST, neil
no flags
Reduction (11.12 KB, text/html)
2026-03-17 00:50 PDT, Ryosuke Niwa
no flags
Radar WebKit Bug Importer
Comment 1 2026-03-11 18:00:14 PDT
Ryosuke Niwa
Comment 2 2026-03-13 02:50:03 PDT
1796 Thread_6593079 DispatchQueue_1: com.apple.main-thread (serial) + 1796 start (in dyld) + 6992 [0x18650fda4] + 1796 WebKit::XPCServiceMain(int, char const**) (in WebKit) + 44 [0x10a54349c] + 1796 xpc_main (in libxpc.dylib) + 64 [0x1865b25e0] init.c:1378 + 1796 _xpc_main (in libxpc.dylib) + 40 [0x1865c4a40] init.c:1295 + 1796 _xpc_objc_main (in libxpc.dylib) + 668 [0x1865b2a20] main.m:268 + 1796 -[NSRunLoop(NSRunLoop) run] (in Foundation) + 64 [0x188248fa0] + 1796 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] (in Foundation) + 212 [0x1881d0b44] + 1796 _CFRunLoopRunSpecificWithOptions (in CoreFoundation) + 532 [0x186a59be0] + 1796 __CFRunLoopRun (in CoreFoundation) + 820 [0x1869874e4] + 1796 __CFRunLoopDoSources0 (in CoreFoundation) + 232 [0x1869888c0] + 1796 __CFRunLoopDoSource0 (in CoreFoundation) + 172 [0x186988b54] + 1796 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ (in CoreFoundation) + 28 [0x186988bc0] + 1796 WTF::RunLoop::performWork(void*) (in JavaScriptCore) + 36 [0x1113e8a5c] + 1796 WTF::RunLoop::performWork() (in JavaScriptCore) + 552 [0x1113e7090] + 1796 WTF::Detail::CallableWrapper<IPC::Connection::enqueueIncomingMessage(WTF::UniqueRef<IPC::Decoder>)::$_1, void>::call() (in WebKit) + 124 [0x10b1a7a6c] + 1796 IPC::Connection::dispatchMessage(WTF::UniqueRef<IPC::Decoder>) (in WebKit) + 504 [0x10b180a08] + 1796 WebKit::NetworkProcessConnection::didReceiveMessage(IPC::Connection&, IPC::Decoder&) (in WebKit) + 128 [0x10a4ed958] + 1796 WebKit::NetworkProcessConnection::dispatchMessage(IPC::Connection&, IPC::Decoder&) (in WebKit) + 248 [0x10af28dc8] + 1796 WebKit::WebResourceLoader::didReceiveMessage(IPC::Connection&, IPC::Decoder&) (in WebKit) + 784 [0x10a642080] + 1796 WebKit::WebResourceLoader::didReceiveData(IPC::SharedBufferReference&&, unsigned long long) (in WebKit) + 644 [0x10af357d4] + 1796 WebCore::SubresourceLoader::didReceiveBuffer(WebCore::FragmentedSharedBuffer const&, long long, WebCore::DataPayloadType) (in WebCore) + 588 [0x12039e660] + 1796 WebCore::CachedRawResource::updateBuffer(WebCore::FragmentedSharedBuffer const&) (in WebCore) + 204 [0x1203c4494] + 1796 WebCore::CachedRawResource::notifyClientsDataWasReceived(WebCore::SharedBuffer const&) (in WebCore) + 452 [0x1203c4950] + 1796 WebCore::DocumentLoader::commitLoad(WebCore::SharedBuffer const&) (in WebCore) + 252 [0x1202edc44] + 1796 WebKit::WebLocalFrameLoaderClient::committedLoad(WebCore::DocumentLoader*, WebCore::SharedBuffer const&) (in WebKit) + 56 [0x10afd00f8] + 1796 WebCore::DocumentLoader::commitData(WebCore::SharedBuffer const&) (in WebCore) + 864 [0x1202e7308] + 1796 WebCore::DocumentWriter::addData(WebCore::SharedBuffer const&) (in WebCore) + 260 [0x12030cad8] + 1796 WebCore::DecodedDataDocumentParser::appendBytes(WebCore::DocumentWriter&, std::span<unsigned char const, 18446744073709551615ul>) (in WebCore) + 208 [0x11fb9d1c0] + 1796 WebCore::HTMLDocumentParser::append(WTF::RefPtr<WTF::StringImpl, WTF::RawPtrTraits<WTF::StringImpl>, WTF::DefaultRefDerefTraits<WTF::StringImpl>>&&, WebCore::HTMLDocumentParser::SynchronousMode) (in WebCore) + 340 [0x1200c12f4] + 1796 WebCore::HTMLDocumentParser::pumpTokenizer(WebCore::HTMLDocumentParser::SynchronousMode) (in WebCore) + 692 [0x11ddcffb0] + 1518 WebCore::HTMLTreeBuilder::constructTree(WebCore::AtomHTMLToken&&) (in WebCore) + 328 [0x1200fcd10] + ! 872 WebCore::HTMLTreeBuilder::processEndTagForInCell(WebCore::AtomHTMLToken&&) (in WebCore) + 396 [0x12010686c] + ! : 557 WebCore::HTMLTreeBuilder::processFakeEndTag(WebCore::TagName) (in WebCore) + 64 [0x120101d60] + ! : | 215 WebCore::HTMLTreeBuilder::processEndTag(WebCore::AtomHTMLToken&&) (in WebCore) + 20,88,... [0x120100dbc,0x120100e00,...] + ! : | 175 WebCore::HTMLTreeBuilder::processEndTagForInCell(WebCore::AtomHTMLToken&&) (in WebCore) + 84,28,... [0x120106734,0x1201066fc,...] + ! : | 167 WebCore::HTMLTreeBuilder::processEndTagForInCell(WebCore::AtomHTMLToken&&) (in WebCore) + 72 [0x120106728] + ! : | 167 WebCore::elementNameForTag(WebCore::Namespace, WebCore::TagName) (in WebCore) + 36,0 [0x120105754,0x120105730] + ! : 155 WebCore::HTMLTreeBuilder::processFakeEndTag(WebCore::TagName) (in WebCore) + 72,36,... [0x120101d68,0x120101d44,...] + ! : 59 WebCore::HTMLTreeBuilder::processEndTag(WebCore::AtomHTMLToken&&) (in WebCore) + 116 [0x120100e1c] + ! : 55 WebCore::HTMLTreeBuilder::processEndTagForInCell(WebCore::AtomHTMLToken&&) (in WebCore) + 236 [0x1201067cc] + ! : 46 WebCore::HTMLTreeBuilder::closeTheCell() (in WebCore) + 0 [0x120104d20] + ! 190 WebCore::HTMLTreeBuilder::processEndTag(WebCore::AtomHTMLToken&&) (in WebCore) + 64,20,... [0x120100de8,0x120100dbc,...] + ! 159 WebCore::HTMLTreeBuilder::processEndTagForInCell(WebCore::AtomHTMLToken&&) (in WebCore) + 384 [0x120106860] + ! : 159 WebCore::HTMLElementStack::inTableScope(WebCore::NodeName) const (in WebCore) + 0,104,... [0x1200c41b4,0x1200c421c,...] + ! 141 WebCore::HTMLTreeBuilder::processEndTagForInCell(WebCore::AtomHTMLToken&&) (in WebCore) + 372 [0x120106854] + ! : 141 WebCore::elementNameForTag(WebCore::Namespace, WebCore::TagName) (in WebCore) + 40,0,... [0x120105758,0x120105730,...] + ! 102 WebCore::HTMLTreeBuilder::processEndTagForInCell(WebCore::AtomHTMLToken&&) (in WebCore) + 44,28,... [0x12010670c,0x1201066fc,...] + ! 54 WebCore::HTMLTreeBuilder::processFakeEndTag(WebCore::TagName) (in WebCore) + 156 [0x120101dbc] + 223 WebCore::HTMLTreeBuilder::processEndTagForInCell(WebCore::AtomHTMLToken&&) (in WebCore) + 412,416 [0x12010687c,0x120106880] + 55 WebCore::HTMLTreeBuilder::processEndTag(WebCore::AtomHTMLToken&&) (in WebCore) + 116 [0x120100e1c]
Brent Fulgham
Comment 3 2026-03-13 11:32:45 PDT
Seems like a dupe of Bug 18282, except much more obviously blocking the render.
Ryosuke Niwa
Comment 4 2026-03-17 00:50:06 PDT
Created attachment 478704 [details] Reduction
Ryosuke Niwa
Comment 5 2026-03-17 16:06:11 PDT
Ryosuke Niwa
Comment 6 2026-03-17 16:47:15 PDT
EWS
Comment 7 2026-03-17 22:51:29 PDT
Committed 309454@main (aff0077f7388): <https://commits.webkit.org/309454@main> Reviewed commits have been landed. Closing PR #60816 and removing active labels.
Note You need to log in before you can comment on or make changes to this bug.