Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 8f4821e1ffd59699e422945d202686753d57ea37
https://github.com/WebKit/WebKit/commit/8f4821e1ffd59699e422945d202686753d57ea37
Author: Abrar Rahman Protyasha <[email protected]>
Date: 2026-02-25 (Wed, 25 Feb 2026)
Changed paths:
M Source/WebCore/loader/NetscapePlugInStreamLoader.cpp
M Source/WebKit/WebProcess/Plugins/PluginView.cpp
Log Message:
-----------
pdf/pdf-plugin-printing.html is flakily crashing, ASSERTION FAILED:
m_plugInStreamLoaders.contains(&loader)
https://bugs.webkit.org/show_bug.cgi?id=308583
rdar://171111801
Reviewed by Wenson Hsieh.
When PDFPluginBase::tryRunScriptsInPDFDocument() triggers window.print(),
WebChromeClient::print() sends a sync PrintFrame message to the UI process.
The UI process responds with BeginPrintingDuringDOMPrintOperation, which is
dispatched re-entrantly during waitForSyncReply. This re-entrant message
triggers layout via updateLayout(), which can destroy the PluginView through
WidgetHierarchyUpdatesSuspensionScope::moveWidgets().
When the PluginView is destroyed, its stream is cancelled, which calls
NetscapePlugInStreamLoader::notifyDone() to remove the loader from
DocumentLoader::m_plugInStreamLoaders. But when the re-entrant unwind
completes and control returns to Stream::didFinishLoading (still on the
stack), it calls notifyDone() again, hitting the assertion that the loader
is still in m_plugInStreamLoaders. It also dereferences m_pluginView, which
is a WeakPtr that has been nulled by the PluginView's destruction.
In this patch, we fix both issues:
1. In NetscapePlugInStreamLoader::notifyDone(), reset m_isInitialized
before removing from m_plugInStreamLoaders, so a next call is a no-op.
2. In PluginView::Stream::didFail() and didFinishLoading(), hold on to
the PluginView object in a local RefPtr and clear out m_pluginView.
This serves two purposes: nulling m_pluginView early ensures that if
the callback triggers re-entrant destruction of the Stream, the
ASSERT(!m_pluginView) in ~Stream() holds; and capturing the result
into a RefPtr keeps the PluginView alive across the callback, so the
cleanup afterward operates on a valid object.
* Source/WebCore/loader/NetscapePlugInStreamLoader.cpp:
(WebCore::NetscapePlugInStreamLoader::notifyDone):
* Source/WebKit/WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::Stream::didFail):
(WebKit::PluginView::Stream::didFinishLoading):
Canonical link: https://commits.webkit.org/308242@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications