diff -urpN webkitgtk-2.36.0.orig/a webkitgtk-2.36.0/a
--- webkitgtk-2.36.0.orig/a	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/a	2022-03-22 16:48:58.416753527 -0500
@@ -0,0 +1,6 @@
+./Source/WebKit/UIProcess/WebProcessPool.cpp.orig
+./Source/WebKit/Shared/AuxiliaryProcess.cpp.orig
+./Source/WebKit/Shared/AuxiliaryProcess.h.orig
+./Source/WebKit/Shared/WebProcessCreationParameters.cpp.orig
+./Source/WebKit/Shared/WebProcessCreationParameters.h.orig
+./Source/WebKit/WebProcess/WebProcess.cpp.orig
diff -urpN webkitgtk-2.36.0.orig/Source/cmake/OptionsGTK.cmake webkitgtk-2.36.0/Source/cmake/OptionsGTK.cmake
--- webkitgtk-2.36.0.orig/Source/cmake/OptionsGTK.cmake	2022-03-21 03:46:05.000000000 -0500
+++ webkitgtk-2.36.0/Source/cmake/OptionsGTK.cmake	2022-03-22 16:38:57.361580047 -0500
@@ -158,7 +158,6 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MOUSE_CURSOR_SCALE PRIVATE ON)
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_OFFSCREEN_CANVAS PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
@@ -171,6 +170,10 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_API_STATISTICS PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_RTC PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 
+if (USE_GTK4)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
+endif ()
+
 include(GStreamerDependencies)
 
 # Finalize the value for all options. Do not attempt to use an option before
@@ -256,7 +259,16 @@ SET_AND_EXPOSE_TO_BUILD(WTF_PLATFORM_QUA
 SET_AND_EXPOSE_TO_BUILD(WTF_PLATFORM_X11 ${ENABLE_X11_TARGET})
 SET_AND_EXPOSE_TO_BUILD(WTF_PLATFORM_WAYLAND ${ENABLE_WAYLAND_TARGET})
 
-SET_AND_EXPOSE_TO_BUILD(ENABLE_PLUGIN_PROCESS FALSE)
+if (ENABLE_NETSCAPE_PLUGIN_API)
+    # MOZ_X11 and XP_UNIX are required by npapi.h. Their value is not checked;
+    # only their definedness is. They should only be defined in the true case.
+    if (ENABLE_X11_TARGET)
+        SET_AND_EXPOSE_TO_BUILD(MOZ_X11 1)
+    endif ()
+    SET_AND_EXPOSE_TO_BUILD(XP_UNIX 1)
+endif ()
+
+SET_AND_EXPOSE_TO_BUILD(ENABLE_PLUGIN_PROCESS ${ENABLE_NETSCAPE_PLUGIN_API})
 
 add_definitions(-DBUILDING_GTK__=1)
 add_definitions(-DGETTEXT_PACKAGE="WebKit2GTK-${WEBKITGTK_API_VERSION}")
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bindings/js/ScriptController.cpp webkitgtk-2.36.0/Source/WebCore/bindings/js/ScriptController.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/bindings/js/ScriptController.cpp	2022-02-23 02:59:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bindings/js/ScriptController.cpp	2022-03-22 16:38:57.361580047 -0500
@@ -43,6 +43,7 @@
 #include "Logging.h"
 #include "ModuleFetchFailureKind.h"
 #include "ModuleFetchParameters.h"
+#include "NP_jsobject.h"
 #include "Page.h"
 #include "PageConsoleClient.h"
 #include "PageGroup.h"
@@ -58,6 +59,7 @@
 #include "UserGestureIndicator.h"
 #include "WebCoreJITOperations.h"
 #include "WebCoreJSClientData.h"
+#include "npruntime_impl.h"
 #include "runtime_root.h"
 #include <JavaScriptCore/Debugger.h>
 #include <JavaScriptCore/Heap.h>
@@ -95,6 +97,9 @@ ScriptController::ScriptController(Frame
     : m_frame(frame)
     , m_sourceURL(0)
     , m_paused(false)
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    , m_windowScriptNPObject(0)
+#endif
 #if PLATFORM(COCOA)
     , m_windowScriptObject(0)
 #endif
@@ -491,6 +496,29 @@ void ScriptController::collectIsolatedCo
     }
 }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+NPObject* ScriptController::windowScriptNPObject()
+{
+    if (!m_windowScriptNPObject) {
+        JSLockHolder lock(commonVM());
+        if (canExecuteScripts(NotAboutToExecuteScript)) {
+            // JavaScript is enabled, so there is a JavaScript window object.
+            // Return an NPObject bound to the window object.
+            auto* window = jsWindowProxy(pluginWorld()).window();
+            ASSERT(window);
+            Bindings::RootObject* root = bindingRootObject();
+            m_windowScriptNPObject = _NPN_CreateScriptObject(0, window, root);
+        } else {
+            // JavaScript is not enabled, so we cannot bind the NPObject to the JavaScript window object.
+            // Instead, we create an NPObject of a different class, one which is not bound to a JavaScript object.
+            m_windowScriptNPObject = _NPN_CreateNoScriptObject();
+        }
+    }
+
+    return m_windowScriptNPObject;
+}
+#endif
+
 #if !PLATFORM(COCOA)
 RefPtr<JSC::Bindings::Instance> ScriptController::createScriptInstanceForWidget(Widget* widget)
 {
@@ -554,6 +582,16 @@ void ScriptController::clearScriptObject
         m_bindingRootObject->invalidate();
         m_bindingRootObject = nullptr;
     }
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    if (m_windowScriptNPObject) {
+        // Call _NPN_DeallocateObject() instead of _NPN_ReleaseObject() so that we don't leak if a plugin fails to release the window
+        // script object properly.
+        // This shouldn't cause any problems for plugins since they should have already been stopped and destroyed at this point.
+        _NPN_DeallocateObject(m_windowScriptNPObject);
+        m_windowScriptNPObject = nullptr;
+    }
+#endif
 }
 
 JSC::JSValue ScriptController::executeScriptIgnoringException(const String& script, bool forceUserGesture)
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bindings/js/ScriptController.h webkitgtk-2.36.0/Source/WebCore/bindings/js/ScriptController.h
--- webkitgtk-2.36.0.orig/Source/WebCore/bindings/js/ScriptController.h	2022-02-23 02:59:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bindings/js/ScriptController.h	2022-03-22 16:38:57.361580047 -0500
@@ -39,6 +39,8 @@ OBJC_CLASS JSContext;
 OBJC_CLASS WebScriptObject;
 #endif
 
+struct NPObject;
+
 namespace JSC {
 class CallFrame;
 class JSGlobalObject;
@@ -162,6 +164,10 @@ public:
 #endif
 
     WEBCORE_EXPORT JSC::JSObject* jsObjectForPluginElement(HTMLPlugInElement*);
+    
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    WEBCORE_EXPORT NPObject* windowScriptNPObject();
+#endif
 
     void initScriptForWindowProxy(JSWindowProxy&);
 
@@ -194,6 +200,9 @@ private:
     // This ensures they are still available when the page is restored.
     RefPtr<JSC::Bindings::RootObject> m_cacheableBindingRootObject;
     RootObjectMap m_rootObjects;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    NPObject* m_windowScriptNPObject;
+#endif
 #if PLATFORM(COCOA)
     RetainPtr<WebScriptObject> m_windowScriptObject;
 #endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_class.cpp webkitgtk-2.36.0/Source/WebCore/bridge/c/c_class.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_class.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/c/c_class.cpp	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2003, 2006 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "c_class.h"
+
+#include "c_instance.h"
+#include "c_runtime.h"
+#include "npruntime_impl.h"
+#include <JavaScriptCore/Identifier.h>
+#include <JavaScriptCore/JSCJSValueInlines.h>
+#include <JavaScriptCore/JSGlobalObject.h>
+#include <JavaScriptCore/JSObject.h>
+#include <wtf/text/StringHash.h>
+
+namespace JSC { namespace Bindings {
+
+CClass::CClass(NPClass* aClass)
+{
+    m_isa = aClass;
+}
+
+CClass::~CClass()
+{
+    m_methods.clear();
+    m_fields.clear();
+}
+
+typedef HashMap<NPClass*, CClass*> ClassesByIsAMap;
+static ClassesByIsAMap* classesByIsA = 0;
+
+CClass* CClass::classForIsA(NPClass* isa)
+{
+    if (!classesByIsA)
+        classesByIsA = new ClassesByIsAMap;
+
+    CClass* aClass = classesByIsA->get(isa);
+    if (!aClass) {
+        aClass = new CClass(isa);
+        classesByIsA->set(isa, aClass);
+    }
+
+    return aClass;
+}
+
+Method* CClass::methodNamed(PropertyName propertyName, Instance* instance) const
+{
+    String name(propertyName.publicName());
+    if (name.isNull())
+        return nullptr;
+    
+    if (Method* method = m_methods.get(name.impl()))
+        return method;
+
+    NPIdentifier ident = _NPN_GetStringIdentifier(name.ascii().data());
+    const CInstance* inst = static_cast<const CInstance*>(instance);
+    NPObject* obj = inst->getObject();
+    if (m_isa->hasMethod && m_isa->hasMethod(obj, ident)) {
+        auto method = makeUnique<CMethod>(ident);
+        CMethod* ret = method.get();
+        m_methods.set(name.impl(), WTFMove(method));
+        return ret;
+    }
+    
+    return nullptr;
+}
+
+Field* CClass::fieldNamed(PropertyName propertyName, Instance* instance) const
+{
+    String name(propertyName.publicName());
+    if (name.isNull())
+        return nullptr;
+    
+    if (Field* field = m_fields.get(name.impl()))
+        return field;
+
+    NPIdentifier ident = _NPN_GetStringIdentifier(name.ascii().data());
+    const CInstance* inst = static_cast<const CInstance*>(instance);
+    NPObject* obj = inst->getObject();
+    if (m_isa->hasProperty && m_isa->hasProperty(obj, ident)) {
+        auto field = makeUnique<CField>(ident);
+        CField* ret = field.get();
+        m_fields.set(name.impl(), WTFMove(field));
+        return ret;
+    }
+
+    return nullptr;
+}
+
+} } // namespace JSC::Bindings
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_class.h webkitgtk-2.36.0/Source/WebCore/bridge/c/c_class.h
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_class.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/c/c_class.h	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2003 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef BINDINGS_C_CLASS_H_
+#define BINDINGS_C_CLASS_H_
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "BridgeJSC.h"
+#include "npruntime_internal.h"
+#include <wtf/HashMap.h>
+
+namespace JSC {
+namespace Bindings {
+
+class CClass : public Class {
+protected:
+    CClass(NPClass*); // Use classForIsA to create a CClass.
+    
+public:
+    static CClass* classForIsA(NPClass*);
+    virtual ~CClass();
+
+    Method* methodNamed(PropertyName, Instance*) const override;
+    Field* fieldNamed(PropertyName, Instance*) const override;
+
+private:
+    NPClass* m_isa;
+    mutable HashMap<RefPtr<StringImpl>, std::unique_ptr<Method>> m_methods;
+    mutable HashMap<RefPtr<StringImpl>, std::unique_ptr<Field>> m_fields;
+};
+
+} // namespace Bindings
+} // namespace JSC
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_instance.cpp webkitgtk-2.36.0/Source/WebCore/bridge/c/c_instance.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_instance.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/c/c_instance.cpp	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2003-2019 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "c_instance.h"
+
+#include "CRuntimeObject.h"
+#include "IdentifierRep.h"
+#include "JSDOMBinding.h"
+#include "c_class.h"
+#include "c_runtime.h"
+#include "c_utility.h"
+#include "npruntime_impl.h"
+#include "runtime_method.h"
+#include "runtime_root.h"
+#include <JavaScriptCore/ArgList.h>
+#include <JavaScriptCore/CallFrame.h>
+#include <JavaScriptCore/Error.h>
+#include <JavaScriptCore/FunctionPrototype.h>
+#include <JavaScriptCore/JSLock.h>
+#include <JavaScriptCore/PropertyNameArray.h>
+#include <wtf/Assertions.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/Vector.h>
+
+using namespace WebCore;
+
+namespace JSC {
+namespace Bindings {
+
+static String& globalExceptionString()
+{
+    static NeverDestroyed<String> exceptionStr;
+    return exceptionStr;
+}
+
+void CInstance::setGlobalException(String exception)
+{
+    globalExceptionString() = exception;
+}
+
+void CInstance::moveGlobalExceptionToExecState(JSGlobalObject* lexicalGlobalObject)
+{
+    if (globalExceptionString().isNull())
+        return;
+
+    {
+        VM& vm = lexicalGlobalObject->vm();
+        JSLockHolder lock(vm);
+        auto scope = DECLARE_THROW_SCOPE(vm);
+        throwException(lexicalGlobalObject, scope, createError(lexicalGlobalObject, globalExceptionString()));
+    }
+
+    globalExceptionString() = String();
+}
+
+CInstance::CInstance(NPObject* o, RefPtr<RootObject>&& rootObject)
+    : Instance(WTFMove(rootObject))
+{
+    _object = _NPN_RetainObject(o);
+    _class = 0;
+}
+
+CInstance::~CInstance()
+{
+    _NPN_ReleaseObject(_object);
+}
+
+RuntimeObject* CInstance::newRuntimeObject(JSGlobalObject* lexicalGlobalObject)
+{
+    // FIXME: deprecatedGetDOMStructure uses the prototype off of the wrong global object.
+    return CRuntimeObject::create(lexicalGlobalObject->vm(), WebCore::deprecatedGetDOMStructure<CRuntimeObject>(lexicalGlobalObject), this);
+}
+
+Class *CInstance::getClass() const
+{
+    if (!_class)
+        _class = CClass::classForIsA(_object->_class);
+    return _class;
+}
+
+bool CInstance::supportsInvokeDefaultMethod() const
+{
+    return _object->_class->invokeDefault;
+}
+
+class CRuntimeMethod final : public RuntimeMethod {
+public:
+    using Base = RuntimeMethod;
+
+    static CRuntimeMethod* create(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject, const String& name, Bindings::Method* method)
+    {
+        VM& vm = globalObject->vm();
+        // FIXME: deprecatedGetDOMStructure uses the prototype off of the wrong global object
+        // We need to pass in the right global object for "i".
+        Structure* domStructure = WebCore::deprecatedGetDOMStructure<CRuntimeMethod>(lexicalGlobalObject);
+        CRuntimeMethod* runtimeMethod = new (NotNull, allocateCell<CRuntimeMethod>(vm)) CRuntimeMethod(vm, domStructure, method);
+        runtimeMethod->finishCreation(vm, name);
+        return runtimeMethod;
+    }
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
+    }
+
+    DECLARE_INFO;
+
+private:
+    CRuntimeMethod(VM& vm, Structure* structure, Bindings::Method* method)
+        : RuntimeMethod(vm, structure, method)
+    {
+    }
+
+    void finishCreation(VM& vm, const String& name)
+    {
+        Base::finishCreation(vm, name);
+        ASSERT(inherits(vm, info()));
+    }
+};
+
+const ClassInfo CRuntimeMethod::s_info = { "CRuntimeMethod", &RuntimeMethod::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(CRuntimeMethod) };
+
+JSValue CInstance::getMethod(JSGlobalObject* lexicalGlobalObject, PropertyName propertyName)
+{
+    Method* method = getClass()->methodNamed(propertyName, this);
+    return CRuntimeMethod::create(lexicalGlobalObject, lexicalGlobalObject, propertyName.publicName(), method);
+}
+
+JSValue CInstance::invokeMethod(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame, RuntimeMethod* runtimeMethod)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (!asObject(runtimeMethod)->inherits<CRuntimeMethod>(vm))
+        return throwTypeError(lexicalGlobalObject, scope, "Attempt to invoke non-plug-in method on plug-in object."_s);
+
+    CMethod* method = static_cast<CMethod*>(runtimeMethod->method());
+    ASSERT(method);
+
+    NPIdentifier ident = method->identifier();
+    if (!_object->_class->hasMethod(_object, ident))
+        return jsUndefined();
+
+    unsigned count = callFrame->argumentCount();
+    Vector<NPVariant, 8> cArgs(count);
+
+    unsigned i;
+    for (i = 0; i < count; i++)
+        convertValueToNPVariant(lexicalGlobalObject, callFrame->uncheckedArgument(i), &cArgs[i]);
+
+    // Invoke the 'C' method.
+    bool retval = true;
+    NPVariant resultVariant;
+    VOID_TO_NPVARIANT(resultVariant);
+
+    {
+        JSLock::DropAllLocks dropAllLocks(lexicalGlobalObject);
+        ASSERT(globalExceptionString().isNull());
+        retval = _object->_class->invoke(_object, ident, cArgs.data(), count, &resultVariant);
+        moveGlobalExceptionToExecState(lexicalGlobalObject);
+    }
+
+    if (!retval)
+        throwException(lexicalGlobalObject, scope, createError(lexicalGlobalObject, "Error calling method on NPObject."_s));
+
+    for (i = 0; i < count; i++)
+        _NPN_ReleaseVariantValue(&cArgs[i]);
+
+    JSValue resultValue = convertNPVariantToValue(lexicalGlobalObject, &resultVariant, m_rootObject.get());
+    _NPN_ReleaseVariantValue(&resultVariant);
+    return resultValue;
+}
+
+
+JSValue CInstance::invokeDefaultMethod(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (!_object->_class->invokeDefault)
+        return jsUndefined();
+
+    unsigned count = callFrame->argumentCount();
+    Vector<NPVariant, 8> cArgs(count);
+
+    unsigned i;
+    for (i = 0; i < count; i++)
+        convertValueToNPVariant(lexicalGlobalObject, callFrame->uncheckedArgument(i), &cArgs[i]);
+
+    // Invoke the 'C' method.
+    bool retval = true;
+    NPVariant resultVariant;
+    VOID_TO_NPVARIANT(resultVariant);
+    {
+        JSLock::DropAllLocks dropAllLocks(lexicalGlobalObject);
+        ASSERT(globalExceptionString().isNull());
+        retval = _object->_class->invokeDefault(_object, cArgs.data(), count, &resultVariant);
+        moveGlobalExceptionToExecState(lexicalGlobalObject);
+    }
+
+    if (!retval)
+        throwException(lexicalGlobalObject, scope, createError(lexicalGlobalObject, "Error calling method on NPObject."_s));
+
+    for (i = 0; i < count; i++)
+        _NPN_ReleaseVariantValue(&cArgs[i]);
+
+    JSValue resultValue = convertNPVariantToValue(lexicalGlobalObject, &resultVariant, m_rootObject.get());
+    _NPN_ReleaseVariantValue(&resultVariant);
+    return resultValue;
+}
+
+bool CInstance::supportsConstruct() const
+{
+    return _object->_class->construct;
+}
+
+JSValue CInstance::invokeConstruct(JSGlobalObject* lexicalGlobalObject, CallFrame*, const ArgList& args)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (!_object->_class->construct)
+        return jsUndefined();
+
+    unsigned count = args.size();
+    Vector<NPVariant, 8> cArgs(count);
+
+    unsigned i;
+    for (i = 0; i < count; i++)
+        convertValueToNPVariant(lexicalGlobalObject, args.at(i), &cArgs[i]);
+
+    // Invoke the 'C' method.
+    bool retval = true;
+    NPVariant resultVariant;
+    VOID_TO_NPVARIANT(resultVariant);
+    {
+        JSLock::DropAllLocks dropAllLocks(lexicalGlobalObject);
+        ASSERT(globalExceptionString().isNull());
+        retval = _object->_class->construct(_object, cArgs.data(), count, &resultVariant);
+        moveGlobalExceptionToExecState(lexicalGlobalObject);
+    }
+
+    if (!retval)
+        throwException(lexicalGlobalObject, scope, createError(lexicalGlobalObject, "Error calling method on NPObject."_s));
+
+    for (i = 0; i < count; i++)
+        _NPN_ReleaseVariantValue(&cArgs[i]);
+
+    JSValue resultValue = convertNPVariantToValue(lexicalGlobalObject, &resultVariant, m_rootObject.get());
+    _NPN_ReleaseVariantValue(&resultVariant);
+    return resultValue;
+}
+
+JSValue CInstance::defaultValue(JSGlobalObject* lexicalGlobalObject, PreferredPrimitiveType hint) const
+{
+    if (hint == PreferString)
+        return stringValue(lexicalGlobalObject);
+    if (hint == PreferNumber)
+        return numberValue(lexicalGlobalObject);
+    return valueOf(lexicalGlobalObject);
+}
+
+JSValue CInstance::stringValue(JSGlobalObject* lexicalGlobalObject) const
+{
+    JSValue value;
+    if (toJSPrimitive(lexicalGlobalObject, "toString", value))
+        return value;
+
+    // Fallback to default implementation.
+    return jsNontrivialString(lexicalGlobalObject->vm(), "NPObject"_s);
+}
+
+JSValue CInstance::numberValue(JSGlobalObject*) const
+{
+    // FIXME: Implement something sensible.
+    return jsNumber(0);
+}
+
+JSValue CInstance::booleanValue() const
+{
+    // As per ECMA 9.2.
+    return jsBoolean(getObject());
+}
+
+JSValue CInstance::valueOf(JSGlobalObject* lexicalGlobalObject) const
+{
+    JSValue value;
+    if (toJSPrimitive(lexicalGlobalObject, "valueOf", value))
+        return value;
+
+    // Fallback to default implementation.
+    return stringValue(lexicalGlobalObject);
+}
+
+bool CInstance::toJSPrimitive(JSGlobalObject* lexicalGlobalObject, const char* name, JSValue& resultValue) const
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    NPIdentifier ident = _NPN_GetStringIdentifier(name);
+    if (!_object->_class->hasMethod(_object, ident))
+        return false;
+
+    // Invoke the 'C' method.
+    bool retval = true;
+    NPVariant resultVariant;
+    VOID_TO_NPVARIANT(resultVariant);
+
+    {
+        JSLock::DropAllLocks dropAllLocks(lexicalGlobalObject);
+        ASSERT(globalExceptionString().isNull());
+        retval = _object->_class->invoke(_object, ident, 0, 0, &resultVariant);
+        moveGlobalExceptionToExecState(lexicalGlobalObject);
+    }
+
+    if (!retval)
+        throwException(lexicalGlobalObject, scope, createError(lexicalGlobalObject, "Error calling method on NPObject."_s));
+
+    resultValue = convertNPVariantToValue(lexicalGlobalObject, &resultVariant, m_rootObject.get());
+    _NPN_ReleaseVariantValue(&resultVariant);
+    return true;
+}
+
+void CInstance::getPropertyNames(JSGlobalObject* lexicalGlobalObject, PropertyNameArray& nameArray)
+{
+    if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(_object->_class) || !_object->_class->enumerate)
+        return;
+
+    uint32_t count;
+    NPIdentifier* identifiers;
+
+    {
+        JSLock::DropAllLocks dropAllLocks(lexicalGlobalObject);
+        ASSERT(globalExceptionString().isNull());
+        bool ok = _object->_class->enumerate(_object, &identifiers, &count);
+        moveGlobalExceptionToExecState(lexicalGlobalObject);
+        if (!ok)
+            return;
+    }
+
+    VM& vm = lexicalGlobalObject->vm();
+    for (uint32_t i = 0; i < count; i++) {
+        IdentifierRep* identifier = static_cast<IdentifierRep*>(identifiers[i]);
+
+        if (identifier->isString())
+            nameArray.add(identifierFromNPIdentifier(lexicalGlobalObject, identifier->string()));
+        else
+            nameArray.add(Identifier::from(vm, identifier->number()));
+    }
+
+    // FIXME: This should really call NPN_MemFree but that's in WebKit
+    free(identifiers);
+}
+
+}
+}
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_instance.h webkitgtk-2.36.0/Source/WebCore/bridge/c/c_instance.h
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_instance.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/c/c_instance.h	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2003 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BINDINGS_C_INSTANCE_H_
+#define BINDINGS_C_INSTANCE_H_
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "BridgeJSC.h"
+#include "runtime_root.h"
+#include <wtf/text/WTFString.h>
+
+typedef struct NPObject NPObject;
+
+namespace JSC {
+
+namespace Bindings {
+
+class CClass;
+
+class CInstance : public Instance {
+public:
+    static Ref<CInstance> create(NPObject* object, RefPtr<RootObject>&& rootObject)
+    {
+        return adoptRef(*new CInstance(object, WTFMove(rootObject)));
+    }
+
+    static void setGlobalException(String);
+    static void moveGlobalExceptionToExecState(JSGlobalObject*);
+
+    virtual ~CInstance();
+
+    Class *getClass() const override;
+
+    JSValue valueOf(JSGlobalObject*) const override;
+    JSValue defaultValue(JSGlobalObject*, PreferredPrimitiveType) const override;
+
+    JSValue getMethod(JSGlobalObject*, PropertyName) override;
+    JSValue invokeMethod(JSGlobalObject*, CallFrame*, RuntimeMethod*) override;
+    bool supportsInvokeDefaultMethod() const override;
+    JSValue invokeDefaultMethod(JSGlobalObject*, CallFrame*) override;
+
+    bool supportsConstruct() const override;
+    JSValue invokeConstruct(JSGlobalObject*, CallFrame*, const ArgList&) override;
+
+    void getPropertyNames(JSGlobalObject*, PropertyNameArray&) override;
+
+    JSValue stringValue(JSGlobalObject*) const;
+    JSValue numberValue(JSGlobalObject*) const;
+    JSValue booleanValue() const;
+
+    NPObject *getObject() const { return _object; }
+
+private:
+    CInstance(NPObject*, RefPtr<RootObject>&&);
+
+    RuntimeObject* newRuntimeObject(JSGlobalObject*) override;
+    bool toJSPrimitive(JSGlobalObject*, const char*, JSValue&) const;
+
+
+    mutable CClass *_class;
+    NPObject *_object;
+};
+
+} // namespace Bindings
+
+} // namespace JSC
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_runtime.cpp webkitgtk-2.36.0/Source/WebCore/bridge/c/c_runtime.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_runtime.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/c/c_runtime.cpp	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2004 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "c_runtime.h"
+
+#include "c_instance.h"
+#include "c_utility.h"
+#include "npruntime_impl.h"
+#include <JavaScriptCore/JSLock.h>
+#include <JavaScriptCore/JSObject.h>
+
+namespace JSC {
+namespace Bindings {
+
+JSValue CField::valueFromInstance(JSGlobalObject* lexicalGlobalObject, const Instance* inst) const
+{
+    const CInstance* instance = static_cast<const CInstance*>(inst);
+    NPObject* obj = instance->getObject();
+    if (obj->_class->getProperty) {
+        NPVariant property;
+        VOID_TO_NPVARIANT(property);
+
+        bool result;
+        {
+            JSLock::DropAllLocks dropAllLocks(lexicalGlobalObject);
+            result = obj->_class->getProperty(obj, _fieldIdentifier, &property);
+            CInstance::moveGlobalExceptionToExecState(lexicalGlobalObject);
+        }
+        if (result) {
+            JSValue result = convertNPVariantToValue(lexicalGlobalObject, &property, instance->rootObject());
+            _NPN_ReleaseVariantValue(&property);
+            return result;
+        }
+    }
+    return jsUndefined();
+}
+
+bool CField::setValueToInstance(JSGlobalObject* lexicalGlobalObject, const Instance *inst, JSValue aValue) const
+{
+    const CInstance* instance = static_cast<const CInstance*>(inst);
+    NPObject* obj = instance->getObject();
+    if (obj->_class->setProperty) {
+        NPVariant variant;
+        convertValueToNPVariant(lexicalGlobalObject, aValue, &variant);
+
+        bool result = false;
+        {
+            JSLock::DropAllLocks dropAllLocks(lexicalGlobalObject);
+            result = obj->_class->setProperty(obj, _fieldIdentifier, &variant);
+            CInstance::moveGlobalExceptionToExecState(lexicalGlobalObject);
+        }
+
+        _NPN_ReleaseVariantValue(&variant);
+        return result;
+    }
+    return false;
+}
+
+} }
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_runtime.h webkitgtk-2.36.0/Source/WebCore/bridge/c/c_runtime.h
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_runtime.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/c/c_runtime.h	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef BINDINGS_C_RUNTIME_H_
+#define BINDINGS_C_RUNTIME_H_
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "BridgeJSC.h"
+#include "npruntime_internal.h"
+
+namespace JSC {
+namespace Bindings {
+
+class CField : public Field {
+public:
+    CField(NPIdentifier ident) : _fieldIdentifier(ident) { }
+
+    JSValue valueFromInstance(JSGlobalObject*, const Instance*) const override;
+    bool setValueToInstance(JSGlobalObject*, const Instance*, JSValue) const override;
+
+    NPIdentifier identifier() const { return _fieldIdentifier; }
+
+private:
+    NPIdentifier _fieldIdentifier;
+};
+
+
+class CMethod : public Method {
+public:
+    CMethod(NPIdentifier ident) : _methodIdentifier(ident) { }
+
+    NPIdentifier identifier() const { return _methodIdentifier; }
+    int numParameters() const override { return 0; }
+
+private:
+    NPIdentifier _methodIdentifier;
+};
+
+} // namespace Bindings
+} // namespace JSC
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/CRuntimeObject.cpp webkitgtk-2.36.0/Source/WebCore/bridge/c/CRuntimeObject.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/CRuntimeObject.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/c/CRuntimeObject.cpp	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "CRuntimeObject.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "JSDOMBinding.h"
+#include "c_instance.h"
+#include <JavaScriptCore/ObjectPrototype.h>
+
+namespace JSC {
+namespace Bindings {
+
+const ClassInfo CRuntimeObject::s_info = { "CRuntimeObject", &RuntimeObject::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(CRuntimeObject) };
+
+CRuntimeObject::CRuntimeObject(VM& vm, Structure* structure, RefPtr<CInstance>&& instance)
+    : RuntimeObject(vm, structure, WTFMove(instance))
+{
+}
+
+void CRuntimeObject::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(vm, info()));
+}
+
+CInstance* CRuntimeObject::getInternalCInstance() const
+{
+    return static_cast<CInstance*>(getInternalInstance());
+}
+
+}
+}
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/CRuntimeObject.h webkitgtk-2.36.0/Source/WebCore/bridge/c/CRuntimeObject.h
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/CRuntimeObject.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/c/CRuntimeObject.h	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef CRuntimeObject_h
+#define CRuntimeObject_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "JSDOMBinding.h"
+#include "runtime_object.h"
+
+namespace WebCore {
+    class JSDOMGlobalObject;
+}
+
+namespace JSC {
+namespace Bindings {
+
+class CInstance;
+
+class CRuntimeObject final : public RuntimeObject {
+public:
+    using Base = RuntimeObject;
+
+    static CRuntimeObject* create(VM& vm, Structure* structure, RefPtr<CInstance>&& instance)
+    {
+        CRuntimeObject* object = new (NotNull, allocateCell<CRuntimeObject>(vm)) CRuntimeObject(vm, structure, WTFMove(instance));
+        object->finishCreation(vm);
+        return object;
+    }
+
+    CInstance* getInternalCInstance() const;
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+private:
+    CRuntimeObject(VM&, Structure*, RefPtr<CInstance>&&);
+    void finishCreation(VM&);
+};
+
+}
+}
+
+#endif
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_utility.cpp webkitgtk-2.36.0/Source/WebCore/bridge/c/c_utility.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_utility.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/c/c_utility.cpp	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2004-2019 Apple Inc.  All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "c_utility.h"
+
+#include "CRuntimeObject.h"
+#include "DOMWindow.h"
+#include "JSDOMBinding.h"
+#include "JSDOMWindow.h"
+#include "NP_jsobject.h"
+#include "c_instance.h"
+#include "npruntime_impl.h"
+#include "npruntime_priv.h"
+#include "runtime_object.h"
+#include "runtime_root.h"
+#include <JavaScriptCore/JSGlobalObject.h>
+#include <JavaScriptCore/JSLock.h>
+#include <wtf/Assertions.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC { namespace Bindings {
+
+static String convertUTF8ToUTF16WithLatin1Fallback(const NPUTF8* UTF8Chars, int UTF8Length)
+{
+    ASSERT(UTF8Chars || UTF8Length == 0);
+    
+    if (UTF8Length == -1)
+        UTF8Length = static_cast<int>(strlen(UTF8Chars));
+
+    String result = String::fromUTF8(UTF8Chars, UTF8Length);
+    
+    // If we got back a null string indicating an unsuccessful conversion, fall back to latin 1.
+    // Some plugins return invalid UTF-8 in NPVariantType_String, see <http://bugs.webkit.org/show_bug.cgi?id=5163>
+    // There is no "bad data" for latin1. It is unlikely that the plugin was really sending text in this encoding,
+    // but it should have used UTF-8, and now we are simply avoiding a crash.
+    if (result.isNull())
+        result = String(UTF8Chars, UTF8Length);
+    
+    return result;
+}
+
+// Variant value must be released with NPReleaseVariantValue()
+void convertValueToNPVariant(JSGlobalObject* exec, JSValue value, NPVariant* result)
+{
+    JSLockHolder lock(exec);
+    VM& vm = exec->vm();
+    
+    VOID_TO_NPVARIANT(*result);
+
+    if (value.isString()) {
+        String ustring = value.toWTFString(exec);
+        CString cstring = ustring.utf8();
+        NPString string = { (const NPUTF8*)cstring.data(), static_cast<uint32_t>(cstring.length()) };
+        NPN_InitializeVariantWithStringCopy(result, &string);
+    } else if (value.isNumber()) {
+        DOUBLE_TO_NPVARIANT(value.toNumber(exec), *result);
+    } else if (value.isBoolean()) {
+        BOOLEAN_TO_NPVARIANT(value.toBoolean(exec), *result);
+    } else if (value.isNull()) {
+        NULL_TO_NPVARIANT(*result);
+    } else if (value.isObject()) {
+        JSObject* object = asObject(value);
+        if (object->classInfo(vm) == CRuntimeObject::info()) {
+            CRuntimeObject* runtimeObject = static_cast<CRuntimeObject*>(object);
+            CInstance* instance = runtimeObject->getInternalCInstance();
+            if (instance) {
+                NPObject* obj = instance->getObject();
+                _NPN_RetainObject(obj);
+                OBJECT_TO_NPVARIANT(obj, *result);
+            }
+        } else {
+            JSGlobalObject* globalObject = vm.deprecatedVMEntryGlobalObject(exec);
+
+            RootObject* rootObject = findRootObject(globalObject);
+            if (rootObject) {
+                NPObject* npObject = _NPN_CreateScriptObject(0, object, rootObject);
+                OBJECT_TO_NPVARIANT(npObject, *result);
+            }
+        }
+    }
+}
+
+JSValue convertNPVariantToValue(JSGlobalObject* exec, const NPVariant* variant, RootObject* rootObject)
+{
+    JSLockHolder lock(exec);
+    
+    NPVariantType type = variant->type;
+
+    if (type == NPVariantType_Bool)
+        return jsBoolean(NPVARIANT_TO_BOOLEAN(*variant));
+    if (type == NPVariantType_Null)
+        return jsNull();
+    if (type == NPVariantType_Void)
+        return jsUndefined();
+    if (type == NPVariantType_Int32)
+        return jsNumber(NPVARIANT_TO_INT32(*variant));
+    if (type == NPVariantType_Double)
+        return jsNumber(NPVARIANT_TO_DOUBLE(*variant));
+    if (type == NPVariantType_String)
+        return jsStringWithCache(exec->vm(), convertNPStringToUTF16(&variant->value.stringValue));
+    if (type == NPVariantType_Object) {
+        NPObject* obj = variant->value.objectValue;
+        
+        if (obj->_class == NPScriptObjectClass)
+            // Get JSObject from NP_JavaScriptObject.
+            return ((JavaScriptObject*)obj)->imp;
+
+        // Wrap NPObject in a CInstance.
+        return CInstance::create(obj, rootObject)->createRuntimeObject(exec);
+    }
+    
+    return jsUndefined();
+}
+
+String convertNPStringToUTF16(const NPString* string)
+{
+    return String::fromUTF8WithLatin1Fallback(string->UTF8Characters, string->UTF8Length);
+}
+
+Identifier identifierFromNPIdentifier(JSGlobalObject* exec, const NPUTF8* name)
+{
+    VM& vm = exec->vm();
+    return Identifier::fromString(vm, convertUTF8ToUTF16WithLatin1Fallback(name, -1));
+}
+
+} }
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_utility.h webkitgtk-2.36.0/Source/WebCore/bridge/c/c_utility.h
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/c/c_utility.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/c/c_utility.h	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2004 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef C_UTILITY_H_
+#define C_UTILITY_H_
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "npruntime_internal.h"
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/JSCJSValue.h>
+#include <wtf/Forward.h>
+
+namespace JSC {
+
+class CallFrame;
+class Identifier;
+
+namespace Bindings {
+
+class RootObject;
+    
+typedef uint16_t NPUTF16;
+
+String convertNPStringToUTF16(const NPString *);
+void convertValueToNPVariant(JSGlobalObject*, JSValue, NPVariant* result);
+JSValue convertNPVariantToValue(JSGlobalObject*, const NPVariant*, RootObject*);
+Identifier identifierFromNPIdentifier(JSGlobalObject*, const NPUTF8* name);
+
+} }
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/NP_jsobject.cpp webkitgtk-2.36.0/Source/WebCore/bridge/NP_jsobject.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/NP_jsobject.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/NP_jsobject.cpp	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,557 @@
+/*
+ * Copyright (C) 2004-2019 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NP_jsobject.h"
+
+#include "IdentifierRep.h"
+#include "JSDOMBinding.h"
+#include "c_instance.h"
+#include "c_utility.h"
+#include "npruntime_priv.h"
+#include "runtime_root.h"
+#include <JavaScriptCore/CatchScope.h>
+#include <JavaScriptCore/Completion.h>
+#include <JavaScriptCore/Error.h>
+#include <JavaScriptCore/JSGlobalObject.h>
+#include <JavaScriptCore/JSLock.h>
+#include <JavaScriptCore/PropertyNameArray.h>
+#include <JavaScriptCore/SourceCode.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/WTFString.h>
+
+#pragma GCC visibility push(default)
+#include "npruntime_impl.h"
+#pragma GCC visibility pop
+
+namespace JSC {
+using namespace Bindings;
+using namespace WebCore;
+
+class ObjectMap {
+public:
+    NPObject* get(RootObject* rootObject, JSObject* jsObject)
+    {
+        return m_map.get(rootObject).get(jsObject);
+    }
+
+    void add(RootObject* rootObject, JSObject* jsObject, NPObject* npObject)
+    {
+        HashMap<RootObject*, JSToNPObjectMap>::iterator iter = m_map.find(rootObject);
+        if (iter == m_map.end()) {
+            rootObject->addInvalidationCallback(&m_invalidationCallback);
+            iter = m_map.add(rootObject, JSToNPObjectMap()).iterator;
+        }
+
+        ASSERT(iter->value.find(jsObject) == iter->value.end());
+        iter->value.add(jsObject, npObject);
+    }
+
+    void remove(RootObject* rootObject)
+    {
+        ASSERT(m_map.contains(rootObject));
+        m_map.remove(rootObject);
+    }
+
+    void remove(RootObject* rootObject, JSObject* jsObject)
+    {
+        HashMap<RootObject*, JSToNPObjectMap>::iterator iter = m_map.find(rootObject);
+        ASSERT(iter != m_map.end());
+        ASSERT(iter->value.find(jsObject) != iter->value.end());
+
+        iter->value.remove(jsObject);
+    }
+
+private:
+    struct RootObjectInvalidationCallback : public RootObject::InvalidationCallback {
+        void operator()(RootObject*) override;
+    };
+    RootObjectInvalidationCallback m_invalidationCallback;
+
+    // JSObjects are protected by RootObject.
+    typedef HashMap<JSObject*, NPObject*> JSToNPObjectMap;
+    HashMap<RootObject*, JSToNPObjectMap> m_map;
+};
+
+
+static ObjectMap& objectMap()
+{
+    static NeverDestroyed<ObjectMap> map;
+    return map;
+}
+
+void ObjectMap::RootObjectInvalidationCallback::operator()(RootObject* rootObject)
+{
+    objectMap().remove(rootObject);
+}
+
+static void getListFromVariantArgs(JSGlobalObject* lexicalGlobalObject, const NPVariant* args, unsigned argCount, RootObject* rootObject, MarkedArgumentBuffer& aList)
+{
+    for (unsigned i = 0; i < argCount; ++i)
+        aList.append(convertNPVariantToValue(lexicalGlobalObject, &args[i], rootObject));
+}
+
+static NPObject* jsAllocate(NPP, NPClass*)
+{
+    return static_cast<NPObject*>(malloc(sizeof(JavaScriptObject)));
+}
+
+static void jsDeallocate(NPObject* npObj)
+{
+    JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(npObj);
+
+    if (obj->rootObject && obj->rootObject->isValid()) {
+        objectMap().remove(obj->rootObject, obj->imp);
+        obj->rootObject->gcUnprotect(obj->imp);
+    }
+
+    if (obj->rootObject)
+        obj->rootObject->deref();
+
+    free(obj);
+}
+
+static NPClass javascriptClass = { 1, jsAllocate, jsDeallocate, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static NPClass noScriptClass = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+extern "C" {
+NPClass* NPScriptObjectClass = &javascriptClass;
+static NPClass* NPNoScriptObjectClass = &noScriptClass;
+
+NPObject* _NPN_CreateScriptObject(NPP npp, JSObject* imp, RefPtr<RootObject>&& rootObject)
+{
+    if (NPObject* object = objectMap().get(rootObject.get(), imp))
+        return _NPN_RetainObject(object);
+
+    JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(_NPN_CreateObject(npp, NPScriptObjectClass));
+
+    obj->rootObject = rootObject.leakRef();
+
+    if (obj->rootObject) {
+        obj->rootObject->gcProtect(imp);
+        objectMap().add(obj->rootObject, imp, reinterpret_cast<NPObject*>(obj));
+    }
+
+    obj->imp = imp;
+
+    return reinterpret_cast<NPObject*>(obj);
+}
+
+NPObject* _NPN_CreateNoScriptObject(void)
+{
+    return _NPN_CreateObject(0, NPNoScriptObjectClass);
+}
+
+bool _NPN_InvokeDefault(NPP, NPObject* o, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+    if (o->_class == NPScriptObjectClass) {
+        JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); 
+        
+        VOID_TO_NPVARIANT(*result);
+        
+        // Lookup the function object.
+        RootObject* rootObject = obj->rootObject;
+        if (!rootObject || !rootObject->isValid())
+            return false;
+        
+        auto globalObject = rootObject->globalObject();
+        VM& vm = globalObject->vm();
+        JSLockHolder lock(vm);
+        auto scope = DECLARE_CATCH_SCOPE(vm);
+
+        JSGlobalObject* lexicalGlobalObject = globalObject;
+        
+        // Call the function object.
+        JSValue function = obj->imp;
+        auto callData = getCallData(vm, function);
+        if (callData.type == CallData::Type::None)
+            return false;
+        
+        MarkedArgumentBuffer argList;
+        getListFromVariantArgs(lexicalGlobalObject, args, argCount, rootObject, argList);
+        RELEASE_ASSERT(!argList.hasOverflowed());
+        JSValue resultV = JSC::call(lexicalGlobalObject, function, callData, function, argList);
+
+        // Convert and return the result of the function call.
+        convertValueToNPVariant(lexicalGlobalObject, resultV, result);
+        scope.clearException();
+        return true;        
+    }
+
+    if (o->_class->invokeDefault)
+        return o->_class->invokeDefault(o, args, argCount, result);    
+    VOID_TO_NPVARIANT(*result);
+    return true;
+}
+
+bool _NPN_Invoke(NPP npp, NPObject* o, NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+    if (o->_class == NPScriptObjectClass) {
+        JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); 
+
+        IdentifierRep* i = static_cast<IdentifierRep*>(methodName);
+        if (!i->isString())
+            return false;
+
+        // Special case the "eval" method.
+        if (methodName == _NPN_GetStringIdentifier("eval")) {
+            if (argCount != 1)
+                return false;
+            if (args[0].type != NPVariantType_String)
+                return false;
+            return _NPN_Evaluate(npp, o, const_cast<NPString*>(&args[0].value.stringValue), result);
+        }
+
+        // Look up the function object.
+        RootObject* rootObject = obj->rootObject;
+        if (!rootObject || !rootObject->isValid())
+            return false;
+
+        auto globalObject = rootObject->globalObject();
+        VM& vm = globalObject->vm();
+        JSLockHolder lock(vm);
+        auto scope = DECLARE_CATCH_SCOPE(vm);
+
+        JSGlobalObject* lexicalGlobalObject = globalObject;
+        JSValue function = obj->imp->get(lexicalGlobalObject, identifierFromNPIdentifier(lexicalGlobalObject, i->string()));
+        auto callData = getCallData(vm, function);
+        if (callData.type == CallData::Type::None)
+            return false;
+
+        // Call the function object.
+        MarkedArgumentBuffer argList;
+        getListFromVariantArgs(lexicalGlobalObject, args, argCount, rootObject, argList);
+        RELEASE_ASSERT(!argList.hasOverflowed());
+        JSValue resultV = JSC::call(lexicalGlobalObject, function, callData, obj->imp, argList);
+
+        // Convert and return the result of the function call.
+        convertValueToNPVariant(lexicalGlobalObject, resultV, result);
+        scope.clearException();
+        return true;
+    }
+
+    if (o->_class->invoke)
+        return o->_class->invoke(o, methodName, args, argCount, result);
+    
+    VOID_TO_NPVARIANT(*result);
+    return true;
+}
+
+bool _NPN_Evaluate(NPP, NPObject* o, NPString* s, NPVariant* variant)
+{
+    if (o->_class == NPScriptObjectClass) {
+        JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); 
+
+        RootObject* rootObject = obj->rootObject;
+        if (!rootObject || !rootObject->isValid())
+            return false;
+
+        auto globalObject = rootObject->globalObject();
+        VM& vm = globalObject->vm();
+        JSLockHolder lock(vm);
+        auto scope = DECLARE_CATCH_SCOPE(vm);
+
+        JSGlobalObject* lexicalGlobalObject = globalObject;
+        String scriptString = convertNPStringToUTF16(s);
+        
+        JSValue returnValue = JSC::evaluate(lexicalGlobalObject, JSC::makeSource(scriptString, { }), JSC::JSValue());
+
+        convertValueToNPVariant(lexicalGlobalObject, returnValue, variant);
+        scope.clearException();
+        return true;
+    }
+
+    VOID_TO_NPVARIANT(*variant);
+    return false;
+}
+
+bool _NPN_GetProperty(NPP, NPObject* o, NPIdentifier propertyName, NPVariant* variant)
+{
+    if (o->_class == NPScriptObjectClass) {
+        JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); 
+
+        RootObject* rootObject = obj->rootObject;
+        if (!rootObject || !rootObject->isValid())
+            return false;
+
+        auto globalObject = rootObject->globalObject();
+        VM& vm = globalObject->vm();
+        JSLockHolder lock(vm);
+        auto scope = DECLARE_CATCH_SCOPE(vm);
+
+        JSGlobalObject* lexicalGlobalObject = globalObject;
+        IdentifierRep* i = static_cast<IdentifierRep*>(propertyName);
+        
+        JSValue result;
+        if (i->isString())
+            result = obj->imp->get(lexicalGlobalObject, identifierFromNPIdentifier(lexicalGlobalObject, i->string()));
+        else
+            result = obj->imp->get(lexicalGlobalObject, static_cast<uint32_t>(i->number()));
+
+        convertValueToNPVariant(lexicalGlobalObject, result, variant);
+        scope.clearException();
+        return true;
+    }
+
+    if (o->_class->hasProperty && o->_class->getProperty) {
+        if (o->_class->hasProperty(o, propertyName))
+            return o->_class->getProperty(o, propertyName, variant);
+        return false;
+    }
+
+    VOID_TO_NPVARIANT(*variant);
+    return false;
+}
+
+bool _NPN_SetProperty(NPP, NPObject* o, NPIdentifier propertyName, const NPVariant* variant)
+{
+    if (o->_class == NPScriptObjectClass) {
+        JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); 
+
+        RootObject* rootObject = obj->rootObject;
+        if (!rootObject || !rootObject->isValid())
+            return false;
+
+        auto globalObject = rootObject->globalObject();
+        VM& vm = globalObject->vm();
+        JSLockHolder lock(vm);
+        auto scope = DECLARE_CATCH_SCOPE(vm);
+
+        JSGlobalObject* lexicalGlobalObject = globalObject;
+        IdentifierRep* i = static_cast<IdentifierRep*>(propertyName);
+
+        if (i->isString()) {
+            PutPropertySlot slot(obj->imp);
+            obj->imp->methodTable(vm)->put(obj->imp, lexicalGlobalObject, identifierFromNPIdentifier(lexicalGlobalObject, i->string()), convertNPVariantToValue(lexicalGlobalObject, variant, rootObject), slot);
+        } else
+            obj->imp->methodTable(vm)->putByIndex(obj->imp, lexicalGlobalObject, i->number(), convertNPVariantToValue(lexicalGlobalObject, variant, rootObject), false);
+        scope.clearException();
+        return true;
+    }
+
+    if (o->_class->setProperty)
+        return o->_class->setProperty(o, propertyName, variant);
+
+    return false;
+}
+
+bool _NPN_RemoveProperty(NPP, NPObject* o, NPIdentifier propertyName)
+{
+    if (o->_class == NPScriptObjectClass) {
+        JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); 
+
+        RootObject* rootObject = obj->rootObject;
+        if (!rootObject || !rootObject->isValid())
+            return false;
+
+        auto globalObject = rootObject->globalObject();
+        VM& vm = globalObject->vm();
+        JSLockHolder lock(vm);
+        auto scope = DECLARE_CATCH_SCOPE(vm);
+
+        JSGlobalObject* lexicalGlobalObject = globalObject;
+
+        IdentifierRep* i = static_cast<IdentifierRep*>(propertyName);
+        if (i->isString()) {
+            if (!obj->imp->hasProperty(lexicalGlobalObject, identifierFromNPIdentifier(lexicalGlobalObject, i->string()))) {
+                scope.clearException();
+                return false;
+            }
+        } else {
+            if (!obj->imp->hasProperty(lexicalGlobalObject, static_cast<uint32_t>(i->number()))) {
+                scope.clearException();
+                return false;
+            }
+        }
+
+        if (i->isString())
+            JSCell::deleteProperty(obj->imp, lexicalGlobalObject, identifierFromNPIdentifier(lexicalGlobalObject, i->string()));
+        else
+            obj->imp->methodTable(vm)->deletePropertyByIndex(obj->imp, lexicalGlobalObject, i->number());
+
+        scope.clearException();
+        return true;
+    }
+    return false;
+}
+
+bool _NPN_HasProperty(NPP, NPObject* o, NPIdentifier propertyName)
+{
+    if (o->_class == NPScriptObjectClass) {
+        JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); 
+
+        RootObject* rootObject = obj->rootObject;
+        if (!rootObject || !rootObject->isValid())
+            return false;
+
+        auto globalObject = rootObject->globalObject();
+        VM& vm = globalObject->vm();
+        JSLockHolder lock(vm);
+        auto scope = DECLARE_CATCH_SCOPE(vm);
+
+        JSGlobalObject* lexicalGlobalObject = globalObject;
+        IdentifierRep* i = static_cast<IdentifierRep*>(propertyName);
+        if (i->isString()) {
+            bool result = obj->imp->hasProperty(lexicalGlobalObject, identifierFromNPIdentifier(lexicalGlobalObject, i->string()));
+            scope.clearException();
+            return result;
+        }
+
+        bool result = obj->imp->hasProperty(lexicalGlobalObject, static_cast<uint32_t>(i->number()));
+        scope.clearException();
+        return result;
+    }
+
+    if (o->_class->hasProperty)
+        return o->_class->hasProperty(o, propertyName);
+
+    return false;
+}
+
+bool _NPN_HasMethod(NPP, NPObject* o, NPIdentifier methodName)
+{
+    if (o->_class == NPScriptObjectClass) {
+        JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); 
+
+        IdentifierRep* i = static_cast<IdentifierRep*>(methodName);
+        if (!i->isString())
+            return false;
+
+        RootObject* rootObject = obj->rootObject;
+        if (!rootObject || !rootObject->isValid())
+            return false;
+
+        auto globalObject = rootObject->globalObject();
+        VM& vm = globalObject->vm();
+        JSLockHolder lock(vm);
+        auto scope = DECLARE_CATCH_SCOPE(vm);
+
+        JSGlobalObject* lexicalGlobalObject = globalObject;
+        JSValue func = obj->imp->get(lexicalGlobalObject, identifierFromNPIdentifier(lexicalGlobalObject, i->string()));
+        scope.clearException();
+        return !func.isUndefined();
+    }
+    
+    if (o->_class->hasMethod)
+        return o->_class->hasMethod(o, methodName);
+    
+    return false;
+}
+
+void _NPN_SetException(NPObject*, const NPUTF8* message)
+{
+    // Ignoring the NPObject param is consistent with the Mozilla implementation.
+    String exception(message);
+    CInstance::setGlobalException(exception);
+}
+
+bool _NPN_Enumerate(NPP, NPObject* o, NPIdentifier** identifier, uint32_t* count)
+{
+    if (o->_class == NPScriptObjectClass) {
+        JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); 
+        
+        RootObject* rootObject = obj->rootObject;
+        if (!rootObject || !rootObject->isValid())
+            return false;
+        
+        auto globalObject = rootObject->globalObject();
+        VM& vm = globalObject->vm();
+        JSLockHolder lock(vm);
+        auto scope = DECLARE_CATCH_SCOPE(vm);
+
+        JSGlobalObject* lexicalGlobalObject = globalObject;
+        PropertyNameArray propertyNames(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
+
+        obj->imp->getPropertyNames(lexicalGlobalObject, propertyNames, DontEnumPropertiesMode::Exclude);
+        unsigned size = static_cast<unsigned>(propertyNames.size());
+        // FIXME: This should really call NPN_MemAlloc but that's in WebKit
+        NPIdentifier* identifiers = static_cast<NPIdentifier*>(malloc(sizeof(NPIdentifier) * size));
+        
+        for (unsigned i = 0; i < size; ++i)
+            identifiers[i] = _NPN_GetStringIdentifier(propertyNames[i].string().utf8().data());
+
+        *identifier = identifiers;
+        *count = size;
+
+        scope.clearException();
+        return true;
+    }
+    
+    if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(o->_class) && o->_class->enumerate)
+        return o->_class->enumerate(o, identifier, count);
+    
+    return false;
+}
+
+bool _NPN_Construct(NPP, NPObject* o, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+    if (o->_class == NPScriptObjectClass) {
+        JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o);
+        
+        VOID_TO_NPVARIANT(*result);
+        
+        // Lookup the constructor object.
+        RootObject* rootObject = obj->rootObject;
+        if (!rootObject || !rootObject->isValid())
+            return false;
+
+        auto globalObject = rootObject->globalObject();
+        VM& vm = globalObject->vm();
+        JSLockHolder lock(vm);
+        auto scope = DECLARE_CATCH_SCOPE(vm);
+
+        JSGlobalObject* lexicalGlobalObject = globalObject;
+        
+        // Call the constructor object.
+        JSValue constructor = obj->imp;
+        auto constructData = getConstructData(vm, constructor);
+        if (constructData.type == CallData::Type::None)
+            return false;
+        
+        MarkedArgumentBuffer argList;
+        getListFromVariantArgs(lexicalGlobalObject, args, argCount, rootObject, argList);
+        RELEASE_ASSERT(!argList.hasOverflowed());
+        JSValue resultV = JSC::construct(lexicalGlobalObject, constructor, constructData, argList);
+        
+        // Convert and return the result.
+        convertValueToNPVariant(lexicalGlobalObject, resultV, result);
+        scope.clearException();
+        return true;
+    }
+    
+    if (NP_CLASS_STRUCT_VERSION_HAS_CTOR(o->_class) && o->_class->construct)
+        return o->_class->construct(o, args, argCount, result);
+    
+    return false;
+}
+
+} // extern "C"
+
+} // namespace JSC
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/NP_jsobject.h webkitgtk-2.36.0/Source/WebCore/bridge/NP_jsobject.h
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/NP_jsobject.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/NP_jsobject.h	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef NP_JSOBJECT_H
+#define NP_JSOBJECT_H
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "npruntime_internal.h"
+#include <wtf/Forward.h>
+
+namespace JSC {
+class JSObject;
+namespace Bindings {
+class RootObject;
+}
+}
+
+struct JavaScriptObject
+{
+    NPObject object;
+    JSC::JSObject* imp;
+    JSC::Bindings::RootObject* rootObject;
+};
+
+extern "C" {
+extern NPClass* NPScriptObjectClass;
+
+WEBCORE_EXPORT NPObject* _NPN_CreateScriptObject(NPP, JSC::JSObject*, RefPtr<JSC::Bindings::RootObject>&&);
+WEBCORE_EXPORT NPObject* _NPN_CreateNoScriptObject(void);
+}
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/npruntime.cpp webkitgtk-2.36.0/Source/WebCore/bridge/npruntime.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/npruntime.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/npruntime.cpp	2022-03-22 16:38:57.361580047 -0500
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "IdentifierRep.h"
+#include "npruntime_internal.h"
+#include "npruntime_priv.h"
+
+#include "c_utility.h"
+#include <JavaScriptCore/Identifier.h>
+#include <wtf/Assertions.h>
+
+#pragma GCC visibility push(default)
+#include "npruntime_impl.h"
+#pragma GCC visibility pop
+
+using namespace WebCore;
+
+NPIdentifier _NPN_GetStringIdentifier(const NPUTF8* name)
+{
+    return static_cast<NPIdentifier>(IdentifierRep::get(name));
+}
+
+void _NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers)
+{
+    ASSERT(names);
+    ASSERT(identifiers);
+    
+    if (names && identifiers) {
+        for (int i = 0; i < nameCount; i++)
+            identifiers[i] = _NPN_GetStringIdentifier(names[i]);
+    }
+}
+
+NPIdentifier _NPN_GetIntIdentifier(int32_t intid)
+{
+    return static_cast<NPIdentifier>(IdentifierRep::get(intid));
+}
+
+bool _NPN_IdentifierIsString(NPIdentifier identifier)
+{
+    return static_cast<IdentifierRep*>(identifier)->isString();
+}
+
+NPUTF8 *_NPN_UTF8FromIdentifier(NPIdentifier identifier)
+{
+    const char* string = static_cast<IdentifierRep*>(identifier)->string();
+    if (!string)
+        return 0;
+    
+    return strdup(string);
+}
+
+int32_t _NPN_IntFromIdentifier(NPIdentifier identifier)
+{
+    return static_cast<IdentifierRep*>(identifier)->number();
+}
+
+void NPN_InitializeVariantWithStringCopy(NPVariant* variant, const NPString* value)
+{
+    variant->type = NPVariantType_String;
+    variant->value.stringValue.UTF8Length = value->UTF8Length;
+    // Switching to fastMalloc would be better to avoid length check but this is not desirable
+    // as NPN_MemAlloc is using malloc and there might be plugins that mix NPN_MemAlloc and malloc too.
+    variant->value.stringValue.UTF8Characters = (NPUTF8*)malloc(sizeof(NPUTF8) * value->UTF8Length);
+    if (value->UTF8Length && !variant->value.stringValue.UTF8Characters)
+        CRASH();
+    memcpy((void*)variant->value.stringValue.UTF8Characters, value->UTF8Characters, sizeof(NPUTF8) * value->UTF8Length);
+}
+
+void _NPN_ReleaseVariantValue(NPVariant* variant)
+{
+    ASSERT(variant);
+
+    if (variant->type == NPVariantType_Object) {
+        _NPN_ReleaseObject(variant->value.objectValue);
+        variant->value.objectValue = 0;
+    } else if (variant->type == NPVariantType_String) {
+        free((void*)variant->value.stringValue.UTF8Characters);
+        variant->value.stringValue.UTF8Characters = 0;
+        variant->value.stringValue.UTF8Length = 0;
+    }
+
+    variant->type = NPVariantType_Void;
+}
+
+NPObject *_NPN_CreateObject(NPP npp, NPClass* aClass)
+{
+    ASSERT(aClass);
+
+    if (aClass) {
+        NPObject* obj;
+        if (aClass->allocate != NULL)
+            obj = aClass->allocate(npp, aClass);
+        else
+            obj = (NPObject*)malloc(sizeof(NPObject));
+        if (!obj)
+            CRASH();
+        obj->_class = aClass;
+        obj->referenceCount = 1;
+
+        return obj;
+    }
+
+    return 0;
+}
+
+NPObject* _NPN_RetainObject(NPObject* obj)
+{
+    ASSERT(obj);
+
+    if (obj)
+        obj->referenceCount++;
+
+    return obj;
+}
+
+void _NPN_ReleaseObject(NPObject* obj)
+{
+    ASSERT(obj);
+    ASSERT(obj->referenceCount >= 1);
+
+    if (obj && obj->referenceCount >= 1) {
+        if (--obj->referenceCount == 0)
+            _NPN_DeallocateObject(obj);
+    }
+}
+
+void _NPN_DeallocateObject(NPObject *obj)
+{
+    ASSERT(obj);
+
+    if (obj) {
+        if (obj->_class->deallocate)
+            obj->_class->deallocate(obj);
+        else
+            free(obj);
+    }
+}
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/npruntime_impl.h webkitgtk-2.36.0/Source/WebCore/bridge/npruntime_impl.h
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/npruntime_impl.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/npruntime_impl.h	2022-03-22 16:38:57.365580068 -0500
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2004 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef _NP_RUNTIME_IMPL_H_
+#define _NP_RUNTIME_IMPL_H_
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "npruntime_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void _NPN_ReleaseVariantValue(NPVariant*);
+extern NPIdentifier _NPN_GetStringIdentifier(const NPUTF8*);
+extern void _NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers);
+extern NPIdentifier _NPN_GetIntIdentifier(int32_t);
+extern bool _NPN_IdentifierIsString(NPIdentifier);
+extern NPUTF8* _NPN_UTF8FromIdentifier(NPIdentifier);
+extern int32_t _NPN_IntFromIdentifier(NPIdentifier);    
+extern NPObject* _NPN_CreateObject(NPP, NPClass*);
+extern NPObject* _NPN_RetainObject(NPObject*);
+extern void _NPN_ReleaseObject(NPObject*);
+extern void _NPN_DeallocateObject(NPObject*);
+extern bool _NPN_Invoke(NPP, NPObject*, NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result);
+extern bool _NPN_InvokeDefault(NPP, NPObject*, const NPVariant* args, uint32_t argCount, NPVariant* result);
+extern bool _NPN_Evaluate(NPP, NPObject*, NPString*, NPVariant* result);
+extern bool _NPN_GetProperty(NPP, NPObject*, NPIdentifier, NPVariant* result);
+extern bool _NPN_SetProperty(NPP, NPObject*, NPIdentifier, const NPVariant*);
+extern bool _NPN_RemoveProperty(NPP, NPObject*, NPIdentifier);
+extern bool _NPN_HasProperty(NPP, NPObject*, NPIdentifier);
+extern bool _NPN_HasMethod(NPP, NPObject*, NPIdentifier);
+extern void _NPN_SetException(NPObject*, const NPUTF8*);
+extern bool _NPN_Enumerate(NPP, NPObject*, NPIdentifier**, uint32_t* count);
+extern bool _NPN_Construct(NPP, NPObject*, const NPVariant* args, uint32_t argCount, NPVariant *result);
+
+#ifdef __cplusplus
+}  /* end extern "C" */
+#endif
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/npruntime_internal.h webkitgtk-2.36.0/Source/WebCore/bridge/npruntime_internal.h
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/npruntime_internal.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/npruntime_internal.h	2022-03-22 16:38:57.365580068 -0500
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007-2008 Collabora Ltd.  All rights reserved.
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This is a internal include header for npapi.h
+ *
+ * Some of the #defines which are in X11 headers conflict with type and enum
+ * names in JavaScriptCore and WebCore
+ * This header #undefs those defines to fix the conflicts
+ * If you need to include npapi.h or npruntime.h when building on X11,
+ * include this file instead of the actual npapi.h or npruntime.h
+ */
+
+#pragma once
+
+#include "npapi.h"
+#include "npfunctions.h"
+#include "npruntime.h"
+
+#if defined(MOZ_X11)
+    #include <X11/Xresource.h>
+
+    #undef Always
+    #undef None
+    #undef Above
+    #undef Below
+    #undef Auto
+    #undef Complex
+    #undef Status
+    #undef CursorShape
+    #undef FocusIn
+    #undef FocusOut
+    #undef KeyPress
+    #undef KeyRelease
+    #undef Unsorted
+    #undef Bool
+    #undef FontChange
+    #undef GrayScale
+    #undef NormalState
+    #undef True
+    #undef False
+    #undef Success
+    #undef Expose
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/bridge/npruntime_priv.h webkitgtk-2.36.0/Source/WebCore/bridge/npruntime_priv.h
--- webkitgtk-2.36.0.orig/Source/WebCore/bridge/npruntime_priv.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/bridge/npruntime_priv.h	2022-03-22 16:38:57.365580068 -0500
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2003, 2006 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef NP_RUNTIME_PRIV_H_
+#define NP_RUNTIME_PRIV_H_
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "npruntime_internal.h"
+
+/*
+    NPN_InitializeVariantWithStringCopy() will copy string data.  The string data
+    will be deallocated by calls to NPReleaseVariantValue().
+*/
+void NPN_InitializeVariantWithStringCopy(NPVariant*, const NPString*);
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+#endif
+
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/Headers.cmake webkitgtk-2.36.0/Source/WebCore/Headers.cmake
--- webkitgtk-2.36.0.orig/Source/WebCore/Headers.cmake	2022-02-23 02:58:58.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/Headers.cmake	2022-03-22 16:38:57.365580068 -0500
@@ -487,10 +487,16 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS
 
     bridge/Bridge.h
     bridge/IdentifierRep.h
+    bridge/NP_jsobject.h
+    bridge/npruntime_impl.h
+    bridge/npruntime_internal.h
     bridge/runtime_method.h
     bridge/runtime_object.h
     bridge/runtime_root.h
 
+    bridge/c/c_instance.h
+    bridge/c/c_utility.h
+
     bridge/jsc/BridgeJSC.h
 
     contentextensions/CombinedFiltersAlphabet.h
@@ -1757,6 +1763,7 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS
     platform/network/ProtectionSpace.h
     platform/network/ProtectionSpaceBase.h
     platform/network/ProtectionSpaceHash.h
+    platform/network/ProxyServer.h
     platform/network/ResourceErrorBase.h
     platform/network/ResourceHandle.h
     platform/network/ResourceHandleClient.h
@@ -1798,6 +1805,10 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS
     plugins/PluginData.h
     plugins/PluginInfoProvider.h
     plugins/PluginViewBase.h
+    plugins/npapi.h
+    plugins/npfunctions.h
+    plugins/npruntime.h
+    plugins/nptypes.h
 
     rendering/BreakLines.h
     rendering/CSSFilter.h
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/history/BackForwardCache.cpp webkitgtk-2.36.0/Source/WebCore/history/BackForwardCache.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/history/BackForwardCache.cpp	2022-02-23 02:59:01.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/history/BackForwardCache.cpp	2022-03-22 16:38:57.365580068 -0500
@@ -135,6 +135,10 @@ static bool canCacheFrame(Frame& frame,
         logBackForwardCacheFailureDiagnosticMessage(diagnosticLoggingClient, DiagnosticLoggingKeys::isErrorPageKey());
         isCacheable = false;
     }
+    if (frameLoader.subframeLoader().containsPlugins() && !frame.page()->settings().backForwardCacheSupportsPlugins()) {
+        PCLOG("   -Frame contains plugins");
+        isCacheable = false;
+    }
     if (frame.isMainFrame() && frame.document() && frame.document()->url().protocolIs("https") && documentLoader->response().cacheControlContainsNoStore()) {
         PCLOG("   -Frame is HTTPS, and cache control prohibits storing");
         logBackForwardCacheFailureDiagnosticMessage(diagnosticLoggingClient, DiagnosticLoggingKeys::httpsNoStoreKey());
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/html/HTMLObjectElement.cpp webkitgtk-2.36.0/Source/WebCore/html/HTMLObjectElement.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/html/HTMLObjectElement.cpp	2022-02-23 02:59:01.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/html/HTMLObjectElement.cpp	2022-03-22 16:38:57.365580068 -0500
@@ -460,6 +460,23 @@ void HTMLObjectElement::didMoveToNewDocu
     HTMLPlugInImageElement::didMoveToNewDocument(oldDocument, newDocument);
 }
 
+bool HTMLObjectElement::appendFormData(DOMFormData& formData)
+{
+    if (name().isEmpty())
+        return false;
+
+    // Use PluginLoadingPolicy::DoNotLoad here or it would fire JS events synchronously
+    // which would not be safe here.
+    RefPtr widget = pluginWidget(PluginLoadingPolicy::DoNotLoad);
+    if (!is<PluginViewBase>(widget))
+        return false;
+    String value;
+    if (!downcast<PluginViewBase>(*widget).getFormValue(value))
+        return false;
+    formData.append(name(), value);
+    return true;
+}
+
 bool HTMLObjectElement::canContainRangeEndPoint() const
 {
     // Call through to HTMLElement because HTMLPlugInElement::canContainRangeEndPoint
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/html/HTMLObjectElement.h webkitgtk-2.36.0/Source/WebCore/html/HTMLObjectElement.h
--- webkitgtk-2.36.0.orig/Source/WebCore/html/HTMLObjectElement.h	2022-02-23 02:59:01.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/html/HTMLObjectElement.h	2022-03-22 16:38:57.365580068 -0500
@@ -99,6 +99,7 @@ private:
     bool isFormControlElement() const final { return false; }
 
     bool isEnumeratable() const final { return true; }
+    bool appendFormData(DOMFormData&) final;
 
     bool canContainRangeEndPoint() const final;
 
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/html/HTMLPlugInElement.cpp webkitgtk-2.36.0/Source/WebCore/html/HTMLPlugInElement.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/html/HTMLPlugInElement.cpp	2022-02-23 02:59:01.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/html/HTMLPlugInElement.cpp	2022-03-22 16:38:57.365580068 -0500
@@ -49,6 +49,10 @@
 #include "Widget.h"
 #include <wtf/IsoMallocInlines.h>
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+#include "npruntime_impl.h"
+#endif
+
 namespace WebCore {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLPlugInElement);
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/page/Frame.cpp webkitgtk-2.36.0/Source/WebCore/page/Frame.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/page/Frame.cpp	2022-02-23 02:59:01.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/page/Frame.cpp	2022-03-22 16:38:57.365580068 -0500
@@ -102,6 +102,7 @@
 #include "UserTypingGestureIndicator.h"
 #include "VisibleUnits.h"
 #include "markup.h"
+#include "npruntime_impl.h"
 #include "runtime_root.h"
 #include <JavaScriptCore/APICast.h>
 #include <JavaScriptCore/RegularExpression.h>
@@ -1114,7 +1115,7 @@ TextStream& operator<<(TextStream& ts, c
     return ts;
 }
 
-bool Frame::arePluginsEnabled()
+bool Frame::arePluginsEnabled() const
 {
     return settings().arePluginsEnabled();
 }
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/page/Frame.h webkitgtk-2.36.0/Source/WebCore/page/Frame.h
--- webkitgtk-2.36.0.orig/Source/WebCore/page/Frame.h	2022-02-23 02:59:01.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/page/Frame.h	2022-03-22 16:38:57.365580068 -0500
@@ -302,7 +302,7 @@ public:
     void selfOnlyRef();
     void selfOnlyDeref();
 
-    WEBCORE_EXPORT bool arePluginsEnabled();
+    WEBCORE_EXPORT bool arePluginsEnabled() const;
 
 private:
     friend class NavigationDisabler;
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/page/Page.cpp webkitgtk-2.36.0/Source/WebCore/page/Page.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/page/Page.cpp	2022-02-23 02:59:01.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/page/Page.cpp	2022-03-22 16:38:57.365580068 -0500
@@ -3113,6 +3113,12 @@ void Page::setSessionID(PAL::SessionID s
     forEachDocument([&] (Document& document) {
         document.privateBrowsingStateDidChange(m_sessionID);
     });
+
+    // Collect the PluginViews in to a vector to ensure that action the plug-in takes
+    // from below privateBrowsingStateChanged does not affect their lifetime.
+
+    for (auto& view : pluginViews())
+        view->privateBrowsingStateChanged(sessionID.isEphemeral());
 }
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/page/RuntimeEnabledFeatures.h webkitgtk-2.36.0/Source/WebCore/page/RuntimeEnabledFeatures.h
--- webkitgtk-2.36.0.orig/Source/WebCore/page/RuntimeEnabledFeatures.h	2022-02-23 02:59:01.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/page/RuntimeEnabledFeatures.h	2022-03-22 16:38:57.365580068 -0500
@@ -101,6 +101,9 @@ public:
     void setServerTimingEnabled(bool isEnabled) { m_isServerTimingEnabled = isEnabled; }
     bool serverTimingEnabled() const { return m_isServerTimingEnabled; }
 
+    void setExperimentalPlugInSandboxProfilesEnabled(bool isEnabled) { m_experimentalPlugInSandboxProfilesEnabled = isEnabled; }
+    bool experimentalPlugInSandboxProfilesEnabled() const { return m_experimentalPlugInSandboxProfilesEnabled; }
+
     void setAttrStyleEnabled(bool isEnabled) { m_attrStyleEnabled = isEnabled; }
     bool attrStyleEnabled() const { return m_attrStyleEnabled; }
 
@@ -290,6 +293,7 @@ private:
     bool m_itpDebugMode { false };
     bool m_isRestrictedHTTPResponseAccess { true };
     bool m_isServerTimingEnabled { false };
+    bool m_experimentalPlugInSandboxProfilesEnabled { false };
     bool m_attrStyleEnabled { false };
     bool m_webAPIStatisticsEnabled { false };
     bool m_syntheticEditingCommandsEnabled { true };
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/platform/Curl.cmake webkitgtk-2.36.0/Source/WebCore/platform/Curl.cmake
--- webkitgtk-2.36.0.orig/Source/WebCore/platform/Curl.cmake	2022-02-23 02:59:01.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/platform/Curl.cmake	2022-03-22 16:38:57.365580068 -0500
@@ -27,6 +27,7 @@ list(APPEND WebCore_SOURCES
     platform/network/curl/NetworkStorageSessionCurl.cpp
     platform/network/curl/OpenSSLHelper.cpp
     platform/network/curl/ProtectionSpaceCurl.cpp
+    platform/network/curl/ProxyServerCurl.cpp
     platform/network/curl/PublicSuffixCurl.cpp
     platform/network/curl/ResourceErrorCurl.cpp
     platform/network/curl/ResourceHandleCurl.cpp
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/platform/network/cf/ProxyServerCFNet.cpp webkitgtk-2.36.0/Source/WebCore/platform/network/cf/ProxyServerCFNet.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/platform/network/cf/ProxyServerCFNet.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/platform/network/cf/ProxyServerCFNet.cpp	2022-03-22 16:38:57.365580068 -0500
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProxyServer.h"
+
+#include <wtf/URL.h>
+#include "Logging.h"
+#include <wtf/RetainPtr.h>
+#include <wtf/cf/TypeCastsCF.h>
+#include <wtf/text/CString.h>
+
+#if PLATFORM(IOS_FAMILY) || PLATFORM(WIN)
+#include <CFNetwork/CFNetwork.h>
+#endif
+
+namespace WebCore {
+
+static void processProxyServers(Vector<ProxyServer>& proxyServers, CFArrayRef proxies, CFURLRef url);
+
+static void proxyAutoConfigurationResultCallback(void *context, CFArrayRef proxies, CFErrorRef error)
+{
+    // We only expect a single result callback per invocation. Stop our runloop to unblock our caller.
+    CFRunLoopStop(CFRunLoopGetCurrent());
+
+    Vector<ProxyServer>* proxyServers = (Vector<ProxyServer>*)context;
+    if (!proxies) {
+        ASSERT(error);
+        RetainPtr<CFStringRef> errorDescriptionCF = adoptCF(CFErrorCopyDescription(error));
+        String errorDescription(errorDescriptionCF.get());
+        LOG(Network, "Failed to process proxy auto-configuration file with error: %s", errorDescription.utf8().data());
+        return;
+    }
+
+    processProxyServers(*proxyServers, proxies, 0);
+}
+
+static void processProxyServers(Vector<ProxyServer>& proxyServers, CFArrayRef proxies, CFURLRef url)
+{
+    CFIndex numProxies = CFArrayGetCount(proxies);
+    for (CFIndex i = 0; i < numProxies; ++i) {
+        CFDictionaryRef proxyDictionary = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(proxies, i));
+
+        ProxyServer::Type type = ProxyServer::Direct;
+        CFStringRef typeString = static_cast<CFStringRef>(CFDictionaryGetValue(proxyDictionary, kCFProxyTypeKey));
+
+        if (!url) {
+            // If we have no URL then we're processing an auto-configuration response.
+            // It isn't sensible to receive another auto-configured proxy in such a response.
+            ASSERT(!CFEqual(typeString, kCFProxyTypeAutoConfigurationURL));
+        }
+
+        if (CFEqual(typeString, kCFProxyTypeAutoConfigurationURL)) {
+            if (!url)
+                continue;
+
+            // FIXME: We should restructure to allow this to happen asynchronously.
+            auto scriptURL = dynamic_cf_cast<CFURLRef>(CFDictionaryGetValue(proxyDictionary, kCFProxyAutoConfigurationURLKey));
+            if (!scriptURL)
+                continue;
+
+            CFStreamClientContext context = { 0, (void*)&proxyServers, 0, 0, 0 };
+            RetainPtr<CFRunLoopSourceRef> runLoopSource = adoptCF(CFNetworkExecuteProxyAutoConfigurationURL(scriptURL, url, proxyAutoConfigurationResultCallback, &context));
+
+            CFStringRef privateRunLoopMode = CFSTR("com.apple.WebKit.ProxyAutoConfiguration");
+            CFTimeInterval timeout = 5;
+            CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource.get(), privateRunLoopMode);
+            CFRunLoopRunInMode(privateRunLoopMode, timeout, 0);
+            CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoopSource.get(), privateRunLoopMode);
+            CFRunLoopSourceInvalidate(runLoopSource.get());
+
+            // The proxyAutoConfigurationResultCallback has added any relevant ProxyServers to proxyServers.
+            continue;
+        }
+
+        if (CFEqual(typeString, kCFProxyTypeNone)) {
+            proxyServers.append(ProxyServer(ProxyServer::Direct, String(), -1));
+            continue;
+        }
+
+        if (CFEqual(typeString, kCFProxyTypeHTTP))
+            type = ProxyServer::HTTP;
+        else if (CFEqual(typeString, kCFProxyTypeHTTPS))
+            type = ProxyServer::HTTPS;
+        else if (CFEqual(typeString, kCFProxyTypeSOCKS))
+            type = ProxyServer::SOCKS;
+        else {
+            // We don't know how to handle this type.
+            continue;
+        }
+
+        CFStringRef host = static_cast<CFStringRef>(CFDictionaryGetValue(proxyDictionary, kCFProxyHostNameKey));
+        CFNumberRef port = static_cast<CFNumberRef>(CFDictionaryGetValue(proxyDictionary, kCFProxyPortNumberKey));
+        SInt32 portValue;
+        CFNumberGetValue(port, kCFNumberSInt32Type, &portValue);
+
+        proxyServers.append(ProxyServer(type, host, portValue));
+    }
+}
+
+static void addProxyServersForURL(Vector<ProxyServer>& proxyServers, const URL& url)
+{
+    RetainPtr<CFDictionaryRef> proxySettings = adoptCF(CFNetworkCopySystemProxySettings());
+    if (!proxySettings)
+        return;
+
+    RetainPtr<CFURLRef> cfURL = url.createCFURL();
+    RetainPtr<CFArrayRef> proxiesForURL = adoptCF(CFNetworkCopyProxiesForURL(cfURL.get(), proxySettings.get()));
+    if (!proxiesForURL)
+        return;
+
+    processProxyServers(proxyServers, proxiesForURL.get(), cfURL.get());
+}
+
+Vector<ProxyServer> proxyServersForURL(const URL& url)
+{
+    Vector<ProxyServer> proxyServers;
+    
+    addProxyServersForURL(proxyServers, url);
+    return proxyServers;
+    
+}
+
+} // namespace WebCore
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/platform/network/curl/ProxyServerCurl.cpp webkitgtk-2.36.0/Source/WebCore/platform/network/curl/ProxyServerCurl.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/platform/network/curl/ProxyServerCurl.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/platform/network/curl/ProxyServerCurl.cpp	2022-03-22 16:38:57.365580068 -0500
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Brent Fulgham <bfulgham@webkit.org>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProxyServer.h"
+
+#if USE(CURL)
+
+#include <wtf/URL.h>
+
+namespace WebCore {
+
+Vector<ProxyServer> proxyServersForURL(const URL&)
+{
+    // FIXME: Implement.
+    return Vector<ProxyServer>();
+}
+
+} // namespace WebCore
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/platform/network/ProxyServer.cpp webkitgtk-2.36.0/Source/WebCore/platform/network/ProxyServer.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/platform/network/ProxyServer.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/platform/network/ProxyServer.cpp	2022-03-22 16:38:57.365580068 -0500
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProxyServer.h"
+
+#include <wtf/text/StringBuilder.h>
+
+namespace WebCore {
+
+static void appendProxyServerString(StringBuilder& builder, const ProxyServer& proxyServer)
+{
+    ASSERT(!proxyServer.hostName().isNull());
+    ASSERT(proxyServer.port() != -1);
+
+    switch (proxyServer.type()) {
+    case ProxyServer::Direct:
+        builder.append("DIRECT");
+        break;
+    case ProxyServer::HTTP:
+    case ProxyServer::HTTPS:
+        builder.append("PROXY ", proxyServer.hostName(), ':', proxyServer.port());
+        break;
+    case ProxyServer::SOCKS:
+        builder.append("SOCKS ", proxyServer.hostName(), ':', proxyServer.port());
+        break;
+    }
+}
+
+String toString(const Vector<ProxyServer>& proxyServers)
+{
+    if (proxyServers.isEmpty())
+        return "DIRECT";
+
+    StringBuilder stringBuilder;
+    for (size_t i = 0; i < proxyServers.size(); ++i) {
+        if (i)
+            stringBuilder.append("; ");
+        appendProxyServerString(stringBuilder, proxyServers[i]);
+    }
+    return stringBuilder.toString();
+}
+
+} // namespace WebCore
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/platform/network/ProxyServer.h webkitgtk-2.36.0/Source/WebCore/platform/network/ProxyServer.h
--- webkitgtk-2.36.0.orig/Source/WebCore/platform/network/ProxyServer.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/platform/network/ProxyServer.h	2022-03-22 16:38:57.365580068 -0500
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class NetworkingContext;
+
+// Represents a single proxy server.
+class ProxyServer {
+public:
+    enum Type {
+        Direct,
+        HTTP,
+        HTTPS,
+        SOCKS,
+    };
+
+    ProxyServer()
+        : m_type(Direct)
+        , m_port(-1)
+    {
+    }
+
+    ProxyServer(Type type, const String& hostName, int port)
+        : m_type(type)
+        , m_hostName(hostName)
+        , m_port(port)
+    {
+    }
+        
+    Type type() const { return m_type; }
+    const String& hostName() const { return m_hostName; }
+    int port() const { return m_port; }
+
+private:
+    Type m_type;
+    String m_hostName;
+    int m_port;
+};
+
+// Return a vector of proxy servers for the given URL.
+WEBCORE_EXPORT Vector<ProxyServer> proxyServersForURL(const URL&);
+
+// Converts the given vector of proxy servers to a PAC string, as described in
+// http://web.archive.org/web/20060424005037/wp.netscape.com/eng/mozilla/2.0/relnotes/demo/proxy-live.html
+WEBCORE_EXPORT String toString(const Vector<ProxyServer>&);
+    
+} // namespace WebCore
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/platform/network/soup/ProxyServerSoup.cpp webkitgtk-2.36.0/Source/WebCore/platform/network/soup/ProxyServerSoup.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/platform/network/soup/ProxyServerSoup.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/platform/network/soup/ProxyServerSoup.cpp	2022-03-22 16:38:57.365580068 -0500
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Brent Fulgham <bfulgham@webkit.org>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProxyServer.h"
+
+#if USE(SOUP)
+
+#include <wtf/URL.h>
+
+namespace WebCore {
+
+Vector<ProxyServer> proxyServersForURL(const URL&)
+{
+    // FIXME: Implement.
+    return Vector<ProxyServer>();
+}
+
+} // namespace WebCore
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/platform/SourcesSoup.txt webkitgtk-2.36.0/Source/WebCore/platform/SourcesSoup.txt
--- webkitgtk-2.36.0.orig/Source/WebCore/platform/SourcesSoup.txt	2022-02-23 02:59:01.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/platform/SourcesSoup.txt	2022-03-22 16:38:57.365580068 -0500
@@ -28,6 +28,7 @@ platform/network/soup/CookieStorageSoup.
 platform/network/soup/CredentialSoup.cpp
 platform/network/soup/CredentialStorageSoup.cpp
 platform/network/soup/NetworkStorageSessionSoup.cpp
+platform/network/soup/ProxyServerSoup.cpp
 platform/network/soup/ResourceErrorSoup.cpp
 platform/network/soup/ResourceHandleSoup.cpp
 platform/network/soup/ResourceRequestSoup.cpp
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/plugins/npapi.h webkitgtk-2.36.0/Source/WebCore/plugins/npapi.h
--- webkitgtk-2.36.0.orig/Source/WebCore/plugins/npapi.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/plugins/npapi.h	2022-03-22 16:38:57.365580068 -0500
@@ -0,0 +1,869 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef npapi_h_
+#define npapi_h_
+
+#if defined(__OS2__)
+#pragma pack(1)
+#endif
+
+#include "nptypes.h"
+
+#if defined(__OS2__) || defined(OS2)
+#ifndef XP_OS2
+#define XP_OS2 1
+#endif
+#endif
+
+#ifdef INCLUDE_JAVA
+#include "jri.h"                /* Java Runtime Interface */
+#else
+#define jref    void *
+#define JRIEnv  void
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#ifndef XP_WIN
+#define XP_WIN 1
+#endif
+#endif
+
+#if defined(__APPLE_CC__) && !defined(XP_UNIX)
+#ifndef XP_MACOSX
+#define XP_MACOSX 1
+#endif
+#endif
+
+#if defined(XP_MACOSX) && defined(__LP64__)
+#define NP_NO_QUICKDRAW
+#define NP_NO_CARBON
+#endif
+
+#if defined(XP_MACOSX)
+#include <CoreGraphics/CoreGraphics.h>
+#include <OpenGL/OpenGL.h>
+#ifndef NP_NO_CARBON
+#include <Carbon/Carbon.h>
+#endif
+#endif
+
+#if defined(XP_UNIX)
+#include <stdio.h>
+#if defined(MOZ_X11)
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#endif
+#endif
+
+/*----------------------------------------------------------------------*/
+/*                        Plugin Version Constants                      */
+/*----------------------------------------------------------------------*/
+
+#define NP_VERSION_MAJOR 0
+#define NP_VERSION_MINOR 26
+
+
+/* The OS/2 version of Netscape uses RC_DATA to define the
+   mime types, file extensions, etc that are required.
+   Use a vertical bar to separate types, end types with \0.
+   FileVersion and ProductVersion are 32bit ints, all other
+   entries are strings that MUST be terminated with a \0.
+
+AN EXAMPLE:
+
+RCDATA NP_INFO_ProductVersion { 1,0,0,1,}
+
+RCDATA NP_INFO_MIMEType    { "video/x-video|",
+                             "video/x-flick\0" }
+RCDATA NP_INFO_FileExtents { "avi|",
+                             "flc\0" }
+RCDATA NP_INFO_FileOpenName{ "MMOS2 video player(*.avi)|",
+                             "MMOS2 Flc/Fli player(*.flc)\0" }
+
+RCDATA NP_INFO_FileVersion       { 1,0,0,1 }
+RCDATA NP_INFO_CompanyName       { "Netscape Communications\0" }
+RCDATA NP_INFO_FileDescription   { "NPAVI32 Extension DLL\0"
+RCDATA NP_INFO_InternalName      { "NPAVI32\0" )
+RCDATA NP_INFO_LegalCopyright    { "Copyright Netscape Communications \251 1996\0"
+RCDATA NP_INFO_OriginalFilename  { "NVAPI32.DLL" }
+RCDATA NP_INFO_ProductName       { "NPAVI32 Dynamic Link Library\0" }
+*/
+/* RC_DATA types for version info - required */
+#define NP_INFO_ProductVersion      1
+#define NP_INFO_MIMEType            2
+#define NP_INFO_FileOpenName        3
+#define NP_INFO_FileExtents         4
+/* RC_DATA types for version info - used if found */
+#define NP_INFO_FileDescription     5
+#define NP_INFO_ProductName         6
+/* RC_DATA types for version info - optional */
+#define NP_INFO_CompanyName         7
+#define NP_INFO_FileVersion         8
+#define NP_INFO_InternalName        9
+#define NP_INFO_LegalCopyright      10
+#define NP_INFO_OriginalFilename    11
+
+#ifndef RC_INVOKED
+
+/*----------------------------------------------------------------------*/
+/*                       Definition of Basic Types                      */
+/*----------------------------------------------------------------------*/
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef NULL
+#define NULL (0L)
+#endif
+
+typedef unsigned char NPBool;
+typedef int16_t       NPError;
+typedef int16_t       NPReason;
+typedef char*         NPMIMEType;
+
+/*----------------------------------------------------------------------*/
+/*                       Structures and definitions                     */
+/*----------------------------------------------------------------------*/
+
+#if !defined(__LP64__)
+#if defined(XP_MACOSX)
+#pragma options align=mac68k
+#endif
+#endif /* __LP64__ */
+
+/*
+ *  NPP is a plug-in's opaque instance handle
+ */
+typedef struct _NPP
+{
+  void* pdata;      /* plug-in private data */
+  void* ndata;      /* netscape private data */
+} NPP_t;
+
+typedef NPP_t*  NPP;
+
+typedef struct _NPStream
+{
+  void*    pdata; /* plug-in private data */
+  void*    ndata; /* netscape private data */
+  const    char* url;
+  uint32_t end;
+  uint32_t lastmodified;
+  void*    notifyData;
+  const    char* headers; /* Response headers from host.
+                           * Exists only for >= NPVERS_HAS_RESPONSE_HEADERS.
+                           * Used for HTTP only; NULL for non-HTTP.
+                           * Available from NPP_NewStream onwards.
+                           * Plugin should copy this data before storing it.
+                           * Includes HTTP status line and all headers,
+                           * preferably verbatim as received from server,
+                           * headers formatted as in HTTP ("Header: Value"),
+                           * and newlines (\n, NOT \r\n) separating lines.
+                           * Terminated by \n\0 (NOT \n\n\0). */
+} NPStream;
+
+typedef struct _NPByteRange
+{
+  int32_t  offset; /* negative offset means from the end */
+  uint32_t length;
+  struct _NPByteRange* next;
+} NPByteRange;
+
+typedef struct _NPSavedData
+{
+  int32_t len;
+  void*   buf;
+} NPSavedData;
+
+typedef struct _NPRect
+{
+  uint16_t top;
+  uint16_t left;
+  uint16_t bottom;
+  uint16_t right;
+} NPRect;
+
+typedef struct _NPSize
+{
+  int32_t width;
+  int32_t height;
+} NPSize;
+
+typedef enum {
+  NPFocusNext = 0,
+  NPFocusPrevious = 1
+} NPFocusDirection;
+
+/* Return values for NPP_HandleEvent */
+#define kNPEventNotHandled 0
+#define kNPEventHandled 1
+/* Exact meaning must be spec'd in event model. */
+#define kNPEventStartIME 2
+
+#if defined(XP_UNIX)
+/*
+ * Unix specific structures and definitions
+ */
+
+/*
+ * Callback Structures.
+ *
+ * These are used to pass additional platform specific information.
+ */
+enum {
+  NP_SETWINDOW = 1,
+  NP_PRINT
+};
+
+typedef struct
+{
+  int32_t type;
+} NPAnyCallbackStruct;
+
+typedef struct
+{
+  int32_t      type;
+#if defined(MOZ_X11)
+  Display*     display;
+  Visual*      visual;
+  Colormap     colormap;
+  unsigned int depth;
+#endif
+} NPSetWindowCallbackStruct;
+
+typedef struct
+{
+  int32_t type;
+  FILE* fp;
+} NPPrintCallbackStruct;
+
+#endif /* XP_UNIX */
+
+#if defined(XP_MACOSX)
+typedef enum {
+#ifndef NP_NO_QUICKDRAW
+  NPDrawingModelQuickDraw = 0,
+#endif
+  NPDrawingModelCoreGraphics = 1,
+  NPDrawingModelOpenGL = 2, // Note: This is not supported.
+  NPDrawingModelCoreAnimation = 3
+} NPDrawingModel;
+
+typedef enum {
+#ifndef NP_NO_CARBON
+  NPEventModelCarbon = 0,
+#endif
+  NPEventModelCocoa = 1
+} NPEventModel;
+#endif
+
+/*
+ *   The following masks are applied on certain platforms to NPNV and
+ *   NPPV selectors that pass around pointers to COM interfaces. Newer
+ *   compilers on some platforms may generate vtables that are not
+ *   compatible with older compilers. To prevent older plugins from
+ *   not understanding a new browser's ABI, these masks change the
+ *   values of those selectors on those platforms. To remain backwards
+ *   compatible with different versions of the browser, plugins can
+ *   use these masks to dynamically determine and use the correct C++
+ *   ABI that the browser is expecting. This does not apply to Windows
+ *   as Microsoft's COM ABI will likely not change.
+ */
+
+#define NP_ABI_GCC3_MASK  0x10000000
+/*
+ *   gcc 3.x generated vtables on UNIX and OSX are incompatible with
+ *   previous compilers.
+ */
+#if (defined(XP_UNIX) && defined(__GNUC__) && (__GNUC__ >= 3))
+#define _NP_ABI_MIXIN_FOR_GCC3 NP_ABI_GCC3_MASK
+#else
+#define _NP_ABI_MIXIN_FOR_GCC3 0
+#endif
+
+#if defined(XP_MACOSX)
+#define NP_ABI_MACHO_MASK 0x01000000
+#define _NP_ABI_MIXIN_FOR_MACHO NP_ABI_MACHO_MASK
+#else
+#define _NP_ABI_MIXIN_FOR_MACHO 0
+#endif
+
+#define NP_ABI_MASK (_NP_ABI_MIXIN_FOR_GCC3 | _NP_ABI_MIXIN_FOR_MACHO)
+
+/*
+ * List of variable names for which NPP_GetValue shall be implemented
+ */
+typedef enum {
+  NPPVpluginNameString = 1,
+  NPPVpluginDescriptionString,
+  NPPVpluginWindowBool,
+  NPPVpluginTransparentBool,
+  NPPVjavaClass,                /* Not implemented in WebKit */
+  NPPVpluginWindowSize,         /* Not implemented in WebKit */
+  NPPVpluginTimerInterval,      /* Not implemented in WebKit */
+  NPPVpluginScriptableInstance = (10 | NP_ABI_MASK), /* Not implemented in WebKit */
+  NPPVpluginScriptableIID = 11, /* Not implemented in WebKit */
+  NPPVjavascriptPushCallerBool = 12,  /* Not implemented in WebKit */
+  NPPVpluginKeepLibraryInMemory = 13, /* Not implemented in WebKit */
+  NPPVpluginNeedsXEmbed         = 14, /* Not implemented in WebKit */
+
+  /* Get the NPObject for scripting the plugin. Introduced in NPAPI minor version 14.
+   */
+  NPPVpluginScriptableNPObject  = 15,
+
+  /* Get the plugin value (as \0-terminated UTF-8 string data) for
+   * form submission if the plugin is part of a form. Use
+   * NPN_MemAlloc() to allocate memory for the string data. Introduced
+   * in NPAPI minor version 15.
+   */
+  NPPVformValue = 16,    /* Not implemented in WebKit */
+
+  NPPVpluginUrlRequestsDisplayedBool = 17, /* Not implemented in WebKit */
+
+  /* Checks if the plugin is interested in receiving the http body of
+   * all http requests (including failed ones, http status != 200).
+   */
+  NPPVpluginWantsAllNetworkStreams = 18,
+
+  /* Browsers can retrieve a native ATK accessibility plug ID via this variable. */
+  NPPVpluginNativeAccessibleAtkPlugId = 19,
+
+  /* Checks to see if the plug-in would like the browser to load the "src" attribute. */
+  NPPVpluginCancelSrcStream = 20
+
+#if defined(XP_MACOSX)
+  /* Used for negotiating drawing models */
+  , NPPVpluginDrawingModel = 1000
+  /* Used for negotiating event models */
+  , NPPVpluginEventModel = 1001
+  /* In the NPDrawingModelCoreAnimation drawing model, the browser asks the plug-in for a Core Animation layer. */
+  , NPPVpluginCoreAnimationLayer = 1003
+#endif
+
+  /* Used for figuring out whether a plug-in is playing audio. */
+  , NPPVpluginIsPlayingAudio = 4000
+
+} NPPVariable;
+
+/*
+ * List of variable names for which NPN_GetValue should be implemented.
+ */
+typedef enum {
+  NPNVxDisplay = 1,
+  NPNVxtAppContext,
+  NPNVnetscapeWindow,
+  NPNVjavascriptEnabledBool,
+  NPNVasdEnabledBool,
+  NPNVisOfflineBool,
+
+  NPNVserviceManager = (10 | NP_ABI_MASK),  /* Not implemented in WebKit */
+  NPNVDOMElement     = (11 | NP_ABI_MASK),  /* Not implemented in WebKit */
+  NPNVDOMWindow      = (12 | NP_ABI_MASK),  /* Not implemented in WebKit */
+  NPNVToolkit        = (13 | NP_ABI_MASK),  /* Not implemented in WebKit */
+  NPNVSupportsXEmbedBool = 14,              /* Not implemented in WebKit */
+
+  /* Get the NPObject wrapper for the browser window. */
+  NPNVWindowNPObject = 15,
+
+  /* Get the NPObject wrapper for the plugins DOM element. */
+  NPNVPluginElementNPObject = 16,
+
+  NPNVSupportsWindowless = 17,
+
+  NPNVprivateModeBool = 18,
+
+  NPNVsupportsAdvancedKeyHandling = 21
+
+#if defined(XP_MACOSX)
+  /* Used for negotiating drawing models */
+  , NPNVpluginDrawingModel = 1000
+  , NPNVcontentsScaleFactor = 1001
+#ifndef NP_NO_QUICKDRAW
+  , NPNVsupportsQuickDrawBool = 2000
+#endif
+  , NPNVsupportsCoreGraphicsBool = 2001
+  , NPNVsupportsOpenGLBool = 2002
+  , NPNVsupportsCoreAnimationBool = 2003
+#ifndef NP_NO_CARBON
+  , NPNVsupportsCarbonBool = 3000 /* TRUE if the browser supports the Carbon event model */
+#endif
+  , NPNVsupportsCocoaBool = 3001 /* TRUE if the browser supports the Cocoa event model */
+  , NPNVsupportsUpdatedCocoaTextInputBool = 3002 /* TRUE if the browser supports the updated
+                                                    Cocoa text input specification. */
+  , NPNVsupportsCompositingCoreAnimationPluginsBool = 74656 /* TRUE if the browser supports
+                                                               CA model compositing */
+#endif /* XP_MACOSX */
+
+  , NPNVmuteAudioBool = 4000
+
+} NPNVariable;
+
+typedef enum {
+  NPNURLVCookie = 501,
+  NPNURLVProxy
+} NPNURLVariable;
+
+/*
+ * The type of Toolkit the widgets use
+ */
+typedef enum {
+  NPNVGtk12 = 1,
+  NPNVGtk2
+} NPNToolkitType;
+
+/*
+ * The type of a NPWindow - it specifies the type of the data structure
+ * returned in the window field.
+ */
+typedef enum {
+  NPWindowTypeWindow = 1,
+  NPWindowTypeDrawable
+} NPWindowType;
+
+typedef struct _NPWindow
+{
+  void* window;  /* Platform specific window handle */
+                 /* OS/2: x - Position of bottom left corner */
+                 /* OS/2: y - relative to visible netscape window */
+  int32_t  x;      /* Position of top left corner relative */
+  int32_t  y;      /* to a netscape page. */
+  uint32_t width;  /* Maximum window size */
+  uint32_t height;
+  NPRect   clipRect; /* Clipping rectangle in port coordinates */
+#if defined(XP_UNIX)
+  void * ws_info; /* Platform-dependent additonal data */
+#endif /* XP_UNIX */
+  NPWindowType type; /* Is this a window or a drawable? */
+} NPWindow;
+
+typedef struct _NPFullPrint
+{
+  NPBool pluginPrinted;/* Set TRUE if plugin handled fullscreen printing */
+  NPBool printOne;     /* TRUE if plugin should print one copy to default
+                          printer */
+  void* platformPrint; /* Platform-specific printing info */
+} NPFullPrint;
+
+typedef struct _NPEmbedPrint
+{
+  NPWindow window;
+  void* platformPrint; /* Platform-specific printing info */
+} NPEmbedPrint;
+
+typedef struct _NPPrint
+{
+  uint16_t mode;               /* NP_FULL or NP_EMBED */
+  union
+  {
+    NPFullPrint fullPrint;   /* if mode is NP_FULL */
+    NPEmbedPrint embedPrint; /* if mode is NP_EMBED */
+  } print;
+} NPPrint;
+
+#if defined(XP_MACOSX)
+#ifndef NP_NO_CARBON
+typedef EventRecord NPEvent;
+#else
+typedef void*  NPEvent;
+#endif
+#elif defined(XP_WIN)
+typedef struct _NPEvent
+{
+  uint16_t event;
+  uintptr_t wParam;
+  uintptr_t lParam;
+} NPEvent;
+#elif defined(XP_OS2)
+typedef struct _NPEvent
+{
+  uint32_t event;
+  uint32_t wParam;
+  uint32_t lParam;
+} NPEvent;
+#elif defined(XP_UNIX) && defined(MOZ_X11)
+typedef XEvent NPEvent;
+#else
+typedef void*  NPEvent;
+#endif
+
+#if defined(XP_MACOSX)
+typedef void* NPRegion;
+#ifndef NP_NO_QUICKDRAW
+typedef RgnHandle NPQDRegion;
+#endif
+typedef CGPathRef NPCGRegion;
+#elif defined(XP_WIN)
+typedef HRGN NPRegion;
+#elif defined(XP_UNIX) && defined(MOZ_X11)
+typedef Region NPRegion;
+#else
+typedef void *NPRegion;
+#endif
+
+typedef struct _NPNSString NPNSString;
+typedef struct _NPNSWindow NPNSWindow;
+typedef struct _NPNSMenu   NPNSMenu;
+
+#if defined(XP_MACOSX)
+typedef NPNSMenu NPMenu;
+#else
+typedef void *NPMenu;
+#endif
+
+typedef enum {
+  NPCoordinateSpacePlugin = 1,
+  NPCoordinateSpaceWindow,
+  NPCoordinateSpaceFlippedWindow,
+  NPCoordinateSpaceScreen,
+  NPCoordinateSpaceFlippedScreen
+} NPCoordinateSpace;
+
+#if defined(XP_MACOSX)
+
+#ifndef NP_NO_QUICKDRAW
+typedef struct NP_Port
+{
+  CGrafPtr port;
+  int32_t portx; /* position inside the topmost window */
+  int32_t porty;
+} NP_Port;
+#endif /* NP_NO_QUICKDRAW */
+
+/*
+ * NP_CGContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelCoreGraphics
+ * as its drawing model.
+ */
+
+typedef struct NP_CGContext
+{
+  CGContextRef context;
+#ifdef NP_NO_CARBON
+  NPNSWindow *window;
+#else
+  void *window; /* A WindowRef or NULL for the Cocoa event model. */
+#endif
+} NP_CGContext;
+
+typedef enum {
+  NPCocoaEventDrawRect = 1,
+  NPCocoaEventMouseDown,
+  NPCocoaEventMouseUp,
+  NPCocoaEventMouseMoved,
+  NPCocoaEventMouseEntered,
+  NPCocoaEventMouseExited,
+  NPCocoaEventMouseDragged,
+  NPCocoaEventKeyDown,
+  NPCocoaEventKeyUp,
+  NPCocoaEventFlagsChanged,
+  NPCocoaEventFocusChanged,
+  NPCocoaEventWindowFocusChanged,
+  NPCocoaEventScrollWheel,
+  NPCocoaEventTextInput
+} NPCocoaEventType;
+
+typedef struct _NPCocoaEvent {
+  NPCocoaEventType type;
+  uint32_t version;
+  union {
+    struct {
+      uint32_t modifierFlags;
+      double   pluginX;
+      double   pluginY;
+      int32_t  buttonNumber;
+      int32_t  clickCount;
+      double   deltaX;
+      double   deltaY;
+      double   deltaZ;
+    } mouse;
+    struct {
+      uint32_t    modifierFlags;
+      NPNSString *characters;
+      NPNSString *charactersIgnoringModifiers;
+      NPBool      isARepeat;
+      uint16_t    keyCode;
+    } key;
+    struct {
+      CGContextRef context;
+      double x;
+      double y;
+      double width;
+      double height;
+    } draw;
+    struct {
+      NPBool hasFocus;
+    } focus;
+    struct {
+      NPNSString *text;
+    } text;
+  } data;
+} NPCocoaEvent;
+
+#ifndef NP_NO_CARBON
+/* Non-standard event types that can be passed to HandleEvent */
+enum NPEventType {
+  NPEventType_GetFocusEvent = (osEvt + 16),
+  NPEventType_LoseFocusEvent,
+  NPEventType_AdjustCursorEvent,
+  NPEventType_MenuCommandEvent,
+  NPEventType_ClippingChangedEvent,
+  NPEventType_ScrollingBeginsEvent = 1000,
+  NPEventType_ScrollingEndsEvent
+};
+#endif /* NP_NO_CARBON */
+
+#endif /* XP_MACOSX */
+
+/*
+ * Values for mode passed to NPP_New:
+ */
+#define NP_EMBED 1
+#define NP_FULL  2
+
+/*
+ * Values for stream type passed to NPP_NewStream:
+ */
+#define NP_NORMAL     1
+#define NP_SEEK       2
+#define NP_ASFILE     3
+#define NP_ASFILEONLY 4
+
+#define NP_MAXREADY (((unsigned)(~0)<<1)>>1)
+
+/*
+ * Flags for NPP_ClearSiteData.
+ */
+#define NP_CLEAR_ALL   0
+#define NP_CLEAR_CACHE (1 << 0)
+
+#if !defined(__LP64__)
+#if defined(XP_MACOSX)
+#pragma options align=reset
+#endif
+#endif /* __LP64__ */
+
+/*----------------------------------------------------------------------*/
+/*       Error and Reason Code definitions                              */
+/*----------------------------------------------------------------------*/
+
+/*
+ * Values of type NPError:
+ */
+#define NPERR_BASE                         0
+#define NPERR_NO_ERROR                    (NPERR_BASE + 0)
+#define NPERR_GENERIC_ERROR               (NPERR_BASE + 1)
+#define NPERR_INVALID_INSTANCE_ERROR      (NPERR_BASE + 2)
+#define NPERR_INVALID_FUNCTABLE_ERROR     (NPERR_BASE + 3)
+#define NPERR_MODULE_LOAD_FAILED_ERROR    (NPERR_BASE + 4)
+#define NPERR_OUT_OF_MEMORY_ERROR         (NPERR_BASE + 5)
+#define NPERR_INVALID_PLUGIN_ERROR        (NPERR_BASE + 6)
+#define NPERR_INVALID_PLUGIN_DIR_ERROR    (NPERR_BASE + 7)
+#define NPERR_INCOMPATIBLE_VERSION_ERROR  (NPERR_BASE + 8)
+#define NPERR_INVALID_PARAM               (NPERR_BASE + 9)
+#define NPERR_INVALID_URL                 (NPERR_BASE + 10)
+#define NPERR_FILE_NOT_FOUND              (NPERR_BASE + 11)
+#define NPERR_NO_DATA                     (NPERR_BASE + 12)
+#define NPERR_STREAM_NOT_SEEKABLE         (NPERR_BASE + 13)
+
+/*
+ * Values of type NPReason:
+ */
+#define NPRES_BASE          0
+#define NPRES_DONE         (NPRES_BASE + 0)
+#define NPRES_NETWORK_ERR  (NPRES_BASE + 1)
+#define NPRES_USER_BREAK   (NPRES_BASE + 2)
+
+/*
+ * Don't use these obsolete error codes any more.
+ */
+#define NP_NOERR  NP_NOERR_is_obsolete_use_NPERR_NO_ERROR
+#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR
+#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK
+
+/*
+ * Version feature information
+ */
+#define NPVERS_HAS_STREAMOUTPUT             8
+#define NPVERS_HAS_NOTIFICATION             9
+#define NPVERS_HAS_LIVECONNECT              9
+#define NPVERS_WIN16_HAS_LIVECONNECT        9
+#define NPVERS_68K_HAS_LIVECONNECT          11
+#define NPVERS_HAS_WINDOWLESS               11
+#define NPVERS_HAS_XPCONNECT_SCRIPTING      13  /* Not implemented in WebKit */
+#define NPVERS_HAS_NPRUNTIME_SCRIPTING      14
+#define NPVERS_HAS_FORM_VALUES              15  /* Not implemented in WebKit; see bug 13061 */
+#define NPVERS_HAS_POPUPS_ENABLED_STATE     16  /* Not implemented in WebKit */
+#define NPVERS_HAS_RESPONSE_HEADERS         17
+#define NPVERS_HAS_NPOBJECT_ENUM            18
+#define NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL 19
+#define NPVERS_HAS_ALL_NETWORK_STREAMS      20
+#define NPVERS_HAS_URL_AND_AUTH_INFO        21
+#define NPVERS_HAS_PRIVATE_MODE             22
+#define NPVERS_MACOSX_HAS_EVENT_MODELS      23
+#define NPVERS_HAS_CANCEL_SRC_STREAM        24
+#define NPVERS_HAS_ADVANCED_KEY_HANDLING    25
+#define NPVERS_HAS_URL_REDIRECT_HANDLING    26
+#define NPVERS_HAS_CLEAR_SITE_DATA          27
+
+/*----------------------------------------------------------------------*/
+/*                        Function Prototypes                           */
+/*----------------------------------------------------------------------*/
+
+#if defined(__OS2__)
+#define NP_LOADDS _System
+#else
+#define NP_LOADDS
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* NPP_* functions are provided by the plugin and called by the navigator. */
+
+#if defined(XP_UNIX)
+const char* NPP_GetMIMEDescription(void);
+#endif
+
+NPError NP_LOADDS NPP_Initialize(void);
+void    NP_LOADDS NPP_Shutdown(void);
+NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance,
+                          uint16_t mode, int16_t argc, char* argn[],
+                          char* argv[], NPSavedData* saved);
+NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save);
+NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window);
+NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type,
+                                NPStream* stream, NPBool seekable,
+                                uint16_t* stype);
+NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream,
+                                    NPReason reason);
+int32_t NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream);
+int32_t NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32_t offset,
+                            int32_t len, void* buffer);
+void    NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream,
+                                   const char* fname);
+void    NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint);
+int16_t NP_LOADDS NPP_HandleEvent(NPP instance, void* event);
+void    NP_LOADDS NPP_URLNotify(NPP instance, const char* url,
+                                NPReason reason, void* notifyData);
+jref    NP_LOADDS NPP_GetJavaClass(void);
+NPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value);
+NPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value);
+NPBool  NP_LOADDS NPP_GotFocus(NPP instance, NPFocusDirection direction);
+void    NP_LOADDS NPP_LostFocus(NPP instance);
+void    NP_LOADDS NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status, void* notifyData);
+NPError NP_LOADDS NPP_ClearSiteData(const char* site, uint64_t flags, uint64_t maxAge);
+char**  NP_LOADDS NPP_GetSitesWithData(void);
+
+/* NPN_* functions are provided by the navigator and called by the plugin. */
+void        NP_LOADDS NPN_Version(int* plugin_major, int* plugin_minor,
+                                  int* netscape_major, int* netscape_minor);
+NPError     NP_LOADDS NPN_GetURLNotify(NPP instance, const char* url,
+                                       const char* target, void* notifyData);
+NPError     NP_LOADDS NPN_GetURL(NPP instance, const char* url,
+                                 const char* target);
+NPError     NP_LOADDS NPN_PostURLNotify(NPP instance, const char* url,
+                                        const char* target, uint32_t len,
+                                        const char* buf, NPBool file,
+                                        void* notifyData);
+NPError     NP_LOADDS NPN_PostURL(NPP instance, const char* url,
+                                  const char* target, uint32_t len,
+                                  const char* buf, NPBool file);
+NPError     NP_LOADDS NPN_RequestRead(NPStream* stream, NPByteRange* rangeList);
+NPError     NP_LOADDS NPN_NewStream(NPP instance, NPMIMEType type,
+                                    const char* target, NPStream** stream);
+int32_t     NP_LOADDS NPN_Write(NPP instance, NPStream* stream, int32_t len,
+                                void* buffer);
+NPError     NP_LOADDS NPN_DestroyStream(NPP instance, NPStream* stream,
+                                        NPReason reason);
+void        NP_LOADDS NPN_Status(NPP instance, const char* message);
+const char* NP_LOADDS NPN_UserAgent(NPP instance);
+void*       NP_LOADDS NPN_MemAlloc(uint32_t size);
+void        NP_LOADDS NPN_MemFree(void* ptr);
+uint32_t    NP_LOADDS NPN_MemFlush(uint32_t size);
+void        NP_LOADDS NPN_ReloadPlugins(NPBool reloadPages);
+JRIEnv*     NP_LOADDS NPN_GetJavaEnv(void);
+jref        NP_LOADDS NPN_GetJavaPeer(NPP instance);
+NPError     NP_LOADDS NPN_GetValue(NPP instance, NPNVariable variable,
+                                   void *value);
+NPError     NP_LOADDS NPN_SetValue(NPP instance, NPPVariable variable,
+                                   void *value);
+void        NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect *invalidRect);
+void        NP_LOADDS NPN_InvalidateRegion(NPP instance,
+                                           NPRegion invalidRegion);
+void        NP_LOADDS NPN_ForceRedraw(NPP instance);
+void        NP_LOADDS NPN_PushPopupsEnabledState(NPP instance, NPBool enabled);
+void        NP_LOADDS NPN_PopPopupsEnabledState(NPP instance);
+void        NP_LOADDS NPN_PluginThreadAsyncCall(NPP instance,
+                                                void (*func) (void *),
+                                                void *userData);
+NPError     NP_LOADDS NPN_GetValueForURL(NPP instance, NPNURLVariable variable,
+                                         const char *url, char **value,
+                                         uint32_t *len);
+NPError     NP_LOADDS NPN_SetValueForURL(NPP instance, NPNURLVariable variable,
+                                         const char *url, const char *value,
+                                         uint32_t len);
+NPError     NP_LOADDS NPN_GetAuthenticationInfo(NPP instance,
+                                                const char *protocol,
+                                                const char *host, int32_t port,
+                                                const char *scheme,
+                                                const char *realm,
+                                                char **username, uint32_t *ulen,
+                                                char **password,
+                                                uint32_t *plen);
+uint32_t    NP_LOADDS NPN_ScheduleTimer(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID));
+void        NP_LOADDS NPN_UnscheduleTimer(NPP instance, uint32_t timerID);
+NPError     NP_LOADDS NPN_PopUpContextMenu(NPP instance, NPMenu* menu);
+NPBool      NP_LOADDS NPN_ConvertPoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
+NPBool      NP_LOADDS NPN_HandleEvent(NPP instance, void *event, NPBool handled);
+NPBool      NP_LOADDS NPN_UnfocusInstance(NPP instance, NPFocusDirection direction);
+void        NP_LOADDS NPN_URLRedirectResponse(NPP instance, void* notifyData, NPBool allow);
+
+#ifdef __cplusplus
+}  /* end extern "C" */
+#endif
+
+#endif /* RC_INVOKED */
+#if defined(__OS2__)
+#pragma pack()
+#endif
+
+#endif /* npapi_h_ */
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/plugins/npfunctions.h webkitgtk-2.36.0/Source/WebCore/plugins/npfunctions.h
--- webkitgtk-2.36.0.orig/Source/WebCore/plugins/npfunctions.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/plugins/npfunctions.h	2022-03-22 16:38:57.369580090 -0500
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2007 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#ifndef NPFUNCTIONS_H
+#define NPFUNCTIONS_H
+
+
+#include "npruntime.h"
+#include "npapi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(XP_WIN)
+#define EXPORTED_CALLBACK(_type, _name) _type (__stdcall * _name)
+#else
+#define EXPORTED_CALLBACK(_type, _name) _type (* _name)
+#endif
+
+typedef NPError (*NPN_GetURLNotifyProcPtr)(NPP instance, const char* URL, const char* window, void* notifyData);
+typedef NPError (*NPN_PostURLNotifyProcPtr)(NPP instance, const char* URL, const char* window, uint32_t len, const char* buf, NPBool file, void* notifyData);
+typedef NPError (*NPN_RequestReadProcPtr)(NPStream* stream, NPByteRange* rangeList);
+typedef NPError (*NPN_NewStreamProcPtr)(NPP instance, NPMIMEType type, const char* window, NPStream** stream);
+typedef int32_t (*NPN_WriteProcPtr)(NPP instance, NPStream* stream, int32_t len, void* buffer);
+typedef NPError (*NPN_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason);
+typedef void (*NPN_StatusProcPtr)(NPP instance, const char* message);
+typedef const char*(*NPN_UserAgentProcPtr)(NPP instance);
+typedef void* (*NPN_MemAllocProcPtr)(uint32_t size);
+typedef void (*NPN_MemFreeProcPtr)(void* ptr);
+typedef uint32_t (*NPN_MemFlushProcPtr)(uint32_t size);
+typedef void (*NPN_ReloadPluginsProcPtr)(NPBool reloadPages);
+typedef NPError (*NPN_GetValueProcPtr)(NPP instance, NPNVariable variable, void *ret_value);
+typedef NPError (*NPN_SetValueProcPtr)(NPP instance, NPPVariable variable, void *value);
+typedef void (*NPN_InvalidateRectProcPtr)(NPP instance, NPRect *rect);
+typedef void (*NPN_InvalidateRegionProcPtr)(NPP instance, NPRegion region);
+typedef void (*NPN_ForceRedrawProcPtr)(NPP instance);
+typedef NPError (*NPN_GetURLProcPtr)(NPP instance, const char* URL, const char* window);
+typedef NPError (*NPN_PostURLProcPtr)(NPP instance, const char* URL, const char* window, uint32_t len, const char* buf, NPBool file);
+typedef void* (*NPN_GetJavaEnvProcPtr)(void);
+typedef void* (*NPN_GetJavaPeerProcPtr)(NPP instance);
+typedef void  (*NPN_PushPopupsEnabledStateProcPtr)(NPP instance, NPBool enabled);
+typedef void  (*NPN_PopPopupsEnabledStateProcPtr)(NPP instance);
+typedef void (*NPN_PluginThreadAsyncCallProcPtr)(NPP npp, void (*func)(void *), void *userData);
+typedef NPError (*NPN_GetValueForURLProcPtr)(NPP npp, NPNURLVariable variable, const char* url, char** value, uint32_t* len);
+typedef NPError (*NPN_SetValueForURLProcPtr)(NPP npp, NPNURLVariable variable, const char* url, const char* value, uint32_t len);
+typedef NPError (*NPN_GetAuthenticationInfoProcPtr)(NPP npp, const char* protocol, const char* host, int32_t port, const char* scheme, const char *realm, char** username, uint32_t* ulen, char** password, uint32_t* plen);
+
+typedef uint32_t (*NPN_ScheduleTimerProcPtr)(NPP npp, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID));
+typedef void (*NPN_UnscheduleTimerProcPtr)(NPP npp, uint32_t timerID);
+typedef NPError (*NPN_PopUpContextMenuProcPtr)(NPP instance, NPMenu* menu);
+typedef NPBool (*NPN_ConvertPointProcPtr)(NPP npp, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
+typedef NPBool (*NPN_HandleEventPtr)(NPP instance, void *event, NPBool handled);
+typedef NPBool (*NPN_UnfocusInstancePtr)(NPP instance, NPFocusDirection direction);
+typedef void (*NPN_URLRedirectResponsePtr)(NPP instance, void* notifyData, NPBool allow);
+
+typedef void (*NPN_ReleaseVariantValueProcPtr) (NPVariant *variant);
+
+typedef NPIdentifier (*NPN_GetStringIdentifierProcPtr) (const NPUTF8 *name);
+typedef void (*NPN_GetStringIdentifiersProcPtr) (const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers);
+typedef NPIdentifier (*NPN_GetIntIdentifierProcPtr) (int32_t intid);
+typedef int32_t (*NPN_IntFromIdentifierProcPtr) (NPIdentifier identifier);
+typedef bool (*NPN_IdentifierIsStringProcPtr) (NPIdentifier identifier);
+typedef NPUTF8 *(*NPN_UTF8FromIdentifierProcPtr) (NPIdentifier identifier);
+
+typedef NPObject* (*NPN_CreateObjectProcPtr) (NPP, NPClass *aClass);
+typedef NPObject* (*NPN_RetainObjectProcPtr) (NPObject *obj);
+typedef void (*NPN_ReleaseObjectProcPtr) (NPObject *obj);
+typedef bool (*NPN_InvokeProcPtr) (NPP npp, NPObject *obj, NPIdentifier methodName, const NPVariant *args, unsigned argCount, NPVariant *result);
+typedef bool (*NPN_InvokeDefaultProcPtr) (NPP npp, NPObject *obj, const NPVariant *args, unsigned argCount, NPVariant *result);
+typedef bool (*NPN_EvaluateProcPtr) (NPP npp, NPObject *obj, NPString *script, NPVariant *result);
+typedef bool (*NPN_GetPropertyProcPtr) (NPP npp, NPObject *obj, NPIdentifier  propertyName, NPVariant *result);
+typedef bool (*NPN_SetPropertyProcPtr) (NPP npp, NPObject *obj, NPIdentifier  propertyName, const NPVariant *value);
+typedef bool (*NPN_HasPropertyProcPtr) (NPP, NPObject *npobj, NPIdentifier propertyName);
+typedef bool (*NPN_HasMethodProcPtr) (NPP npp, NPObject *npobj, NPIdentifier methodName);
+typedef bool (*NPN_RemovePropertyProcPtr) (NPP npp, NPObject *obj, NPIdentifier propertyName);
+typedef void (*NPN_SetExceptionProcPtr) (NPObject *obj, const NPUTF8 *message);
+typedef bool (*NPN_EnumerateProcPtr) (NPP npp, NPObject *npobj, NPIdentifier **identifier, uint32_t *count);
+typedef bool (*NPN_ConstructProcPtr)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result);    
+
+typedef NPError (*NPP_NewProcPtr)(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved);
+typedef NPError (*NPP_DestroyProcPtr)(NPP instance, NPSavedData** save);
+typedef NPError (*NPP_SetWindowProcPtr)(NPP instance, NPWindow* window);
+typedef NPError (*NPP_NewStreamProcPtr)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype);
+typedef NPError (*NPP_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason);
+typedef void (*NPP_StreamAsFileProcPtr)(NPP instance, NPStream* stream, const char* fname);
+typedef int32_t (*NPP_WriteReadyProcPtr)(NPP instance, NPStream* stream);
+typedef int32_t (*NPP_WriteProcPtr)(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer);
+typedef void (*NPP_PrintProcPtr)(NPP instance, NPPrint* platformPrint);
+typedef int16_t (*NPP_HandleEventProcPtr)(NPP instance, void* event);
+typedef void (*NPP_URLNotifyProcPtr)(NPP instance, const char* URL, NPReason reason, void* notifyData);
+typedef NPError (*NPP_GetValueProcPtr)(NPP instance, NPPVariable variable, void *ret_value);
+typedef NPError (*NPP_SetValueProcPtr)(NPP instance, NPNVariable variable, void *value);
+typedef NPBool (*NPP_GotFocusPtr)(NPP instance, NPFocusDirection direction);
+typedef void (*NPP_LostFocusPtr)(NPP instance);
+typedef void (*NPP_URLRedirectNotifyPtr)(NPP instance, const char* url, int32_t status, void* notifyData);
+typedef NPError (*NPP_ClearSiteDataPtr)(const char* site, uint64_t flags, uint64_t maxAge);
+typedef char** (*NPP_GetSitesWithDataPtr)(void);
+
+typedef void *(*NPP_GetJavaClassProcPtr)(void);
+typedef void* JRIGlobalRef; //not using this right now
+
+typedef struct _NPNetscapeFuncs {
+    uint16_t size;
+    uint16_t version;
+    
+    NPN_GetURLProcPtr geturl;
+    NPN_PostURLProcPtr posturl;
+    NPN_RequestReadProcPtr requestread;
+    NPN_NewStreamProcPtr newstream;
+    NPN_WriteProcPtr write;
+    NPN_DestroyStreamProcPtr destroystream;
+    NPN_StatusProcPtr status;
+    NPN_UserAgentProcPtr uagent;
+    NPN_MemAllocProcPtr memalloc;
+    NPN_MemFreeProcPtr memfree;
+    NPN_MemFlushProcPtr memflush;
+    NPN_ReloadPluginsProcPtr reloadplugins;
+    NPN_GetJavaEnvProcPtr getJavaEnv;
+    NPN_GetJavaPeerProcPtr getJavaPeer;
+    NPN_GetURLNotifyProcPtr geturlnotify;
+    NPN_PostURLNotifyProcPtr posturlnotify;
+    NPN_GetValueProcPtr getvalue;
+    NPN_SetValueProcPtr setvalue;
+    NPN_InvalidateRectProcPtr invalidaterect;
+    NPN_InvalidateRegionProcPtr invalidateregion;
+    NPN_ForceRedrawProcPtr forceredraw;
+    
+    NPN_GetStringIdentifierProcPtr getstringidentifier;
+    NPN_GetStringIdentifiersProcPtr getstringidentifiers;
+    NPN_GetIntIdentifierProcPtr getintidentifier;
+    NPN_IdentifierIsStringProcPtr identifierisstring;
+    NPN_UTF8FromIdentifierProcPtr utf8fromidentifier;
+    NPN_IntFromIdentifierProcPtr intfromidentifier;
+    NPN_CreateObjectProcPtr createobject;
+    NPN_RetainObjectProcPtr retainobject;
+    NPN_ReleaseObjectProcPtr releaseobject;
+    NPN_InvokeProcPtr invoke;
+    NPN_InvokeDefaultProcPtr invokeDefault;
+    NPN_EvaluateProcPtr evaluate;
+    NPN_GetPropertyProcPtr getproperty;
+    NPN_SetPropertyProcPtr setproperty;
+    NPN_RemovePropertyProcPtr removeproperty;
+    NPN_HasPropertyProcPtr hasproperty;
+    NPN_HasMethodProcPtr hasmethod;
+    NPN_ReleaseVariantValueProcPtr releasevariantvalue;
+    NPN_SetExceptionProcPtr setexception;
+    NPN_PushPopupsEnabledStateProcPtr pushpopupsenabledstate;
+    NPN_PopPopupsEnabledStateProcPtr poppopupsenabledstate;
+    NPN_EnumerateProcPtr enumerate;
+    NPN_PluginThreadAsyncCallProcPtr pluginthreadasynccall;
+    NPN_ConstructProcPtr construct;
+    NPN_GetValueForURLProcPtr getvalueforurl;
+    NPN_SetValueForURLProcPtr setvalueforurl;
+    NPN_GetAuthenticationInfoProcPtr getauthenticationinfo;
+    NPN_ScheduleTimerProcPtr scheduletimer;
+    NPN_UnscheduleTimerProcPtr unscheduletimer;
+    NPN_PopUpContextMenuProcPtr popupcontextmenu;
+    NPN_ConvertPointProcPtr convertpoint;
+    NPN_HandleEventPtr handleevent;
+    NPN_UnfocusInstancePtr unfocusinstance;
+    NPN_URLRedirectResponsePtr urlredirectresponse;
+} NPNetscapeFuncs;
+
+typedef struct _NPPluginFuncs {
+    uint16_t size;
+    uint16_t version;
+    NPP_NewProcPtr newp;
+    NPP_DestroyProcPtr destroy;
+    NPP_SetWindowProcPtr setwindow;
+    NPP_NewStreamProcPtr newstream;
+    NPP_DestroyStreamProcPtr destroystream;
+    NPP_StreamAsFileProcPtr asfile;
+    NPP_WriteReadyProcPtr writeready;
+    NPP_WriteProcPtr write;
+    NPP_PrintProcPtr print;
+    NPP_HandleEventProcPtr event;
+    NPP_URLNotifyProcPtr urlnotify;
+    JRIGlobalRef javaClass;
+    NPP_GetValueProcPtr getvalue;
+    NPP_SetValueProcPtr setvalue;
+    NPP_GotFocusPtr gotfocus;
+    NPP_LostFocusPtr lostfocus;
+    NPP_URLRedirectNotifyPtr urlredirectnotify;
+    NPP_ClearSiteDataPtr clearsitedata;
+    NPP_GetSitesWithDataPtr getsiteswithdata;
+} NPPluginFuncs;
+
+typedef EXPORTED_CALLBACK(NPError, NP_GetEntryPointsFuncPtr)(NPPluginFuncs*);
+typedef EXPORTED_CALLBACK(void, NPP_ShutdownProcPtr)(void);    
+
+#if defined(XP_MACOSX)
+typedef void (*BP_CreatePluginMIMETypesPreferencesFuncPtr)(void);
+typedef NPError (*MainFuncPtr)(NPNetscapeFuncs*, NPPluginFuncs*, NPP_ShutdownProcPtr*);
+#endif
+
+#if defined(XP_UNIX)
+typedef EXPORTED_CALLBACK(NPError, NP_InitializeFuncPtr)(NPNetscapeFuncs*, NPPluginFuncs*);
+typedef EXPORTED_CALLBACK(const char*, NP_GetMIMEDescriptionFuncPtr)(void);
+#else
+typedef EXPORTED_CALLBACK(NPError, NP_InitializeFuncPtr)(NPNetscapeFuncs*);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/plugins/npruntime.h webkitgtk-2.36.0/Source/WebCore/plugins/npruntime.h
--- webkitgtk-2.36.0.orig/Source/WebCore/plugins/npruntime.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/plugins/npruntime.h	2022-03-22 16:38:57.369580090 -0500
@@ -0,0 +1,393 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (c) 2004, Apple Inc. and The Mozilla Foundation. 
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of Apple Inc. ("Apple") or The Mozilla
+ * Foundation ("Mozilla") nor the names of their contributors may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR
+ * THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef _NP_RUNTIME_H_
+#define _NP_RUNTIME_H_
+
+#include "npapi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+    This API is used to facilitate binding code written in C to script
+    objects.  The API in this header does not assume the presence of a
+    user agent.  That is, it can be used to bind C code to scripting
+    environments outside of the context of a user agent.
+    
+    However, the normal use of the this API is in the context of a
+    scripting environment running in a browser or other user agent.
+    In particular it is used to support the extended Netscape
+    script-ability API for plugins (NP-SAP).  NP-SAP is an extension
+    of the Netscape plugin API.  As such we have adopted the use of
+    the "NP" prefix for this API.
+
+    The following NP{N|P}Variables were added to the Netscape plugin
+    API (in npapi.h):
+
+    NPNVWindowNPObject
+    NPNVPluginElementNPObject
+    NPPVpluginScriptableNPObject
+
+    These variables are exposed through NPN_GetValue() and
+    NPP_GetValue() (respectively) and are used to establish the
+    initial binding between the user agent and native code.  The DOM
+    objects in the user agent can be examined and manipulated using
+    the NPN_ functions that operate on NPObjects described in this
+    header.
+
+    To the extent possible the assumptions about the scripting
+    language used by the scripting environment have been minimized.
+*/
+
+#define NP_BEGIN_MACRO  do {
+#define NP_END_MACRO    } while (0)
+
+/*
+    Objects (non-primitive data) passed between 'C' and script is
+    always wrapped in an NPObject.  The 'interface' of an NPObject is
+    described by an NPClass.
+*/
+typedef struct NPObject NPObject;
+typedef struct NPClass NPClass;
+
+typedef char NPUTF8;
+typedef struct _NPString {
+    const NPUTF8 *UTF8Characters;
+    uint32_t UTF8Length;
+} NPString;
+
+typedef enum {
+    NPVariantType_Void,
+    NPVariantType_Null,
+    NPVariantType_Bool,
+    NPVariantType_Int32,
+    NPVariantType_Double,
+    NPVariantType_String,
+    NPVariantType_Object
+} NPVariantType;
+
+typedef struct _NPVariant {
+    NPVariantType type;
+    union {
+        bool boolValue;
+        int32_t intValue;
+        double doubleValue;
+        NPString stringValue;
+        NPObject *objectValue;
+    } value;
+} NPVariant;
+
+/*
+    NPN_ReleaseVariantValue is called on all 'out' parameters
+    references.  Specifically it is to be called on variants that own
+    their value, as is the case with all non-const NPVariant*
+    arguments after a successful call to any methods (except this one)
+    in this API.
+
+    After calling NPN_ReleaseVariantValue, the type of the variant
+    will be NPVariantType_Void.
+*/
+void NPN_ReleaseVariantValue(NPVariant *variant);
+
+#define NPVARIANT_IS_VOID(_v)    ((_v).type == NPVariantType_Void)
+#define NPVARIANT_IS_NULL(_v)    ((_v).type == NPVariantType_Null)
+#define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool)
+#define NPVARIANT_IS_INT32(_v)   ((_v).type == NPVariantType_Int32)
+#define NPVARIANT_IS_DOUBLE(_v)  ((_v).type == NPVariantType_Double)
+#define NPVARIANT_IS_STRING(_v)  ((_v).type == NPVariantType_String)
+#define NPVARIANT_IS_OBJECT(_v)  ((_v).type == NPVariantType_Object)
+
+#define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue)
+#define NPVARIANT_TO_INT32(_v)   ((_v).value.intValue)
+#define NPVARIANT_TO_DOUBLE(_v)  ((_v).value.doubleValue)
+#define NPVARIANT_TO_STRING(_v)  ((_v).value.stringValue)
+#define NPVARIANT_TO_OBJECT(_v)  ((_v).value.objectValue)
+
+#define VOID_TO_NPVARIANT(_v)                                                 \
+NP_BEGIN_MACRO                                                                \
+    (_v).type = NPVariantType_Void;                                           \
+    (_v).value.objectValue = NULL;                                            \
+NP_END_MACRO
+
+#define NULL_TO_NPVARIANT(_v)                                                 \
+NP_BEGIN_MACRO                                                                \
+    (_v).type = NPVariantType_Null;                                           \
+    (_v).value.objectValue = NULL;                                            \
+NP_END_MACRO
+
+#define BOOLEAN_TO_NPVARIANT(_val, _v)                                        \
+NP_BEGIN_MACRO                                                                \
+    (_v).type = NPVariantType_Bool;                                           \
+    (_v).value.boolValue = !!(_val);                                          \
+NP_END_MACRO
+
+#define INT32_TO_NPVARIANT(_val, _v)                                          \
+NP_BEGIN_MACRO                                                                \
+    (_v).type = NPVariantType_Int32;                                          \
+    (_v).value.intValue = _val;                                               \
+NP_END_MACRO
+
+#define DOUBLE_TO_NPVARIANT(_val, _v)                                         \
+NP_BEGIN_MACRO                                                                \
+    (_v).type = NPVariantType_Double;                                         \
+    (_v).value.doubleValue = _val;                                            \
+NP_END_MACRO
+
+#define STRINGZ_TO_NPVARIANT(_val, _v)                                        \
+NP_BEGIN_MACRO                                                                \
+    (_v).type = NPVariantType_String;                                         \
+    NPString str = { _val, uint32_t(strlen(_val)) };                          \
+    (_v).value.stringValue = str;                                             \
+NP_END_MACRO
+
+#define STRINGN_TO_NPVARIANT(_val, _len, _v)                                  \
+NP_BEGIN_MACRO                                                                \
+    (_v).type = NPVariantType_String;                                         \
+    NPString str = { _val, uint32_t(_len) };                                  \
+    (_v).value.stringValue = str;                                             \
+NP_END_MACRO
+
+#define OBJECT_TO_NPVARIANT(_val, _v)                                         \
+NP_BEGIN_MACRO                                                                \
+    (_v).type = NPVariantType_Object;                                         \
+    (_v).value.objectValue = _val;                                            \
+NP_END_MACRO
+
+
+/*
+  Type mappings (JavaScript types have been used for illustration
+    purposes):
+
+  JavaScript       to             C (NPVariant with type:)
+  undefined                       NPVariantType_Void
+  null                            NPVariantType_Null
+  Boolean                         NPVariantType_Bool
+  Number                          NPVariantType_Double or NPVariantType_Int32
+  String                          NPVariantType_String
+  Object                          NPVariantType_Object
+
+  C (NPVariant with type:)   to   JavaScript
+  NPVariantType_Void              undefined
+  NPVariantType_Null              null
+  NPVariantType_Bool              Boolean
+  NPVariantType_Int32             Number
+  NPVariantType_Double            Number
+  NPVariantType_String            String
+  NPVariantType_Object            Object
+*/
+
+typedef void *NPIdentifier;
+
+/*
+    NPObjects have methods and properties.  Methods and properties are
+    identified with NPIdentifiers.  These identifiers may be reflected
+    in script.  NPIdentifiers can be either strings or integers, IOW,
+    methods and properties can be identified by either strings or
+    integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be
+    compared using ==.  In case of any errors, the requested
+    NPIdentifier(s) will be NULL. NPIdentifier lifetime is controlled
+    by the browser. Plugins do not need to worry about memory management
+    with regards to NPIdentifiers.
+*/
+NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name);
+void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount,
+                              NPIdentifier *identifiers);
+NPIdentifier NPN_GetIntIdentifier(int32_t intid);
+bool NPN_IdentifierIsString(NPIdentifier identifier);
+
+/*
+    The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed.
+*/
+NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier);
+
+/*
+    Get the integer represented by identifier. If identifier is not an
+    integer identifier, the behaviour is undefined.
+*/
+int32_t NPN_IntFromIdentifier(NPIdentifier identifier);
+
+/*
+    NPObject behavior is implemented using the following set of
+    callback functions.
+
+    The NPVariant *result argument of these functions (where
+    applicable) should be released using NPN_ReleaseVariantValue().
+*/
+typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass);
+typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj);
+typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj);
+typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name);
+typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name,
+                                    const NPVariant *args, uint32_t argCount,
+                                    NPVariant *result);
+typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj,
+                                           const NPVariant *args,
+                                           uint32_t argCount,
+                                           NPVariant *result);
+typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name);
+typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
+                                         NPVariant *result);
+typedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
+                                         const NPVariant *value);
+typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj,
+                                            NPIdentifier name);
+typedef bool (*NPEnumerationFunctionPtr)(NPObject *npobj, NPIdentifier **value,
+                                         uint32_t *count);
+typedef bool (*NPConstructFunctionPtr)(NPObject *npobj,
+                                       const NPVariant *args,
+                                       uint32_t argCount,
+                                       NPVariant *result);
+
+/*
+    NPObjects returned by create, retain, invoke, and getProperty pass
+    a reference count to the caller.  That is, the callee adds a
+    reference count which passes to the caller.  It is the caller's
+    responsibility to release the returned object.
+
+    NPInvokeFunctionPtr function may return 0 to indicate a void
+    result.
+
+    NPInvalidateFunctionPtr is called by the scripting environment
+    when the native code is shutdown.  Any attempt to message a
+    NPObject instance after the invalidate callback has been
+    called will result in undefined behavior, even if the native code
+    is still retaining those NPObject instances.  (The runtime
+    will typically return immediately, with 0 or NULL, from an attempt
+    to dispatch to a NPObject, but this behavior should not be
+    depended upon.)
+
+    The NPEnumerationFunctionPtr function may pass an array of
+    NPIdentifiers back to the caller. The callee allocs the memory of
+    the array using NPN_MemAlloc(), and it's the caller's responsibility
+    to release it using NPN_MemFree().
+*/
+struct NPClass
+{
+    uint32_t structVersion;
+    NPAllocateFunctionPtr allocate;
+    NPDeallocateFunctionPtr deallocate;
+    NPInvalidateFunctionPtr invalidate;
+    NPHasMethodFunctionPtr hasMethod;
+    NPInvokeFunctionPtr invoke;
+    NPInvokeDefaultFunctionPtr invokeDefault;
+    NPHasPropertyFunctionPtr hasProperty;
+    NPGetPropertyFunctionPtr getProperty;
+    NPSetPropertyFunctionPtr setProperty;
+    NPRemovePropertyFunctionPtr removeProperty;
+    NPEnumerationFunctionPtr enumerate;
+    NPConstructFunctionPtr construct;
+};
+
+#define NP_CLASS_STRUCT_VERSION      3
+
+#define NP_CLASS_STRUCT_VERSION_ENUM 2
+#define NP_CLASS_STRUCT_VERSION_CTOR 3
+
+#define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass)   \
+        ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM)
+
+#define NP_CLASS_STRUCT_VERSION_HAS_CTOR(npclass)   \
+        ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR)
+
+struct NPObject {
+    NPClass *_class;
+    uint32_t referenceCount;
+    /*
+     * Additional space may be allocated here by types of NPObjects
+     */
+};
+
+/*
+    If the class has an allocate function, NPN_CreateObject invokes
+    that function, otherwise a NPObject is allocated and
+    returned. This method will initialize the referenceCount member of
+    the NPObject to 1.
+*/
+NPObject *NPN_CreateObject(NPP npp, NPClass *aClass);
+
+/*
+    Increment the NPObject's reference count.
+*/
+NPObject *NPN_RetainObject(NPObject *npobj);
+
+/*
+    Decremented the NPObject's reference count.  If the reference
+    count goes to zero, the class's destroy function is invoke if
+    specified, otherwise the object is freed directly.
+*/
+void NPN_ReleaseObject(NPObject *npobj);
+
+/*
+    Functions to access script objects represented by NPObject.
+
+    Calls to script objects are synchronous.  If a function returns a
+    value, it will be supplied via the result NPVariant
+    argument. Successful calls will return true, false will be
+    returned in case of an error.
+    
+    Calls made from plugin code to script must be made from the thread
+    on which the plugin was initialized.
+*/
+
+bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName,
+                const NPVariant *args, uint32_t argCount, NPVariant *result);
+bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args,
+                       uint32_t argCount, NPVariant *result);
+bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script,
+                  NPVariant *result);
+bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
+                     NPVariant *result);
+bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
+                     const NPVariant *value);
+bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
+bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
+bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName);
+bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier,
+                   uint32_t *count);
+bool NPN_Construct(NPP npp, NPObject *npobj, const NPVariant *args,
+                   uint32_t argCount, NPVariant *result);
+
+/*
+    NPN_SetException may be called to trigger a script exception upon
+    return from entry points into NPObjects.  Typical usage:
+
+    NPN_SetException (npobj, message);
+*/
+void NPN_SetException(NPObject *npobj, const NPUTF8 *message);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/plugins/nptypes.h webkitgtk-2.36.0/Source/WebCore/plugins/nptypes.h
--- webkitgtk-2.36.0.orig/Source/WebCore/plugins/nptypes.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/plugins/nptypes.h	2022-03-22 16:38:57.369580090 -0500
@@ -0,0 +1,121 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * mozilla.org.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Johnny Stenback <jst@mozilla.org> (Original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nptypes_h_
+#define nptypes_h_
+
+/*
+ * Header file for ensuring that C99 types ([u]int32_t, [u]int64_t and bool) and
+ * true/false macros are available.
+ */
+
+#if defined(WIN32) || defined(OS2)
+  /*
+   * Win32 and OS/2 don't know C99, so define [u]int_16/32/64 here. The bool
+   * is predefined tho, both in C and C++.
+   */
+  typedef short int16_t;
+  typedef unsigned short uint16_t;
+  typedef int int32_t;
+  typedef unsigned int uint32_t;
+  typedef long long int64_t;
+  typedef unsigned long long uint64_t;
+#elif defined(_AIX) || defined(__sun) || defined(__osf__) || defined(IRIX) || defined(HPUX)
+  /*
+   * AIX and SunOS ship a inttypes.h header that defines [u]int32_t,
+   * but not bool for C.
+   */
+  #include <inttypes.h>
+
+  #ifndef __cplusplus
+    typedef int bool;
+    #define true   1
+    #define false  0
+  #endif
+#elif defined(bsdi) || defined(FREEBSD) || defined(OPENBSD)
+  /*
+   * BSD/OS, FreeBSD, and OpenBSD ship sys/types.h that define int32_t and 
+   * u_int32_t.
+   */
+  #include <sys/types.h>
+
+  /*
+   * BSD/OS ships no header that defines uint32_t, nor bool (for C)
+   */
+  #if defined(bsdi)
+  typedef u_int32_t uint32_t;
+  typedef u_int64_t uint64_t;
+
+  #if !defined(__cplusplus)
+    typedef int bool;
+    #define true   1
+    #define false  0
+  #endif
+  #else
+  /*
+   * FreeBSD and OpenBSD define uint32_t and bool.
+   */
+    #include <inttypes.h>
+    #include <stdbool.h>
+  #endif
+#elif defined(BEOS)
+  #include <inttypes.h>
+#else
+  /*
+   * For those that ship a standard C99 stdint.h header file, include
+   * it. Can't do the same for stdbool.h tho, since some systems ship
+   * with a stdbool.h file that doesn't compile!
+   */
+  #include <stdint.h>
+
+  #ifndef __cplusplus
+    #if !defined(__GNUC__) || (__GNUC__ > 2 || __GNUC_MINOR__ > 95)
+      #include <stdbool.h>
+    #else
+      /*
+       * GCC 2.91 can't deal with a typedef for bool, but a #define
+       * works.
+       */
+      #define bool int
+      #define true   1
+      #define false  0
+    #endif
+  #endif
+#endif
+
+#endif /* nptypes_h_ */
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/plugins/PluginViewBase.h webkitgtk-2.36.0/Source/WebCore/plugins/PluginViewBase.h
--- webkitgtk-2.36.0.orig/Source/WebCore/plugins/PluginViewBase.h	2022-02-23 02:59:02.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/plugins/PluginViewBase.h	2022-03-22 16:38:57.369580090 -0500
@@ -58,6 +58,8 @@ public:
 
     virtual JSC::JSObject* scriptObject(JSC::JSGlobalObject*) { return 0; }
     virtual void storageBlockingStateChanged() { }
+    virtual void privateBrowsingStateChanged(bool) { }
+    virtual bool getFormValue(String&) { return false; }
     virtual bool scroll(ScrollDirection, ScrollGranularity) { return false; }
 
     // A plug-in can ask WebKit to handle scrollbars for it.
@@ -71,6 +73,7 @@ public:
     virtual bool shouldAllowNavigationFromDrags() const { return false; }
 
     bool isPluginViewBase() const override { return true; }
+    virtual bool shouldNotAddLayer() const { return false; }
 
     virtual AudioHardwareActivityType audioHardwareActivity() const { return AudioHardwareActivityType::Unknown; }
 
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/rendering/RenderLayerBacking.cpp webkitgtk-2.36.0/Source/WebCore/rendering/RenderLayerBacking.cpp
--- webkitgtk-2.36.0.orig/Source/WebCore/rendering/RenderLayerBacking.cpp	2022-02-23 02:59:02.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/rendering/RenderLayerBacking.cpp	2022-03-22 16:38:57.369580090 -0500
@@ -1080,7 +1080,8 @@ bool RenderLayerBacking::updateConfigura
             pluginViewBase->attachPluginLayer();
         }
 #else
-        m_graphicsLayer->setContentsToPlatformLayer(pluginViewBase->platformLayer(), GraphicsLayer::ContentsLayerPurpose::Plugin);
+        if (!pluginViewBase->shouldNotAddLayer())
+            m_graphicsLayer->setContentsToPlatformLayer(pluginViewBase->platformLayer(), GraphicsLayer::ContentsLayerPurpose::Plugin);
 #endif
     }
 #if ENABLE(VIDEO)
diff -urpN webkitgtk-2.36.0.orig/Source/WebCore/Sources.txt webkitgtk-2.36.0/Source/WebCore/Sources.txt
--- webkitgtk-2.36.0.orig/Source/WebCore/Sources.txt	2022-02-23 02:58:59.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebCore/Sources.txt	2022-03-22 16:38:57.369580090 -0500
@@ -648,7 +648,14 @@ bindings/js/WebCoreTypedArrayController.
 bindings/js/WorkerModuleScriptLoader.cpp
 bindings/js/WindowProxy.cpp
 bridge/IdentifierRep.cpp
+bridge/NP_jsobject.cpp
+bridge/c/CRuntimeObject.cpp
+bridge/c/c_class.cpp
+bridge/c/c_instance.cpp
+bridge/c/c_runtime.cpp
+bridge/c/c_utility.cpp
 bridge/jsc/BridgeJSC.cpp
+bridge/npruntime.cpp
 bridge/runtime_array.cpp
 bridge/runtime_method.cpp
 bridge/runtime_object.cpp
@@ -2241,6 +2248,7 @@ platform/network/ParsedContentRange.cpp
 platform/network/ParsedContentType.cpp
 platform/network/ParsedRequestRange.cpp
 platform/network/ProtectionSpaceBase.cpp
+platform/network/ProxyServer.cpp
 platform/network/ResourceErrorBase.cpp
 platform/network/ResourceHandle.cpp
 platform/network/ResourceHandleClient.cpp
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/CMakeLists.txt webkitgtk-2.36.0/Source/WebKit/CMakeLists.txt
--- webkitgtk-2.36.0.orig/Source/WebKit/CMakeLists.txt	2022-02-23 02:59:03.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/CMakeLists.txt	2022-03-22 16:38:57.369580090 -0500
@@ -218,6 +218,10 @@ set(WebKit_MESSAGES_IN_FILES
     NetworkProcess/webrtc/NetworkRTCProvider
     NetworkProcess/webrtc/RTCDataChannelRemoteManagerProxy
 
+    PluginProcess/PluginControllerProxy
+    PluginProcess/PluginProcess
+    PluginProcess/WebProcessConnection
+
     Shared/AuxiliaryProcess
     Shared/IPCTester
     Shared/WebConnection
@@ -226,6 +230,8 @@ set(WebKit_MESSAGES_IN_FILES
 
     Shared/Notifications/NotificationManagerMessageHandler
 
+    Shared/Plugins/NPObjectMessageReceiver
+
     UIProcess/DrawingAreaProxy
 
     UIProcess/Media/RemoteMediaSessionCoordinatorProxy
@@ -253,6 +259,8 @@ set(WebKit_MESSAGES_IN_FILES
 
     UIProcess/Network/NetworkProcessProxy
 
+    UIProcess/Plugins/PluginProcessProxy
+
     UIProcess/UserContent/WebUserContentControllerProxy
 
     UIProcess/XR/PlatformXRSystem
@@ -309,6 +317,10 @@ set(WebKit_MESSAGES_IN_FILES
 
     WebProcess/Notifications/WebNotificationManager
 
+    WebProcess/Plugins/PluginProcessConnection
+    WebProcess/Plugins/PluginProcessConnectionManager
+    WebProcess/Plugins/PluginProxy
+
     WebProcess/Speech/SpeechRecognitionRealtimeMediaSourceManager
 
     WebProcess/Storage/WebSharedWorkerContextManagerConnection
@@ -660,7 +672,7 @@ else ()
 
     set_target_properties(WebKit PROPERTIES VERSION ${WEBKIT_VERSION} SOVERSION ${WEBKIT_VERSION_MAJOR})
 
-    install(TARGETS WebKit WebProcess NetworkProcess
+    install(TARGETS WebKit WebProcess NetworkProcess PluginProcess
         LIBRARY DESTINATION "${LIB_INSTALL_DIR}"
         RUNTIME DESTINATION "${LIBEXEC_INSTALL_DIR}"
     )
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/DerivedSources.make webkitgtk-2.36.0/Source/WebKit/DerivedSources.make
--- webkitgtk-2.36.0.orig/Source/WebKit/DerivedSources.make	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/DerivedSources.make	2022-03-22 16:38:57.369580090 -0500
@@ -38,6 +38,8 @@ VPATH = \
     $(WebKit2)/NetworkProcess/ServiceWorker \
     $(WebKit2)/NetworkProcess/WebStorage \
     $(WebKit2)/NetworkProcess/storage \
+    $(WebKit2)/PluginProcess \
+    $(WebKit2)/PluginProcess/mac \
     $(WebKit2)/Resources/SandboxProfiles/ios \
     $(WebKit2)/Shared/Plugins \
     $(WebKit2)/Shared \
@@ -145,6 +147,7 @@ MESSAGE_RECEIVERS = \
 	NetworkProcess/webrtc/RTCDataChannelRemoteManagerProxy \
 	NetworkProcess/Cookies/WebCookieManager \
 	NetworkProcess/storage/NetworkStorageManager \
+	Shared/Plugins/NPObjectMessageReceiver \
 	Shared/AuxiliaryProcess \
 	Shared/API/Cocoa/RemoteObjectRegistry \
 	Shared/ApplePay/WebPaymentCoordinatorProxy \
@@ -162,6 +165,7 @@ MESSAGE_RECEIVERS = \
 	UIProcess/Inspector/WebInspectorUIProxy \
 	UIProcess/Inspector/RemoteWebInspectorUIProxy \
 	UIProcess/Inspector/WebInspectorUIExtensionControllerProxy \
+	UIProcess/Plugins/PluginProcessProxy \
 	UIProcess/DrawingAreaProxy \
 	UIProcess/Network/NetworkProcessProxy \
 	UIProcess/Network/CustomProtocols/LegacyCustomProtocolManagerProxy \
@@ -214,6 +218,9 @@ MESSAGE_RECEIVERS = \
 	WebProcess/Inspector/WebInspector \
 	WebProcess/Inspector/RemoteWebInspectorUI \
 	WebProcess/MediaSession/RemoteMediaSessionCoordinator \
+	WebProcess/Plugins/PluginProcessConnectionManager \
+	WebProcess/Plugins/PluginProxy \
+	WebProcess/Plugins/PluginProcessConnection \
 	WebProcess/Network/WebSocketChannel \
 	WebProcess/Network/NetworkProcessConnection \
 	WebProcess/Network/WebSocketStream \
@@ -253,6 +260,9 @@ MESSAGE_RECEIVERS = \
 	WebProcess/WebPage/ViewUpdateDispatcher \
 	WebProcess/WebAuthentication/WebAuthnProcessConnection \
 	WebProcess/XR/PlatformXRSystemProxy \
+	PluginProcess/WebProcessConnection \
+	PluginProcess/PluginControllerProxy \
+	PluginProcess/PluginProcess \
 	GPUProcess/GPUConnectionToWebProcess \
 	GPUProcess/graphics/RemoteDisplayListRecorder \
 	GPUProcess/graphics/RemoteRenderingBackend \
@@ -350,6 +360,7 @@ endif
 
 SANDBOX_PROFILES = \
 	com.apple.WebProcess.sb \
+	com.apple.WebKit.plugin-common.sb \
 	com.apple.WebKit.NetworkProcess.sb \
 	com.apple.WebKit.GPUProcess.sb \
 	com.apple.WebKit.WebAuthnProcess.sb \
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp webkitgtk-2.36.0/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp	2022-03-22 16:38:57.369580090 -0500
@@ -30,6 +30,8 @@
 
 #include "Logging.h"
 #include "NetworkSession.h"
+#include "PluginProcessManager.h"
+#include "PluginProcessProxy.h"
 #include "PrivateClickMeasurementManager.h"
 #include "PrivateClickMeasurementManagerProxy.h"
 #include "StorageAccessStatus.h"
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp webkitgtk-2.36.0/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp	2022-03-22 16:38:57.369580090 -0500
@@ -31,6 +31,8 @@
 #include "Logging.h"
 #include "NetworkProcess.h"
 #include "NetworkSession.h"
+#include "PluginProcessManager.h"
+#include "PluginProcessProxy.h"
 #include "StorageAccessStatus.h"
 #include "WebProcessProxy.h"
 #include "WebsiteDataStore.h"
@@ -162,6 +164,12 @@ void ResourceLoadStatisticsStore::remove
         return;
     }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    m_activePluginTokens.clear();
+    for (const auto& plugin : PluginProcessManager::singleton().pluginProcesses())
+        m_activePluginTokens.add(plugin->pluginProcessToken());
+#endif
+
     auto domainsToDeleteOrRestrictWebsiteDataFor = registrableDomainsToDeleteOrRestrictWebsiteDataFor();
     if (domainsToDeleteOrRestrictWebsiteDataFor.isEmpty()) {
         completionHandler();
@@ -384,6 +392,13 @@ bool ResourceLoadStatisticsStore::should
     if (m_dataRecordsBeingRemoved)
         return false;
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    for (const auto& plugin : PluginProcessManager::singleton().pluginProcesses()) {
+        if (!m_activePluginTokens.contains(plugin->pluginProcessToken()))
+            return true;
+    }
+#endif
+
     return !m_lastTimeDataRecordsWereRemoved || MonotonicTime::now() >= (m_lastTimeDataRecordsWereRemoved + m_parameters.minimumTimeBetweenDataRecordsRemoval) || parameters().isRunningTest;
 }
 
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h webkitgtk-2.36.0/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h
--- webkitgtk-2.36.0.orig/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h	2022-03-22 16:38:57.369580090 -0500
@@ -273,6 +273,9 @@ private:
 #else
     ResourceLoadStatisticsClassifier m_resourceLoadStatisticsClassifier;
 #endif
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    HashSet<uint64_t> m_activePluginTokens;
+#endif
     Parameters m_parameters;
     WallTime m_endOfGrandfatheringTimestamp;
     RegistrableDomain m_debugManualPrevalentResource;
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp webkitgtk-2.36.0/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp	2022-03-22 16:38:57.369580090 -0500
@@ -69,6 +69,9 @@ const OptionSet<WebsiteDataType>& WebRes
         WebsiteDataType::LocalStorage,
         WebsiteDataType::MediaKeys,
         WebsiteDataType::OfflineWebApplicationCache,
+#if ENABLE(NETSCAPE_PLUGIN_API)
+        WebsiteDataType::PlugInData,
+#endif
         WebsiteDataType::SearchFieldRecentSearches,
         WebsiteDataType::SessionStorage,
 #if ENABLE(SERVICE_WORKER)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Platform/ExtraPrivateSymbolsForTAPI.h webkitgtk-2.36.0/Source/WebKit/Platform/ExtraPrivateSymbolsForTAPI.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Platform/ExtraPrivateSymbolsForTAPI.h	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Platform/ExtraPrivateSymbolsForTAPI.h	2022-03-22 16:38:57.369580090 -0500
@@ -31,6 +31,7 @@ extern "C" {
 
 // FIXME: Remove these after <rdar://problem/30772033> is fixed.
 void NetworkServiceInitializer();
+void PluginServiceInitializer();
 void WebContentServiceInitializer();
 void GPUServiceInitializer();
 void WebAuthnServiceInitializer();
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Platform/SharedMemory.h webkitgtk-2.36.0/Source/WebKit/Platform/SharedMemory.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Platform/SharedMemory.h	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Platform/SharedMemory.h	2022-03-22 16:38:57.373580110 -0500
@@ -56,6 +56,7 @@ class MachSendRight;
 
 namespace WebKit {
 
+#undef None
 enum class MemoryLedger { None, Default, Network, Media, Graphics, Neural };
 
 class SharedMemory : public ThreadSafeRefCounted<SharedMemory> {
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PlatformGTK.cmake webkitgtk-2.36.0/Source/WebKit/PlatformGTK.cmake
--- webkitgtk-2.36.0.orig/Source/WebKit/PlatformGTK.cmake	2022-03-22 16:34:52.864289238 -0500
+++ webkitgtk-2.36.0/Source/WebKit/PlatformGTK.cmake	2022-03-22 16:38:57.373580110 -0500
@@ -4,6 +4,7 @@ set(WebKit_OUTPUT_NAME webkit2gtk-${WEBK
 set(WebProcess_OUTPUT_NAME WebKitWebProcess)
 set(NetworkProcess_OUTPUT_NAME WebKitNetworkProcess)
 set(GPUProcess_OUTPUT_NAME WebKitGPUProcess)
+set(PluginProcess_OUTPUT_NAME WebKitPluginProcess)
 
 file(MAKE_DIRECTORY ${WebKit2Gtk_DERIVED_SOURCES_DIR}/webkit)
 file(MAKE_DIRECTORY ${WebKit2Gtk_FRAMEWORK_HEADERS_DIR})
@@ -422,6 +423,7 @@ list(APPEND WebKit_INCLUDE_DIRECTORIES
     "${WEBKIT_DIR}/Shared/API/glib"
     "${WEBKIT_DIR}/Shared/CoordinatedGraphics"
     "${WEBKIT_DIR}/Shared/CoordinatedGraphics/threadedcompositor"
+    "${WEBKIT_DIR}/Shared/Plugins/unix"
     "${WEBKIT_DIR}/Shared/glib"
     "${WEBKIT_DIR}/Shared/gtk"
     "${WEBKIT_DIR}/Shared/linux"
@@ -435,6 +437,9 @@ list(APPEND WebKit_INCLUDE_DIRECTORIES
     "${WEBKIT_DIR}/UIProcess/CoordinatedGraphics"
     "${WEBKIT_DIR}/UIProcess/Inspector/glib"
     "${WEBKIT_DIR}/UIProcess/Inspector/gtk"
+    "${WEBKIT_DIR}/WebProcess/Plugins/Netscape/unix"
+    "${WEBKIT_DIR}/WebProcess/Plugins/Netscape/x11"
+    "${WEBKIT_DIR}/UIProcess/Plugins/gtk"
     "${WEBKIT_DIR}/UIProcess/geoclue"
     "${WEBKIT_DIR}/UIProcess/glib"
     "${WEBKIT_DIR}/UIProcess/gstreamer"
@@ -620,6 +625,11 @@ if (ENABLE_WAYLAND_TARGET)
     )
 endif ()
 
+# GTK3 PluginProcess
+list(APPEND PluginProcess_SOURCES
+    PluginProcess/EntryPoint/unix/PluginProcessMain.cpp
+)
+
 # Commands for building the built-in injected bundle.
 add_library(webkit2gtkinjectedbundle MODULE "${WEBKIT_DIR}/WebProcess/InjectedBundle/API/glib/WebKitInjectedBundleMain.cpp")
 ADD_WEBKIT_PREFIX_HEADER(webkit2gtkinjectedbundle)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginControllerProxy.cpp webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginControllerProxy.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginControllerProxy.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginControllerProxy.cpp	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,675 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginControllerProxy.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NPObjectProxy.h"
+#include "NPRemoteObjectMap.h"
+#include "NPRuntimeUtilities.h"
+#include "NPVariantData.h"
+#include "NetscapePlugin.h"
+#include "PluginCreationParameters.h"
+#include "PluginProcess.h"
+#include "PluginProxyMessages.h"
+#include "ShareableBitmap.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebProcessConnection.h"
+#include "WebProcessConnectionMessages.h"
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/HTTPHeaderMap.h>
+#include <WebCore/IdentifierRep.h>
+#include <WebCore/NotImplemented.h>
+#include <wtf/SetForScope.h>
+#include <wtf/text/WTFString.h>
+
+#if PLATFORM(COCOA)
+#include "LayerHostingContext.h"
+#endif
+
+namespace WebKit {
+using namespace WebCore;
+
+PluginControllerProxy::PluginControllerProxy(WebProcessConnection* connection, const PluginCreationParameters& creationParameters)
+    : m_connection(connection)
+    , m_pluginInstanceID(creationParameters.pluginInstanceID)
+    , m_userAgent(creationParameters.userAgent)
+    , m_isPrivateBrowsingEnabled(creationParameters.isPrivateBrowsingEnabled)
+    , m_isMuted(creationParameters.isMuted)
+    , m_isAcceleratedCompositingEnabled(creationParameters.isAcceleratedCompositingEnabled)
+    , m_isInitializing(false)
+    , m_isVisible(false)
+    , m_isWindowVisible(false)
+    , m_paintTimer(RunLoop::main(), this, &PluginControllerProxy::paint)
+    , m_pluginDestructionProtectCount(0)
+    , m_pluginDestroyTimer(RunLoop::main(), this, &PluginControllerProxy::destroy)
+    , m_waitingForDidUpdate(false)
+    , m_pluginCanceledManualStreamLoad(false)
+#if PLATFORM(COCOA)
+    , m_isComplexTextInputEnabled(false)
+#endif
+    , m_contentsScaleFactor(creationParameters.contentsScaleFactor)
+    , m_windowNPObject(0)
+    , m_pluginElementNPObject(0)
+    , m_visiblityActivity("Plugin is visible.")
+{
+}
+
+PluginControllerProxy::~PluginControllerProxy()
+{
+    ASSERT(!m_plugin);
+
+    if (m_windowNPObject)
+        releaseNPObject(m_windowNPObject);
+
+    if (m_pluginElementNPObject)
+        releaseNPObject(m_pluginElementNPObject);
+}
+
+void PluginControllerProxy::setInitializationReply(Messages::WebProcessConnection::CreatePlugin::DelayedReply&& reply)
+{
+    ASSERT(!m_initializationReply);
+    m_initializationReply = WTFMove(reply);
+}
+
+Messages::WebProcessConnection::CreatePlugin::DelayedReply PluginControllerProxy::takeInitializationReply()
+{
+    return std::exchange(m_initializationReply, nullptr);
+}
+
+bool PluginControllerProxy::initialize(const PluginCreationParameters& creationParameters)
+{
+    ASSERT(!m_plugin);
+
+    ASSERT(!m_isInitializing);
+    m_isInitializing = true; // Cannot use SetForScope here, because this object can be deleted before the function returns.
+
+    m_plugin = NetscapePlugin::create(PluginProcess::singleton().netscapePluginModule());
+    if (!m_plugin) {
+        // This will delete the plug-in controller proxy object.
+        m_connection->removePluginControllerProxy(this, 0);
+        return false;
+    }
+
+    if (creationParameters.windowNPObjectID)
+        m_windowNPObject = m_connection->npRemoteObjectMap()->createNPObjectProxy(creationParameters.windowNPObjectID, m_plugin.get());
+
+    bool returnValue = m_plugin->initialize(*this, creationParameters.parameters);
+
+    if (!returnValue) {
+        // Get the plug-in so we can pass it to removePluginControllerProxy. The pointer is only
+        // used as an identifier so it's OK to just get a weak reference.
+        Plugin* plugin = m_plugin.get();
+        
+        m_plugin = nullptr;
+
+        // This will delete the plug-in controller proxy object.
+        m_connection->removePluginControllerProxy(this, plugin);
+        return false;
+    }
+
+    platformInitialize(creationParameters);
+
+    m_isInitializing = false;
+    return true;
+}
+
+void PluginControllerProxy::destroy()
+{
+    ASSERT(m_plugin);
+
+    // FIXME: Consider removing m_pluginDestructionProtectCount and always use inSendSync here.
+    if (m_pluginDestructionProtectCount || m_connection->connection()->inSendSync()) {
+        // We have plug-in code on the stack so we can't destroy it right now.
+        // Destroy it later.
+        m_pluginDestroyTimer.startOneShot(0_s);
+        return;
+    }
+
+    // Get the plug-in so we can pass it to removePluginControllerProxy. The pointer is only
+    // used as an identifier so it's OK to just get a weak reference.
+    Plugin* plugin = m_plugin.get();
+
+    m_plugin->destroyPlugin();
+    m_plugin = nullptr;
+
+    platformDestroy();
+
+    // This will delete the plug-in controller proxy object.
+    m_connection->removePluginControllerProxy(this, plugin);
+}
+
+bool PluginControllerProxy::wantsWheelEvents() const
+{
+    return m_plugin->wantsWheelEvents();
+}
+
+void PluginControllerProxy::paint()
+{
+    ASSERT(!m_dirtyRect.isEmpty());
+    m_paintTimer.stop();
+
+    if (!m_backingStore)
+        return;
+
+    IntRect dirtyRect = m_dirtyRect;
+    m_dirtyRect = IntRect();
+
+    ASSERT(m_plugin);
+
+    // Create a graphics context.
+    auto graphicsContext = m_backingStore->createGraphicsContext();
+    if (!graphicsContext)
+        return;
+
+#if PLATFORM(COCOA)
+    // FIXME: We should really call applyDeviceScaleFactor instead of scale, but that ends up calling into WKSI
+    // which we currently don't have initiated in the plug-in process.
+    graphicsContext->scale(m_contentsScaleFactor);
+#endif
+
+    if (m_plugin->isTransparent())
+        graphicsContext->clearRect(dirtyRect);
+
+    m_plugin->paint(*graphicsContext, dirtyRect);
+
+    m_connection->connection()->send(Messages::PluginProxy::Update(dirtyRect), m_pluginInstanceID);
+}
+
+void PluginControllerProxy::startPaintTimer()
+{
+    // Check if we should start the timer.
+    
+    if (m_dirtyRect.isEmpty())
+        return;
+
+    // FIXME: Check clip rect.
+    
+    if (m_paintTimer.isActive())
+        return;
+
+    if (m_waitingForDidUpdate)
+        return;
+
+    // Start the timer.
+    m_paintTimer.startOneShot(0_s);
+
+    m_waitingForDidUpdate = true;
+}
+
+void PluginControllerProxy::invalidate(const IntRect& rect)
+{
+    IntRect dirtyRect = rect;
+
+    // Make sure that the dirty rect is not greater than the plug-in itself.
+    dirtyRect.intersect(IntRect(IntPoint(), m_pluginSize));
+    m_dirtyRect.unite(dirtyRect);
+
+    startPaintTimer();
+}
+
+String PluginControllerProxy::userAgent()
+{
+    return m_userAgent;
+}
+
+void PluginControllerProxy::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups)
+{
+    m_connection->connection()->send(Messages::PluginProxy::LoadURL(requestID, method, urlString, target, headerFields, httpBody, allowPopups), m_pluginInstanceID);
+}
+
+void PluginControllerProxy::continueStreamLoad(uint64_t streamID)
+{
+    m_connection->connection()->send(Messages::PluginProxy::ContinueStreamLoad(streamID), m_pluginInstanceID);
+}
+
+void PluginControllerProxy::cancelStreamLoad(uint64_t streamID)
+{
+    m_connection->connection()->send(Messages::PluginProxy::CancelStreamLoad(streamID), m_pluginInstanceID);
+}
+
+void PluginControllerProxy::cancelManualStreamLoad()
+{
+    m_pluginCanceledManualStreamLoad = true;
+
+    m_connection->connection()->send(Messages::PluginProxy::CancelManualStreamLoad(), m_pluginInstanceID);
+}
+
+NPObject* PluginControllerProxy::windowScriptNPObject()
+{
+    if (!m_windowNPObject)
+        return 0;
+
+    retainNPObject(m_windowNPObject);
+    return m_windowNPObject;
+}
+
+NPObject* PluginControllerProxy::pluginElementNPObject()
+{
+    if (!m_pluginElementNPObject) {
+        uint64_t pluginElementNPObjectID = 0;
+
+        if (!m_connection->connection()->sendSync(Messages::PluginProxy::GetPluginElementNPObject(), Messages::PluginProxy::GetPluginElementNPObject::Reply(pluginElementNPObjectID), m_pluginInstanceID))
+            return 0;
+
+        if (!pluginElementNPObjectID)
+            return 0;
+
+        m_pluginElementNPObject = m_connection->npRemoteObjectMap()->createNPObjectProxy(pluginElementNPObjectID, m_plugin.get());
+        ASSERT(m_pluginElementNPObject);
+    }
+
+    retainNPObject(m_pluginElementNPObject);
+    return m_pluginElementNPObject;
+}
+
+bool PluginControllerProxy::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result, bool allowPopups)
+{
+    PluginDestructionProtector protector(this);
+
+    NPVariant npObjectAsNPVariant;
+    OBJECT_TO_NPVARIANT(npObject, npObjectAsNPVariant);
+
+    // Send the NPObject over as an NPVariantData.
+    NPVariantData npObjectAsNPVariantData = m_connection->npRemoteObjectMap()->npVariantToNPVariantData(npObjectAsNPVariant, m_plugin.get());
+
+    bool returnValue = false;
+    NPVariantData resultData;
+
+    if (!m_connection->connection()->sendSync(Messages::PluginProxy::Evaluate(npObjectAsNPVariantData, scriptString, allowPopups), Messages::PluginProxy::Evaluate::Reply(returnValue, resultData), m_pluginInstanceID))
+        return false;
+
+    if (!returnValue)
+        return false;
+
+    *result = m_connection->npRemoteObjectMap()->npVariantDataToNPVariant(resultData, m_plugin.get());
+    return true;
+}
+
+void PluginControllerProxy::setPluginIsPlayingAudio(bool pluginIsPlayingAudio)
+{
+    m_connection->connection()->send(Messages::PluginProxy::SetPluginIsPlayingAudio(pluginIsPlayingAudio), m_pluginInstanceID);
+}
+
+void PluginControllerProxy::setStatusbarText(const String& statusbarText)
+{
+    m_connection->connection()->send(Messages::PluginProxy::SetStatusbarText(statusbarText), m_pluginInstanceID);
+}
+
+bool PluginControllerProxy::isAcceleratedCompositingEnabled()
+{
+    return m_isAcceleratedCompositingEnabled;
+}
+
+void PluginControllerProxy::pluginProcessCrashed()
+{
+    // This should never be called from here.
+    ASSERT_NOT_REACHED();
+}
+
+void PluginControllerProxy::didInitializePlugin()
+{
+    // This should only be called on the plugin in the web process.
+    ASSERT_NOT_REACHED();
+}
+
+void PluginControllerProxy::didFailToInitializePlugin()
+{
+    // This should only be called on the plugin in the web process.
+    ASSERT_NOT_REACHED();
+}
+
+float PluginControllerProxy::contentsScaleFactor()
+{
+    return m_contentsScaleFactor;
+}
+
+String PluginControllerProxy::proxiesForURL(const String& urlString)
+{
+    String proxyString;
+
+    if (!m_connection->connection()->sendSync(Messages::PluginProxy::ProxiesForURL(urlString), Messages::PluginProxy::ProxiesForURL::Reply(proxyString), m_pluginInstanceID))
+        return String();
+
+    return proxyString;
+}
+
+String PluginControllerProxy::cookiesForURL(const String& urlString)
+{
+    String cookieString;
+
+    if (!m_connection->connection()->sendSync(Messages::PluginProxy::CookiesForURL(urlString), Messages::PluginProxy::CookiesForURL::Reply(cookieString), m_pluginInstanceID))
+        return String();
+
+    return cookieString;
+}
+
+void PluginControllerProxy::setCookiesForURL(const String& urlString, const String& cookieString)
+{
+    m_connection->connection()->send(Messages::PluginProxy::SetCookiesForURL(urlString, cookieString), m_pluginInstanceID);
+}
+
+bool PluginControllerProxy::isPrivateBrowsingEnabled()
+{
+    return m_isPrivateBrowsingEnabled;
+}
+
+bool PluginControllerProxy::getAuthenticationInfo(const ProtectionSpace& protectionSpace, String& username, String& password)
+{
+    bool returnValue;
+    if (!m_connection->connection()->sendSync(Messages::PluginProxy::GetAuthenticationInfo(protectionSpace), Messages::PluginProxy::GetAuthenticationInfo::Reply(returnValue, username, password), m_pluginInstanceID))
+        return false;
+
+    return returnValue;
+}
+
+void PluginControllerProxy::protectPluginFromDestruction()
+{
+    m_pluginDestructionProtectCount++;
+}
+
+void PluginControllerProxy::unprotectPluginFromDestruction()
+{
+    ASSERT(m_pluginDestructionProtectCount);
+
+    m_pluginDestructionProtectCount--;
+}
+
+void PluginControllerProxy::frameDidFinishLoading(uint64_t requestID)
+{
+    m_plugin->frameDidFinishLoading(requestID);
+}
+
+void PluginControllerProxy::frameDidFail(uint64_t requestID, bool wasCancelled)
+{
+    m_plugin->frameDidFail(requestID, wasCancelled);
+}
+
+void PluginControllerProxy::geometryDidChange(const IntSize& pluginSize, const IntRect& clipRect, const AffineTransform& pluginToRootViewTransform, float contentsScaleFactor, const ShareableBitmap::Handle& backingStoreHandle)
+{
+    ASSERT(m_plugin);
+
+    m_pluginSize = pluginSize;
+
+    if (contentsScaleFactor != m_contentsScaleFactor) {
+        m_contentsScaleFactor = contentsScaleFactor;
+        m_plugin->contentsScaleFactorChanged(m_contentsScaleFactor);
+    }
+
+    platformGeometryDidChange();
+
+    if (!backingStoreHandle.isNull()) {
+        // Create a new backing store.
+        m_backingStore = ShareableBitmap::create(backingStoreHandle);
+    }
+
+    m_plugin->geometryDidChange(pluginSize, clipRect, pluginToRootViewTransform);
+}
+
+void PluginControllerProxy::visibilityDidChange(bool isVisible)
+{
+    m_isVisible = isVisible;
+    
+    ASSERT(m_plugin);
+    m_plugin->visibilityDidChange(isVisible);
+
+    updateVisibilityActivity();
+}
+
+void PluginControllerProxy::windowFocusChanged(bool hasFocus)
+{
+    ASSERT(m_plugin);
+    m_plugin->windowFocusChanged(hasFocus);
+}
+
+void PluginControllerProxy::windowVisibilityChanged(bool isVisible)
+{
+    m_isWindowVisible = isVisible;
+
+    ASSERT(m_plugin);
+    m_plugin->windowVisibilityChanged(isVisible);
+
+    updateVisibilityActivity();
+}
+
+void PluginControllerProxy::updateVisibilityActivity()
+{
+    if (m_isVisible && m_isWindowVisible)
+        m_visiblityActivity.start();
+    else
+        m_visiblityActivity.stop();
+}
+
+void PluginControllerProxy::didEvaluateJavaScript(uint64_t requestID, const String& result)
+{
+    m_plugin->didEvaluateJavaScript(requestID, result);
+}
+
+void PluginControllerProxy::streamWillSendRequest(uint64_t streamID, const String& requestURLString, const String& redirectResponseURLString, uint32_t redirectResponseStatusCode)
+{
+    m_plugin->streamWillSendRequest(streamID, URL({ }, requestURLString), URL({ }, redirectResponseURLString), redirectResponseStatusCode);
+}
+
+void PluginControllerProxy::streamDidReceiveResponse(uint64_t streamID, const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers)
+{
+    m_plugin->streamDidReceiveResponse(streamID, URL({ }, responseURLString), streamLength, lastModifiedTime, mimeType, headers, String());
+}
+
+void PluginControllerProxy::streamDidReceiveData(uint64_t streamID, const IPC::DataReference& data)
+{
+    m_plugin->streamDidReceiveData(streamID, SharedBuffer::create(data.data(), data.size()));
+}
+
+void PluginControllerProxy::streamDidFinishLoading(uint64_t streamID)
+{
+    m_plugin->streamDidFinishLoading(streamID);
+}
+
+void PluginControllerProxy::streamDidFail(uint64_t streamID, bool wasCancelled)
+{
+    m_plugin->streamDidFail(streamID, wasCancelled);
+}
+
+void PluginControllerProxy::manualStreamDidReceiveResponse(const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers)
+{
+    if (m_pluginCanceledManualStreamLoad)
+        return;
+
+    m_plugin->manualStreamDidReceiveResponse(URL({ }, responseURLString), streamLength, lastModifiedTime, mimeType, headers, String());
+}
+
+void PluginControllerProxy::manualStreamDidReceiveData(const IPC::DataReference& data)
+{
+    if (m_pluginCanceledManualStreamLoad)
+        return;
+
+    m_plugin->manualStreamDidReceiveData(SharedBuffer::create(data.data(), data.size()));
+}
+
+void PluginControllerProxy::manualStreamDidFinishLoading()
+{
+    if (m_pluginCanceledManualStreamLoad)
+        return;
+    
+    m_plugin->manualStreamDidFinishLoading();
+}
+
+void PluginControllerProxy::manualStreamDidFail(bool wasCancelled)
+{
+    if (m_pluginCanceledManualStreamLoad)
+        return;
+    
+    m_plugin->manualStreamDidFail(wasCancelled);
+}
+
+void PluginControllerProxy::handleMouseEvent(const WebMouseEvent& mouseEvent)
+{
+    m_plugin->handleMouseEvent(mouseEvent);
+}
+
+void PluginControllerProxy::handleWheelEvent(const WebWheelEvent& wheelEvent, CompletionHandler<void(bool)>&& completionHandler)
+{
+    completionHandler(m_plugin->handleWheelEvent(wheelEvent));
+}
+
+void PluginControllerProxy::handleMouseEnterEvent(const WebMouseEvent& mouseEnterEvent, CompletionHandler<void(bool)>&& completionHandler)
+{
+    completionHandler(m_plugin->handleMouseEnterEvent(mouseEnterEvent));
+}
+
+void PluginControllerProxy::handleMouseLeaveEvent(const WebMouseEvent& mouseLeaveEvent, CompletionHandler<void(bool)>&& completionHandler)
+{
+    completionHandler(m_plugin->handleMouseLeaveEvent(mouseLeaveEvent));
+}
+
+void PluginControllerProxy::handleKeyboardEvent(const WebKeyboardEvent& keyboardEvent, CompletionHandler<void(bool)>&& completionHandler)
+{
+    completionHandler(m_plugin->handleKeyboardEvent(keyboardEvent));
+}
+
+void PluginControllerProxy::handleEditingCommand(const String& commandName, const String& argument, CompletionHandler<void(bool)>&& completionHandler)
+{
+    completionHandler(m_plugin->handleEditingCommand(commandName, argument));
+}
+    
+void PluginControllerProxy::isEditingCommandEnabled(const String& commandName, CompletionHandler<void(bool)>&& completionHandler)
+{
+    completionHandler(m_plugin->isEditingCommandEnabled(commandName));
+}
+    
+void PluginControllerProxy::handlesPageScaleFactor(CompletionHandler<void(bool)>&& completionHandler)
+{
+    completionHandler(m_plugin->handlesPageScaleFactor());
+}
+
+void PluginControllerProxy::requiresUnifiedScaleFactor(CompletionHandler<void(bool)>&& completionHandler)
+{
+    completionHandler(m_plugin->requiresUnifiedScaleFactor());
+}
+
+void PluginControllerProxy::paintEntirePlugin(CompletionHandler<void()>&& completionHandler)
+{
+    if (m_pluginSize.isEmpty())
+        return completionHandler();
+
+    m_dirtyRect = IntRect(IntPoint(), m_pluginSize);
+    paint();
+    completionHandler();
+}
+
+void PluginControllerProxy::supportsSnapshotting(CompletionHandler<void(bool)>&& completionHandler)
+{
+    completionHandler(m_plugin->supportsSnapshotting());
+}
+
+void PluginControllerProxy::snapshot(CompletionHandler<void(ShareableBitmap::Handle&&)> completionHandler)
+{
+    ASSERT(m_plugin);
+    RefPtr<ShareableBitmap> bitmap = m_plugin->snapshot();
+    if (!bitmap)
+        return completionHandler({ });
+
+    ShareableBitmap::Handle backingStoreHandle;
+    bitmap->createHandle(backingStoreHandle);
+    completionHandler(WTFMove(backingStoreHandle));
+}
+
+void PluginControllerProxy::setFocus(bool hasFocus)
+{
+    m_plugin->setFocus(hasFocus);
+}
+
+void PluginControllerProxy::didUpdate()
+{
+    m_waitingForDidUpdate = false;
+    startPaintTimer();
+}
+
+void PluginControllerProxy::getPluginScriptableNPObject(CompletionHandler<void(uint64_t)>&& completionHandler)
+{
+    NPObject* pluginScriptableNPObject = m_plugin->pluginScriptableNPObject();
+    if (!pluginScriptableNPObject)
+        return completionHandler(0);
+    
+    uint64_t pluginScriptableNPObjectID = m_connection->npRemoteObjectMap()->registerNPObject(pluginScriptableNPObject, m_plugin.get());
+    releaseNPObject(pluginScriptableNPObject);
+    completionHandler(pluginScriptableNPObjectID);
+}
+
+void PluginControllerProxy::storageBlockingStateChanged(bool isStorageBlockingEnabled)
+{
+    if (m_storageBlockingEnabled != isStorageBlockingEnabled) {
+        m_storageBlockingEnabled = isStorageBlockingEnabled;
+        m_plugin->storageBlockingStateChanged(m_storageBlockingEnabled);
+    }
+}
+
+void PluginControllerProxy::privateBrowsingStateChanged(bool isPrivateBrowsingEnabled)
+{
+    m_isPrivateBrowsingEnabled = isPrivateBrowsingEnabled;
+
+    m_plugin->privateBrowsingStateChanged(isPrivateBrowsingEnabled);
+}
+
+void PluginControllerProxy::mutedStateChanged(bool isMuted)
+{
+    if (m_isMuted == isMuted)
+        return;
+    
+    m_isMuted = isMuted;
+    m_plugin->mutedStateChanged(isMuted);
+}
+
+void PluginControllerProxy::getFormValue(CompletionHandler<void(bool, String&&)>&& completionHandler)
+{
+    String formValue;
+    bool returnValue = m_plugin->getFormValue(formValue);
+    completionHandler(returnValue, WTFMove(formValue));
+}
+
+#if PLATFORM(X11)
+uint64_t PluginControllerProxy::createPluginContainer()
+{
+    uint64_t windowID = 0;
+    m_connection->connection()->sendSync(Messages::PluginProxy::CreatePluginContainer(), Messages::PluginProxy::CreatePluginContainer::Reply(windowID), m_pluginInstanceID);
+    return windowID;
+}
+
+void PluginControllerProxy::windowedPluginGeometryDidChange(const IntRect& frameRect, const IntRect& clipRect, uint64_t windowID)
+{
+    m_connection->connection()->send(Messages::PluginProxy::WindowedPluginGeometryDidChange(frameRect, clipRect, windowID), m_pluginInstanceID);
+}
+
+void PluginControllerProxy::windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID)
+{
+    m_connection->connection()->send(Messages::PluginProxy::WindowedPluginVisibilityDidChange(isVisible, windowID), m_pluginInstanceID);
+}
+#endif
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginControllerProxy.h webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginControllerProxy.h
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginControllerProxy.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginControllerProxy.h	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "Connection.h"
+#include "DataReference.h"
+#include "Plugin.h"
+#include "PluginController.h"
+#include "ShareableBitmap.h"
+#include "WebProcessConnectionMessagesReplies.h"
+#include <WebCore/SecurityOrigin.h>
+#include <WebCore/UserActivity.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/RunLoop.h>
+
+namespace WebKit {
+
+class LayerHostingContext;
+class ShareableBitmap;
+class WebProcessConnection;
+struct PluginCreationParameters;
+
+class PluginControllerProxy : public PluginController {
+    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_NONCOPYABLE(PluginControllerProxy);
+
+public:
+    PluginControllerProxy(WebProcessConnection*, const PluginCreationParameters&);
+    ~PluginControllerProxy();
+
+    uint64_t pluginInstanceID() const { return m_pluginInstanceID; }
+
+    bool initialize(const PluginCreationParameters&);
+    void destroy();
+
+    void didReceivePluginControllerProxyMessage(IPC::Connection&, IPC::Decoder&);
+    bool didReceiveSyncPluginControllerProxyMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&);
+
+    bool wantsWheelEvents() const;
+
+#if PLATFORM(COCOA)
+    uint32_t remoteLayerClientID() const;
+#endif
+
+    PluginController* asPluginController() { return this; }
+
+    bool isInitializing() const { return m_isInitializing; }
+    
+    void setInitializationReply(Messages::WebProcessConnection::CreatePluginDelayedReply&&);
+    Messages::WebProcessConnection::CreatePluginDelayedReply takeInitializationReply();
+
+private:
+    void startPaintTimer();
+    void paint();
+
+    // PluginController
+    void invalidate(const WebCore::IntRect&) override;
+    String userAgent() override;
+    void loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const WebCore::HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups) override;
+    void continueStreamLoad(uint64_t streamID) override;
+    void cancelStreamLoad(uint64_t streamID) override;
+    void cancelManualStreamLoad() override;
+    NPObject* windowScriptNPObject() override;
+    NPObject* pluginElementNPObject() override;
+    bool evaluate(NPObject*, const String& scriptString, NPVariant* result, bool allowPopups) override;
+    void setPluginIsPlayingAudio(bool) override;
+    void setStatusbarText(const String&) override;
+    bool isAcceleratedCompositingEnabled() override;
+    void pluginProcessCrashed() override;
+    void didInitializePlugin() override;
+    void didFailToInitializePlugin() override;
+
+#if PLATFORM(COCOA)
+    void pluginFocusOrWindowFocusChanged(bool) override;
+    void setComplexTextInputState(PluginComplexTextInputState) override;
+    const WTF::MachSendRight& compositingRenderServerPort() override;
+#endif
+
+    float contentsScaleFactor() override;
+    String proxiesForURL(const String&) override;
+    String cookiesForURL(const String&) override;
+    void setCookiesForURL(const String& urlString, const String& cookieString) override;
+    bool isPrivateBrowsingEnabled() override;
+    bool isMuted() const override { return m_isMuted; }
+    bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password) override;
+    void protectPluginFromDestruction() override;
+    void unprotectPluginFromDestruction() override;
+#if PLATFORM(X11)
+    uint64_t createPluginContainer() override;
+    void windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID) override;
+    void windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID) override;
+#endif
+    
+    // Message handlers.
+    void frameDidFinishLoading(uint64_t requestID);
+    void frameDidFail(uint64_t requestID, bool wasCancelled);
+    void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform, float contentsScaleFactor, const ShareableBitmap::Handle& backingStoreHandle);
+    void visibilityDidChange(bool isVisible);
+    void didEvaluateJavaScript(uint64_t requestID, const String& result);
+    void streamWillSendRequest(uint64_t streamID, const String& requestURLString, const String& redirectResponseURLString, uint32_t redirectResponseStatusCode);
+    void streamDidReceiveResponse(uint64_t streamID, const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers);
+    void streamDidReceiveData(uint64_t streamID, const IPC::DataReference& data);
+    void streamDidFinishLoading(uint64_t streamID);
+    void streamDidFail(uint64_t streamID, bool wasCancelled);
+    void manualStreamDidReceiveResponse(const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers);
+    void manualStreamDidReceiveData(const IPC::DataReference& data);
+    void manualStreamDidFinishLoading();
+    void manualStreamDidFail(bool wasCancelled);
+    void handleMouseEvent(const WebMouseEvent&);
+    void handleWheelEvent(const WebWheelEvent&, CompletionHandler<void(bool handled)>&&);
+    void handleMouseEnterEvent(const WebMouseEvent&, CompletionHandler<void(bool handled)>&&);
+    void handleMouseLeaveEvent(const WebMouseEvent&, CompletionHandler<void(bool handled)>&&);
+    void handleKeyboardEvent(const WebKeyboardEvent&, CompletionHandler<void(bool handled)>&&);
+    void handleEditingCommand(const String&, const String&, CompletionHandler<void(bool handled)>&&);
+    void isEditingCommandEnabled(const String&, CompletionHandler<void(bool)>&&);
+    void handlesPageScaleFactor(CompletionHandler<void(bool)>&&);
+    void requiresUnifiedScaleFactor(CompletionHandler<void(bool)>&&);
+    void paintEntirePlugin(CompletionHandler<void()>&&);
+    void supportsSnapshotting(CompletionHandler<void(bool)>&&);
+    void snapshot(CompletionHandler<void(ShareableBitmap::Handle&&)>);
+    void setFocus(bool);
+    void didUpdate();
+    void getPluginScriptableNPObject(CompletionHandler<void(uint64_t pluginScriptableNPObjectID)>&&);
+
+    void windowFocusChanged(bool);
+    void windowVisibilityChanged(bool);
+    void updateVisibilityActivity();
+
+#if PLATFORM(COCOA)
+    void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates);
+    void sendComplexTextInput(const String& textInput);
+    void setLayerHostingMode(uint32_t);
+
+    void updateLayerHostingContext(LayerHostingMode);
+#endif
+
+    void storageBlockingStateChanged(bool);
+    void privateBrowsingStateChanged(bool);
+    void mutedStateChanged(bool);
+    void getFormValue(CompletionHandler<void(bool returnValue, String&& formValue)>&&);
+
+    void platformInitialize(const PluginCreationParameters&);
+    void platformDestroy();
+    void platformGeometryDidChange();
+
+    WebProcessConnection* m_connection;
+    uint64_t m_pluginInstanceID;
+
+    String m_userAgent;
+    bool m_storageBlockingEnabled;
+    bool m_isPrivateBrowsingEnabled;
+    bool m_isMuted;
+    bool m_isAcceleratedCompositingEnabled;
+    bool m_isInitializing;
+    bool m_isVisible;
+    bool m_isWindowVisible;
+
+    Messages::WebProcessConnection::CreatePluginDelayedReply m_initializationReply;
+
+    RefPtr<Plugin> m_plugin;
+
+    WebCore::IntSize m_pluginSize;
+
+    // The dirty rect in plug-in coordinates.
+    WebCore::IntRect m_dirtyRect;
+
+    // The paint timer, used for coalescing painting.
+    RunLoop::Timer<PluginControllerProxy> m_paintTimer;
+    
+    // A counter used to prevent the plug-in from being destroyed.
+    unsigned m_pluginDestructionProtectCount;
+
+    // A timer that we use to prevent destruction of the plug-in while plug-in
+    // code is on the stack.
+    RunLoop::Timer<PluginControllerProxy> m_pluginDestroyTimer;
+
+    // Whether we're waiting for the plug-in proxy in the web process to draw the contents of its
+    // backing store into the web process backing store.
+    bool m_waitingForDidUpdate;
+
+    // Whether the plug-in has canceled the manual stream load.
+    bool m_pluginCanceledManualStreamLoad;
+
+#if PLATFORM(COCOA)
+    // Whether complex text input is enabled for this plug-in.
+    bool m_isComplexTextInputEnabled;
+
+    // For CA plug-ins, this holds the information needed to export the layer hierarchy to the UI process.
+    std::unique_ptr<LayerHostingContext> m_layerHostingContext;
+#endif
+
+    // The contents scale factor of this plug-in.
+    float m_contentsScaleFactor;
+    
+    // The backing store that this plug-in draws into.
+    RefPtr<ShareableBitmap> m_backingStore;
+
+    // The window NPObject.
+    NPObject* m_windowNPObject;
+
+    // The plug-in element NPObject.
+    NPObject* m_pluginElementNPObject;
+
+    // Hold an activity when the plugin is visible to prevent throttling.
+    UserActivity m_visiblityActivity;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginControllerProxy.messages.in webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginControllerProxy.messages.in
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginControllerProxy.messages.in	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginControllerProxy.messages.in	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,143 @@
+# Copyright (C) 2010 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+messages -> PluginControllerProxy LegacyReceiver NotRefCounted {
+    # Sent when the plug-in geometry changes.
+    GeometryDidChange(WebCore::IntSize pluginSize, WebCore::IntRect clipRect, WebCore::AffineTransform pluginToRootViewTransform, float scaleFactor, WebKit::ShareableBitmap::Handle backingStoreHandle)
+
+    # Sent when the plug-in visibility changes.
+    VisibilityDidChange(bool isVisible)
+
+    # Sent when a frame has finished loading.
+    FrameDidFinishLoading(uint64_t requestID)
+
+    # Sent when a frame dfailed to load.
+    FrameDidFail(uint64_t requestID, bool wasCancelled)
+
+    # Sent when JavaScript that the plug-in asked to be evaluated has been evaluated.
+    DidEvaluateJavaScript(uint64_t requestID, String result)
+
+    # Sent when the plug-in receives will send a request for a stream.
+    StreamWillSendRequest(uint64_t streamID, String requestURLString, String redirectResponseURLString, uint32_t redirectResponseStatusCode)
+
+    # Sent when the plug-in receives a response for a stream.
+    StreamDidReceiveResponse(uint64_t streamID, String responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, String mimeType, String headers)
+
+    # Sent when the plug-in receives data for a stream.
+    StreamDidReceiveData(uint64_t streamID, IPC::DataReference data)
+
+    # Sent when a plug-in stream has finishes loading.
+    StreamDidFinishLoading(uint64_t streamID)
+
+    # Sent when a plug-in stream has failed to load.
+    StreamDidFail(uint64_t streamID, bool wasCancelled)
+
+    # Sent when the plug-in receives a response for the manual stream.
+    ManualStreamDidReceiveResponse(String responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, String mimeType, String headers)
+
+    # Sent when the plug-in receives data for the manual stream.
+    ManualStreamDidReceiveData(IPC::DataReference data)
+
+    # Sent when the plug-in manual stream has finishes loading.
+    ManualStreamDidFinishLoading()
+
+    # Sent when the plug-in manual stream has failed to load.
+    ManualStreamDidFail(bool wasCancelled)
+
+    # Sent when a mouse event (that isn't a mouse enter/leave event or a wheel event) should be processed.
+    HandleMouseEvent(WebKit::WebMouseEvent mouseEvent)
+    
+    # Sent when a mouse wheel event should be processed.
+    HandleWheelEvent(WebKit::WebWheelEvent wheelEvent) -> (bool handled) Synchronous
+
+    # Sent when a mouse enter event should be processed.
+    HandleMouseEnterEvent(WebKit::WebMouseEvent mouseEvent) -> (bool handled) Synchronous
+    
+    # Sent when a mouse leave event should be processed.
+    HandleMouseLeaveEvent(WebKit::WebMouseEvent mouseEvent) -> (bool handled) Synchronous
+
+    # Sent when a keyboard should be processed.
+    HandleKeyboardEvent(WebKit::WebKeyboardEvent keyboardEvent) -> (bool handled) Synchronous
+    
+    # Sent when an editing command should be processed.
+    HandleEditingCommand(String commandName, String argument) -> (bool handled) Synchronous
+    
+    # Return whether or not a plugin wants to enable the given editing command.
+    IsEditingCommandEnabled(String commandName) -> (bool enabled) Synchronous
+    
+    # Return whether or not a plugin wants to handle page scale factor itself.
+    HandlesPageScaleFactor() -> (bool enabled) Synchronous
+
+    # Return whether or not a plugin wants page scale, page zoom, and text zoom all to affect page scale.
+    RequiresUnifiedScaleFactor() -> (bool required) Synchronous
+
+    # Sent when the plug-in focus changes.
+    SetFocus(bool isFocused)
+
+    # Sent when the update requested by Update has been painted.
+    DidUpdate()
+
+    # Paint the entire plug-in.
+    PaintEntirePlugin() -> () Synchronous
+
+    # Get a reference to the plug-in's scriptable NPObject.
+    GetPluginScriptableNPObject() -> (uint64_t pluginScriptableNPObjectID) Synchronous
+
+    # Sent when the containing NSWindow's focus changes
+    WindowFocusChanged(bool hasFocus)
+
+    # Sent when the containing NSWindow's visibility changes
+    WindowVisibilityChanged(bool isVisible)
+
+#if PLATFORM(COCOA)
+    # Send the complex text input to the plug-in.
+    SendComplexTextInput(String textInput)
+
+    # Sent when the containing NSWindow or NSView frame changes
+    WindowAndViewFramesChanged(WebCore::IntRect windowFrameInScreenCoordinates, WebCore::IntRect viewFrameInWindowCoordinates)
+
+    # Sent when the containing window's layer hosting mode changes
+    SetLayerHostingMode(uint32_t layerHostingMode)
+#endif
+
+    # Does the plugin support snapshotting?
+    SupportsSnapshotting() -> (bool isSupported) Synchronous
+
+    # Return a snapshot of the plugin.
+    Snapshot() -> (WebKit::ShareableBitmap::Handle backingStoreHandle) Synchronous
+
+    # Sent when storage blocking policy changes
+    StorageBlockingStateChanged(bool storageBlockingEnabled)
+
+    # Sent when private browsing is enabled or disabled
+    PrivateBrowsingStateChanged(bool isPrivateBrowsingEnabled)
+
+    # Gets the string representating the form value of the plug-in
+    GetFormValue() -> (bool returnValue, String formValue) Synchronous
+
+    # Sent when the browser wants to mute or unmute the plugin.
+    MutedStateChanged(bool muted)
+}
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginCreationParameters.cpp webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginCreationParameters.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginCreationParameters.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginCreationParameters.cpp	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginCreationParameters.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "ArgumentCoders.h"
+
+namespace WebKit {
+
+PluginCreationParameters::PluginCreationParameters()
+    : pluginInstanceID(0)
+    , windowNPObjectID(0)
+    , contentsScaleFactor(1)
+    , isPrivateBrowsingEnabled(false)
+    , isMuted(false)
+    , asynchronousCreationIncomplete(false)
+    , artificialPluginInitializationDelayEnabled(false)
+    , isAcceleratedCompositingEnabled(false)
+{
+}
+
+void PluginCreationParameters::encode(IPC::Encoder& encoder) const
+{
+    encoder << pluginInstanceID;
+    encoder << windowNPObjectID;
+    encoder << parameters;
+    encoder << userAgent;
+    encoder << contentsScaleFactor;
+    encoder << isPrivateBrowsingEnabled;
+    encoder << isMuted;
+    encoder << asynchronousCreationIncomplete;
+    encoder << artificialPluginInitializationDelayEnabled;
+    encoder << isAcceleratedCompositingEnabled;
+}
+
+bool PluginCreationParameters::decode(IPC::Decoder& decoder, PluginCreationParameters& result)
+{
+    if (!decoder.decode(result.pluginInstanceID) || !result.pluginInstanceID)
+        return false;
+
+    if (!decoder.decode(result.windowNPObjectID))
+        return false;
+
+    if (!decoder.decode(result.parameters))
+        return false;
+
+    if (!decoder.decode(result.userAgent))
+        return false;
+
+    if (!decoder.decode(result.contentsScaleFactor))
+        return false;
+
+    if (!decoder.decode(result.isPrivateBrowsingEnabled))
+        return false;
+
+    if (!decoder.decode(result.isMuted))
+        return false;
+
+    if (!decoder.decode(result.asynchronousCreationIncomplete))
+        return false;
+
+    if (!decoder.decode(result.artificialPluginInitializationDelayEnabled))
+        return false;
+
+    if (!decoder.decode(result.isAcceleratedCompositingEnabled))
+        return false;
+
+    return true;
+}
+
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginCreationParameters.h webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginCreationParameters.h
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginCreationParameters.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginCreationParameters.h	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PluginCreationParameters_h
+#define PluginCreationParameters_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "Plugin.h"
+
+namespace IPC {
+class Decoder;
+class Encoder;
+}
+
+namespace WebKit {
+
+struct PluginCreationParameters {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    PluginCreationParameters();
+
+    void encode(IPC::Encoder&) const;
+    static WARN_UNUSED_RETURN bool decode(IPC::Decoder&, PluginCreationParameters&);
+
+    // The unique ID of this plug-in instance.
+    uint64_t pluginInstanceID;
+
+    // The ID of the window NPObject.
+    uint64_t windowNPObjectID;
+
+    // The parameters passed to the plug-in.
+    Plugin::Parameters parameters;
+
+    // The browser user agent.
+    String userAgent;
+
+    // The current contents scale factor that this plug-in should have.
+    float contentsScaleFactor;
+
+    // Whether private browsing is enabled at the time of instantiation.
+    bool isPrivateBrowsingEnabled;
+
+    // Whether the plugin should be muted.
+    bool isMuted;
+    
+    // If requesting synchronous initialization, whether this plugin had previously been requested asynchronously
+    bool asynchronousCreationIncomplete;
+
+    // Simulated initialization delay test asynchronous plugin initialization
+    bool artificialPluginInitializationDelayEnabled;
+
+    // Whether accelerated compositing is enabled.
+    bool isAcceleratedCompositingEnabled;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // PluginCreationParameters_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginProcess.cpp webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginProcess.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginProcess.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginProcess.cpp	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginProcess.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "ArgumentCoders.h"
+#include "Attachment.h"
+#include "AuxiliaryProcessMessages.h"
+#include "NetscapePlugin.h"
+#include "NetscapePluginModule.h"
+#include "PluginProcessConnectionMessages.h"
+#include "PluginProcessCreationParameters.h"
+#include "PluginProcessProxyMessages.h"
+#include "WebProcessConnection.h"
+#include <WebCore/NetworkStorageSession.h>
+#include <WebCore/NotImplemented.h>
+#include <unistd.h>
+#include <wtf/MemoryPressureHandler.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/ProcessPrivilege.h>
+#include <wtf/RunLoop.h>
+
+#if PLATFORM(MAC)
+#include <crt_externs.h>
+#endif
+
+namespace WebKit {
+
+using namespace WebCore;
+
+NO_RETURN static void callExit(IPC::Connection*)
+{
+    _exit(EXIT_SUCCESS);
+}
+
+PluginProcess& PluginProcess::singleton()
+{
+    static NeverDestroyed<PluginProcess> pluginProcess;
+    return pluginProcess;
+}
+
+PluginProcess::PluginProcess()
+    : m_supportsAsynchronousPluginInitialization(false)
+    , m_minimumLifetimeTimer(RunLoop::main(), this, &PluginProcess::minimumLifetimeTimerFired)
+    , m_connectionActivity("PluginProcess connection activity.")
+{
+    NetscapePlugin::setSetExceptionFunction(WebProcessConnection::setGlobalException);
+}
+
+PluginProcess::~PluginProcess()
+{
+}
+
+void PluginProcess::initializeProcess(const AuxiliaryProcessInitializationParameters& parameters)
+{
+    WTF::setProcessPrivileges(allPrivileges());
+    WebCore::NetworkStorageSession::permitProcessToUseCookieAPI(true);
+    m_pluginPath = parameters.extraInitializationData.get("plugin-path");
+    platformInitializeProcess(parameters);
+}
+
+void PluginProcess::initializeConnection(IPC::Connection* connection)
+{
+    AuxiliaryProcess::initializeConnection(connection);
+
+    // We call _exit() directly from the background queue in case the main thread is unresponsive
+    // and AuxiliaryProcess::didClose() does not get called.
+    connection->setDidCloseOnConnectionWorkQueueCallback(callExit);
+}
+
+void PluginProcess::removeWebProcessConnection(WebProcessConnection* webProcessConnection)
+{
+    size_t vectorIndex = m_webProcessConnections.find(webProcessConnection);
+    ASSERT(vectorIndex != notFound);
+
+    m_webProcessConnections.remove(vectorIndex);
+    
+    if (m_webProcessConnections.isEmpty() && m_pluginModule) {
+        // Decrement the load count. This is balanced by a call to incrementLoadCount in createWebProcessConnection.
+        m_pluginModule->decrementLoadCount();
+    }        
+
+    enableTermination();
+}
+
+NetscapePluginModule* PluginProcess::netscapePluginModule()
+{
+    if (!m_pluginModule) {
+        ASSERT(!m_pluginPath.isNull());
+        m_pluginModule = NetscapePluginModule::getOrCreate(m_pluginPath);
+
+#if PLATFORM(MAC)
+        if (m_pluginModule) {
+            if (m_pluginModule->pluginQuirks().contains(PluginQuirks::PrognameShouldBeWebKitPluginHost))
+                *const_cast<const char**>(_NSGetProgname()) = "WebKitPluginHost";
+        }
+#endif
+    }
+
+    return m_pluginModule.get();
+}
+
+bool PluginProcess::shouldTerminate()
+{
+    return m_webProcessConnections.isEmpty();
+}
+
+void PluginProcess::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
+{
+#if OS(LINUX)
+    if (decoder.messageReceiverName() == Messages::AuxiliaryProcess::messageReceiverName()) {
+        AuxiliaryProcess::didReceiveMessage(connection, decoder);
+        return;
+    }
+#endif
+
+    didReceivePluginProcessMessage(connection, decoder);
+}
+
+void PluginProcess::initializePluginProcess(PluginProcessCreationParameters&& parameters)
+{
+    ASSERT(!m_pluginModule);
+
+    auto& memoryPressureHandler = MemoryPressureHandler::singleton();
+    memoryPressureHandler.setLowMemoryHandler([this] (Critical, Synchronous) {
+        if (shouldTerminate())
+            terminate();
+    });
+    memoryPressureHandler.install();
+
+    m_supportsAsynchronousPluginInitialization = parameters.supportsAsynchronousPluginInitialization;
+    setMinimumLifetime(parameters.minimumLifetime);
+    setTerminationTimeout(parameters.terminationTimeout);
+
+    platformInitializePluginProcess(WTFMove(parameters));
+}
+
+void PluginProcess::createWebProcessConnection()
+{
+    // FIXME: Merge this with AuxiliaryProcess::createIPCConnectionPair().
+
+    bool didHaveAnyWebProcessConnections = !m_webProcessConnections.isEmpty();
+
+#if USE(UNIX_DOMAIN_SOCKETS)
+    IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
+
+    auto connection = WebProcessConnection::create(socketPair.server);
+    m_webProcessConnections.append(WTFMove(connection));
+
+    IPC::Attachment clientSocket(socketPair.client);
+    parentProcessConnection()->send(Messages::PluginProcessProxy::DidCreateWebProcessConnection(clientSocket, m_supportsAsynchronousPluginInitialization), 0);
+#elif OS(DARWIN)
+    // Create the listening port.
+    mach_port_t listeningPort = MACH_PORT_NULL;
+    auto kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort);
+    if (kr != KERN_SUCCESS) {
+        LOG_ERROR("Could not allocate mach port, error %x", kr);
+        CRASH();
+    }
+
+    // Create a listening connection.
+    auto connection = WebProcessConnection::create(IPC::Connection::Identifier(listeningPort));
+
+    m_webProcessConnections.append(WTFMove(connection));
+
+    IPC::Attachment clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND);
+    parentProcessConnection()->send(Messages::PluginProcessProxy::DidCreateWebProcessConnection(clientPort, m_supportsAsynchronousPluginInitialization), 0);
+#else
+    notImplemented();
+#endif
+
+    if (NetscapePluginModule* module = netscapePluginModule()) {
+        if (!didHaveAnyWebProcessConnections) {
+            // Increment the load count. This is matched by a call to decrementLoadCount in removeWebProcessConnection.
+            // We do this so that the plug-in module's NP_Shutdown won't be called until right before exiting.
+            module->incrementLoadCount();
+        }
+    }
+
+    disableTermination();
+}
+
+void PluginProcess::getSitesWithData(uint64_t callbackID)
+{
+    Vector<String> sites;
+    if (NetscapePluginModule* module = netscapePluginModule())
+        sites = module->sitesWithData();
+
+    parentProcessConnection()->send(Messages::PluginProcessProxy::DidGetSitesWithData(sites, callbackID), 0);
+}
+
+void PluginProcess::deleteWebsiteData(WallTime modifiedSince, uint64_t callbackID)
+{
+    if (auto* module = netscapePluginModule()) {
+        auto currentTime = WallTime::now();
+
+        if (currentTime > modifiedSince) {
+            uint64_t maximumAge = (currentTime - modifiedSince).secondsAs<uint64_t>();
+
+            module->clearSiteData(String(), NP_CLEAR_ALL, maximumAge);
+        }
+    }
+
+    parentProcessConnection()->send(Messages::PluginProcessProxy::DidDeleteWebsiteData(callbackID), 0);
+}
+
+void PluginProcess::deleteWebsiteDataForHostNames(const Vector<String>& hostNames, uint64_t callbackID)
+{
+    if (auto* module = netscapePluginModule()) {
+        for (auto& hostName : hostNames)
+            module->clearSiteData(hostName, NP_CLEAR_ALL, std::numeric_limits<uint64_t>::max());
+    }
+
+    parentProcessConnection()->send(Messages::PluginProcessProxy::DidDeleteWebsiteDataForHostNames(callbackID), 0);
+}
+
+void PluginProcess::setMinimumLifetime(Seconds lifetime)
+{
+    if (lifetime <= 0_s)
+        return;
+    
+    disableTermination();
+    
+    m_minimumLifetimeTimer.startOneShot(lifetime);
+}
+
+void PluginProcess::minimumLifetimeTimerFired()
+{
+    enableTermination();
+}
+
+#if !PLATFORM(COCOA)
+void PluginProcess::initializeProcessName(const AuxiliaryProcessInitializationParameters&)
+{
+}
+
+void PluginProcess::initializeSandbox(const AuxiliaryProcessInitializationParameters&, SandboxInitializationParameters&)
+{
+}
+#endif
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginProcess.h webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginProcess.h
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginProcess.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginProcess.h	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "AuxiliaryProcess.h"
+#include <WebCore/CountedUserActivity.h>
+#include <wtf/Forward.h>
+#include <wtf/text/WTFString.h>
+
+#if PLATFORM(COCOA)
+#include <wtf/MachSendRight.h>
+#endif
+
+namespace WebKit {
+
+class NetscapePluginModule;
+class WebProcessConnection;
+struct PluginProcessCreationParameters;
+        
+class PluginProcess : public AuxiliaryProcess
+{
+    WTF_MAKE_NONCOPYABLE(PluginProcess);
+    friend NeverDestroyed<PluginProcess>;
+
+public:
+    static PluginProcess& singleton();
+    static constexpr WebCore::AuxiliaryProcessType processType = WebCore::AuxiliaryProcessType::Plugin;
+
+    void removeWebProcessConnection(WebProcessConnection*);
+
+    NetscapePluginModule* netscapePluginModule();
+
+    const String& pluginPath() const { return m_pluginPath; }
+
+#if PLATFORM(COCOA)
+    void setModalWindowIsShowing(bool);
+    void setFullscreenWindowIsShowing(bool);
+
+    const WTF::MachSendRight& compositingRenderServerPort() const { return m_compositingRenderServerPort; }
+
+    bool launchProcess(const String& launchPath, const Vector<String>& arguments);
+    bool launchApplicationAtURL(const String& urlString, const Vector<String>& arguments);
+    bool openURL(const String& urlString, int32_t& status, String& launchedURLString);
+    bool openFile(const String& urlString);
+#endif
+
+    CountedUserActivity& connectionActivity() { return m_connectionActivity; }
+
+private:
+    PluginProcess();
+    ~PluginProcess();
+
+#if PLATFORM(MAC)
+    bool shouldOverrideQuarantine() final;
+#endif
+
+    // AuxiliaryProcess
+    void initializeProcess(const AuxiliaryProcessInitializationParameters&) override;
+    void initializeProcessName(const AuxiliaryProcessInitializationParameters&) override;
+    void initializeConnection(IPC::Connection*) override;
+    void initializeSandbox(const AuxiliaryProcessInitializationParameters&, SandboxInitializationParameters&) override;
+    bool shouldTerminate() override;
+    void platformInitializeProcess(const AuxiliaryProcessInitializationParameters&);
+
+#if USE(APPKIT)
+    void stopRunLoop() override;
+#endif
+
+    // IPC::Connection::Client
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+
+    // Message handlers.
+    void didReceivePluginProcessMessage(IPC::Connection&, IPC::Decoder&);
+    void initializePluginProcess(PluginProcessCreationParameters&&);
+    void createWebProcessConnection();
+
+    void getSitesWithData(uint64_t callbackID);
+    void deleteWebsiteData(WallTime modifiedSince, uint64_t callbackID);
+    void deleteWebsiteDataForHostNames(const Vector<String>& hostNames, uint64_t callbackID);
+
+    void platformInitializePluginProcess(PluginProcessCreationParameters&&);
+    
+    void setMinimumLifetime(Seconds);
+    void minimumLifetimeTimerFired();
+    // Our web process connections.
+    Vector<RefPtr<WebProcessConnection>> m_webProcessConnections;
+
+    // The plug-in path.
+    String m_pluginPath;
+
+#if PLATFORM(COCOA)
+    String m_pluginBundleIdentifier;
+#endif
+
+    // The plug-in module.
+    RefPtr<NetscapePluginModule> m_pluginModule;
+    
+    bool m_supportsAsynchronousPluginInitialization;
+
+    RunLoop::Timer<PluginProcess> m_minimumLifetimeTimer;
+
+#if PLATFORM(COCOA)
+    // The Mach port used for accelerated compositing.
+    WTF::MachSendRight m_compositingRenderServerPort;
+
+    String m_nsurlCacheDirectory;
+#endif
+
+    CountedUserActivity m_connectionActivity;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginProcess.messages.in webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginProcess.messages.in
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/PluginProcess.messages.in	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/PluginProcess.messages.in	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,46 @@
+# Copyright (C) 2010 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+messages -> PluginProcess LegacyReceiver NotRefCounted {
+    # Initializes the plug-in process.
+    InitializePluginProcess(struct WebKit::PluginProcessCreationParameters processCreationParameters)
+    
+    # Creates a web process connection. When the connection has been created,
+    # The plug-in process sends back a DidCreateWebProcessConnection message with
+    # a connection identifier.
+    CreateWebProcessConnection()
+
+    # Asks the plug-in process for sites with data. The plug-in process sends back a 
+    # DidGetSitesWithData message with the sites.
+    GetSitesWithData(uint64_t callbackID)
+
+    DeleteWebsiteData(WallTime modifiedSince, uint64_t callbackID)
+    DeleteWebsiteDataForHostNames(Vector<String> hostNames, uint64_t callbackID)
+
+#if PLATFORM(COCOA)
+    SetQOS(int latencyQOS, int throughputQOS)
+#endif
+}
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/unix/PluginControllerProxyUnix.cpp webkitgtk-2.36.0/Source/WebKit/PluginProcess/unix/PluginControllerProxyUnix.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/unix/PluginControllerProxyUnix.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/unix/PluginControllerProxyUnix.cpp	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginControllerProxy.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <WebCore/NotImplemented.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+void PluginControllerProxy::platformInitialize(const PluginCreationParameters&)
+{
+    notImplemented();
+}
+
+void PluginControllerProxy::platformDestroy()
+{
+    notImplemented();
+}
+
+void PluginControllerProxy::platformGeometryDidChange()
+{
+    notImplemented();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/unix/PluginProcessMainUnix.cpp webkitgtk-2.36.0/Source/WebKit/PluginProcess/unix/PluginProcessMainUnix.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/unix/PluginProcessMainUnix.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/unix/PluginProcessMainUnix.cpp	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2011, 2014 Igalia S.L.
+ * Copyright (C) 2011 Apple Inc.
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginProcessMain.h"
+
+#if ENABLE(PLUGIN_PROCESS)
+
+#include "AuxiliaryProcessMain.h"
+#include "Logging.h"
+#include "NetscapePlugin.h"
+#include "PluginProcess.h"
+#include <stdlib.h>
+#include <wtf/FileSystem.h>
+
+#if PLATFORM(GTK)
+#include <gtk/gtk.h>
+#endif
+
+#if PLATFORM(X11)
+#include <WebCore/PlatformDisplayX11.h>
+#include <WebCore/XErrorTrapper.h>
+#include <wtf/NeverDestroyed.h>
+#endif
+
+namespace WebKit {
+
+#if PLATFORM(X11)
+static LazyNeverDestroyed<WebCore::XErrorTrapper> xErrorTrapper;
+#endif
+
+class PluginProcessMainUnix final: public AuxiliaryProcessMainBase<PluginProcess> {
+public:
+    bool platformInitialize() override
+    {
+#if PLATFORM(GTK)
+        gtk_init(nullptr, nullptr);
+#endif
+
+        return true;
+    }
+
+    bool parseCommandLine(int argc, char** argv) override
+    {
+        ASSERT(argc > 2);
+        if (argc < 3)
+            return false;
+
+        if (!strcmp(argv[1], "-scanPlugin")) {
+            ASSERT(argc == 3);
+#if PLUGIN_ARCHITECTURE(UNIX)
+            InitializeWebKit2();
+            exit(NetscapePluginModule::scanPlugin(argv[2]) ? EXIT_SUCCESS : EXIT_FAILURE);
+#else
+            exit(EXIT_FAILURE);
+#endif
+        }
+
+        ASSERT(argc == 4);
+#if PLATFORM(X11)
+        if (WebCore::PlatformDisplay::sharedDisplay().type() == WebCore::PlatformDisplay::Type::X11) {
+            auto* display = downcast<WebCore::PlatformDisplayX11>(WebCore::PlatformDisplay::sharedDisplay()).native();
+            xErrorTrapper.construct(display, WebCore::XErrorTrapper::Policy::Warn);
+        }
+#endif
+
+        m_parameters.extraInitializationData.add("plugin-path", argv[3]);
+        return AuxiliaryProcessMainBase::parseCommandLine(argc, argv);
+    }
+};
+
+int PluginProcessMain(int argc, char** argv)
+{
+    return AuxiliaryProcessMain<PluginProcessMainUnix>(argc, argv);
+}
+
+} // namespace WebKit
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/unix/PluginProcessUnix.cpp webkitgtk-2.36.0/Source/WebKit/PluginProcess/unix/PluginProcessUnix.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/unix/PluginProcessUnix.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/unix/PluginProcessUnix.cpp	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginProcess.h"
+
+#if ENABLE(PLUGIN_PROCESS)
+
+#include "PluginProcessCreationParameters.h"
+#include <WebCore/NotImplemented.h>
+
+namespace WebKit {
+
+void PluginProcess::platformInitializeProcess(const AuxiliaryProcessInitializationParameters&)
+{
+}
+
+void PluginProcess::platformInitializePluginProcess(PluginProcessCreationParameters&&)
+{
+    notImplemented();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(PLUGIN_PROCESS)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/WebProcessConnection.cpp webkitgtk-2.36.0/Source/WebKit/PluginProcess/WebProcessConnection.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/WebProcessConnection.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/WebProcessConnection.cpp	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebProcessConnection.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "ActivityAssertion.h"
+#include "ArgumentCoders.h"
+#include "NPObjectMessageReceiverMessages.h"
+#include "NPRemoteObjectMap.h"
+#include "PluginControllerProxy.h"
+#include "PluginCreationParameters.h"
+#include "PluginProcess.h"
+#include "PluginProcessConnectionMessages.h"
+#include "PluginProxyMessages.h"
+#include "WebProcessConnectionMessages.h"
+#include <wtf/SetForScope.h>
+
+#if !OS(WINDOWS)
+#include <unistd.h>
+#endif
+
+namespace WebKit {
+using namespace WebCore;
+
+static IPC::Connection* currentConnection;
+
+Ref<WebProcessConnection> WebProcessConnection::create(IPC::Connection::Identifier connectionIdentifier)
+{
+    return adoptRef(*new WebProcessConnection(connectionIdentifier));
+}
+
+WebProcessConnection::~WebProcessConnection()
+{
+    ASSERT(m_pluginControllers.isEmpty());
+    ASSERT(!m_npRemoteObjectMap);
+    ASSERT(!m_connection);
+}
+    
+WebProcessConnection::WebProcessConnection(IPC::Connection::Identifier connectionIdentifier)
+{
+    m_connection = IPC::Connection::createServerConnection(connectionIdentifier, *this);
+    m_npRemoteObjectMap = NPRemoteObjectMap::create(m_connection.get());
+
+    // Use this flag to force synchronous messages to be treated as asynchronous messages in the WebProcess.
+    // Otherwise, the WebProcess would process incoming synchronous IPC while waiting for a synchronous IPC
+    // reply from the Plugin process, which would be unsafe.
+    m_connection->setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(true);
+    m_connection->open();
+}
+
+void WebProcessConnection::addPluginControllerProxy(std::unique_ptr<PluginControllerProxy> pluginController)
+{
+    uint64_t pluginInstanceID = pluginController->pluginInstanceID();
+
+    ASSERT(!m_pluginControllers.contains(pluginInstanceID));
+    m_pluginControllers.set(pluginInstanceID, WTFMove(pluginController));
+}
+
+void WebProcessConnection::destroyPluginControllerProxy(PluginControllerProxy* pluginController)
+{
+    // This may end up calling removePluginControllerProxy which ends up deleting
+    // the WebProcessConnection object if this was the last object.
+    pluginController->destroy();
+}
+
+void WebProcessConnection::removePluginControllerProxy(PluginControllerProxy* pluginController, Plugin* plugin)
+{
+    unsigned pluginInstanceID = pluginController->pluginInstanceID();
+    {
+        ASSERT(m_pluginControllers.contains(pluginInstanceID));
+
+        std::unique_ptr<PluginControllerProxy> pluginControllerUniquePtr = m_pluginControllers.take(pluginInstanceID);
+        ASSERT(pluginControllerUniquePtr.get() == pluginController);
+    }
+
+    // Invalidate all objects related to this plug-in.
+    if (plugin)
+        m_npRemoteObjectMap->pluginDestroyed(plugin);
+
+    if (!m_pluginControllers.isEmpty())
+        return;
+
+    m_npRemoteObjectMap = nullptr;
+
+    // The last plug-in went away, close this connection.
+    m_connection->invalidate();
+    m_connection = nullptr;
+
+    // This will cause us to be deleted.    
+    PluginProcess::singleton().removeWebProcessConnection(this);
+}
+
+void WebProcessConnection::setGlobalException(const String& exceptionString)
+{
+    if (!currentConnection)
+        return;
+
+    currentConnection->sendSync(Messages::PluginProcessConnection::SetException(exceptionString), Messages::PluginProcessConnection::SetException::Reply(), 0);
+}
+
+void WebProcessConnection::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
+{
+    SetForScope<IPC::Connection*> currentConnectionChange(currentConnection, &connection);
+
+    if (decoder.messageReceiverName() == Messages::WebProcessConnection::messageReceiverName()) {
+        didReceiveWebProcessConnectionMessage(connection, decoder);
+        return;
+    }
+
+    if (!decoder.destinationID()) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    PluginControllerProxy* pluginControllerProxy = m_pluginControllers.get(decoder.destinationID());
+    if (!pluginControllerProxy)
+        return;
+
+    PluginController::PluginDestructionProtector protector(pluginControllerProxy->asPluginController());
+    pluginControllerProxy->didReceivePluginControllerProxyMessage(connection, decoder);
+}
+
+bool WebProcessConnection::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, UniqueRef<IPC::Encoder>& replyEncoder)
+{
+    SetForScope<IPC::Connection*> currentConnectionChange(currentConnection, &connection);
+
+    uint64_t destinationID = decoder.destinationID();
+
+    if (!destinationID)
+        return didReceiveSyncWebProcessConnectionMessage(connection, decoder, replyEncoder);
+
+    if (decoder.messageReceiverName() == Messages::NPObjectMessageReceiver::messageReceiverName())
+        return m_npRemoteObjectMap->didReceiveSyncMessage(connection, decoder, replyEncoder);
+
+    PluginControllerProxy* pluginControllerProxy = m_pluginControllers.get(decoder.destinationID());
+    if (!pluginControllerProxy)
+        return false;
+
+    PluginController::PluginDestructionProtector protector(pluginControllerProxy->asPluginController());
+    return pluginControllerProxy->didReceiveSyncPluginControllerProxyMessage(connection, decoder, replyEncoder);
+}
+
+void WebProcessConnection::didClose(IPC::Connection&)
+{
+    // The web process crashed. Destroy all the plug-in controllers. Destroying the last plug-in controller
+    // will cause the web process connection itself to be destroyed.
+    Vector<PluginControllerProxy*> pluginControllers;
+    for (auto it = m_pluginControllers.values().begin(), end = m_pluginControllers.values().end(); it != end; ++it)
+        pluginControllers.append(it->get());
+
+    for (size_t i = 0; i < pluginControllers.size(); ++i)
+        destroyPluginControllerProxy(pluginControllers[i]);
+}
+
+void WebProcessConnection::destroyPlugin(uint64_t pluginInstanceID, bool asynchronousCreationIncomplete, Messages::WebProcessConnection::DestroyPlugin::DelayedReply&& reply)
+{
+    // We return immediately from this synchronous IPC. We want to make sure the plugin destruction is just about to start so audio playback
+    // will finish soon after returning. However we don't want to wait for destruction to complete fully as that may take a while.
+    reply();
+
+    // Ensure we don't clamp any timers during destruction
+    ActivityAssertion activityAssertion(PluginProcess::singleton().connectionActivity());
+
+    PluginControllerProxy* pluginControllerProxy = m_pluginControllers.get(pluginInstanceID);
+    
+    // If there is no PluginControllerProxy then this plug-in doesn't exist yet and we probably have nothing to do.
+    if (!pluginControllerProxy) {
+        // If the plugin we're supposed to destroy was requested asynchronously and doesn't exist yet,
+        // we need to flag the instance ID so it is not created later.
+        if (asynchronousCreationIncomplete)
+            m_asynchronousInstanceIDsToIgnore.add(pluginInstanceID);
+        
+        return;
+    }
+    
+    destroyPluginControllerProxy(pluginControllerProxy);
+}
+
+void WebProcessConnection::didReceiveInvalidMessage(IPC::Connection&, IPC::MessageName)
+{
+    // FIXME: Implement.
+}
+
+void WebProcessConnection::createPluginInternal(const PluginCreationParameters& creationParameters, bool& result, bool& wantsWheelEvents, uint32_t& remoteLayerClientID)
+{
+    auto pluginControllerProxy = makeUnique<PluginControllerProxy>(this, creationParameters);
+
+    PluginControllerProxy* pluginControllerProxyPtr = pluginControllerProxy.get();
+
+    // Make sure to add the proxy to the map before initializing it, since the plug-in might call out to the web process from 
+    // its NPP_New function. This will hand over ownership of the proxy to the web process connection.
+    addPluginControllerProxy(WTFMove(pluginControllerProxy));
+
+    // Now try to initialize the plug-in.
+    result = pluginControllerProxyPtr->initialize(creationParameters);
+
+    if (!result)
+        return;
+
+    wantsWheelEvents = pluginControllerProxyPtr->wantsWheelEvents();
+#if PLATFORM(COCOA)
+    remoteLayerClientID = pluginControllerProxyPtr->remoteLayerClientID();
+#else
+    UNUSED_PARAM(remoteLayerClientID);
+#endif
+}
+
+void WebProcessConnection::createPlugin(const PluginCreationParameters& creationParameters, Messages::WebProcessConnection::CreatePlugin::DelayedReply&& reply)
+{
+    // Ensure we don't clamp any timers during initialization
+    ActivityAssertion activityAssertion(PluginProcess::singleton().connectionActivity());
+
+    PluginControllerProxy* pluginControllerProxy = m_pluginControllers.get(creationParameters.pluginInstanceID);
+
+    // The controller proxy for the plug-in we're being asked to create synchronously might already exist if it was requested asynchronously before.
+    if (pluginControllerProxy) {
+        // It might still be in the middle of initialization in which case we have to let that initialization complete and respond to this message later.
+        if (pluginControllerProxy->isInitializing()) {
+            pluginControllerProxy->setInitializationReply(WTFMove(reply));
+            return;
+        }
+        
+        // If its initialization is complete then we need to respond to this message with the correct information about its creation.
+#if PLATFORM(COCOA)
+        reply(true, pluginControllerProxy->wantsWheelEvents(), pluginControllerProxy->remoteLayerClientID());
+#else
+        reply(true, pluginControllerProxy->wantsWheelEvents(), 0);
+#endif
+        return;
+    }
+    
+    // The plugin we're supposed to create might have been requested asynchronously before.
+    // In that case we need to create it synchronously now but flag the instance ID so we don't recreate it asynchronously later.
+    if (creationParameters.asynchronousCreationIncomplete)
+        m_asynchronousInstanceIDsToIgnore.add(creationParameters.pluginInstanceID);
+    
+    bool result = false;
+    bool wantsWheelEvents = false;
+    uint32_t remoteLayerClientID = 0;
+    createPluginInternal(creationParameters, result, wantsWheelEvents, remoteLayerClientID);
+    
+    reply(result, wantsWheelEvents, remoteLayerClientID);
+}
+
+void WebProcessConnection::createPluginAsynchronously(const PluginCreationParameters& creationParameters)
+{
+    // In the time since this plugin was requested asynchronously we might have created it synchronously or destroyed it.
+    // In either of those cases we need to ignore this creation request.
+    if (m_asynchronousInstanceIDsToIgnore.contains(creationParameters.pluginInstanceID)) {
+        m_asynchronousInstanceIDsToIgnore.remove(creationParameters.pluginInstanceID);
+        return;
+    }
+    
+    // This version of CreatePlugin is only used by plug-ins that are known to behave when started asynchronously.
+    bool result = false;
+    bool wantsWheelEvents = false;
+    uint32_t remoteLayerClientID = 0;
+    
+    if (creationParameters.artificialPluginInitializationDelayEnabled) {
+        Seconds artificialPluginInitializationDelay { 5_s };
+        sleep(artificialPluginInitializationDelay);
+    }
+
+    // Since plug-in creation can often message to the WebProcess synchronously (with NPP_Evaluate for example)
+    // we need to make sure that the web process will handle the plug-in process's synchronous messages,
+    // even if the web process is waiting on a synchronous reply itself.
+    // Normally the plug-in process doesn't give its synchronous messages the special flag to allow for that.
+    // We can force it to do so by incrementing the "DispatchMessageMarkedDispatchWhenWaitingForSyncReply" count.
+    m_connection->incrementDispatchMessageMarkedDispatchWhenWaitingForSyncReplyCount();
+
+    // The call to createPluginInternal can potentially cause the plug-in to be destroyed and
+    // thus free the WebProcessConnection object. Protect it.
+    Ref<WebProcessConnection> protect(*this);
+    createPluginInternal(creationParameters, result, wantsWheelEvents, remoteLayerClientID);
+
+    if (!m_connection) {
+        // createPluginInternal caused the connection to go away.
+        return;
+    }
+
+    m_connection->decrementDispatchMessageMarkedDispatchWhenWaitingForSyncReplyCount();
+
+    // If someone asked for this plug-in synchronously while it was in the middle of being created then we need perform the
+    // synchronous reply instead of sending the asynchronous reply.
+    PluginControllerProxy* pluginControllerProxy = m_pluginControllers.get(creationParameters.pluginInstanceID);
+    ASSERT(pluginControllerProxy);
+    if (auto delayedSyncReply = pluginControllerProxy->takeInitializationReply()) {
+        delayedSyncReply(result, wantsWheelEvents, remoteLayerClientID);
+        return;
+    }
+
+    // Otherwise, send the asynchronous results now.
+    if (!result) {
+        m_connection->sendSync(Messages::PluginProxy::DidFailToCreatePlugin(), Messages::PluginProxy::DidFailToCreatePlugin::Reply(), creationParameters.pluginInstanceID);
+        return;
+    }
+
+    m_connection->sendSync(Messages::PluginProxy::DidCreatePlugin(wantsWheelEvents, remoteLayerClientID), Messages::PluginProxy::DidCreatePlugin::Reply(), creationParameters.pluginInstanceID);
+}
+    
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/WebProcessConnection.h webkitgtk-2.36.0/Source/WebKit/PluginProcess/WebProcessConnection.h
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/WebProcessConnection.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/WebProcessConnection.h	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "Connection.h"
+#include "Plugin.h"
+#include "WebProcessConnectionMessagesReplies.h"
+#include <wtf/HashSet.h>
+#include <wtf/RefCounted.h>
+
+namespace WebKit {
+
+class NPRemoteObjectMap;
+class PluginControllerProxy;
+struct PluginCreationParameters;
+    
+// A connection from a plug-in process to a web process.
+
+class WebProcessConnection : public RefCounted<WebProcessConnection>, IPC::Connection::Client {
+public:
+    static Ref<WebProcessConnection> create(IPC::Connection::Identifier);
+    virtual ~WebProcessConnection();
+
+    IPC::Connection* connection() const { return m_connection.get(); }
+    NPRemoteObjectMap* npRemoteObjectMap() const { return m_npRemoteObjectMap.get(); }
+
+    void removePluginControllerProxy(PluginControllerProxy*, Plugin*);
+
+    static void setGlobalException(const String&);
+    
+private:
+    WebProcessConnection(IPC::Connection::Identifier);
+
+    void addPluginControllerProxy(std::unique_ptr<PluginControllerProxy>);
+
+    void destroyPluginControllerProxy(PluginControllerProxy*);
+
+    // IPC::Connection::Client
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+    bool didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&) override;
+    void didClose(IPC::Connection&) override;
+    void didReceiveInvalidMessage(IPC::Connection&, IPC::MessageName) override;
+
+    // Message handlers.
+    void didReceiveWebProcessConnectionMessage(IPC::Connection&, IPC::Decoder&);
+    bool didReceiveSyncWebProcessConnectionMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&);
+    void createPlugin(const PluginCreationParameters&, Messages::WebProcessConnection::CreatePluginDelayedReply&&);
+    void createPluginAsynchronously(const PluginCreationParameters&);
+    void destroyPlugin(uint64_t pluginInstanceID, bool asynchronousCreationIncomplete, Messages::WebProcessConnection::DestroyPluginDelayedReply&&);
+    
+    void createPluginInternal(const PluginCreationParameters&, bool& result, bool& wantsWheelEvents, uint32_t& remoteLayerClientID);
+
+    RefPtr<IPC::Connection> m_connection;
+
+    HashMap<uint64_t, std::unique_ptr<PluginControllerProxy>> m_pluginControllers;
+    RefPtr<NPRemoteObjectMap> m_npRemoteObjectMap;
+    HashSet<uint64_t> m_asynchronousInstanceIDsToIgnore;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/WebProcessConnection.messages.in webkitgtk-2.36.0/Source/WebKit/PluginProcess/WebProcessConnection.messages.in
--- webkitgtk-2.36.0.orig/Source/WebKit/PluginProcess/WebProcessConnection.messages.in	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/PluginProcess/WebProcessConnection.messages.in	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,36 @@
+# Copyright (C) 2010 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+messages -> WebProcessConnection LegacyReceiver {
+    # Creates a plug-in instance using the given creation parameters.
+    CreatePlugin(struct WebKit::PluginCreationParameters pluginCreationParameters) -> (bool creationResult, bool wantsWheelEvents, uint32_t remoteLayerClientID) Synchronous
+
+    # Creates a plug-in instance asynchronously using the given creation parameters.
+    CreatePluginAsynchronously(struct WebKit::PluginCreationParameters pluginCreationParameters)
+
+    # Destroys the plug-in instance with the given instance ID.
+    DestroyPlugin(uint64_t pluginInstanceID, bool asynchronousCreationIncomplete) -> () Synchronous
+}
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/cn.microdone.cmb.safari.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/cn.microdone.cmb.safari.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/cn.microdone.cmb.safari.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/cn.microdone.cmb.safari.sb	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,23 @@
+; Copyright (C) 2018 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.appstore.CodeRedeemerNetscapePlugin.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.appstore.CodeRedeemerNetscapePlugin.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.appstore.CodeRedeemerNetscapePlugin.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.appstore.CodeRedeemerNetscapePlugin.sb	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,24 @@
+; Copyright (C) 2014 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(webkit-camera)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.BocomSubmitCtrl.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.BocomSubmitCtrl.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.BocomSubmitCtrl.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.BocomSubmitCtrl.sb	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,23 @@
+; Copyright (C) 2018 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.ist.ds.appleconnect.webplugin.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.ist.ds.appleconnect.webplugin.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.ist.ds.appleconnect.webplugin.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.ist.ds.appleconnect.webplugin.sb	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,65 @@
+; Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(allow mach-lookup
+    (global-name "com.apple.ist.ds.appleconnect2.service.admin")
+    (global-name "com.apple.ist.ds.appleconnect2.service.agent")
+    (global-name "com.apple.ist.ds.appleconnect2.service.kdctunnelcontroller")
+    (global-name "com.apple.ist.ds.appleconnect2.service.menuextra")
+    (global-name "com.apple.wifi.anqp")
+    (global-name "com.apple.GSSCred")
+    (global-name "org.h5l.kcm"))
+(allow mach-lookup
+    (global-name-regex #"^com\.apple\.ist\.ds\.appleconnect2\.service\.com\.apple\.WebKit\.Plugin\.(32|64)(\.Development)?\[[0-9]+\]$")
+    (global-name-regex #"^com\.apple\.ist\.ds\.appleconnect2\.service\.PluginProcess\[[0-9]+\]$"))
+
+(shared-preferences-read
+    "com.apple.GSS"
+    "com.apple.ist.ds.appleconnect2"
+    "com.apple.ist.ds.appleconnect2.acceptanceTest"
+    "com.apple.ist.ds.appleconnect2.production"
+    "com.apple.ist.ds.appleconnect2.uat"
+    "com.apple.Kerberos"
+    "com.apple.networkConnect"
+    "edu.mit.Kerberos")
+
+(allow file-read*
+    (subpath "/Library/KerberosPlugins/GSSAPI")
+    (subpath "/Library/KerberosPlugins/KerberosFrameworkPlugins")
+    (literal "/Library/Preferences/edu.mit.Kerberos")
+    (literal "/Library/Preferences/SystemConfiguration/preferences.plist")
+    (home-library-preferences-literal "/edu.mit.Kerberos"))
+
+(allow file-read*
+    (literal "/private/etc/services"))
+
+(if (defined? 'mach-register)
+    (allow mach-register
+        (global-name-regex #"^com\.apple\.ist\.ds\.appleconnect2\.service\.com\.apple\.WebKit\.Plugin\.(32|64)(\.Development)?\[[0-9]+\]$")
+        (global-name-regex #"^com\.apple\.ist\.ds\.appleconnect2\.service\.PluginProcess\[[0-9]+\]$")))
+
+(allow system-socket)
+(allow network-outbound
+   (remote udp "*:4160" "*:88"))
+(allow network-inbound
+   (local udp))
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.NPSafeInput.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.NPSafeInput.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.NPSafeInput.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.NPSafeInput.sb	2022-03-22 16:38:57.373580110 -0500
@@ -0,0 +1,32 @@
+; Copyright (C) 2018 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(allow mach-lookup
+    (global-name "com.apple.dock.fullscreen")
+    (global-name "com.apple.iohideventsystem"))
+
+(allow file-read*
+    (literal "/Library/Internet Plug-Ins/data.ini"))
+
+(allow iokit-get-properties
+    (iokit-property "manufacturer"))
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.NPSafeSubmit.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.NPSafeSubmit.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.NPSafeSubmit.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.NPSafeSubmit.sb	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,23 @@
+; Copyright (C) 2018 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
diff -urpN "webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.QuickTime Plugin.plugin.sb" "webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.QuickTime Plugin.plugin.sb"
--- "webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.QuickTime Plugin.plugin.sb"	1969-12-31 18:00:00.000000000 -0600
+++ "webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.apple.QuickTime Plugin.plugin.sb"	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,31 @@
+; Copyright (C) 2013 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(webkit-powerbox)
+(shared-preferences-read-write "com.apple.quicktime.plugin.preferences")
+
+(allow file-read* file-write*
+    (home-library-subpath "/Caches/QuickTime")
+    (home-library-preferences-literal "/QuickTime Preferences"))
+
+(allow network-bind (local ip))
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.cfca.npSecEditCtl.MAC.BOC.plugin.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.cfca.npSecEditCtl.MAC.BOC.plugin.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.cfca.npSecEditCtl.MAC.BOC.plugin.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.cfca.npSecEditCtl.MAC.BOC.plugin.sb	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,25 @@
+; Copyright (C) 2018 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(allow file-read* file-write*
+    (literal "/Library/Internet Plug-Ins/npSecEditCtl.MAC.BOC.sig"))
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.cisco.webex.plugin.gpc64.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.cisco.webex.plugin.gpc64.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.cisco.webex.plugin.gpc64.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.cisco.webex.plugin.gpc64.sb	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,83 @@
+; Copyright (C) 2018 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(define allow-symlinks #t)
+
+(define (home-subpath home-relative-subpath)
+    (subpath (string-append (param "HOME_DIR") home-relative-subpath)))
+(define (home-literal home-relative-literal)
+    (literal (string-append (param "HOME_DIR") home-relative-literal)))
+
+(allow file-read* file-write*
+    (home-literal "/Library/Preferences/com.cisco.webex.fuzzyWindowConfig.plist"))
+
+(allow file-read* file-write*
+    (home-literal "/Library/Preferences/com.webex.meetingmanager.plist"))
+
+(allow file-read* file-write* file-write-create
+    (home-subpath "/Library/Application Support/WebEx Folder"))
+
+;; FIXME: We should tigthen the sandbox to some tmp subfolders
+(allow file*
+    (prefix "/private/tmp"))
+
+(allow file-read-data file-write-data
+    (path "/dev/tty"))
+
+(allow process-exec)
+(allow process-fork)
+(allow distributed-notification-post)
+
+(allow mach-lookup
+    (global-name "com.apple.PerformanceAnalysis.animationperfd")
+    (global-name "com.apple.dock.fullscreen")
+    (global-name "com.apple.quicklook.ui.helper.active")
+    (global-name "com.apple.quicklook.ui.helper")
+    (global-name "com.apple.inputmethodkit.launchagent")
+    (global-name "com.apple.inputmethodkit.launcher")
+    (global-name "com.apple.inputmethodkit.getxpcendpoint"))
+
+(allow iokit-get-properties
+    (iokit-property "PowerControlSupported")
+    (iokit-property "SupportTapToWake")
+    (iokit-property "ResetOnLockMs")
+    (iokit-property "ResetOnUnlockMs")
+    (iokit-property "ShouldResetOnButton")
+    (iokit-property "WirelessChargingNotificationSupported")
+    (iokit-property "SupportsSilentClick")
+    (iokit-property "MinDigitizerPressureValue")
+    (iokit-property "AccurateMaxDigitizerPressureValue")
+    (iokit-property "ExtendedMaxDigitizerPressureValue")
+    (iokit-property "AnimationThresholds")
+    (iokit-property "ActivationThresholds")
+    (iokit-property "mt-device-id"))
+
+(webkit-powerbox)
+(webkit-printing)
+(webkit-camera)
+(webkit-microphone)
+
+(allow network-bind (local ip))
+
+(allow network-outbound)
+(allow network-inbound (local ip))
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.cmbchina.CMBSecurity.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.cmbchina.CMBSecurity.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.cmbchina.CMBSecurity.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.cmbchina.CMBSecurity.sb	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,26 @@
+; Copyright (C) 2018 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(allow mach-lookup
+    (global-name "com.apple.dock.fullscreen")
+    (global-name "com.apple.iohideventsystem"))
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.ftsafe.NPAPI-Core-Safe-SoftKeybaord.plugin.rfc1034identifier.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.ftsafe.NPAPI-Core-Safe-SoftKeybaord.plugin.rfc1034identifier.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.ftsafe.NPAPI-Core-Safe-SoftKeybaord.plugin.rfc1034identifier.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.ftsafe.NPAPI-Core-Safe-SoftKeybaord.plugin.rfc1034identifier.sb	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,23 @@
+; Copyright (C) 2018 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.google.googletalkbrowserplugin.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.google.googletalkbrowserplugin.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.google.googletalkbrowserplugin.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.google.googletalkbrowserplugin.sb	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,45 @@
+; Copyright (C) 2018 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(define (home-subpath home-relative-subpath)
+    (subpath (string-append (param "HOME_DIR") home-relative-subpath)))
+
+(allow file-read* file-write*
+    (home-subpath "/Library/Application Support/Google/Google Talk Plugin"))
+
+(allow file-read* file-write*
+    (subpath "/Library/Application Support/Google"))
+
+(allow job-creation)
+(allow signal)
+(allow mach-lookup)
+
+(webkit-powerbox)
+(webkit-printing)
+(webkit-camera)
+(webkit-microphone)
+
+(allow network-bind (local ip))
+
+(allow network-outbound)
+(allow network-inbound (local ip))
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.google.o1dbrowserplugin.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.google.o1dbrowserplugin.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.google.o1dbrowserplugin.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.google.o1dbrowserplugin.sb	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,50 @@
+; Copyright (C) 2018 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(define (home-subpath home-relative-subpath)
+    (subpath (string-append (param "HOME_DIR") home-relative-subpath)))
+
+(allow file-read* file-write*
+    (home-subpath "/Library/Application Support/Google/Google Talk Plugin"))
+
+(allow file-read* file-write*
+    (subpath "/Library/Application Support/Google"))
+
+(allow file*
+    (prefix "/private/tmp"))
+
+(allow network-bind (prefix "/private/tmp"))
+
+(allow job-creation)
+(allow signal)
+(allow mach-lookup)
+
+(webkit-powerbox)
+(webkit-printing)
+(webkit-camera)
+(webkit-microphone)
+
+(allow network-bind (local ip))
+
+(allow network-outbound)
+(allow network-inbound (local ip))
diff -urpN "webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.macromedia.Flash Player ESR.plugin.sb" "webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.macromedia.Flash Player ESR.plugin.sb"
--- "webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.macromedia.Flash Player ESR.plugin.sb"	1969-12-31 18:00:00.000000000 -0600
+++ "webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.macromedia.Flash Player ESR.plugin.sb"	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,79 @@
+; Copyright (C) 2016 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(webkit-powerbox)
+(webkit-printing)
+(webkit-camera)
+(webkit-microphone)
+
+(allow ipc-posix-sem
+    (ipc-posix-name "MacromediaSemaphoreDig")
+    (ipc-posix-name "59918130"))
+
+(allow file-read*
+    (home-literal "/mm.cfg")
+    (home-literal "/mms.cfg"))
+
+(deny file-read-xattr (with no-log)
+    (home-library-literal "/Caches")
+    (home-library-preferences-literal "/"))
+
+(allow file-read* file-write-create file-write-mode file-write-owner
+    (home-library-literal "/Caches/Adobe")
+    (home-library-preferences-literal "/Macromedia"))
+
+(allow file-read* file-write*
+    (literal "/Library/Application Support/Macromedia/mms.cfg")
+    (home-library-literal "/Application Support/Macromedia/mms.cfg")
+    (home-library-subpath "/Caches/Adobe/Flash Player")
+    (home-library-preferences-subpath "/Macromedia/Flash Player"))
+
+(allow file-read*
+    (literal "/Library/PreferencePanes/Flash Player.prefPane")
+    (home-library-literal "/PreferencePanes/Flash Player.prefPane")
+    (home-library-regex "/Application Support/Macromedia/ss\.(cfg|cfn|sgn)$"))
+
+(allow file-read* file-write*
+    (mount-relative-regex #"^/\.TemporaryItems/"))
+
+(deny file-read* (with no-log)
+    (literal "/Library/Application Support/Macromedia/FlashAuthor.cfg")
+    (subpath "/Library/Application Support/Macromedia/FlashPlayerTrust"))
+
+(allow network-bind (local ip))
+
+;;;
+;;; Needed for Camera access
+;;;
+(allow iokit-get-properties
+    (iokit-property-regex #"^(Activation|Animation)Thresholds")
+    (iokit-property-regex #"^((Accurate|Extended)Max|Min)DigitizerPressureValue")
+    (iokit-property "IOPCITunnelCompatible")
+    (iokit-property "PowerControlSupported")
+    (iokit-property "Removable")
+    (iokit-property "ResetOnLockMs")
+    (iokit-property "ResetOnUnlockMs")
+    (iokit-property "ShouldResetOnButton")
+    (iokit-property-regex #"^Support(sSilentClick|TapToWake)")
+    (iokit-property "WirelessChargingNotificationSupported")
+)
diff -urpN "webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.macromedia.Flash Player.plugin.sb" "webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.macromedia.Flash Player.plugin.sb"
--- "webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.macromedia.Flash Player.plugin.sb"	1969-12-31 18:00:00.000000000 -0600
+++ "webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.macromedia.Flash Player.plugin.sb"	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,79 @@
+; Copyright (C) 2013 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(webkit-powerbox)
+(webkit-printing)
+(webkit-camera)
+(webkit-microphone)
+
+(allow ipc-posix-sem
+    (ipc-posix-name "MacromediaSemaphoreDig")
+    (ipc-posix-name "59918130"))
+
+(allow file-read*
+    (home-literal "/mm.cfg")
+    (home-literal "/mms.cfg"))
+
+(deny file-read-xattr (with no-log)
+    (home-library-literal "/Caches")
+    (home-library-preferences-literal "/"))
+
+(allow file-read* file-write-create file-write-mode file-write-owner
+    (home-library-literal "/Caches/Adobe")
+    (home-library-preferences-literal "/Macromedia"))
+
+(allow file-read* file-write*
+    (literal "/Library/Application Support/Macromedia/mms.cfg")
+    (home-library-literal "/Application Support/Macromedia/mms.cfg")
+    (home-library-subpath "/Caches/Adobe/Flash Player")
+    (home-library-preferences-subpath "/Macromedia/Flash Player"))
+
+(allow file-read*
+    (literal "/Library/PreferencePanes/Flash Player.prefPane")
+    (home-library-literal "/PreferencePanes/Flash Player.prefPane")
+    (home-library-regex "/Application Support/Macromedia/ss\.(cfg|cfn|sgn)$"))
+
+(allow file-read* file-write*
+    (mount-relative-regex #"^/\.TemporaryItems/"))
+
+(deny file-read* (with no-log)
+    (literal "/Library/Application Support/Macromedia/FlashAuthor.cfg")
+    (subpath "/Library/Application Support/Macromedia/FlashPlayerTrust"))
+
+(allow network-bind (local ip))
+
+;;;
+;;; Needed for Camera access
+;;;
+(allow iokit-get-properties
+    (iokit-property-regex #"^(Activation|Animation)Thresholds")
+    (iokit-property-regex #"^((Accurate|Extended)Max|Min)DigitizerPressureValue")
+    (iokit-property "IOPCITunnelCompatible")
+    (iokit-property "PowerControlSupported")
+    (iokit-property "Removable")
+    (iokit-property "ResetOnLockMs")
+    (iokit-property "ResetOnUnlockMs")
+    (iokit-property "ShouldResetOnButton")
+    (iokit-property-regex #"^Support(sSilentClick|TapToWake)")
+    (iokit-property "WirelessChargingNotificationSupported")
+)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.microsoft.SilverlightPlugin.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.microsoft.SilverlightPlugin.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.microsoft.SilverlightPlugin.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.microsoft.SilverlightPlugin.sb	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,56 @@
+; Copyright (C) 2013 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(allow iokit-open
+    (iokit-user-client-class "IOHIDLibUserClient")
+    (iokit-user-client-class "IOBluetoothHCIUserClient"))
+
+(shared-preferences-read
+    "com.microsoft.PlayReady"
+    "com.microsoft.autoupdate2")
+(shared-preferences-read-write "com.microsoft.silverlight")
+
+(allow file-write-create
+    (home-library-literal "/Application Support/Microsoft"))
+
+(allow file-read* file-write*
+    ;; Sigh, mode 777 in /Library.
+    (subpath "/Library/Application Support/Microsoft/PlayReady")
+    (home-library-subpath "/Application Support/Microsoft/PlayReady")
+    (home-library-subpath "/Application Support/Microsoft/Silverlight")
+    (home-library-subpath "/Caches/TemporaryItems"))
+
+(if (defined? 'semaphore-owner)
+    (allow ipc-posix-sem
+         (semaphore-owner same-sandbox))
+    (allow ipc-posix-sem
+         (ipc-posix-name "LC_Mutex")))
+
+;; FIXME: <rdar://problem/13636078>
+(allow ipc-posix-shm*
+    (ipc-posix-name-regex #"^CoreCLR_"))
+
+(allow network-bind (local ip))
+
+(webkit-powerbox)
+(webkit-printing)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.oracle.java.JavaAppletPlugin.sb webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.oracle.java.JavaAppletPlugin.sb
--- webkitgtk-2.36.0.orig/Source/WebKit/Resources/PlugInSandboxProfiles/com.oracle.java.JavaAppletPlugin.sb	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Resources/PlugInSandboxProfiles/com.oracle.java.JavaAppletPlugin.sb	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,70 @@
+; Copyright (C) 2013 Apple Inc. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+;    notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+(webkit-printing)
+
+(allow signal network-inbound)
+(allow process-fork)
+(allow process-exec
+    (subpath "/System/Library/Java/JavaVirtualMachines")
+    (subpath "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin"))
+
+(allow mach-lookup
+    (global-name "com.apple.coreservices.launchservicesd")
+    (global-name-regex #"^PlaceHolderServerName-"))
+
+(allow file-read*
+    (literal "/dev/fd")
+    (literal "/usr/bin")
+    (literal "/private/etc/hosts")
+    (subpath "/Library/Java")
+    (subpath "/System/Library/Java"))
+
+(shared-preferences-read
+    "com.apple.java.JavaPreferences"
+    "net.java.openjdk.cmd")
+
+(shared-preferences-read-write
+    "com.apple.java.util.prefs"
+    "com.oracle.javadeployment")
+
+(allow file-read* file-write*
+    (home-library-subpath "/Saved Application State/net.java.openjdk.cmd.savedState")
+    (home-library-subpath "/Application Support/Oracle/Java/Deployment")
+    (home-library-subpath "/Caches/Java"))
+
+(allow file-write-create
+    (home-library-literal "/Application Support/Oracle")
+    (home-library-literal "/Application Support/Oracle/Java"))
+
+(allow file-read*
+    (subpath "/Library/Application Support/Java/PublicFiles")
+    (subpath "/Library/Application Support/Oracle/Java/Deployment"))
+
+(allow network-bind network-outbound (subpath (param "DARWIN_USER_TEMP_DIR")))
+(allow network-bind (local ip))
+
+(deny file-write* (with no-log) (subpath "/Library/Application Support/Oracle"))
+(deny file-write* (with no-log) (subpath (param "WEBKIT2_FRAMEWORK_DIR")))
+
+(deny job-creation (with no-log))
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/API/c/WKPluginInformation.cpp webkitgtk-2.36.0/Source/WebKit/Shared/API/c/WKPluginInformation.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/API/c/WKPluginInformation.cpp	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/API/c/WKPluginInformation.cpp	2022-03-22 16:38:57.377580131 -0500
@@ -27,74 +27,145 @@
 #include "WKPluginInformation.h"
 
 #include "APIString.h"
+#include "PluginInformation.h"
 #include "WKSharedAPICast.h"
 
 WKStringRef WKPluginInformationBundleIdentifierKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationBundleIdentifierKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPluginInformationBundleVersionKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationBundleVersionKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPluginInformationBundleShortVersionKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationBundleShortVersionKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPluginInformationPathKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationPathKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPluginInformationDisplayNameKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationDisplayNameKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPluginInformationDefaultLoadPolicyKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationDefaultLoadPolicyKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPluginInformationUpdatePastLastBlockedVersionIsKnownAvailableKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationUpdatePastLastBlockedVersionIsKnownAvailableKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPluginInformationHasSandboxProfileKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationHasSandboxProfileKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPluginInformationFrameURLKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationFrameURLKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPluginInformationMIMETypeKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationMIMETypeKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPluginInformationPageURLKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationPageURLKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPluginInformationPluginspageAttributeURLKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationPluginspageAttributeURLKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPluginInformationPluginURLKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::pluginInformationPluginURLKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
 
 WKStringRef WKPlugInInformationReplacementObscuredKey()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    static API::String& key = API::String::create(WebKit::plugInInformationReplacementObscuredKey()).leakRef();
+    return WebKit::toAPI(&key);
+#else
     return 0;
+#endif
 }
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/AuxiliaryProcess.cpp webkitgtk-2.36.0/Source/WebKit/Shared/AuxiliaryProcess.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/AuxiliaryProcess.cpp	2022-03-18 07:53:49.000000000 -0500
+++ webkitgtk-2.36.0/Source/WebKit/Shared/AuxiliaryProcess.cpp	2022-03-22 16:43:52.291137272 -0500
@@ -50,6 +50,7 @@ using namespace WebCore;
 
 AuxiliaryProcess::AuxiliaryProcess()
     : m_terminationCounter(0)
+    , m_terminationTimer(RunLoop::main(), this, &AuxiliaryProcess::terminationTimerFired)
     , m_processSuppressionDisabled("Process Suppression Disabled by UIProcess")
 {
 }
@@ -155,6 +156,7 @@ void AuxiliaryProcess::removeMessageRece
 void AuxiliaryProcess::disableTermination()
 {
     m_terminationCounter++;
+    m_terminationTimer.stop();
 }
 
 void AuxiliaryProcess::enableTermination()
@@ -165,8 +167,12 @@ void AuxiliaryProcess::enableTermination
     if (m_terminationCounter || m_isInShutDown)
         return;
 
-    if (shouldTerminate())
-        terminate();
+    if (!m_terminationTimeout) {
+        terminationTimerFired();
+        return;
+    }
+
+    m_terminationTimer.startOneShot(m_terminationTimeout);
 }
 
 void AuxiliaryProcess::mainThreadPing(CompletionHandler<void()>&& completionHandler)
@@ -184,6 +190,14 @@ uint64_t AuxiliaryProcess::messageSender
     return 0;
 }
 
+void AuxiliaryProcess::terminationTimerFired()
+{
+    if (!shouldTerminate())
+        return;
+
+    terminate();
+}
+
 void AuxiliaryProcess::stopRunLoop()
 {
     platformStopRunLoop();
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/AuxiliaryProcess.h webkitgtk-2.36.0/Source/WebKit/Shared/AuxiliaryProcess.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/AuxiliaryProcess.h	2022-03-18 07:53:49.000000000 -0500
+++ webkitgtk-2.36.0/Source/WebKit/Shared/AuxiliaryProcess.h	2022-03-22 16:48:52.000719668 -0500
@@ -105,6 +105,8 @@ protected:
     explicit AuxiliaryProcess();
     virtual ~AuxiliaryProcess();
 
+    void setTerminationTimeout(Seconds seconds) { m_terminationTimeout = seconds; }
+
     virtual void initializeProcess(const AuxiliaryProcessInitializationParameters&);
     virtual void initializeProcessName(const AuxiliaryProcessInitializationParameters&);
     virtual void initializeSandbox(const AuxiliaryProcessInitializationParameters&, SandboxInitializationParameters&);
@@ -160,12 +162,21 @@ private:
 
     void shutDown();
 
+    void terminationTimerFired();
+
     void platformInitialize(const AuxiliaryProcessInitializationParameters&);
     void platformStopRunLoop();
 
-    // A termination counter; when the counter reaches zero, the process will be terminated.
+    // The timeout, in seconds, before this process will be terminated if termination
+    // has been enabled. If the timeout is 0 seconds, the process will be terminated immediately.
+    Seconds m_terminationTimeout;
+
+    // A termination counter; when the counter reaches zero, the process will be terminated
+    // after a given period of time.
     unsigned m_terminationCounter;
 
+    RunLoop::Timer<AuxiliaryProcess> m_terminationTimer;
+
     bool m_isInShutDown { false };
 
     RefPtr<IPC::Connection> m_connection;
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/AuxiliaryProcess.h.rej webkitgtk-2.36.0/Source/WebKit/Shared/AuxiliaryProcess.h.rej
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/AuxiliaryProcess.h.rej	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/AuxiliaryProcess.h.rej	2022-03-22 16:43:52.291137272 -0500
@@ -0,0 +1,25 @@
+--- Source/WebKit/Shared/AuxiliaryProcess.h
++++ Source/WebKit/Shared/AuxiliaryProcess.h
+@@ -162,12 +164,21 @@ private:
+ 
+     void shutDown();
+ 
++    void terminationTimerFired();
++
+     void platformInitialize(const AuxiliaryProcessInitializationParameters&);
+     void platformStopRunLoop();
+ 
+-    // A termination counter; when the counter reaches zero, the process will be terminated.
++    // The timeout, in seconds, before this process will be terminated if termination
++    // has been enabled. If the timeout is 0 seconds, the process will be terminated immediately.
++    Seconds m_terminationTimeout;
++
++    // A termination counter; when the counter reaches zero, the process will be terminated
++    // after a given period of time.
+     unsigned m_terminationCounter;
+ 
++    RunLoop::Timer<AuxiliaryProcess> m_terminationTimer;
++
+     RefPtr<IPC::Connection> m_connection;
+     IPC::MessageReceiverMap m_messageReceiverMap;
+ 
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/AuxiliaryProcessMain.h webkitgtk-2.36.0/Source/WebKit/Shared/AuxiliaryProcessMain.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/AuxiliaryProcessMain.h	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/AuxiliaryProcessMain.h	2022-03-22 16:38:57.377580131 -0500
@@ -36,7 +36,7 @@ namespace WebKit {
 
 class AuxiliaryProcessMainCommon {
 public:
-    bool parseCommandLine(int argc, char** argv);
+    virtual bool parseCommandLine(int argc, char** argv);
 
 protected:
     AuxiliaryProcessInitializationParameters m_parameters;
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/Netscape/NetscapePluginModule.cpp webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/Netscape/NetscapePluginModule.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/Netscape/NetscapePluginModule.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/Netscape/NetscapePluginModule.cpp	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NetscapePluginModule.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "Module.h"
+#include "NPRuntimeUtilities.h"
+#include "NetscapeBrowserFuncs.h"
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/CString.h>
+
+namespace WebKit {
+
+static Vector<NetscapePluginModule*>& initializedNetscapePluginModules()
+{
+    static NeverDestroyed<Vector<NetscapePluginModule*>> initializedNetscapePluginModules;
+    return initializedNetscapePluginModules;
+}
+
+NetscapePluginModule::NetscapePluginModule(const String& pluginPath)
+    : m_pluginPath(pluginPath)
+    , m_isInitialized(false)
+    , m_loadCount(0)
+    , m_shutdownProcPtr(0)
+    , m_pluginFuncs()
+{
+}
+
+NetscapePluginModule::~NetscapePluginModule()
+{
+    ASSERT(initializedNetscapePluginModules().find(this) == notFound);
+}
+
+Vector<String> NetscapePluginModule::sitesWithData()
+{
+    Vector<String> sites;
+
+    incrementLoadCount();
+    tryGetSitesWithData(sites);
+    decrementLoadCount();
+
+    return sites;
+}
+
+bool NetscapePluginModule::clearSiteData(const String& site, uint64_t flags, uint64_t maxAge)
+{
+    incrementLoadCount();
+    bool result = tryClearSiteData(site, flags, maxAge);
+    decrementLoadCount();
+
+    return result;
+}
+
+bool NetscapePluginModule::tryGetSitesWithData(Vector<String>& sites)
+{
+    if (!m_isInitialized)
+        return false;
+
+    // Check if the plug-in supports NPP_GetSitesWithData.
+    if (!m_pluginFuncs.getsiteswithdata)
+        return false;
+
+    char** siteArray = m_pluginFuncs.getsiteswithdata();
+
+    // There were no sites with data.
+    if (!siteArray)
+        return true;
+
+    for (int i = 0; siteArray[i]; ++i) {
+        char* site = siteArray[i];
+
+        String siteString = String::fromUTF8(site);
+        if (!siteString.isNull())
+            sites.append(siteString);
+
+        npnMemFree(site);
+    }
+
+    npnMemFree(siteArray);
+    return true;
+}
+
+bool NetscapePluginModule::tryClearSiteData(const String& site, uint64_t flags, uint64_t maxAge)
+{
+    if (!m_isInitialized)
+        return false;
+
+    // Check if the plug-in supports NPP_ClearSiteData.
+    if (!m_pluginFuncs.clearsitedata)
+        return false;
+
+    CString siteString;
+    if (!site.isNull())
+        siteString = site.utf8();
+
+    return m_pluginFuncs.clearsitedata(siteString.data(), flags, maxAge) == NPERR_NO_ERROR;
+}
+
+void NetscapePluginModule::shutdown()
+{
+    ASSERT(m_isInitialized);
+
+    m_shutdownProcPtr();
+
+    m_isInitialized = false;
+
+    size_t pluginModuleIndex = initializedNetscapePluginModules().find(this);
+    ASSERT(pluginModuleIndex != notFound);
+
+    initializedNetscapePluginModules().remove(pluginModuleIndex);
+}
+
+RefPtr<NetscapePluginModule> NetscapePluginModule::getOrCreate(const String& pluginPath)
+{
+    // First, see if we already have a module with this plug-in path.
+    for (size_t i = 0; i < initializedNetscapePluginModules().size(); ++i) {
+        NetscapePluginModule* pluginModule = initializedNetscapePluginModules()[i];
+
+        if (pluginModule->m_pluginPath == pluginPath)
+            return pluginModule;
+    }
+
+    auto pluginModule(adoptRef(*new NetscapePluginModule(pluginPath)));
+    
+    // Try to load and initialize the plug-in module.
+    if (!pluginModule->load())
+        return nullptr;
+    
+    return pluginModule;
+}
+
+void NetscapePluginModule::incrementLoadCount()
+{
+    if (!m_loadCount) {
+        // Load the plug-in module if necessary.
+        load();
+    }
+    
+    m_loadCount++;
+}
+    
+void NetscapePluginModule::decrementLoadCount()
+{
+    ASSERT(m_loadCount > 0);
+    m_loadCount--;
+    
+    if (!m_loadCount && m_isInitialized) {
+        shutdown();
+        unload();
+    }
+}
+
+bool NetscapePluginModule::load()
+{
+    if (m_isInitialized) {
+        ASSERT(initializedNetscapePluginModules().find(this) != notFound);
+        return true;
+    }
+
+    if (!tryLoad()) {
+        unload();
+        return false;
+    }
+    
+    m_isInitialized = true;
+
+    ASSERT(initializedNetscapePluginModules().find(this) == notFound);
+    initializedNetscapePluginModules().append(this);
+
+    determineQuirks();
+
+    return true;
+}
+
+#if PLATFORM(GTK)
+static bool moduleMixesGtkSymbols(Module* module)
+{
+    return module->functionPointer<gpointer>("gtk_object_get_type");
+}
+#endif
+
+bool NetscapePluginModule::tryLoad()
+{
+    m_module = makeUnique<Module>(m_pluginPath);
+    if (!m_module->load())
+        return false;
+
+#if PLATFORM(GTK)
+    if (moduleMixesGtkSymbols(m_module.get()))
+        return false;
+#endif
+
+    NP_InitializeFuncPtr initializeFuncPtr = m_module->functionPointer<NP_InitializeFuncPtr>("NP_Initialize");
+    if (!initializeFuncPtr)
+        return false;
+
+#if !PLUGIN_ARCHITECTURE(UNIX)
+    NP_GetEntryPointsFuncPtr getEntryPointsFuncPtr = m_module->functionPointer<NP_GetEntryPointsFuncPtr>("NP_GetEntryPoints");
+    if (!getEntryPointsFuncPtr)
+        return false;
+#endif
+
+    m_shutdownProcPtr = m_module->functionPointer<NPP_ShutdownProcPtr>("NP_Shutdown");
+    if (!m_shutdownProcPtr)
+        return false;
+
+    m_pluginFuncs.size = sizeof(NPPluginFuncs);
+    m_pluginFuncs.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
+
+    // On Mac, NP_Initialize must be called first, then NP_GetEntryPoints. On Windows, the order is
+    // reversed. Failing to follow this order results in crashes (e.g., in Silverlight on Mac and
+    // in Flash and QuickTime on Windows).
+#if PLUGIN_ARCHITECTURE(MAC)
+    return initializeFuncPtr(netscapeBrowserFuncs()) == NPERR_NO_ERROR && getEntryPointsFuncPtr(&m_pluginFuncs) == NPERR_NO_ERROR;
+#elif PLUGIN_ARCHITECTURE(UNIX)
+    if (initializeFuncPtr(netscapeBrowserFuncs(), &m_pluginFuncs) != NPERR_NO_ERROR)
+        return false;
+#endif
+
+    return true;
+}
+
+void NetscapePluginModule::unload()
+{
+    ASSERT(!m_isInitialized);
+
+    m_module = nullptr;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/Netscape/NetscapePluginModule.h webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/Netscape/NetscapePluginModule.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/Netscape/NetscapePluginModule.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/Netscape/NetscapePluginModule.h	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NetscapePluginModule_h
+#define NetscapePluginModule_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "Module.h"
+#include "PluginModuleInfo.h"
+#include "PluginQuirks.h"
+#include <WebCore/npruntime_internal.h>
+#include <wtf/RefCounted.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+struct MimeClassInfo;
+}
+
+namespace WebKit {
+
+struct RawPluginMetaData;
+
+class NetscapePluginModule : public RefCounted<NetscapePluginModule> {
+public:
+    static RefPtr<NetscapePluginModule> getOrCreate(const String& pluginPath);
+    ~NetscapePluginModule();
+
+    const NPPluginFuncs& pluginFuncs() const { return m_pluginFuncs; }
+ 
+    void incrementLoadCount();
+    void decrementLoadCount();
+
+    static bool getPluginInfo(const String& pluginPath, PluginModuleInfo&);
+
+    const PluginQuirks& pluginQuirks() const { return m_pluginQuirks; }
+
+    // Return a list of domains for which the plug-in has data stored.
+    Vector<String> sitesWithData();
+
+    // Request that the plug-in clear the site data.
+    bool clearSiteData(const String& site, uint64_t flags, uint64_t maxAge);
+
+    Module* module() const { return m_module.get(); }
+
+#if PLUGIN_ARCHITECTURE(UNIX)
+    static bool scanPlugin(const String& pluginPath);
+    static void parseMIMEDescription(const String& mimeDescription, Vector<WebCore::MimeClassInfo>& result);
+    static String buildMIMEDescription(const Vector<WebCore::MimeClassInfo>&);
+#endif
+
+private:
+    explicit NetscapePluginModule(const String& pluginPath);
+
+    void determineQuirks();
+
+#if PLUGIN_ARCHITECTURE(UNIX)
+    bool getPluginInfoForLoadedPlugin(RawPluginMetaData&);
+#endif
+
+    bool tryGetSitesWithData(Vector<String>&);
+    bool tryClearSiteData(const String& site, uint64_t flags, uint64_t maxAge);
+
+    bool tryLoad();
+    bool load();
+    void unload();
+
+    void shutdown();
+
+    String m_pluginPath;
+    bool m_isInitialized;
+    unsigned m_loadCount;
+
+    PluginQuirks m_pluginQuirks;
+
+    NPP_ShutdownProcPtr m_shutdownProcPtr;
+    NPPluginFuncs m_pluginFuncs;
+
+    std::unique_ptr<Module> m_module;
+};
+    
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // NetscapePluginModule_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/Netscape/PluginInformation.cpp webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/Netscape/PluginInformation.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/Netscape/PluginInformation.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/Netscape/PluginInformation.cpp	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginInformation.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "APINumber.h"
+#include "APIString.h"
+#include "APIURL.h"
+#include "PluginInfoStore.h"
+#include "PluginModuleInfo.h"
+#include "WKAPICast.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+String pluginInformationBundleIdentifierKey()
+{
+    return "PluginInformationBundleIdentifier"_s;
+}
+
+String pluginInformationBundleVersionKey()
+{
+    return "PluginInformationBundleVersion"_s;
+}
+
+String pluginInformationBundleShortVersionKey()
+{
+    return "PluginInformationBundleShortVersion"_s;
+}
+
+String pluginInformationPathKey()
+{
+    return "PluginInformationPath"_s;
+}
+
+String pluginInformationDisplayNameKey()
+{
+    return "PluginInformationDisplayName"_s;
+}
+
+String pluginInformationDefaultLoadPolicyKey()
+{
+    return "PluginInformationDefaultLoadPolicy"_s;
+}
+
+String pluginInformationUpdatePastLastBlockedVersionIsKnownAvailableKey()
+{
+    return "PluginInformationUpdatePastLastBlockedVersionIsKnownAvailable"_s;
+}
+
+String pluginInformationHasSandboxProfileKey()
+{
+    return "PluginInformationHasSandboxProfile"_s;
+}
+
+String pluginInformationFrameURLKey()
+{
+    return "PluginInformationFrameURL"_s;
+}
+
+String pluginInformationMIMETypeKey()
+{
+    return "PluginInformationMIMEType"_s;
+}
+
+String pluginInformationPageURLKey()
+{
+    return "PluginInformationPageURL"_s;
+}
+
+String pluginInformationPluginspageAttributeURLKey()
+{
+    return "PluginInformationPluginspageAttributeURL"_s;
+}
+
+String pluginInformationPluginURLKey()
+{
+    return "PluginInformationPluginURL"_s;
+}
+
+String plugInInformationReplacementObscuredKey()
+{
+    return "PlugInInformationReplacementObscured"_s;
+}
+
+void getPluginModuleInformation(const PluginModuleInfo& plugin, API::Dictionary::MapType& map)
+{
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    map.set(pluginInformationPathKey(), API::String::create(plugin.path));
+    map.set(pluginInformationDisplayNameKey(), API::String::create(plugin.info.name));
+    map.set(pluginInformationDefaultLoadPolicyKey(), API::UInt64::create(toWKPluginLoadPolicy(PluginInfoStore::defaultLoadPolicyForPlugin(plugin))));
+
+    getPlatformPluginModuleInformation(plugin, map);
+#else
+    UNUSED_PARAM(plugin);
+    UNUSED_PARAM(map);
+#endif
+}
+
+Ref<API::Dictionary> createPluginInformationDictionary(const PluginModuleInfo& plugin)
+{
+    API::Dictionary::MapType map;
+    getPluginModuleInformation(plugin, map);
+
+    return API::Dictionary::create(WTFMove(map));
+}
+
+Ref<API::Dictionary> createPluginInformationDictionary(const PluginModuleInfo& plugin, const String& frameURLString, const String& mimeType, const String& pageURLString, const String& pluginspageAttributeURLString, const String& pluginURLString, bool replacementObscured)
+{
+    API::Dictionary::MapType map;
+    getPluginModuleInformation(plugin, map);
+
+    if (!frameURLString.isEmpty())
+        map.set(pluginInformationFrameURLKey(), API::URL::create(frameURLString));
+    if (!mimeType.isEmpty())
+        map.set(pluginInformationMIMETypeKey(), API::String::create(mimeType));
+    if (!pageURLString.isEmpty())
+        map.set(pluginInformationPageURLKey(), API::URL::create(pageURLString));
+    if (!pluginspageAttributeURLString.isEmpty())
+        map.set(pluginInformationPluginspageAttributeURLKey(), API::URL::create(pluginspageAttributeURLString));
+    if (!pluginURLString.isEmpty())
+        map.set(pluginInformationPluginURLKey(), API::URL::create(pluginURLString));
+    map.set(plugInInformationReplacementObscuredKey(), API::Boolean::create(replacementObscured));
+
+    return API::Dictionary::create(WTFMove(map));
+}
+
+Ref<API::Dictionary> createPluginInformationDictionary(const String& mimeType, const String& frameURLString, const String& pageURLString)
+{
+    API::Dictionary::MapType map;
+
+    if (!frameURLString.isEmpty())
+        map.set(pluginInformationFrameURLKey(), API::URL::create(frameURLString));
+    if (!mimeType.isEmpty())
+        map.set(pluginInformationMIMETypeKey(), API::String::create(mimeType));
+    if (!pageURLString.isEmpty())
+        map.set(pluginInformationPageURLKey(), API::URL::create(pageURLString));
+
+    return API::Dictionary::create(WTFMove(map));
+}
+
+#if !PLATFORM(COCOA)
+void getPlatformPluginModuleInformation(const PluginModuleInfo&, API::Dictionary::MapType&)
+{
+}
+#endif
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/Netscape/PluginInformation.h webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/Netscape/PluginInformation.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/Netscape/PluginInformation.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/Netscape/PluginInformation.h	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PluginInformation_h
+#define PluginInformation_h
+
+#include "APIDictionary.h"
+#include <wtf/Forward.h>
+
+namespace WebKit {
+
+struct PluginModuleInfo;
+
+// Plug-in module information keys
+String pluginInformationBundleIdentifierKey();
+String pluginInformationBundleVersionKey();
+String pluginInformationBundleShortVersionKey();
+String pluginInformationPathKey();
+String pluginInformationDisplayNameKey();
+String pluginInformationDefaultLoadPolicyKey();
+String pluginInformationUpdatePastLastBlockedVersionIsKnownAvailableKey();
+String pluginInformationHasSandboxProfileKey();
+
+// Plug-in load specific information keys
+String pluginInformationFrameURLKey();
+String pluginInformationMIMETypeKey();
+String pluginInformationPageURLKey();
+String pluginInformationPluginspageAttributeURLKey();
+String pluginInformationPluginURLKey();
+String plugInInformationReplacementObscuredKey();
+
+Ref<API::Dictionary> createPluginInformationDictionary(const PluginModuleInfo&);
+Ref<API::Dictionary> createPluginInformationDictionary(const PluginModuleInfo&, const String& frameURLString, const String& mimeType, const String& pageURLString, const String& pluginspageAttributeURLString, const String& pluginURLString, bool replacementObscured = false);
+Ref<API::Dictionary> createPluginInformationDictionary(const String& mimeType, const String& frameURLString, const String& pageURLString);
+
+void getPluginModuleInformation(const PluginModuleInfo&, API::Dictionary::MapType&);
+void getPlatformPluginModuleInformation(const PluginModuleInfo&, API::Dictionary::MapType&);
+
+} // namespace WebKit
+
+#endif // PluginInformation_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/Netscape/unix/NetscapePluginModuleUnix.cpp webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/Netscape/unix/NetscapePluginModuleUnix.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/Netscape/unix/NetscapePluginModuleUnix.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/Netscape/unix/NetscapePluginModuleUnix.cpp	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NetscapePluginModule.h"
+
+#if PLUGIN_ARCHITECTURE(UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NetscapeBrowserFuncs.h"
+#include "PluginProcessProxy.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <wtf/FileSystem.h>
+#include <wtf/text/StringBuilder.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+class StdoutDevNullRedirector {
+public:
+    StdoutDevNullRedirector();
+    ~StdoutDevNullRedirector();
+
+private:
+    int m_savedStdout;
+};
+
+StdoutDevNullRedirector::StdoutDevNullRedirector()
+    : m_savedStdout(-1)
+{
+    int newStdout = open("/dev/null", O_WRONLY);
+    if (newStdout == -1)
+        return;
+    m_savedStdout = dup(STDOUT_FILENO);
+    dup2(newStdout, STDOUT_FILENO);
+    close(newStdout);
+}
+
+StdoutDevNullRedirector::~StdoutDevNullRedirector()
+{
+    if (m_savedStdout != -1) {
+        dup2(m_savedStdout, STDOUT_FILENO);
+        close(m_savedStdout);
+    }
+}
+
+
+void NetscapePluginModule::parseMIMEDescription(const String& mimeDescription, Vector<MimeClassInfo>& result)
+{
+    ASSERT_ARG(result, result.isEmpty());
+
+    Vector<String> types = mimeDescription.convertToASCIILowercase().split(';');
+    result.reserveInitialCapacity(types.size());
+
+    size_t mimeInfoCount = 0;
+    for (size_t i = 0; i < types.size(); ++i) {
+        Vector<String> mimeTypeParts = types[i].splitAllowingEmptyEntries(':');
+        if (mimeTypeParts.size() <= 0)
+            continue;
+
+        result.uncheckedAppend(MimeClassInfo());
+        MimeClassInfo& mimeInfo = result[mimeInfoCount++];
+        mimeInfo.type = mimeTypeParts[0];
+
+        if (mimeTypeParts.size() > 1)
+            mimeInfo.extensions = mimeTypeParts[1].split(',');
+
+        if (mimeTypeParts.size() > 2)
+            mimeInfo.desc = mimeTypeParts[2];
+    }
+}
+
+String NetscapePluginModule::buildMIMEDescription(const Vector<MimeClassInfo>& mimeDescription)
+{
+    StringBuilder builder;
+
+    size_t mimeInfoCount = mimeDescription.size();
+    for (size_t i = 0; i < mimeInfoCount; ++i) {
+        const MimeClassInfo& mimeInfo = mimeDescription[i];
+        builder.append(mimeInfo.type);
+        builder.append(':');
+
+        size_t extensionsCount = mimeInfo.extensions.size();
+        for (size_t j = 0; j < extensionsCount; ++j) {
+            builder.append(mimeInfo.extensions[j]);
+            if (j != extensionsCount - 1)
+                builder.append(',');
+        }
+        builder.append(':');
+
+        builder.append(mimeInfo.desc);
+        if (i != mimeInfoCount - 1)
+            builder.append(';');
+    }
+
+    return builder.toString();
+}
+
+bool NetscapePluginModule::getPluginInfoForLoadedPlugin(RawPluginMetaData& metaData)
+{
+    ASSERT(m_isInitialized);
+
+    Module* module = m_module.get();
+    NPP_GetValueProcPtr NPP_GetValue = module->functionPointer<NPP_GetValueProcPtr>("NP_GetValue");
+    if (!NPP_GetValue)
+        return false;
+
+    NP_GetMIMEDescriptionFuncPtr NP_GetMIMEDescription = module->functionPointer<NP_GetMIMEDescriptionFuncPtr>("NP_GetMIMEDescription");
+    if (!NP_GetMIMEDescription)
+        return false;
+
+    char* buffer;
+    NPError error = NPP_GetValue(0, NPPVpluginNameString, &buffer);
+    if (error == NPERR_NO_ERROR)
+        metaData.name = String::fromUTF8(buffer);
+
+    error = NPP_GetValue(0, NPPVpluginDescriptionString, &buffer);
+    if (error == NPERR_NO_ERROR)
+        metaData.description = String::fromUTF8(buffer);
+
+    String mimeDescription = String::fromUTF8(NP_GetMIMEDescription());
+    if (mimeDescription.isNull())
+        return false;
+
+    metaData.mimeDescription = mimeDescription;
+
+    return true;
+}
+
+bool NetscapePluginModule::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
+{
+    RawPluginMetaData metaData;
+    if (!PluginProcessProxy::scanPlugin(pluginPath, metaData))
+        return false;
+
+    plugin.path = pluginPath;
+    plugin.info.file = FileSystem::pathFileName(pluginPath);
+    plugin.info.name = metaData.name;
+    plugin.info.desc = metaData.description;
+    parseMIMEDescription(metaData.mimeDescription, plugin.info.mimes);
+
+    return true;
+}
+
+void NetscapePluginModule::determineQuirks()
+{
+    RawPluginMetaData metaData;
+    if (!getPluginInfoForLoadedPlugin(metaData))
+        return;
+
+    Vector<MimeClassInfo> mimeTypes;
+    parseMIMEDescription(metaData.mimeDescription, mimeTypes);
+
+#if PLATFORM(X11)
+    for (size_t i = 0; i < mimeTypes.size(); ++i) {
+        if (mimeTypes[i].type == "application/x-shockwave-flash") {
+#if CPU(X86_64)
+            m_pluginQuirks.add(PluginQuirks::IgnoreRightClickInWindowlessMode);
+#endif
+            m_pluginQuirks.add(PluginQuirks::DoNotCancelSrcStreamInWindowedMode);
+            break;
+        }
+    }
+#endif // PLATFORM(X11)
+}
+
+static void writeCharacter(char byte)
+{
+    int result;
+    while ((result = fputc(byte, stdout)) == EOF && errno == EINTR) { }
+    ASSERT(result != EOF);
+}
+
+static void writeLine(const String& line)
+{
+    CString utf8String = line.utf8();
+    const char* utf8Data = utf8String.data();
+
+    for (unsigned i = 0; i < utf8String.length(); i++) {
+        char character = utf8Data[i];
+        if (character != '\n')
+            writeCharacter(character);
+    }
+    writeCharacter('\n');
+}
+
+bool NetscapePluginModule::scanPlugin(const String& pluginPath)
+{
+    RawPluginMetaData metaData;
+
+    {
+        // Don't allow the plugin to pollute the standard output.
+        StdoutDevNullRedirector stdOutRedirector;
+
+        // We are loading the plugin here since it does not seem to be a standardized way to
+        // get the needed informations from a UNIX plugin without loading it.
+        RefPtr<NetscapePluginModule> pluginModule = NetscapePluginModule::getOrCreate(pluginPath);
+        if (!pluginModule)
+            return false;
+
+        pluginModule->incrementLoadCount();
+        bool success = pluginModule->getPluginInfoForLoadedPlugin(metaData);
+        pluginModule->decrementLoadCount();
+
+        if (!success)
+            return false;
+    }
+
+    // Write data to standard output for the UI process.
+    writeLine(metaData.name);
+    writeLine(metaData.description);
+    writeLine(metaData.mimeDescription);
+
+    fflush(stdout);
+
+    return true;
+}
+
+} // namespace WebKit
+
+#endif // PLUGIN_ARCHITECTURE(UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPIdentifierData.cpp webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPIdentifierData.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPIdentifierData.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPIdentifierData.cpp	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NPIdentifierData.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "Decoder.h"
+#include "Encoder.h"
+#include "WebCoreArgumentCoders.h"
+#include <WebCore/IdentifierRep.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+NPIdentifierData::NPIdentifierData()
+    : m_isString(false)
+    , m_number(0)
+{
+}
+
+
+NPIdentifierData NPIdentifierData::fromNPIdentifier(NPIdentifier npIdentifier)
+{
+    NPIdentifierData npIdentifierData;
+
+    IdentifierRep* identifierRep = static_cast<IdentifierRep*>(npIdentifier);
+    npIdentifierData.m_isString = identifierRep->isString();
+
+    if (npIdentifierData.m_isString)
+        npIdentifierData.m_string = identifierRep->string();
+    else
+        npIdentifierData.m_number = identifierRep->number();
+
+    return npIdentifierData;
+}
+
+NPIdentifier NPIdentifierData::createNPIdentifier() const
+{
+    if (m_isString)
+        return static_cast<NPIdentifier>(IdentifierRep::get(m_string.data()));
+    
+    return static_cast<NPIdentifier>(IdentifierRep::get(m_number));
+}
+
+void NPIdentifierData::encode(IPC::Encoder& encoder) const
+{
+    encoder << m_isString;
+    if (m_isString)
+        encoder << m_string;
+    else
+        encoder << m_number;
+}
+
+std::optional<NPIdentifierData> NPIdentifierData::decode(IPC::Decoder& decoder)
+{
+    NPIdentifierData result;
+    if (!decoder.decode(result.m_isString))
+        return std::nullopt;
+        
+    if (result.m_isString) {
+        if (!decoder.decode(result.m_string))
+            return std::nullopt;
+        return result;
+    }
+
+    if (!decoder.decode(result.m_number))
+        return std::nullopt;
+    return result;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPIdentifierData.h webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPIdentifierData.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPIdentifierData.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPIdentifierData.h	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <WebCore/npruntime_internal.h>
+#include <wtf/text/CString.h>
+
+namespace IPC {
+class Decoder;
+class Encoder;
+}
+
+namespace WebKit {
+
+class NPIdentifierData {
+public:
+    NPIdentifierData();
+    
+    static NPIdentifierData fromNPIdentifier(NPIdentifier);
+    NPIdentifier createNPIdentifier() const;
+
+    void encode(IPC::Encoder&) const;
+    static std::optional<NPIdentifierData> decode(IPC::Decoder&);
+
+private:
+    bool m_isString;
+    CString m_string;
+    int m_number;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPObjectMessageReceiver.cpp webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPObjectMessageReceiver.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPObjectMessageReceiver.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPObjectMessageReceiver.cpp	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NPObjectMessageReceiver.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NPIdentifierData.h"
+#include "NPRemoteObjectMap.h"
+#include "NPRuntimeUtilities.h"
+#include "NPVariantData.h"
+#include "Plugin.h"
+#include "PluginController.h"
+
+namespace WebKit {
+
+NPObjectMessageReceiver::NPObjectMessageReceiver(NPRemoteObjectMap* npRemoteObjectMap, Plugin* plugin, uint64_t npObjectID, NPObject* npObject)
+    : m_npRemoteObjectMap(npRemoteObjectMap)
+    , m_plugin(plugin)
+    , m_npObjectID(npObjectID)
+    , m_npObject(npObject)
+{
+    retainNPObject(m_npObject);
+}
+
+NPObjectMessageReceiver::~NPObjectMessageReceiver()
+{
+    m_npRemoteObjectMap->unregisterNPObject(m_npObjectID);
+
+    releaseNPObject(m_npObject);
+}
+
+void NPObjectMessageReceiver::deallocate(CompletionHandler<void()>&& completionHandler)
+{
+    delete this;
+    completionHandler();
+}
+
+void NPObjectMessageReceiver::hasMethod(const NPIdentifierData& methodNameData, CompletionHandler<void(bool)>&& completionHandler)
+{
+    if (m_plugin->isBeingDestroyed() || !m_npObject->_class->hasMethod)
+        return completionHandler(false);
+
+    completionHandler(m_npObject->_class->hasMethod(m_npObject, methodNameData.createNPIdentifier()));
+}
+
+void NPObjectMessageReceiver::invoke(const NPIdentifierData& methodNameData, const Vector<NPVariantData>& argumentsData, CompletionHandler<void(bool, NPVariantData&&)>&& completionHandler)
+{
+    if (m_plugin->isBeingDestroyed() || !m_npObject->_class->invoke)
+        return completionHandler(false, { });
+
+    Vector<NPVariant> arguments;
+    for (size_t i = 0; i < argumentsData.size(); ++i)
+        arguments.append(m_npRemoteObjectMap->npVariantDataToNPVariant(argumentsData[i], m_plugin));
+
+    NPVariant result;
+    VOID_TO_NPVARIANT(result);
+
+    PluginController::PluginDestructionProtector protector(m_plugin->controller());
+
+    NPVariantData resultData;
+    bool returnValue = m_npObject->_class->invoke(m_npObject, methodNameData.createNPIdentifier(), arguments.data(), arguments.size(), &result);
+    if (returnValue) {
+        // Convert the NPVariant to an NPVariantData.
+        resultData = m_npRemoteObjectMap->npVariantToNPVariantData(result, m_plugin);
+    }
+
+    // Release all arguments.
+    for (size_t i = 0; i < argumentsData.size(); ++i)
+        releaseNPVariantValue(&arguments[i]);
+    
+    // And release the result.
+    releaseNPVariantValue(&result);
+    completionHandler(returnValue, WTFMove(resultData));
+}
+
+void NPObjectMessageReceiver::invokeDefault(const Vector<NPVariantData>& argumentsData, CompletionHandler<void(bool, NPVariantData&&)>&& completionHandler)
+{
+    if (m_plugin->isBeingDestroyed() || !m_npObject->_class->invokeDefault)
+        return completionHandler(false, { });
+
+    Vector<NPVariant> arguments;
+    for (size_t i = 0; i < argumentsData.size(); ++i)
+        arguments.append(m_npRemoteObjectMap->npVariantDataToNPVariant(argumentsData[i], m_plugin));
+
+    NPVariant result;
+    VOID_TO_NPVARIANT(result);
+
+    PluginController::PluginDestructionProtector protector(m_plugin->controller());
+
+    NPVariantData resultData;
+    bool returnValue = m_npObject->_class->invokeDefault(m_npObject, arguments.data(), arguments.size(), &result);
+    if (returnValue) {
+        // Convert the NPVariant to an NPVariantData.
+        resultData = m_npRemoteObjectMap->npVariantToNPVariantData(result, m_plugin);
+    }
+
+    // Release all arguments.
+    for (size_t i = 0; i < argumentsData.size(); ++i)
+        releaseNPVariantValue(&arguments[i]);
+    
+    // And release the result.
+    releaseNPVariantValue(&result);
+    completionHandler(returnValue, WTFMove(resultData));
+}
+
+void NPObjectMessageReceiver::hasProperty(const NPIdentifierData& propertyNameData, CompletionHandler<void(bool)>&& completionHandler)
+{
+    if (m_plugin->isBeingDestroyed() || !m_npObject->_class->hasProperty)
+        return completionHandler(false);
+
+    completionHandler(m_npObject->_class->hasProperty(m_npObject, propertyNameData.createNPIdentifier()));
+}
+
+void NPObjectMessageReceiver::getProperty(const NPIdentifierData& propertyNameData, CompletionHandler<void(bool, NPVariantData&&)>&& completionHandler)
+{
+    if (m_plugin->isBeingDestroyed() || !m_npObject->_class->getProperty)
+        return completionHandler(false, { });
+
+    NPVariant result;
+    VOID_TO_NPVARIANT(result);
+
+    PluginController::PluginDestructionProtector protector(m_plugin->controller());
+
+    bool returnValue = m_npObject->_class->getProperty(m_npObject, propertyNameData.createNPIdentifier(), &result);
+    if (!returnValue)
+        return completionHandler(false, { });
+
+
+    NPVariantData resultData = m_npRemoteObjectMap->npVariantToNPVariantData(result, m_plugin);
+
+    releaseNPVariantValue(&result);
+    completionHandler(true, WTFMove(resultData));
+}
+
+void NPObjectMessageReceiver::setProperty(const NPIdentifierData& propertyNameData, const NPVariantData& propertyValueData, CompletionHandler<void(bool)>&& completionHandler)
+{
+    if (m_plugin->isBeingDestroyed() || !m_npObject->_class->setProperty)
+        return completionHandler(false);
+
+    NPVariant propertyValue = m_npRemoteObjectMap->npVariantDataToNPVariant(propertyValueData, m_plugin);
+
+    PluginController::PluginDestructionProtector protector(m_plugin->controller());
+
+    bool returnValue = m_npObject->_class->setProperty(m_npObject, propertyNameData.createNPIdentifier(), &propertyValue);
+
+    releaseNPVariantValue(&propertyValue);
+    completionHandler(returnValue);
+}
+
+void NPObjectMessageReceiver::removeProperty(const NPIdentifierData& propertyNameData, CompletionHandler<void(bool)>&& completionHandler)
+{
+    if (m_plugin->isBeingDestroyed() || !m_npObject->_class->removeProperty)
+        return completionHandler(false);
+
+    completionHandler(m_npObject->_class->removeProperty(m_npObject, propertyNameData.createNPIdentifier()));
+}
+
+void NPObjectMessageReceiver::enumerate(CompletionHandler<void(bool, Vector<NPIdentifierData>&&)>&& completionHandler)
+{
+    if (m_plugin->isBeingDestroyed() || !NP_CLASS_STRUCT_VERSION_HAS_ENUM(m_npObject->_class) || !m_npObject->_class->enumerate)
+        return completionHandler(false, { });
+
+    NPIdentifier* identifiers = 0;
+    uint32_t identifierCount = 0;
+
+    bool returnValue = m_npObject->_class->enumerate(m_npObject, &identifiers, &identifierCount);
+    if (!returnValue)
+        return completionHandler(false, { });
+
+    Vector<WebKit::NPIdentifierData> identifiersData;
+    for (uint32_t i = 0; i < identifierCount; ++i)
+        identifiersData.append(NPIdentifierData::fromNPIdentifier(identifiers[i]));
+
+    npnMemFree(identifiers);
+    completionHandler(true, WTFMove(identifiersData));
+}
+
+void NPObjectMessageReceiver::construct(const Vector<NPVariantData>& argumentsData, CompletionHandler<void(bool, NPVariantData&&)>&& completionHandler)
+{
+    if (m_plugin->isBeingDestroyed() || !NP_CLASS_STRUCT_VERSION_HAS_CTOR(m_npObject->_class) || !m_npObject->_class->construct)
+        return completionHandler(false, { });
+
+    Vector<NPVariant> arguments;
+    for (size_t i = 0; i < argumentsData.size(); ++i)
+        arguments.append(m_npRemoteObjectMap->npVariantDataToNPVariant(argumentsData[i], m_plugin));
+
+    NPVariant result;
+    VOID_TO_NPVARIANT(result);
+
+    PluginController::PluginDestructionProtector protector(m_plugin->controller());
+
+    bool returnValue = m_npObject->_class->construct(m_npObject, arguments.data(), arguments.size(), &result);
+    NPVariantData resultData;
+    if (returnValue)
+        resultData = m_npRemoteObjectMap->npVariantToNPVariantData(result, m_plugin);
+
+    for (size_t i = 0; i < argumentsData.size(); ++i)
+        releaseNPVariantValue(&arguments[i]);
+    
+    releaseNPVariantValue(&result);
+    completionHandler(returnValue, WTFMove(resultData));
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPObjectMessageReceiver.h webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPObjectMessageReceiver.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPObjectMessageReceiver.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPObjectMessageReceiver.h	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "Connection.h"
+#include <WebCore/npruntime.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebKit {
+
+class NPIdentifierData;
+class NPRemoteObjectMap;
+class NPVariantData;
+class Plugin;
+
+class NPObjectMessageReceiver {
+    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_NONCOPYABLE(NPObjectMessageReceiver);
+
+public:
+    NPObjectMessageReceiver(NPRemoteObjectMap*, Plugin*, uint64_t npObjectID, NPObject*);
+    ~NPObjectMessageReceiver();
+
+    bool didReceiveSyncNPObjectMessageReceiverMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&);
+
+    Plugin* plugin() const { return m_plugin; }
+    NPObject* npObject() const { return m_npObject; }
+    
+private:
+    // Message handlers.
+    void deallocate(CompletionHandler<void()>&&);
+    void hasMethod(const NPIdentifierData&, CompletionHandler<void(bool)>&&);
+    void invoke(const NPIdentifierData&, const Vector<NPVariantData>& argumentsData, CompletionHandler<void(bool, NPVariantData&&)>&&);
+    void invokeDefault(const Vector<NPVariantData>& argumentsData, CompletionHandler<void(bool, NPVariantData&&)>&&);
+    void hasProperty(const NPIdentifierData&, CompletionHandler<void(bool)>&&);
+    void getProperty(const NPIdentifierData&, CompletionHandler<void(bool, NPVariantData&&)>&&);
+    void setProperty(const NPIdentifierData&, const NPVariantData& propertyValueData, CompletionHandler<void(bool)>&&);
+    void removeProperty(const NPIdentifierData&, CompletionHandler<void(bool)>&&);
+    void enumerate(CompletionHandler<void(bool, Vector<NPIdentifierData>&&)>&&);
+    void construct(const Vector<NPVariantData>& argumentsData, CompletionHandler<void(bool, NPVariantData&&)>&&);
+
+    NPRemoteObjectMap* m_npRemoteObjectMap;
+    Plugin* m_plugin;
+    uint64_t m_npObjectID;
+    NPObject* m_npObject;
+};
+    
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPObjectMessageReceiver.messages.in webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPObjectMessageReceiver.messages.in
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPObjectMessageReceiver.messages.in	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPObjectMessageReceiver.messages.in	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,38 @@
+# Copyright (C) 2010 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+messages -> NPObjectMessageReceiver LegacyReceiver NotRefCounted {
+    Deallocate() -> () Synchronous
+    HasMethod(WebKit::NPIdentifierData methodName) -> (bool returnValue) Synchronous
+    Invoke(WebKit::NPIdentifierData methodName, Vector<WebKit::NPVariantData> argumentsData) -> (bool returnValue, WebKit::NPVariantData resultData) Synchronous
+    InvokeDefault(Vector<WebKit::NPVariantData> argumentsData) -> (bool returnValue, WebKit::NPVariantData resultData) Synchronous
+    HasProperty(WebKit::NPIdentifierData propertyName) -> (bool returnValue) Synchronous
+    GetProperty(WebKit::NPIdentifierData propertyName) -> (bool returnValue, WebKit::NPVariantData resultData) Synchronous
+    SetProperty(WebKit::NPIdentifierData propertyName, WebKit::NPVariantData propertyValueData) -> (bool returnValue) Synchronous
+    RemoveProperty(WebKit::NPIdentifierData propertyName) -> (bool returnValue) Synchronous
+    Enumerate() -> (bool returnValue, Vector<WebKit::NPIdentifierData> identifiersData) Synchronous
+    Construct(Vector<WebKit::NPVariantData> argumentsData) -> (bool returnValue, WebKit::NPVariantData resultData) Synchronous
+}
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPObjectProxy.cpp webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPObjectProxy.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPObjectProxy.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPObjectProxy.cpp	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NPObjectProxy.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "ArgumentCoders.h"
+#include "Connection.h"
+#include "NPIdentifierData.h"
+#include "NPObjectMessageReceiverMessages.h"
+#include "NPRemoteObjectMap.h"
+#include "NPRuntimeUtilities.h"
+#include "NPVariantData.h"
+#include <wtf/MainThread.h>
+#include <wtf/RunLoop.h>
+
+namespace WebKit {
+
+NPObjectProxy* NPObjectProxy::create(NPRemoteObjectMap* npRemoteObjectMap, Plugin* plugin, uint64_t npObjectID)
+{
+    NPObjectProxy* npObjectProxy = toNPObjectProxy(createNPObject(0, npClass()));
+    npObjectProxy->initialize(npRemoteObjectMap, plugin, npObjectID);
+
+    return npObjectProxy;
+}
+
+NPObjectProxy::NPObjectProxy()
+    : m_npRemoteObjectMap(0)
+    , m_plugin(0)
+    , m_npObjectID(0)
+{
+}
+
+NPObjectProxy::~NPObjectProxy()
+{
+    ASSERT(RunLoop::isMain());
+
+    if (!m_npRemoteObjectMap)
+        return;
+
+    m_npRemoteObjectMap->npObjectProxyDestroyed(this);
+    m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::Deallocate(), Messages::NPObjectMessageReceiver::Deallocate::Reply(), m_npObjectID);
+}
+
+bool NPObjectProxy::isNPObjectProxy(NPObject* npObject)
+{
+    return npObject->_class == npClass();
+}
+
+void NPObjectProxy::invalidate()
+{
+    ASSERT(m_npRemoteObjectMap);
+    ASSERT(m_plugin);
+
+    m_npRemoteObjectMap = 0;
+    m_plugin = 0;
+}
+    
+void NPObjectProxy::initialize(NPRemoteObjectMap* npRemoteObjectMap, Plugin* plugin, uint64_t npObjectID)
+{
+    ASSERT(!m_npRemoteObjectMap);
+    ASSERT(!m_plugin);
+    ASSERT(!m_npObjectID);
+
+    ASSERT(npRemoteObjectMap);
+    ASSERT(plugin);
+    ASSERT(npObjectID);
+
+    m_npRemoteObjectMap = npRemoteObjectMap;
+    m_plugin = plugin;
+    m_npObjectID = npObjectID;
+}
+
+bool NPObjectProxy::hasMethod(NPIdentifier methodName)
+{
+    if (!m_npRemoteObjectMap)
+        return false;
+    
+    NPIdentifierData methodNameData = NPIdentifierData::fromNPIdentifier(methodName);
+    
+    bool returnValue = false;
+    
+    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::HasMethod(methodNameData), Messages::NPObjectMessageReceiver::HasMethod::Reply(returnValue), m_npObjectID))
+        return false;
+    
+    return returnValue;
+}
+
+bool NPObjectProxy::invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    if (!m_npRemoteObjectMap)
+        return false;
+
+    NPIdentifierData methodNameData = NPIdentifierData::fromNPIdentifier(methodName);
+    Vector<NPVariantData> argumentsData;
+    for (uint32_t i = 0; i < argumentCount; ++i)
+        argumentsData.append(m_npRemoteObjectMap->npVariantToNPVariantData(arguments[i], m_plugin));
+
+    bool returnValue = false;
+    NPVariantData resultData;
+    
+    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::Invoke(methodNameData, argumentsData), Messages::NPObjectMessageReceiver::Invoke::Reply(returnValue, resultData), m_npObjectID))
+        return false;
+    
+    if (!returnValue)
+        return false;
+    
+    *result = m_npRemoteObjectMap->npVariantDataToNPVariant(resultData, m_plugin);
+    return true;
+}
+
+bool NPObjectProxy::invokeDefault(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    if (!m_npRemoteObjectMap)
+        return false;
+
+    Vector<NPVariantData> argumentsData;
+    for (uint32_t i = 0; i < argumentCount; ++i)
+        argumentsData.append(m_npRemoteObjectMap->npVariantToNPVariantData(arguments[i], m_plugin));
+
+    bool returnValue = false;
+    NPVariantData resultData;
+    
+    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::InvokeDefault(argumentsData), Messages::NPObjectMessageReceiver::InvokeDefault::Reply(returnValue, resultData), m_npObjectID))
+        return false;
+    
+    if (!returnValue)
+        return false;
+    
+    *result = m_npRemoteObjectMap->npVariantDataToNPVariant(resultData, m_plugin);
+    return true;
+}
+
+bool NPObjectProxy::hasProperty(NPIdentifier propertyName)
+{
+    if (!m_npRemoteObjectMap)
+        return false;
+    
+    NPIdentifierData propertyNameData = NPIdentifierData::fromNPIdentifier(propertyName);
+
+    bool returnValue = false;
+    
+    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::HasProperty(propertyNameData), Messages::NPObjectMessageReceiver::HasProperty::Reply(returnValue), m_npObjectID))
+        return false;
+
+    return returnValue;
+}
+
+bool NPObjectProxy::getProperty(NPIdentifier propertyName, NPVariant* result)
+{
+    if (!m_npRemoteObjectMap)
+        return false;
+
+    NPIdentifierData propertyNameData = NPIdentifierData::fromNPIdentifier(propertyName);
+
+    bool returnValue = false;
+    NPVariantData resultData;
+    
+    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::GetProperty(propertyNameData), Messages::NPObjectMessageReceiver::GetProperty::Reply(returnValue, resultData), m_npObjectID))
+        return false;
+
+    if (!returnValue)
+        return false;
+
+    *result = m_npRemoteObjectMap->npVariantDataToNPVariant(resultData, m_plugin);
+    return true;
+}
+
+bool NPObjectProxy::setProperty(NPIdentifier propertyName, const NPVariant* value)
+{
+    if (!m_npRemoteObjectMap)
+        return false;
+    
+    NPIdentifierData propertyNameData = NPIdentifierData::fromNPIdentifier(propertyName);
+    NPVariantData propertyValueData = m_npRemoteObjectMap->npVariantToNPVariantData(*value, m_plugin);
+
+    bool returnValue = false;
+
+    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::SetProperty(propertyNameData, propertyValueData), Messages::NPObjectMessageReceiver::SetProperty::Reply(returnValue), m_npObjectID))
+        return false;
+
+    return returnValue;
+}
+
+bool NPObjectProxy::removeProperty(NPIdentifier propertyName)
+{
+    if (!m_npRemoteObjectMap)
+        return false;
+    
+    NPIdentifierData propertyNameData = NPIdentifierData::fromNPIdentifier(propertyName);
+
+    bool returnValue = false;
+    
+    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::RemoveProperty(propertyNameData), Messages::NPObjectMessageReceiver::RemoveProperty::Reply(returnValue), m_npObjectID))
+        return false;
+
+    return returnValue;
+}
+
+bool NPObjectProxy::enumerate(NPIdentifier** identifiers, uint32_t* identifierCount)
+{
+    if (!m_npRemoteObjectMap)
+        return false;
+
+    bool returnValue;
+    Vector<NPIdentifierData> identifiersData;
+
+    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::Enumerate(), Messages::NPObjectMessageReceiver::Enumerate::Reply(returnValue, identifiersData), m_npObjectID))
+        return false;
+
+    if (!returnValue)
+        return false;
+
+    NPIdentifier* nameIdentifiers = npnMemNewArray<NPIdentifier>(identifiersData.size());
+    
+    for (size_t i = 0; i < identifiersData.size(); ++i)
+        nameIdentifiers[i] = identifiersData[i].createNPIdentifier();
+    
+    *identifiers = nameIdentifiers;
+    *identifierCount = identifiersData.size();
+    return true;
+}
+
+bool NPObjectProxy::construct(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    if (!m_npRemoteObjectMap)
+        return false;
+
+    Vector<NPVariantData> argumentsData;
+    for (uint32_t i = 0; i < argumentCount; ++i)
+        argumentsData.append(m_npRemoteObjectMap->npVariantToNPVariantData(arguments[i], m_plugin));
+
+    bool returnValue = false;
+    NPVariantData resultData;
+    
+    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::Construct(argumentsData), Messages::NPObjectMessageReceiver::Construct::Reply(returnValue, resultData), m_npObjectID))
+        return false;
+    
+    if (!returnValue)
+        return false;
+    
+    *result = m_npRemoteObjectMap->npVariantDataToNPVariant(resultData, m_plugin);
+    return true;
+}
+
+NPClass* NPObjectProxy::npClass()
+{
+    static NPClass npClass = {
+        NP_CLASS_STRUCT_VERSION,
+        NP_Allocate,
+        NP_Deallocate,
+        0,
+        NP_HasMethod,
+        NP_Invoke,
+        NP_InvokeDefault,
+        NP_HasProperty,
+        NP_GetProperty,
+        NP_SetProperty,
+        NP_RemoveProperty,
+        NP_Enumerate,
+        NP_Construct
+    };
+
+    return &npClass;
+}
+
+NPObject* NPObjectProxy::NP_Allocate(NPP npp, NPClass*)
+{
+    ASSERT_UNUSED(npp, !npp);
+
+    return new NPObjectProxy;
+}
+
+void NPObjectProxy::NP_Deallocate(NPObject* npObject)
+{
+    // http://webkit.org/b/118535 - The Java Netscape Plug-in has a background thread do some of their NPP_Destroy work.
+    // That background thread can call NP_Deallocate, and this leads to a WebProcess <-> PluginProcess deadlock.
+    // Since NPAPI behavior on a background thread is undefined, it is okay to limit this workaround to the one API
+    // that is known to be misused during plugin teardown, and to not be concerned about change in behavior if this
+    // occured at any other time.
+    ensureOnMainRunLoop([npObject] {
+        delete toNPObjectProxy(npObject);
+    });
+}
+
+bool NPObjectProxy::NP_HasMethod(NPObject* npObject, NPIdentifier methodName)
+{
+    return toNPObjectProxy(npObject)->hasMethod(methodName);
+}
+
+bool NPObjectProxy::NP_Invoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    return toNPObjectProxy(npObject)->invoke(methodName, arguments, argumentCount, result);
+}
+
+bool NPObjectProxy::NP_InvokeDefault(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    return toNPObjectProxy(npObject)->invokeDefault(arguments, argumentCount, result);
+}
+
+bool NPObjectProxy::NP_HasProperty(NPObject* npObject, NPIdentifier propertyName)
+{
+    return toNPObjectProxy(npObject)->hasProperty(propertyName);
+}
+
+bool NPObjectProxy::NP_GetProperty(NPObject* npObject, NPIdentifier propertyName, NPVariant* result)
+{
+    return toNPObjectProxy(npObject)->getProperty(propertyName, result);
+}
+
+bool NPObjectProxy::NP_SetProperty(NPObject* npObject, NPIdentifier propertyName, const NPVariant* value)
+{
+    return toNPObjectProxy(npObject)->setProperty(propertyName, value);
+}
+
+bool NPObjectProxy::NP_RemoveProperty(NPObject* npObject, NPIdentifier propertyName)
+{
+    return toNPObjectProxy(npObject)->removeProperty(propertyName);
+}
+
+bool NPObjectProxy::NP_Enumerate(NPObject* npObject, NPIdentifier** identifiers, uint32_t* identifierCount)
+{
+    return toNPObjectProxy(npObject)->enumerate(identifiers, identifierCount);
+}
+
+bool NPObjectProxy::NP_Construct(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    return toNPObjectProxy(npObject)->construct(arguments, argumentCount, result);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPObjectProxy.h webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPObjectProxy.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPObjectProxy.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPObjectProxy.h	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <WebCore/npruntime_internal.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebKit {
+
+class NPRemoteObjectMap;
+class Plugin;
+
+class NPObjectProxy : public NPObject {
+    WTF_MAKE_NONCOPYABLE(NPObjectProxy);
+
+public:
+    static NPObjectProxy* create(NPRemoteObjectMap*, Plugin*, uint64_t npObjectID);
+
+    static bool isNPObjectProxy(NPObject*);
+    
+    static NPObjectProxy* toNPObjectProxy(NPObject* npObject)
+    {
+        RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(isNPObjectProxy(npObject));
+        return static_cast<NPObjectProxy*>(npObject);
+    }
+
+    Plugin* plugin() const { return m_plugin; }
+    uint64_t npObjectID() const { return m_npObjectID; }
+
+    void invalidate();
+
+private:
+    NPObjectProxy();
+    ~NPObjectProxy();
+
+    void initialize(NPRemoteObjectMap*, Plugin*, uint64_t npObjectID);
+
+    bool hasMethod(NPIdentifier methodName);
+    bool invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+    bool invokeDefault(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+    bool hasProperty(NPIdentifier propertyName);
+    bool getProperty(NPIdentifier propertyName, NPVariant* result);
+    bool setProperty(NPIdentifier propertyName, const NPVariant* value);
+    bool removeProperty(NPIdentifier propertyName);
+    bool enumerate(NPIdentifier** identifiers, uint32_t* identifierCount);
+    bool construct(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+
+    static NPClass* npClass();
+    static NPObject* NP_Allocate(NPP, NPClass*);
+    static void NP_Deallocate(NPObject*);
+    static bool NP_HasMethod(NPObject*, NPIdentifier methodName);
+    static bool NP_Invoke(NPObject*, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+    static bool NP_InvokeDefault(NPObject*, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+    static bool NP_HasProperty(NPObject*, NPIdentifier propertyName);
+    static bool NP_GetProperty(NPObject*, NPIdentifier propertyName, NPVariant* result);
+    static bool NP_SetProperty(NPObject*, NPIdentifier propertyName, const NPVariant* value);
+    static bool NP_RemoveProperty(NPObject*, NPIdentifier propertyName);
+    static bool NP_Enumerate(NPObject*, NPIdentifier** identifiers, uint32_t* identifierCount);
+    static bool NP_Construct(NPObject*, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+
+    NPRemoteObjectMap* m_npRemoteObjectMap;
+    Plugin* m_plugin;
+    uint64_t m_npObjectID;
+};
+    
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPRemoteObjectMap.cpp webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPRemoteObjectMap.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPRemoteObjectMap.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPRemoteObjectMap.cpp	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NPRemoteObjectMap.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NPObjectMessageReceiver.h"
+#include "NPObjectProxy.h"
+#include "NPRuntimeUtilities.h"
+#include "NPVariantData.h"
+
+namespace WebKit {
+
+static uint64_t generateNPObjectID()
+{
+    static uint64_t generateNPObjectID;
+    return ++generateNPObjectID;
+}
+
+Ref<NPRemoteObjectMap> NPRemoteObjectMap::create(IPC::Connection* connection)
+{
+    return adoptRef(*new NPRemoteObjectMap(connection));
+}
+
+NPRemoteObjectMap::NPRemoteObjectMap(IPC::Connection* connection)
+    : m_connection(connection)
+{
+}
+
+NPRemoteObjectMap::~NPRemoteObjectMap()
+{
+    ASSERT(m_npObjectProxies.isEmpty());
+    ASSERT(m_registeredNPObjects.isEmpty());
+}
+
+NPObject* NPRemoteObjectMap::createNPObjectProxy(uint64_t remoteObjectID, Plugin* plugin)
+{
+    NPObjectProxy* npObjectProxy = NPObjectProxy::create(this, plugin, remoteObjectID);
+
+    m_npObjectProxies.add(npObjectProxy);
+
+    return npObjectProxy;
+}
+
+void NPRemoteObjectMap::npObjectProxyDestroyed(NPObject* npObject)
+{
+    NPObjectProxy* npObjectProxy = NPObjectProxy::toNPObjectProxy(npObject);
+    ASSERT(m_npObjectProxies.contains(npObjectProxy));
+
+    m_npObjectProxies.remove(npObjectProxy);
+}
+
+uint64_t NPRemoteObjectMap::registerNPObject(NPObject* npObject, Plugin* plugin)
+{
+    uint64_t npObjectID = generateNPObjectID();
+    m_registeredNPObjects.set(npObjectID, makeUnique<NPObjectMessageReceiver>(this, plugin, npObjectID, npObject).release());
+
+    return npObjectID;
+}
+
+void NPRemoteObjectMap::unregisterNPObject(uint64_t npObjectID)
+{
+    m_registeredNPObjects.remove(npObjectID);
+}
+
+static uint64_t remoteNPObjectID(Plugin* plugin, NPObject* npObject)
+{
+    if (!NPObjectProxy::isNPObjectProxy(npObject))
+        return 0;
+
+    NPObjectProxy* npObjectProxy = NPObjectProxy::toNPObjectProxy(npObject);
+    if (npObjectProxy->plugin() != plugin)
+        return 0;
+
+    return npObjectProxy->npObjectID();
+}
+
+NPVariantData NPRemoteObjectMap::npVariantToNPVariantData(const NPVariant& variant, Plugin* plugin)
+{
+    switch (variant.type) {
+    case NPVariantType_Void:
+        return NPVariantData::makeVoid();
+
+    case NPVariantType_Null:
+        return NPVariantData::makeNull();
+
+    case NPVariantType_Bool:
+        return NPVariantData::makeBool(variant.value.boolValue);
+
+    case NPVariantType_Int32:
+        return NPVariantData::makeInt32(variant.value.intValue);
+
+    case NPVariantType_Double:
+        return NPVariantData::makeDouble(variant.value.doubleValue);
+
+    case NPVariantType_String:
+        return NPVariantData::makeString(variant.value.stringValue.UTF8Characters, variant.value.stringValue.UTF8Length);
+
+    case NPVariantType_Object: {
+        NPObject* npObject = variant.value.objectValue;
+
+        if (uint64_t npObjectID = remoteNPObjectID(plugin, npObject)) {
+            // FIXME: Under some circumstances, this might leak the NPObjectProxy object. 
+            // Figure out how to avoid that.
+            retainNPObject(npObject);
+            return NPVariantData::makeRemoteNPObjectID(npObjectID);
+        }
+
+        uint64_t npObjectID = registerNPObject(npObject, plugin);
+        return NPVariantData::makeLocalNPObjectID(npObjectID);
+    }
+
+    }
+
+    ASSERT_NOT_REACHED();
+    return NPVariantData::makeVoid();
+}
+
+NPVariant NPRemoteObjectMap::npVariantDataToNPVariant(const NPVariantData& npVariantData, Plugin* plugin)
+{
+    NPVariant npVariant;
+
+    switch (npVariantData.type()) {
+    case NPVariantData::Void:
+        VOID_TO_NPVARIANT(npVariant);
+        break;
+    case NPVariantData::Null:
+        NULL_TO_NPVARIANT(npVariant);
+        break;
+    case NPVariantData::Bool:
+        BOOLEAN_TO_NPVARIANT(npVariantData.boolValue(), npVariant);
+        break;
+    case NPVariantData::Int32:
+        INT32_TO_NPVARIANT(npVariantData.int32Value(), npVariant);
+        break;
+    case NPVariantData::Double:
+        DOUBLE_TO_NPVARIANT(npVariantData.doubleValue(), npVariant);
+        break;
+    case NPVariantData::String: {
+        NPString npString = createNPString(npVariantData.stringValue());
+        STRINGN_TO_NPVARIANT(npString.UTF8Characters, npString.UTF8Length, npVariant);
+        break;
+    }
+    case NPVariantData::LocalNPObjectID: {
+        uint64_t npObjectID = npVariantData.localNPObjectIDValue();
+        ASSERT(npObjectID);
+
+        NPObjectMessageReceiver* npObjectMessageReceiver = m_registeredNPObjects.get(npObjectID);
+        if (!npObjectMessageReceiver) {
+            ASSERT_NOT_REACHED();
+            VOID_TO_NPVARIANT(npVariant);
+            break;
+        }
+
+        NPObject* npObject = npObjectMessageReceiver->npObject();
+        ASSERT(npObject);
+
+        retainNPObject(npObject);
+        OBJECT_TO_NPVARIANT(npObject, npVariant);
+        break;
+    }
+    case NPVariantData::RemoteNPObjectID: {
+        NPObject* npObjectProxy = createNPObjectProxy(npVariantData.remoteNPObjectIDValue(), plugin);
+        OBJECT_TO_NPVARIANT(npObjectProxy, npVariant);
+        break;
+    }
+    }
+
+    return npVariant;
+}
+
+void NPRemoteObjectMap::pluginDestroyed(Plugin* plugin)
+{
+    // Gather and delete the receivers associated with this plug-in.
+    Vector<NPObjectMessageReceiver*> receivers;
+    for (auto* receiver : m_registeredNPObjects.values()) {
+        if (receiver->plugin() == plugin)
+            receivers.append(receiver);
+    }
+    for (auto* receiver : receivers)
+        delete receiver;
+
+    // Invalidate and remove all proxies associated with this plug-in.
+    Vector<NPObjectProxy*> proxies;
+    for (auto* proxy : m_npObjectProxies) {
+        if (proxy->plugin() == plugin)
+            proxies.append(proxy);
+    }
+    for (auto* proxy : proxies) {
+        proxy->invalidate();
+        ASSERT(m_npObjectProxies.contains(proxy));
+        m_npObjectProxies.remove(proxy);
+    }
+}
+
+bool NPRemoteObjectMap::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, UniqueRef<IPC::Encoder>& replyEncoder)
+{
+    NPObjectMessageReceiver* messageReceiver = m_registeredNPObjects.get(decoder.destinationID());
+    if (!messageReceiver)
+        return false;
+
+    return messageReceiver->didReceiveSyncNPObjectMessageReceiverMessage(connection, decoder, replyEncoder);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPRemoteObjectMap.h webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPRemoteObjectMap.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPRemoteObjectMap.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPRemoteObjectMap.h	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NPRemoteObjectMap_h
+#define NPRemoteObjectMap_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "Connection.h"
+#include <WebCore/npruntime.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/RefCounted.h>
+
+namespace WebKit {
+
+class NPObjectMessageReceiver;
+class NPObjectProxy;
+class NPVariantData;
+class Plugin;
+
+class NPRemoteObjectMap : public RefCounted<NPRemoteObjectMap> {
+public:
+    static Ref<NPRemoteObjectMap> create(IPC::Connection*);
+    ~NPRemoteObjectMap();
+
+    // Creates an NPObjectProxy wrapper for the remote object with the given remote object ID.
+    NPObject* createNPObjectProxy(uint64_t remoteObjectID, Plugin*);
+    void npObjectProxyDestroyed(NPObject*);
+
+    // Expose the given NPObject as a remote object. Returns the objectID.
+    uint64_t registerNPObject(NPObject*, Plugin*);
+    void unregisterNPObject(uint64_t);
+
+    NPVariantData npVariantToNPVariantData(const NPVariant&, Plugin*);
+    NPVariant npVariantDataToNPVariant(const NPVariantData&, Plugin*);
+
+    IPC::Connection* connection() const { return m_connection; }
+
+    void pluginDestroyed(Plugin*);
+
+    bool didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&);
+
+private:
+    explicit NPRemoteObjectMap(IPC::Connection*);
+    IPC::Connection* m_connection;
+
+    // A map of NPObjectMessageReceiver classes, wrapping objects that we export to the
+    // other end of the connection.
+    HashMap<uint64_t, NPObjectMessageReceiver*> m_registeredNPObjects;
+
+    // A set of NPObjectProxy objects associated with this map.
+    HashSet<NPObjectProxy*> m_npObjectProxies;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // NPRemoteObjectMap_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPVariantData.cpp webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPVariantData.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPVariantData.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPVariantData.cpp	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NPVariantData.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "Decoder.h"
+#include "Encoder.h"
+#include "WebCoreArgumentCoders.h"
+
+namespace WebKit {
+
+NPVariantData::NPVariantData()
+    : m_type(NPVariantData::Void)
+    , m_boolValue(false)
+    , m_int32Value(0)
+    , m_doubleValue(0)
+    , m_localNPObjectIDValue(0)
+    , m_remoteNPObjectIDValue(0)
+{
+}
+
+NPVariantData NPVariantData::makeVoid()
+{
+    return NPVariantData();
+}
+
+NPVariantData NPVariantData::makeNull()
+{
+    NPVariantData npVariantData;
+    
+    npVariantData.m_type = NPVariantData::Null;
+    
+    return npVariantData;
+}
+    
+NPVariantData NPVariantData::makeBool(bool value)
+{
+    NPVariantData npVariantData;
+
+    npVariantData.m_type = NPVariantData::Bool;
+    npVariantData.m_boolValue = value;
+
+    return npVariantData;
+}
+
+NPVariantData NPVariantData::makeInt32(int32_t value)
+{
+    NPVariantData npVariantData;
+
+    npVariantData.m_type = NPVariantData::Int32;
+    npVariantData.m_int32Value = value;
+
+    return npVariantData;
+}    
+
+NPVariantData NPVariantData::makeDouble(double value)
+{
+    NPVariantData npVariantData;
+
+    npVariantData.m_type = NPVariantData::Double;
+    npVariantData.m_doubleValue = value;
+
+    return npVariantData;
+}
+
+NPVariantData NPVariantData::makeString(const char* string, unsigned length)
+{
+    NPVariantData npVariantData;
+    
+    npVariantData.m_type = NPVariantData::String;
+    npVariantData.m_stringValue = CString(string, length);
+    
+    return npVariantData;
+}
+
+NPVariantData NPVariantData::makeLocalNPObjectID(uint64_t value)
+{
+    NPVariantData npVariantData;
+
+    npVariantData.m_type = NPVariantData::LocalNPObjectID;
+    npVariantData.m_localNPObjectIDValue = value;
+
+    return npVariantData;
+}
+
+NPVariantData NPVariantData::makeRemoteNPObjectID(uint64_t value)
+{
+    NPVariantData npVariantData;
+
+    npVariantData.m_type = NPVariantData::RemoteNPObjectID;
+    npVariantData.m_remoteNPObjectIDValue = value;
+
+    return npVariantData;
+}
+
+void NPVariantData::encode(IPC::Encoder& encoder) const
+{
+    encoder << m_type;
+
+    switch (type()) {
+    case NPVariantData::Void:
+    case NPVariantData::Null:
+        break;
+    case NPVariantData::Bool:
+        encoder << boolValue();
+        break;
+    case NPVariantData::Int32:
+        encoder << int32Value();
+        break;
+    case NPVariantData::Double:
+        encoder << doubleValue();
+        break;
+    case NPVariantData::String:
+        encoder << stringValue();
+        break;
+    case NPVariantData::LocalNPObjectID:
+        encoder << localNPObjectIDValue();
+        break;
+    case NPVariantData::RemoteNPObjectID:
+        encoder << remoteNPObjectIDValue();
+        break;
+    }
+}
+
+std::optional<NPVariantData> NPVariantData::decode(IPC::Decoder& decoder)
+{
+    NPVariantData result;
+    uint32_t type;
+    if (!decoder.decode(type))
+        return std::nullopt;
+
+    // We special-case LocalNPObjectID and RemoteNPObjectID here so a LocalNPObjectID is
+    // decoded as a RemoteNPObjectID and vice versa.
+    // This is done because the type is from the perspective of the other connection, and
+    // thus we have to adjust it to match our own perspective.
+    if (type == NPVariantData::LocalNPObjectID)
+        type = NPVariantData::RemoteNPObjectID;
+    else if (type == NPVariantData::RemoteNPObjectID)
+        type = NPVariantData::LocalNPObjectID;
+
+    result.m_type = type;
+
+    switch (result.m_type) {
+    case NPVariantData::Void:
+    case NPVariantData::Null:
+        return result;
+    case NPVariantData::Bool:
+        if (!decoder.decode(result.m_boolValue))
+            return std::nullopt;
+        return result;
+    case NPVariantData::Int32:
+        if (!decoder.decode(result.m_int32Value))
+            return std::nullopt;
+        return result;
+    case NPVariantData::Double:
+        if (!decoder.decode(result.m_doubleValue))
+            return std::nullopt;
+        return result;
+    case NPVariantData::String:
+        if (!decoder.decode(result.m_stringValue))
+            return std::nullopt;
+        return result;
+    case NPVariantData::LocalNPObjectID:
+        if (!decoder.decode(result.m_localNPObjectIDValue))
+            return std::nullopt;
+        return result;
+    case NPVariantData::RemoteNPObjectID:
+        if (!decoder.decode(result.m_remoteNPObjectIDValue))
+            return std::nullopt;
+        return result;
+    }
+
+    return std::nullopt;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPVariantData.h webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPVariantData.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/NPVariantData.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/NPVariantData.h	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <wtf/text/CString.h>
+
+namespace IPC {
+class Decoder;
+class Encoder;
+}
+
+namespace WebKit {
+
+class NPVariantData {
+public:
+    enum Type {
+        Void,
+        Null,
+        Bool,
+        Int32,
+        Double,
+        String,
+        LocalNPObjectID,
+        RemoteNPObjectID,
+    };
+    NPVariantData();
+
+    static NPVariantData makeVoid();
+    static NPVariantData makeNull();
+    static NPVariantData makeBool(bool value);
+    static NPVariantData makeInt32(int32_t value);
+    static NPVariantData makeDouble(double value);
+    static NPVariantData makeString(const char* string, unsigned length);
+    static NPVariantData makeLocalNPObjectID(uint64_t value);
+    static NPVariantData makeRemoteNPObjectID(uint64_t value);
+
+    Type type() const { return static_cast<Type>(m_type); }
+
+    bool boolValue() const
+    {
+        ASSERT(type() == NPVariantData::Bool);
+        return m_boolValue;
+    }
+
+    int32_t int32Value() const
+    {
+        ASSERT(type() == NPVariantData::Int32);
+        return m_int32Value;
+    }
+
+    double doubleValue() const
+    {
+        ASSERT(type() == NPVariantData::Double);
+        return m_doubleValue;
+    }
+
+    const CString& stringValue() const
+    {
+        ASSERT(type() == NPVariantData::String);
+        return m_stringValue;
+    }
+
+    uint64_t localNPObjectIDValue() const
+    {
+        ASSERT(type() == NPVariantData::LocalNPObjectID);
+        return m_localNPObjectIDValue;
+    }
+
+    uint64_t remoteNPObjectIDValue() const
+    {
+        ASSERT(type() == NPVariantData::RemoteNPObjectID);
+        return m_remoteNPObjectIDValue;
+    }
+
+    void encode(IPC::Encoder&) const;
+    static std::optional<NPVariantData> decode(IPC::Decoder&);
+
+private:
+    uint32_t m_type;
+    bool m_boolValue;
+    int32_t m_int32Value;
+    double m_doubleValue;
+    CString m_stringValue;
+    uint64_t m_localNPObjectIDValue;
+    uint64_t m_remoteNPObjectIDValue;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/PluginModuleInfo.h webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/PluginModuleInfo.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/PluginModuleInfo.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/PluginModuleInfo.h	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <WebCore/PluginData.h>
+
+#if PLATFORM(COCOA)
+#include <mach/machine.h>
+#endif
+
+namespace WebKit {
+
+enum PluginModuleLoadPolicy {
+    // The plug-in module should be loaded normally.
+    PluginModuleLoadNormally,
+
+    // The plug-in module should be loaded normally. If the plug-in has a sandbox, it will be disabled.
+    PluginModuleLoadUnsandboxed,
+
+    // The plug-in should be blocked from being instantiated.
+    // Note that the plug-in will still be seen by e.g. navigator.plugins
+    PluginModuleBlockedForSecurity,
+    PluginModuleBlockedForCompatibility,
+};
+
+struct PluginModuleInfo {
+    String path;
+    WebCore::PluginInfo info;
+
+#if PLATFORM(COCOA)
+    cpu_type_t pluginArchitecture;
+    String bundleIdentifier;
+    String versionString;
+    String shortVersionString;
+    bool hasSandboxProfile;
+#endif
+};
+
+} // namespace WebKit
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/PluginProcessAttributes.h webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/PluginProcessAttributes.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/PluginProcessAttributes.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/PluginProcessAttributes.h	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "PluginModuleInfo.h"
+#include <wtf/EnumTraits.h>
+
+namespace WebKit {
+
+enum class PluginProcessSandboxPolicy : bool {
+    Normal,
+    Unsandboxed,
+};
+
+struct PluginProcessAttributes {
+    PluginModuleInfo moduleInfo;
+    PluginProcessSandboxPolicy sandboxPolicy;
+};
+
+} // namespace WebKit
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/PluginProcessCreationParameters.cpp webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/PluginProcessCreationParameters.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/PluginProcessCreationParameters.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/PluginProcessCreationParameters.cpp	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginProcessCreationParameters.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+#if PLATFORM(COCOA)
+#include "ArgumentCodersCF.h"
+#endif
+#include "WebCoreArgumentCoders.h"
+
+namespace WebKit {
+
+PluginProcessCreationParameters::PluginProcessCreationParameters()
+    : supportsAsynchronousPluginInitialization(false)
+{
+}
+
+void PluginProcessCreationParameters::encode(IPC::Encoder& encoder) const
+{
+    encoder << supportsAsynchronousPluginInitialization;
+    encoder << minimumLifetime;
+    encoder << terminationTimeout;
+#if PLATFORM(COCOA)
+    encoder << acceleratedCompositingPort;
+    encoder << networkATSContext;
+#endif
+}
+
+bool PluginProcessCreationParameters::decode(IPC::Decoder& decoder, PluginProcessCreationParameters& result)
+{
+    if (!decoder.decode(result.supportsAsynchronousPluginInitialization))
+        return false;
+    if (!decoder.decode(result.minimumLifetime))
+        return false;
+    if (!decoder.decode(result.terminationTimeout))
+        return false;
+#if PLATFORM(COCOA)
+    if (!decoder.decode(result.acceleratedCompositingPort))
+        return false;
+    if (!decoder.decode(result.networkATSContext))
+        return false;
+#endif
+
+    return true;
+}
+
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/PluginProcessCreationParameters.h webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/PluginProcessCreationParameters.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/PluginProcessCreationParameters.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/PluginProcessCreationParameters.h	2022-03-22 16:38:57.377580131 -0500
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "PluginProcessAttributes.h"
+#include <wtf/Seconds.h>
+
+#if PLATFORM(COCOA)
+#include <wtf/MachSendRight.h>
+#endif
+
+namespace IPC {
+class Decoder;
+class Encoder;
+}
+
+namespace WebKit {
+
+struct PluginProcessCreationParameters {
+    PluginProcessCreationParameters();
+
+    void encode(IPC::Encoder&) const;
+    static WARN_UNUSED_RETURN bool decode(IPC::Decoder&, PluginProcessCreationParameters&);
+
+    bool supportsAsynchronousPluginInitialization;
+
+    Seconds minimumLifetime;
+    Seconds terminationTimeout;
+
+#if PLATFORM(COCOA)
+    WTF::MachSendRight acceleratedCompositingPort;
+    RetainPtr<CFDataRef> networkATSContext;
+#endif
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/PluginQuirks.h webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/PluginQuirks.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/PluginQuirks.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/PluginQuirks.h	2022-03-22 16:38:57.381580153 -0500
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+namespace WebKit {
+
+class PluginQuirks {
+public:
+    enum PluginQuirk {
+        // Mac specific quirks:
+#if PLUGIN_ARCHITECTURE(MAC)
+        // The plug-in wants the call to getprogname() to return "WebKitPluginHost".
+        // Adobe Flash Will not handle key down events otherwise.
+        PrognameShouldBeWebKitPluginHost,
+
+        // Supports receiving a paint event, even when using CoreAnimation rendering.
+        SupportsSnapshotting,
+
+        // Make the plug-in opaque unless it has a "background" attribute set to a transparent color
+        // according to http://msdn.microsoft.com/en-us/library/cc838148(VS.95).aspx
+        // A non-existent "background" attribute is interpreted as the named color White which is opaque.
+        // Microsoft Silverlight doesn't opt into transparency using NPN_SetValue and
+        // NPPVpluginTransparentBool, so we'll always force it unless the plug-in has a "background"
+        // attribute that specifies a opaque color.
+        MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists,
+
+        // Whether calling NPP_GetValue with NPPVpluginCoreAnimationLayer returns a retained Core Animation
+        // layer or not. According to the NPAPI specifications, plug-in shouldn't return a retained layer but
+        // WebKit1 expects a retained plug-in layer. We use this for Flash to avoid leaking OpenGL layers.
+        ReturnsRetainedCoreAnimationLayer,
+
+        // Whether NPP_GetValue with NPPVpluginScriptableNPObject returns a non-retained NPObject or not.
+        // Versions of Silverlight prior to 4 never retained the returned NPObject.
+        ReturnsNonRetainedScriptableNPObject,
+
+        // Whether the plug-in wants parameter names to be lowercase.
+        // <rdar://problem/8440903>: AppleConnect has a bug where it does not
+        // understand the parameter names specified in the <object> element that
+        // embeds its plug-in. 
+        WantsLowercaseParameterNames,
+
+        // Whether to append Version/3.2.1 to the user-agent passed to the plugin
+        // This is necessary to disable Silverlight's workaround for a Safari 2 leak
+        // which is enabled if it doesn't find Version/3 in the user-agent.
+        AppendVersion3UserAgent,
+
+        // Whether all thrown NSExceptions should be leaked.
+        // <rdar://problem/13003470> Adobe Flash has a bug where exceptions are released too early.
+        LeakAllThrownNSExceptions,
+
+        // X11 specific quirks:
+#elif PLATFORM(X11)
+        // Flash and npwrapper ask the browser about which GTK version does it use
+        // and refuse to load and work if it is not GTK 2 so we need to fake it in
+        // NPN_GetValue even when it is a lie.
+        RequiresGTKToolKit,
+
+        // Some version 10 releases of Flash run under nspluginwrapper will completely
+        // freeze when sending right click events to them in windowed mode.
+        IgnoreRightClickInWindowlessMode,
+
+        // Some ports don't support windowed plugins.
+        ForceFlashWindowlessMode,
+
+        // Flash crashes when NPP_GetValue is called for NPPVpluginCancelSrcStream in windowed mode.
+        DoNotCancelSrcStreamInWindowedMode,
+#endif
+
+        // This isn't really a quirk as much as the opposite of a quirk. By default, we don't send wheel events
+        // to plug-ins unless we know that they handle them correctly. Adobe Reader on Mac handles wheel events correctly.
+        WantsWheelEvents,
+
+        NumPluginQuirks
+    };
+    
+    PluginQuirks()
+        : m_quirks(0)
+    {
+        COMPILE_ASSERT(sizeof(m_quirks) * 8 >= NumPluginQuirks, not_enough_room_for_quirks);
+    }
+    
+    void add(PluginQuirk quirk)
+    {
+        ASSERT(quirk >= 0);
+        RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(quirk < NumPluginQuirks);
+        
+        m_quirks |= (1 << quirk);
+    }
+    
+    bool contains(PluginQuirk quirk) const
+    {
+        return m_quirks & (1 << quirk);
+    }
+
+private:
+    uint32_t m_quirks;
+};
+
+} // namespace WebKit
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/unix/PluginSearchPath.cpp webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/unix/PluginSearchPath.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/unix/PluginSearchPath.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/unix/PluginSearchPath.cpp	2022-03-22 16:38:57.381580153 -0500
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginSearchPath.h"
+
+#include <wtf/FileSystem.h>
+
+namespace WebKit {
+
+Vector<String> pluginsDirectories()
+{
+    Vector<String> result;
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    String mozillaPaths(getenv("MOZ_PLUGIN_PATH"));
+    if (!mozillaPaths.isEmpty()) {
+        Vector<String> paths = mozillaPaths.split(':');
+        result.appendVector(paths);
+    }
+
+    String mozillaHome(getenv("MOZILLA_HOME"));
+    if (!mozillaHome.isEmpty())
+        result.append(mozillaHome + "/plugins");
+
+    result.append("/usr/lib/browser/plugins");
+    result.append("/usr/local/lib/mozilla/plugins");
+    result.append("/usr/lib/firefox/plugins");
+    result.append("/usr/lib64/browser-plugins");
+    result.append("/usr/lib/browser-plugins");
+    result.append("/usr/lib/mozilla/plugins");
+    result.append("/usr/local/netscape/plugins");
+    result.append("/opt/mozilla/plugins");
+    result.append("/opt/mozilla/lib/plugins");
+    result.append("/opt/netscape/plugins");
+    result.append("/opt/netscape/communicator/plugins");
+    result.append("/usr/lib/netscape/plugins");
+    result.append("/usr/lib/netscape/plugins-libc5");
+    result.append("/usr/lib/netscape/plugins-libc6");
+    result.append("/usr/lib64/netscape/plugins");
+    result.append("/usr/lib64/mozilla/plugins");
+    result.append("/usr/lib/nsbrowser/plugins");
+    result.append("/usr/lib64/nsbrowser/plugins");
+#endif
+
+    return result;
+}
+
+} // namespace WebKit
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/unix/PluginSearchPath.h webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/unix/PluginSearchPath.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/Plugins/unix/PluginSearchPath.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/Plugins/unix/PluginSearchPath.h	2022-03-22 16:38:57.381580153 -0500
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PluginSearchPath_h
+#define PluginSearchPath_h
+
+#include <wtf/Forward.h>
+#include <wtf/Vector.h>
+
+namespace WebKit {
+
+Vector<String> pluginsDirectories();
+
+} // namespace WebKit
+
+#endif // PluginSandboxProfile_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/WebPreferencesDefaultValues.cpp webkitgtk-2.36.0/Source/WebKit/Shared/WebPreferencesDefaultValues.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/WebPreferencesDefaultValues.cpp	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/WebPreferencesDefaultValues.cpp	2022-03-22 16:38:57.381580153 -0500
@@ -321,7 +321,7 @@ bool defaultMediaSessionCoordinatorEnabl
     static dispatch_once_t onceToken;
     static bool enabled { false };
     dispatch_once(&onceToken, ^{
-        if (WebCore::isInWebProcess())
+        if (isInWebProcess())
             enabled = WebProcess::singleton().parentProcessHasEntitlement("com.apple.developer.group-session.urlactivity");
         else
             enabled = WTF::processHasEntitlement("com.apple.developer.group-session.urlactivity");
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/WebProcessCreationParameters.cpp webkitgtk-2.36.0/Source/WebKit/Shared/WebProcessCreationParameters.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/WebProcessCreationParameters.cpp	2022-03-18 07:53:19.000000000 -0500
+++ webkitgtk-2.36.0/Source/WebKit/Shared/WebProcessCreationParameters.cpp	2022-03-22 16:43:52.291137272 -0500
@@ -80,6 +80,7 @@ void WebProcessCreationParameters::encod
     encoder << shouldSuppressMemoryPressureHandler;
     encoder << shouldUseFontSmoothing;
     encoder << fontAllowList;
+    encoder << terminationTimeout;
     encoder << overrideLanguages;
 #if USE(GSTREAMER)
     encoder << gstreamerOptions;
@@ -309,6 +310,8 @@ bool WebProcessCreationParameters::decod
         return false;
     if (!decoder.decode(parameters.fontAllowList))
         return false;
+    if (!decoder.decode(parameters.terminationTimeout))
+        return false;
     if (!decoder.decode(parameters.overrideLanguages))
         return false;
 #if USE(GSTREAMER)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/WebProcessCreationParameters.h webkitgtk-2.36.0/Source/WebKit/Shared/WebProcessCreationParameters.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/WebProcessCreationParameters.h	2022-03-18 07:53:19.000000000 -0500
+++ webkitgtk-2.36.0/Source/WebKit/Shared/WebProcessCreationParameters.h	2022-03-22 16:43:52.291137272 -0500
@@ -50,6 +50,10 @@
 #include <WebCore/RenderThemeIOS.h>
 #endif
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+#include <WebCore/PluginData.h>
+#endif
+
 #if PLATFORM(GTK) || PLATFORM(WPE)
 #include <wtf/MemoryPressureHandler.h>
 #endif
@@ -143,6 +147,8 @@ struct WebProcessCreationParameters {
     bool hasRichContentServices { false };
 #endif
 
+    Seconds terminationTimeout;
+
     TextCheckerState textCheckerState;
 
 #if PLATFORM(COCOA)
@@ -170,6 +176,10 @@ struct WebProcessCreationParameters {
     HashMap<String, bool> notificationPermissions;
 #endif
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    HashMap<String, HashMap<String, HashMap<String, WebCore::PluginLoadClientPolicy>>> pluginLoadClientPolicies;
+#endif
+
 #if PLATFORM(COCOA)
     RetainPtr<CFDataRef> networkATSContext;
 #endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/WebsiteData/WebsiteData.cpp webkitgtk-2.36.0/Source/WebKit/Shared/WebsiteData/WebsiteData.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/WebsiteData/WebsiteData.cpp	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/WebsiteData/WebsiteData.cpp	2022-03-22 16:38:57.381580153 -0500
@@ -65,6 +65,9 @@ void WebsiteData::encode(IPC::Encoder& e
 {
     encoder << entries;
     encoder << hostNamesWithCookies;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    encoder << hostNamesWithPluginData;
+#endif
     encoder << hostNamesWithHSTSCache;
 #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
     encoder << registrableDomainsWithResourceLoadStatistics;
@@ -77,6 +80,10 @@ bool WebsiteData::decode(IPC::Decoder& d
         return false;
     if (!decoder.decode(result.hostNamesWithCookies))
         return false;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    if (!decoder.decode(result.hostNamesWithPluginData))
+        return false;
+#endif
     if (!decoder.decode(result.hostNamesWithHSTSCache))
         return false;
 #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
@@ -111,6 +118,10 @@ WebsiteDataProcessType WebsiteData::owne
         return WebsiteDataProcessType::Network;
     case WebsiteDataType::SearchFieldRecentSearches:
         return WebsiteDataProcessType::UI;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    case WebsiteDataType::PlugInData:
+        return WebsiteDataProcessType::UI;
+#endif
     case WebsiteDataType::ResourceLoadStatistics:
         return WebsiteDataProcessType::Network;
     case WebsiteDataType::Credentials:
@@ -152,6 +163,9 @@ WebsiteData WebsiteData::isolatedCopy()
     return WebsiteData {
         crossThreadCopy(entries),
         crossThreadCopy(hostNamesWithCookies),
+#if ENABLE(NETSCAPE_PLUGIN_API)
+        crossThreadCopy(hostNamesWithPluginData),
+#endif
         crossThreadCopy(hostNamesWithHSTSCache),
 #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
         crossThreadCopy(registrableDomainsWithResourceLoadStatistics),
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/WebsiteData/WebsiteData.h webkitgtk-2.36.0/Source/WebKit/Shared/WebsiteData/WebsiteData.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/WebsiteData/WebsiteData.h	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/WebsiteData/WebsiteData.h	2022-03-22 16:38:57.381580153 -0500
@@ -59,6 +59,9 @@ struct WebsiteData {
     Vector<Entry> entries;
     HashSet<String> hostNamesWithCookies;
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    HashSet<String> hostNamesWithPluginData;
+#endif
     HashSet<String> hostNamesWithHSTSCache;
 #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
     HashSet<WebCore::RegistrableDomain> registrableDomainsWithResourceLoadStatistics;
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Shared/WebsiteData/WebsiteDataType.h webkitgtk-2.36.0/Source/WebKit/Shared/WebsiteData/WebsiteDataType.h
--- webkitgtk-2.36.0.orig/Source/WebKit/Shared/WebsiteData/WebsiteDataType.h	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Shared/WebsiteData/WebsiteDataType.h	2022-03-22 16:38:57.381580153 -0500
@@ -41,6 +41,9 @@ enum class WebsiteDataType : uint32_t {
     MediaKeys = 1 << 8,
     HSTSCache = 1 << 9,
     SearchFieldRecentSearches = 1 << 10,
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    PlugInData = 1 << 11,
+#endif
     ResourceLoadStatistics = 1 << 12,
     Credentials = 1 << 13,
 #if ENABLE(SERVICE_WORKER)
@@ -73,6 +76,9 @@ template<> struct EnumTraits<WebKit::Web
         WebKit::WebsiteDataType::MediaKeys,
         WebKit::WebsiteDataType::HSTSCache,
         WebKit::WebsiteDataType::SearchFieldRecentSearches,
+#if ENABLE(NETSCAPE_PLUGIN_API)
+        WebKit::WebsiteDataType::PlugInData,
+#endif
         WebKit::WebsiteDataType::ResourceLoadStatistics,
         WebKit::WebsiteDataType::Credentials,
 #if ENABLE(SERVICE_WORKER)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/SourcesCocoa.txt webkitgtk-2.36.0/Source/WebKit/SourcesCocoa.txt
--- webkitgtk-2.36.0.orig/Source/WebKit/SourcesCocoa.txt	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/SourcesCocoa.txt	2022-03-22 16:38:57.381580153 -0500
@@ -110,6 +110,11 @@ Platform/mac/StringUtilities.mm
 
 Platform/unix/EnvironmentUtilities.cpp
 
+PluginProcess/EntryPoint/Cocoa/XPCService/PluginServiceEntryPoint.mm @no-unify
+
+PluginProcess/mac/PluginControllerProxyMac.mm @no-unify
+PluginProcess/mac/PluginProcessMac.mm @no-unify
+
 Shared/API/c/cf/WKErrorCF.cpp
 Shared/API/c/cf/WKStringCF.mm
 Shared/API/c/cf/WKURLCF.mm
@@ -239,6 +244,11 @@ Shared/mac/MediaFormatReader/MediaSample
 Shared/mac/MediaFormatReader/MediaSampleCursor.cpp
 Shared/mac/MediaFormatReader/MediaTrackReader.cpp
 
+Shared/Plugins/mac/PluginSandboxProfile.mm
+
+Shared/Plugins/Netscape/mac/NetscapePluginModuleMac.mm
+Shared/Plugins/Netscape/mac/PluginInformationMac.mm
+
 Shared/RemoteLayerTree/RemoteLayerBackingStore.mm
 Shared/RemoteLayerTree/RemoteLayerBackingStoreCollection.mm
 Shared/RemoteLayerTree/RemoteLayerWithRemoteRenderingBackingStoreCollection.mm
@@ -560,6 +570,10 @@ UIProcess/Media/cocoa/MediaUsageManagerC
 
 UIProcess/Network/CustomProtocols/LegacyCustomProtocolManagerProxy.cpp
 
+UIProcess/Plugins/mac/PluginInfoStoreMac.mm
+UIProcess/Plugins/mac/PluginProcessManagerMac.mm
+UIProcess/Plugins/mac/PluginProcessProxyMac.mm
+
 UIProcess/RemoteLayerTree/cocoa/RemoteLayerTreeLayers.mm
 
 UIProcess/RemoteLayerTree/mac/ScrollerMac.mm
@@ -672,6 +686,9 @@ WebProcess/Model/ARKitInlinePreviewModel
 WebProcess/Model/ios/ARKitInlinePreviewModelPlayerIOS.mm
 WebProcess/Model/mac/ARKitInlinePreviewModelPlayerMac.mm
 
+WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm
+WebProcess/Plugins/Netscape/mac/PluginProxyMac.mm
+
 WebProcess/Plugins/PDF/PDFPlugin.mm
 WebProcess/Plugins/PDF/PDFPluginAnnotation.mm
 WebProcess/Plugins/PDF/PDFPluginChoiceAnnotation.mm
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/SourcesGTK.txt webkitgtk-2.36.0/Source/WebKit/SourcesGTK.txt
--- webkitgtk-2.36.0.orig/Source/WebKit/SourcesGTK.txt	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/SourcesGTK.txt	2022-03-22 16:38:57.381580153 -0500
@@ -61,6 +61,10 @@ Platform/glib/ModuleGlib.cpp
 Platform/unix/LoggingUnix.cpp
 Platform/unix/SharedMemoryUnix.cpp
 
+PluginProcess/unix/PluginControllerProxyUnix.cpp
+PluginProcess/unix/PluginProcessMainUnix.cpp
+PluginProcess/unix/PluginProcessUnix.cpp
+
 Shared/API/c/cairo/WKImageCairo.cpp
 
 Shared/API/glib/WebKitContextMenu.cpp @no-unify
@@ -78,6 +82,11 @@ Shared/CoordinatedGraphics/threadedcompo
 Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp
 Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp
 
+Shared/Plugins/Netscape/NetscapePluginModuleNone.cpp
+Shared/Plugins/Netscape/unix/NetscapePluginModuleUnix.cpp
+
+Shared/Plugins/unix/PluginSearchPath.cpp
+
 Shared/cairo/ShareableBitmapCairo.cpp
 
 Shared/glib/ArgumentCodersGLib.cpp
@@ -238,6 +247,11 @@ UIProcess/Launcher/glib/XDGDBusProxy.cpp
 
 UIProcess/linux/MemoryPressureMonitor.cpp
 
+UIProcess/Plugins/gtk/PluginInfoCache.cpp
+
+UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp
+UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp
+
 UIProcess/WebsiteData/soup/WebsiteDataStoreSoup.cpp
 UIProcess/WebsiteData/unix/WebsiteDataStoreUnix.cpp
 
@@ -416,6 +430,11 @@ WebProcess/MediaCache/WebMediaKeyStorage
 
 WebProcess/WebCoreSupport/WebValidationMessageClient.cpp
 
+WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.cpp @no-unify
+WebProcess/Plugins/Netscape/unix/PluginProxyUnix.cpp @no-unify
+
+WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp @no-unify
+
 WebProcess/WebCoreSupport/glib/WebEditorClientGLib.cpp
 
 WebProcess/WebCoreSupport/gtk/WebContextMenuClientGtk.cpp
@@ -450,3 +469,5 @@ WebProcess/glib/WebProcessGLib.cpp
 WebProcess/gtk/GtkSettingsManagerProxy.cpp
 WebProcess/gtk/WaylandCompositorDisplay.cpp
 WebProcess/gtk/WebProcessMainGtk.cpp
+
+WebProcess/Plugins/Netscape/NetscapePluginNone.cpp
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/Sources.txt webkitgtk-2.36.0/Source/WebKit/Sources.txt
--- webkitgtk-2.36.0.orig/Source/WebKit/Sources.txt	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/Sources.txt	2022-03-22 16:38:57.381580153 -0500
@@ -218,6 +218,11 @@ Platform/IPC/SharedFileHandle.cpp
 Platform/IPC/StreamServerConnection.cpp
 Platform/IPC/StringReference.cpp
 
+PluginProcess/PluginControllerProxy.cpp @no-unify
+PluginProcess/PluginCreationParameters.cpp @no-unify
+PluginProcess/PluginProcess.cpp @no-unify
+PluginProcess/WebProcessConnection.cpp @no-unify
+
 Shared/AccessibilityPreferences.cpp
 Shared/ActivityAssertion.cpp
 Shared/AuxiliaryProcess.cpp
@@ -243,7 +248,7 @@ Shared/RTCPacketOptions.cpp
 Shared/RemoteWorkerInitializationData.cpp
 Shared/ScrollingAccelerationCurve.cpp
 Shared/SessionState.cpp
-Shared/ShareableBitmap.cpp
+Shared/ShareableBitmap.cpp @no-unify
 Shared/ShareableResource.cpp
 Shared/SharedStringHashStore.cpp
 Shared/SharedStringHashTableReadOnly.cpp
@@ -397,6 +402,18 @@ Shared/WebGPU/WebGPUVertexAttribute.cpp
 Shared/WebGPU/WebGPUVertexBufferLayout.cpp
 Shared/WebGPU/WebGPUVertexState.cpp
 
+// TODO: These files should be unified once GTK's PluginProcess2 is removed.
+Shared/Plugins/NPIdentifierData.cpp @no-unify
+Shared/Plugins/NPObjectMessageReceiver.cpp @no-unify
+Shared/Plugins/NPObjectProxy.cpp @no-unify
+Shared/Plugins/NPRemoteObjectMap.cpp @no-unify
+Shared/Plugins/NPVariantData.cpp @no-unify
+Shared/Plugins/PluginProcessCreationParameters.cpp @no-unify
+
+// TODO: These files should be unified once GTK's PluginProcess2 is removed.
+Shared/Plugins/Netscape/NetscapePluginModule.cpp  @no-unify
+Shared/Plugins/Netscape/PluginInformation.cpp @no-unify
+
 Shared/WebsiteData/WebsiteData.cpp
 
 Shared/XR/XRDeviceInfo.cpp
@@ -592,6 +609,10 @@ UIProcess/Notifications/WebNotificationM
 UIProcess/Notifications/WebNotificationManagerProxy.cpp
 UIProcess/Notifications/WebNotificationProvider.cpp
 
+UIProcess/Plugins/PluginInfoStore.cpp
+UIProcess/Plugins/PluginProcessManager.cpp
+UIProcess/Plugins/PluginProcessProxy.cpp
+
 UIProcess/UserContent/WebScriptMessageHandler.cpp
 UIProcess/UserContent/WebUserContentControllerProxy.cpp
 
@@ -787,9 +808,22 @@ WebProcess/Notifications/WebNotification
 
 // TODO: These files should be unified once GTK's PluginProcess2 is removed.
 WebProcess/Plugins/Plugin.cpp @no-unify
+WebProcess/Plugins/PluginProcessConnection.cpp @no-unify
+WebProcess/Plugins/PluginProcessConnectionManager.cpp @no-unify
+WebProcess/Plugins/PluginProxy.cpp @no-unify
 WebProcess/Plugins/PluginView.cpp @no-unify
 WebProcess/Plugins/WebPluginInfoProvider.cpp @no-unify
 
+// TODO: These files should be unified once GTK's PluginProcess2 is removed.
+WebProcess/Plugins/Netscape/JSNPMethod.cpp @no-unify
+WebProcess/Plugins/Netscape/JSNPObject.cpp @no-unify
+WebProcess/Plugins/Netscape/NPJSObject.cpp @no-unify
+WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp @no-unify
+WebProcess/Plugins/Netscape/NPRuntimeUtilities.cpp @no-unify
+WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp @no-unify
+WebProcess/Plugins/Netscape/NetscapePlugin.cpp @no-unify
+WebProcess/Plugins/Netscape/NetscapePluginStream.cpp @no-unify
+
 WebProcess/Speech/SpeechRecognitionRealtimeMediaSourceManager.cpp
 
 WebProcess/Storage/RemoteWorkerFrameLoaderClient.cpp
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/SourcesWPE.txt webkitgtk-2.36.0/Source/WebKit/SourcesWPE.txt
--- webkitgtk-2.36.0.orig/Source/WebKit/SourcesWPE.txt	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/SourcesWPE.txt	2022-03-22 16:38:57.381580153 -0500
@@ -61,6 +61,10 @@ Platform/glib/ModuleGlib.cpp
 Platform/unix/LoggingUnix.cpp
 Platform/unix/SharedMemoryUnix.cpp
 
+PluginProcess/unix/PluginControllerProxyUnix.cpp
+PluginProcess/unix/PluginProcessMainUnix.cpp
+PluginProcess/unix/PluginProcessUnix.cpp
+
 Shared/API/c/cairo/WKImageCairo.cpp
 
 Shared/API/glib/WebKitContextMenu.cpp @no-unify
@@ -78,6 +82,9 @@ Shared/CoordinatedGraphics/threadedcompo
 Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp
 Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp
 
+Shared/Plugins/Netscape/NetscapePluginModuleNone.cpp
+Shared/Plugins/Netscape/unix/NetscapePluginModuleUnix.cpp
+
 Shared/cairo/ShareableBitmapCairo.cpp
 
 Shared/glib/ArgumentCodersGLib.cpp
@@ -212,6 +219,9 @@ UIProcess/Launcher/glib/BubblewrapLaunch
 UIProcess/Launcher/glib/FlatpakLauncher.cpp
 UIProcess/Launcher/glib/XDGDBusProxy.cpp
 
+UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp
+UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp
+
 UIProcess/WebsiteData/soup/WebsiteDataStoreSoup.cpp
 UIProcess/WebsiteData/unix/WebsiteDataStoreUnix.cpp
 
@@ -249,6 +259,8 @@ WebProcess/InjectedBundle/glib/InjectedB
 
 WebProcess/MediaCache/WebMediaKeyStorageManager.cpp
 
+WebProcess/Plugins/Netscape/NetscapePluginNone.cpp @no-unify
+
 WebProcess/WebCoreSupport/glib/WebEditorClientGLib.cpp
 
 WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/APILoaderClient.h webkitgtk-2.36.0/Source/WebKit/UIProcess/API/APILoaderClient.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/APILoaderClient.h	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/APILoaderClient.h	2022-03-22 16:38:57.381580153 -0500
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "APIData.h"
+#include "PluginModuleInfo.h"
 #include "SameDocumentNavigationType.h"
 #include <WebCore/FrameLoaderTypes.h>
 #include <WebCore/LayoutMilestone.h>
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/APINavigationClient.h webkitgtk-2.36.0/Source/WebKit/UIProcess/API/APINavigationClient.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/APINavigationClient.h	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/APINavigationClient.h	2022-03-22 16:38:57.381580153 -0500
@@ -30,6 +30,7 @@
 #include "AuthenticationChallengeDisposition.h"
 #include "AuthenticationChallengeProxy.h"
 #include "AuthenticationDecisionListener.h"
+#include "PluginModuleInfo.h"
 #include "ProcessTerminationReason.h"
 #include "SameDocumentNavigationType.h"
 #include "WebFramePolicyListenerProxy.h"
@@ -133,6 +134,15 @@ public:
     }
     
     virtual void contentRuleListNotification(WebKit::WebPageProxy&, WTF::URL&&, WebCore::ContentRuleListResults&&) { };
+    
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    virtual bool didFailToInitializePlugIn(WebKit::WebPageProxy&, API::Dictionary&) { return false; }
+    virtual bool didBlockInsecurePluginVersion(WebKit::WebPageProxy&, API::Dictionary&) { return false; }
+    virtual void decidePolicyForPluginLoad(WebKit::WebPageProxy&, WebKit::PluginModuleLoadPolicy currentPluginLoadPolicy, Dictionary&, CompletionHandler<void(WebKit::PluginModuleLoadPolicy, const WTF::String&)>&& completionHandler)
+    {
+        completionHandler(currentPluginLoadPolicy, { });
+    }
+#endif
 
 #if ENABLE(WEBGL)
     virtual void webGLLoadPolicy(WebKit::WebPageProxy&, const WTF::URL&, CompletionHandler<void(WebCore::WebGLLoadPolicy)>&& completionHandler) const { completionHandler(WebCore::WebGLLoadPolicy::WebGLAllowCreation); }
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/APIUIClient.h webkitgtk-2.36.0/Source/WebKit/UIProcess/API/APIUIClient.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/APIUIClient.h	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/APIUIClient.h	2022-03-22 16:38:57.381580153 -0500
@@ -108,6 +108,9 @@ public:
 
     virtual void setStatusText(WebKit::WebPageProxy*, const WTF::String&) { }
     virtual void mouseDidMoveOverElement(WebKit::WebPageProxy&, const WebKit::WebHitTestResultData&, OptionSet<WebKit::WebEvent::Modifier>, Object*) { }
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    virtual void unavailablePluginButtonClicked(WebKit::WebPageProxy&, WKPluginUnavailabilityReason, Dictionary&) { }
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
 
     virtual void didNotHandleKeyEvent(WebKit::WebPageProxy*, const WebKit::NativeWebKeyboardEvent&) { }
     virtual void didNotHandleWheelEvent(WebKit::WebPageProxy*, const WebKit::NativeWebWheelEvent&) { }
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/C/WKAPICast.h webkitgtk-2.36.0/Source/WebKit/UIProcess/API/C/WKAPICast.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/C/WKAPICast.h	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/C/WKAPICast.h	2022-03-22 16:38:57.381580153 -0500
@@ -29,6 +29,7 @@
 
 #include "CacheModel.h"
 #include "InjectedBundleHitTestResultMediaType.h"
+#include "PluginModuleInfo.h"
 #include "ProcessTerminationReason.h"
 #include "WKBundleHitTestResult.h"
 #include "WKContext.h"
@@ -419,6 +420,78 @@ inline WKStorageBlockingPolicy toAPI(Web
     return kWKAllowAllStorage;
 }
 
+inline WKPluginLoadPolicy toWKPluginLoadPolicy(PluginModuleLoadPolicy pluginModuleLoadPolicy)
+{
+    switch (pluginModuleLoadPolicy) {
+    case PluginModuleLoadNormally:
+        return kWKPluginLoadPolicyLoadNormally;
+    case PluginModuleLoadUnsandboxed:
+        return kWKPluginLoadPolicyLoadUnsandboxed;
+    case PluginModuleBlockedForSecurity:
+        return kWKPluginLoadPolicyBlocked;
+    case PluginModuleBlockedForCompatibility:
+        return kWKPluginLoadPolicyBlockedForCompatibility;
+    }
+    
+    ASSERT_NOT_REACHED();
+    return kWKPluginLoadPolicyBlocked;
+}
+
+inline WKPluginLoadClientPolicy toWKPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy PluginLoadClientPolicy)
+{
+    switch (PluginLoadClientPolicy) {
+    case WebCore::PluginLoadClientPolicy::Undefined:
+        return kWKPluginLoadClientPolicyUndefined;
+    case WebCore::PluginLoadClientPolicy::Block:
+        return kWKPluginLoadClientPolicyBlock;
+    case WebCore::PluginLoadClientPolicy::Ask:
+        return kWKPluginLoadClientPolicyAsk;
+    case WebCore::PluginLoadClientPolicy::Allow:
+        return kWKPluginLoadClientPolicyAllow;
+    case WebCore::PluginLoadClientPolicy::AllowAlways:
+        return kWKPluginLoadClientPolicyAllowAlways;
+    }
+
+    ASSERT_NOT_REACHED();
+    return kWKPluginLoadClientPolicyBlock;
+}
+
+inline PluginModuleLoadPolicy toPluginModuleLoadPolicy(WKPluginLoadPolicy pluginLoadPolicy)
+{
+    switch (pluginLoadPolicy) {
+    case kWKPluginLoadPolicyLoadNormally:
+        return PluginModuleLoadNormally;
+    case kWKPluginLoadPolicyBlocked:
+        return PluginModuleBlockedForSecurity;
+    case kWKPluginLoadPolicyBlockedForCompatibility:
+        return PluginModuleBlockedForCompatibility;
+    case kWKPluginLoadPolicyLoadUnsandboxed:
+        return PluginModuleLoadUnsandboxed;
+    }
+    
+    ASSERT_NOT_REACHED();
+    return PluginModuleBlockedForSecurity;
+}
+
+inline WebCore::PluginLoadClientPolicy toPluginLoadClientPolicy(WKPluginLoadClientPolicy pluginLoadClientPolicy)
+{
+    switch (pluginLoadClientPolicy) {
+    case kWKPluginLoadClientPolicyUndefined:
+        return WebCore::PluginLoadClientPolicy::Undefined;
+    case kWKPluginLoadClientPolicyBlock:
+        return WebCore::PluginLoadClientPolicy::Block;
+    case kWKPluginLoadClientPolicyAsk:
+        return WebCore::PluginLoadClientPolicy::Ask;
+    case kWKPluginLoadClientPolicyAllow:
+        return WebCore::PluginLoadClientPolicy::Allow;
+    case kWKPluginLoadClientPolicyAllowAlways:
+        return WebCore::PluginLoadClientPolicy::AllowAlways;
+    }
+
+    ASSERT_NOT_REACHED();
+    return WebCore::PluginLoadClientPolicy::Block;
+}
+
 inline WebCore::WebGLLoadPolicy toWebGLLoadPolicy(WKWebGLLoadPolicy webGLLoadPolicy)
 {
     switch (webGLLoadPolicy) {
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/C/WKContext.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/API/C/WKContext.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/C/WKContext.cpp	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/C/WKContext.cpp	2022-03-22 16:38:57.381580153 -0500
@@ -334,13 +334,21 @@ void WKContextSetShouldUseFontSmoothing(
 
 void WKContextSetAdditionalPluginsDirectory(WKContextRef contextRef, WKStringRef pluginsDirectory)
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    WebKit::toImpl(contextRef)->setAdditionalPluginsDirectory(WebKit::toImpl(pluginsDirectory)->string());
+#else
     UNUSED_PARAM(contextRef);
     UNUSED_PARAM(pluginsDirectory);
+#endif
 }
 
 void WKContextRefreshPlugIns(WKContextRef context)
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    WebKit::toImpl(context)->refreshPlugins();
+#else
     UNUSED_PARAM(context);
+#endif
 }
 
 void WKContextRegisterURLSchemeAsEmptyDocument(WKContextRef contextRef, WKStringRef urlScheme)
@@ -553,10 +561,26 @@ void WKContextTerminateServiceWorkers(WK
 
 void WKContextAddSupportedPlugin(WKContextRef contextRef, WKStringRef domainRef, WKStringRef nameRef, WKArrayRef mimeTypesRef, WKArrayRef extensionsRef)
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    HashSet<String> mimeTypes;
+    HashSet<String> extensions;
+
+    size_t count = WKArrayGetSize(mimeTypesRef);
+    for (size_t i = 0; i < count; ++i)
+        mimeTypes.add(WebKit::toWTFString(static_cast<WKStringRef>(WKArrayGetItemAtIndex(mimeTypesRef, i))));
+    count = WKArrayGetSize(extensionsRef);
+    for (size_t i = 0; i < count; ++i)
+        extensions.add(WebKit::toWTFString(static_cast<WKStringRef>(WKArrayGetItemAtIndex(extensionsRef, i))));
+
+    WebKit::toImpl(contextRef)->addSupportedPlugin(WebKit::toWTFString(domainRef), WebKit::toWTFString(nameRef), WTFMove(mimeTypes), WTFMove(extensions));
+#endif
 }
 
 void WKContextClearSupportedPlugins(WKContextRef contextRef)
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    WebKit::toImpl(contextRef)->clearSupportedPlugins();
+#endif
 }
 
 void WKContextClearCurrentModifierStateForTesting(WKContextRef contextRef)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/C/WKPage.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/API/C/WKPage.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/C/WKPage.cpp	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/C/WKPage.cpp	2022-03-22 16:38:57.381580153 -0500
@@ -64,6 +64,7 @@
 #include "NavigationActionData.h"
 #include "NotificationPermissionRequest.h"
 #include "PageClient.h"
+#include "PluginInformation.h"
 #include "PrintInfo.h"
 #include "QueryPermissionResultCallback.h"
 #include "SpeechRecognitionPermissionRequest.h"
@@ -1787,6 +1788,37 @@ void WKPageSetPageUIClient(WKPageRef pag
             m_client.mouseDidMoveOverElement(toAPI(&page), toAPI(apiHitTestResult.ptr()), toAPI(modifiers), toAPI(userData), m_client.base.clientInfo);
         }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+        void unavailablePluginButtonClicked(WebPageProxy& page, WKPluginUnavailabilityReason pluginUnavailabilityReason, API::Dictionary& pluginInformation) final
+        {
+            if (pluginUnavailabilityReason == kWKPluginUnavailabilityReasonPluginMissing) {
+                if (m_client.missingPluginButtonClicked_deprecatedForUseWithV0)
+                    m_client.missingPluginButtonClicked_deprecatedForUseWithV0(
+                        toAPI(&page),
+                        toAPI(pluginInformation.get<API::String>(pluginInformationMIMETypeKey())),
+                        toAPI(pluginInformation.get<API::String>(pluginInformationPluginURLKey())),
+                        toAPI(pluginInformation.get<API::String>(pluginInformationPluginspageAttributeURLKey())),
+                        m_client.base.clientInfo);
+            }
+
+            if (m_client.unavailablePluginButtonClicked_deprecatedForUseWithV1)
+                m_client.unavailablePluginButtonClicked_deprecatedForUseWithV1(
+                    toAPI(&page),
+                    pluginUnavailabilityReason,
+                    toAPI(pluginInformation.get<API::String>(pluginInformationMIMETypeKey())),
+                    toAPI(pluginInformation.get<API::String>(pluginInformationPluginURLKey())),
+                    toAPI(pluginInformation.get<API::String>(pluginInformationPluginspageAttributeURLKey())),
+                    m_client.base.clientInfo);
+
+            if (m_client.unavailablePluginButtonClicked)
+                m_client.unavailablePluginButtonClicked(
+                    toAPI(&page),
+                    pluginUnavailabilityReason,
+                    toAPI(&pluginInformation),
+                    m_client.base.clientInfo);
+        }
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
         void didNotHandleKeyEvent(WebPageProxy* page, const NativeWebKeyboardEvent& event) final
         {
             if (!m_client.didNotHandleKeyEvent)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/C/WKPreferences.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/API/C/WKPreferences.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/C/WKPreferences.cpp	2022-02-23 02:59:04.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/C/WKPreferences.cpp	2022-03-22 16:38:57.381580153 -0500
@@ -25,6 +25,7 @@
 
 #include "config.h"
 
+#include "PluginProcessManager.h"
 #include "WKPreferencesRef.h"
 #include "WKPreferencesRefPrivate.h"
 #include "WKAPICast.h"
@@ -605,13 +606,14 @@ bool WKPreferencesGetPageCacheEnabled(WK
     return toImpl(preferencesRef)->usesBackForwardCache();
 }
 
-void WKPreferencesSetPageCacheSupportsPlugins(WKPreferencesRef, bool)
+void WKPreferencesSetPageCacheSupportsPlugins(WKPreferencesRef preferencesRef, bool backForwardCacheSupportsPlugins)
 {
+    toImpl(preferencesRef)->setBackForwardCacheSupportsPlugins(backForwardCacheSupportsPlugins);
 }
 
-bool WKPreferencesGetPageCacheSupportsPlugins(WKPreferencesRef)
+bool WKPreferencesGetPageCacheSupportsPlugins(WKPreferencesRef preferencesRef)
 {
-    return false;
+    return toImpl(preferencesRef)->backForwardCacheSupportsPlugins();
 }
 
 void WKPreferencesSetPaginateDuringLayoutEnabled(WKPreferencesRef preferencesRef, bool enabled)
@@ -1003,31 +1005,34 @@ bool WKPreferencesGetDiagnosticLoggingEn
     return toImpl(preferencesRef)->diagnosticLoggingEnabled();
 }
 
-void WKPreferencesSetAsynchronousPluginInitializationEnabled(WKPreferencesRef, bool)
+void WKPreferencesSetAsynchronousPluginInitializationEnabled(WKPreferencesRef preferencesRef, bool enabled)
 {
+    toImpl(preferencesRef)->setAsynchronousPluginInitializationEnabled(enabled);
 }
 
-bool WKPreferencesGetAsynchronousPluginInitializationEnabled(WKPreferencesRef)
+bool WKPreferencesGetAsynchronousPluginInitializationEnabled(WKPreferencesRef preferencesRef)
 {
-    return false;
+    return toImpl(preferencesRef)->asynchronousPluginInitializationEnabled();
 }
 
-void WKPreferencesSetAsynchronousPluginInitializationEnabledForAllPlugins(WKPreferencesRef, bool)
+void WKPreferencesSetAsynchronousPluginInitializationEnabledForAllPlugins(WKPreferencesRef preferencesRef, bool enabled)
 {
+    toImpl(preferencesRef)->setAsynchronousPluginInitializationEnabledForAllPlugins(enabled);
 }
 
-bool WKPreferencesGetAsynchronousPluginInitializationEnabledForAllPlugins(WKPreferencesRef)
+bool WKPreferencesGetAsynchronousPluginInitializationEnabledForAllPlugins(WKPreferencesRef preferencesRef)
 {
-    return false;
+    return toImpl(preferencesRef)->asynchronousPluginInitializationEnabledForAllPlugins();
 }
 
-void WKPreferencesSetArtificialPluginInitializationDelayEnabled(WKPreferencesRef, bool)
+void WKPreferencesSetArtificialPluginInitializationDelayEnabled(WKPreferencesRef preferencesRef, bool enabled)
 {
+    toImpl(preferencesRef)->setArtificialPluginInitializationDelayEnabled(enabled);
 }
 
-bool WKPreferencesGetArtificialPluginInitializationDelayEnabled(WKPreferencesRef)
+bool WKPreferencesGetArtificialPluginInitializationDelayEnabled(WKPreferencesRef preferencesRef)
 {
-    return false;
+    return toImpl(preferencesRef)->artificialPluginInitializationDelayEnabled();
 }
 
 void WKPreferencesSetInteractiveFormValidationEnabled(WKPreferencesRef preferencesRef, bool enabled)
@@ -1059,13 +1064,17 @@ bool WKPreferencesGetPlugInSnapshottingE
     return false;
 }
 
-void WKPreferencesSetPluginSandboxProfilesEnabledForAllPlugins(WKPreferencesRef, bool)
+void WKPreferencesSetPluginSandboxProfilesEnabledForAllPlugins(WKPreferencesRef preferencesRef, bool enabled)
 {
+#if ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(MAC)
+    WebKit::PluginProcessManager::singleton().setExperimentalPlugInSandboxProfilesEnabled(enabled);
+#endif
+    toImpl(preferencesRef)->setExperimentalPlugInSandboxProfilesEnabled(enabled);
 }
 
-bool WKPreferencesGetPluginSandboxProfilesEnabledForAllPlugins(WKPreferencesRef)
+bool WKPreferencesGetPluginSandboxProfilesEnabledForAllPlugins(WKPreferencesRef preferencesRef)
 {
-    return false;
+    return toImpl(preferencesRef)->experimentalPlugInSandboxProfilesEnabled();
 }
 
 void WKPreferencesSetSnapshotAllPlugIns(WKPreferencesRef, bool)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitMimeInfo.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitMimeInfo.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitMimeInfo.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitMimeInfo.cpp	2022-03-22 16:38:57.381580153 -0500
@@ -20,12 +20,32 @@
 #include "config.h"
 #include "WebKitMimeInfo.h"
 
+#include "WebKitMimeInfoPrivate.h"
+#include <wtf/glib/GRefPtr.h>
+#include <wtf/text/CString.h>
+
 struct _WebKitMimeInfo {
+    _WebKitMimeInfo(const WebCore::MimeClassInfo& mimeInfo)
+        : mimeInfo(mimeInfo)
+    {
+    }
+
+    WebCore::MimeClassInfo mimeInfo;
+    CString mimeType;
+    CString description;
+    GRefPtr<GPtrArray> extensions;
+
+    int referenceCount { 0 };
 };
 
-ALLOW_DEPRECATED_DECLARATIONS_BEGIN
 G_DEFINE_BOXED_TYPE(WebKitMimeInfo, webkit_mime_info, webkit_mime_info_ref, webkit_mime_info_unref)
-ALLOW_DEPRECATED_DECLARATIONS_END
+
+WebKitMimeInfo* webkitMimeInfoCreate(const WebCore::MimeClassInfo& mimeInfo)
+{
+    WebKitMimeInfo* info = static_cast<WebKitMimeInfo*>(fastMalloc(sizeof(WebKitMimeInfo)));
+    new (info) WebKitMimeInfo(mimeInfo);
+    return info;
+}
 
 /**
  * webkit_mime_info_ref:
@@ -35,12 +55,11 @@ ALLOW_DEPRECATED_DECLARATIONS_END
  * function is MT-safe and may be called from any thread.
  *
  * Returns: The passed in #WebKitMimeInfo
- *
- * Deprecated: 2.32
  */
-WebKitMimeInfo* webkit_mime_info_ref(WebKitMimeInfo*)
+WebKitMimeInfo* webkit_mime_info_ref(WebKitMimeInfo* info)
 {
-    return nullptr;
+    g_atomic_int_inc(&info->referenceCount);
+    return info;
 }
 
 /**
@@ -51,11 +70,13 @@ WebKitMimeInfo* webkit_mime_info_ref(Web
  * reference count drops to 0, all memory allocated by the #WebKitMimeInfo is
  * released. This function is MT-safe and may be called from any
  * thread.
- *
- * Deprecated: 2.32
  */
-void webkit_mime_info_unref(WebKitMimeInfo*)
+void webkit_mime_info_unref(WebKitMimeInfo* info)
 {
+    if (g_atomic_int_dec_and_test(&info->referenceCount)) {
+        info->~WebKitMimeInfo();
+        fastFree(info);
+    }
 }
 
 /**
@@ -63,12 +84,17 @@ void webkit_mime_info_unref(WebKitMimeIn
  * @info: a #WebKitMimeInfo
  *
  * Returns: the MIME type of @info
- *
- * Deprecated: 2.32
  */
-const char* webkit_mime_info_get_mime_type(WebKitMimeInfo*)
+const char* webkit_mime_info_get_mime_type(WebKitMimeInfo* info)
 {
-    return nullptr;
+    if (!info->mimeType.isNull())
+        return info->mimeType.data();
+
+    if (info->mimeInfo.type.isEmpty())
+        return 0;
+
+    info->mimeType = info->mimeInfo.type.utf8();
+    return info->mimeType.data();
 }
 
 /**
@@ -76,12 +102,17 @@ const char* webkit_mime_info_get_mime_ty
  * @info: a #WebKitMimeInfo
  *
  * Returns: the description of the MIME type of @info
- *
- * Deprecated: 2.32
  */
-const char* webkit_mime_info_get_description(WebKitMimeInfo*)
+const char* webkit_mime_info_get_description(WebKitMimeInfo* info)
 {
-    return nullptr;
+    if (!info->description.isNull())
+        return info->description.data();
+
+    if (info->mimeInfo.desc.isEmpty())
+        return 0;
+
+    info->description = info->mimeInfo.desc.utf8();
+    return info->description.data();
 }
 
 /**
@@ -93,10 +124,22 @@ const char* webkit_mime_info_get_descrip
  *
  * Returns: (array zero-terminated=1) (transfer none): a
  *     %NULL-terminated array of strings
- *
- * Deprecated: 2.32
  */
-const char* const* webkit_mime_info_get_extensions(WebKitMimeInfo*)
+const char* const* webkit_mime_info_get_extensions(WebKitMimeInfo* info)
 {
-    return nullptr;
+    if (info->extensions)
+        return reinterpret_cast<gchar**>(info->extensions->pdata);
+
+    if (info->mimeInfo.extensions.isEmpty())
+        return 0;
+
+    info->extensions = adoptGRef(g_ptr_array_new_with_free_func(g_free));
+    for (size_t i = 0; i < info->mimeInfo.extensions.size(); ++i) {
+        if (info->mimeInfo.extensions[i].isEmpty())
+            continue;
+        g_ptr_array_add(info->extensions.get(), g_strdup(info->mimeInfo.extensions[i].utf8().data()));
+    }
+    g_ptr_array_add(info->extensions.get(), 0);
+
+    return reinterpret_cast<gchar**>(info->extensions->pdata);
 }
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitMimeInfoPrivate.h webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitMimeInfoPrivate.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitMimeInfoPrivate.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitMimeInfoPrivate.h	2022-03-22 16:38:57.381580153 -0500
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "WebKitMimeInfo.h"
+#include <WebCore/PluginData.h>
+
+WebKitMimeInfo* webkitMimeInfoCreate(const WebCore::MimeClassInfo&);
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitPlugin.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitPlugin.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitPlugin.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitPlugin.cpp	2022-03-22 16:38:57.381580153 -0500
@@ -20,7 +20,12 @@
 #include "config.h"
 #include "WebKitPlugin.h"
 
+#include "WebKitMimeInfoPrivate.h"
+#include "WebKitPluginPrivate.h"
 #include <wtf/glib/WTFGType.h>
+#include <wtf/text/CString.h>
+
+using namespace WebKit;
 
 /**
  * SECTION: WebKitPlugin
@@ -34,31 +39,52 @@
  * be obtained from the #WebKitWebContext, with
  * webkit_web_context_get_plugins().
  *
- * Deprecated: 2.32
  */
 
 struct _WebKitPluginPrivate {
+    ~_WebKitPluginPrivate()
+    {
+        g_list_free_full(mimeInfoList, reinterpret_cast<GDestroyNotify>(webkit_mime_info_unref));
+    }
+
+    PluginModuleInfo pluginInfo;
+    CString name;
+    CString description;
+    CString path;
+    GList* mimeInfoList;
 };
 
-ALLOW_DEPRECATED_DECLARATIONS_BEGIN
 WEBKIT_DEFINE_TYPE(WebKitPlugin, webkit_plugin, G_TYPE_OBJECT)
-ALLOW_DEPRECATED_DECLARATIONS_END
 
 static void webkit_plugin_class_init(WebKitPluginClass*)
 {
 }
 
+WebKitPlugin* webkitPluginCreate(const PluginModuleInfo& pluginInfo)
+{
+    WebKitPlugin* plugin = WEBKIT_PLUGIN(g_object_new(WEBKIT_TYPE_PLUGIN, NULL));
+    plugin->priv->pluginInfo = pluginInfo;
+    return plugin;
+}
+
 /**
  * webkit_plugin_get_name:
  * @plugin: a #WebKitPlugin
  *
  * Returns: the name of the plugin.
- *
- * Deprecated: 2.32
  */
-const char* webkit_plugin_get_name(WebKitPlugin*)
+const char* webkit_plugin_get_name(WebKitPlugin* plugin)
 {
-    return nullptr;
+    g_return_val_if_fail(WEBKIT_IS_PLUGIN(plugin), 0);
+
+    if (!plugin->priv->name.isNull())
+        return plugin->priv->name.data();
+
+    if (plugin->priv->pluginInfo.info.name.isEmpty())
+        return 0;
+
+    plugin->priv->name = plugin->priv->pluginInfo.info.name.utf8();
+    return plugin->priv->name.data();
 }
 
 /**
@@ -66,12 +92,19 @@ const char* webkit_plugin_get_name(WebKi
  * @plugin: a #WebKitPlugin
  *
  * Returns: the description of the plugin.
- *
- * Deprecated: 2.32
  */
-const char* webkit_plugin_get_description(WebKitPlugin*)
+const char* webkit_plugin_get_description(WebKitPlugin* plugin)
 {
-    return nullptr;
+    g_return_val_if_fail(WEBKIT_IS_PLUGIN(plugin), 0);
+
+    if (!plugin->priv->description.isNull())
+        return plugin->priv->description.data();
+
+    if (plugin->priv->pluginInfo.info.desc.isEmpty())
+        return 0;
+
+    plugin->priv->description = plugin->priv->pluginInfo.info.desc.utf8();
+    return plugin->priv->description.data();
 }
 
 /**
@@ -79,12 +112,19 @@ const char* webkit_plugin_get_descriptio
  * @plugin: a #WebKitPlugin
  *
  * Returns: the absolute path where the plugin is installed.
- *
- * Deprecated: 2.32
  */
-const char* webkit_plugin_get_path(WebKitPlugin*)
+const char* webkit_plugin_get_path(WebKitPlugin* plugin)
 {
-    return nullptr;
+    g_return_val_if_fail(WEBKIT_IS_PLUGIN(plugin), 0);
+
+    if (!plugin->priv->path.isNull())
+        return plugin->priv->path.data();
+
+    if (plugin->priv->pluginInfo.path.isEmpty())
+        return 0;
+
+    plugin->priv->path = plugin->priv->pluginInfo.path.utf8();
+    return plugin->priv->path.data();
 }
 
 /**
@@ -95,10 +135,18 @@ const char* webkit_plugin_get_path(WebKi
  * as a list of #WebKitMimeInfo.
  *
  * Returns: (element-type WebKitMimeInfo) (transfer none): a #GList of #WebKitMimeInfo.
- *
- * Deprecated: 2.32
  */
-GList* webkit_plugin_get_mime_info_list(WebKitPlugin*)
+GList* webkit_plugin_get_mime_info_list(WebKitPlugin* plugin)
 {
-    return nullptr;
+    g_return_val_if_fail(WEBKIT_IS_PLUGIN(plugin), 0);
+
+    if (plugin->priv->mimeInfoList)
+        return plugin->priv->mimeInfoList;
+
+    if (plugin->priv->pluginInfo.info.mimes.isEmpty())
+        return 0;
+
+    for (size_t i = 0; i < plugin->priv->pluginInfo.info.mimes.size(); ++i)
+        plugin->priv->mimeInfoList = g_list_prepend(plugin->priv->mimeInfoList, webkitMimeInfoCreate(plugin->priv->pluginInfo.info.mimes[i]));
+    return plugin->priv->mimeInfoList;
 }
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitPluginPrivate.h webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitPluginPrivate.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitPluginPrivate.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitPluginPrivate.h	2022-03-22 16:38:57.385580173 -0500
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "PluginModuleInfo.h"
+#include "WebKitPlugin.h"
+
+WebKitPlugin* webkitPluginCreate(const WebKit::PluginModuleInfo&);
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp	2022-03-22 16:38:57.385580173 -0500
@@ -235,6 +235,7 @@ static void webKitSettingsSetProperty(GO
         webkit_settings_set_enable_frame_flattening(settings, g_value_get_boolean(value));
         break;
     case PROP_ENABLE_PLUGINS:
+        webkit_settings_set_enable_plugins(settings, g_value_get_boolean(value));
         break;
     case PROP_ENABLE_JAVA:
         webkit_settings_set_enable_java(settings, g_value_get_boolean(value));
@@ -437,7 +438,7 @@ static void webKitSettingsGetProperty(GO
         g_value_set_boolean(value, webkit_settings_get_enable_frame_flattening(settings));
         break;
     case PROP_ENABLE_PLUGINS:
-        g_value_set_boolean(value, FALSE);
+        g_value_set_boolean(value, webkit_settings_get_enable_plugins(settings));
         break;
     case PROP_ENABLE_JAVA:
         g_value_set_boolean(value, webkit_settings_get_enable_java(settings));
@@ -746,7 +747,7 @@ static void webkit_settings_class_init(W
             "enable-plugins",
             _("Enable plugins"),
             _("Enable embedded plugin objects."),
-            FALSE,
+            TRUE,
             readWriteConstructParamFlags);
 
     /**
@@ -1886,16 +1887,12 @@ void webkit_settings_set_enable_frame_fl
  * Get the #WebKitSettings:enable-plugins property.
  *
  * Returns: %TRUE If plugins are enabled or %FALSE otherwise.
- *
- * Deprecated: 2.32
  */
 gboolean webkit_settings_get_enable_plugins(WebKitSettings* settings)
 {
     g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE);
 
-    g_warning("webkit_settings_get_enable_plugins is deprecated and always returns FALSE. Plugins are no longer supported.");
-
-    return FALSE;
+    return settings->priv->preferences->pluginsEnabled();
 }
 
 /**
@@ -1904,15 +1901,18 @@ gboolean webkit_settings_get_enable_plug
  * @enabled: Value to be set
  *
  * Set the #WebKitSettings:enable-plugins property.
- *
- * Deprecated: 2.32
  */
 void webkit_settings_set_enable_plugins(WebKitSettings* settings, gboolean enabled)
 {
     g_return_if_fail(WEBKIT_IS_SETTINGS(settings));
 
-    if (enabled)
-        g_warning("webkit_settings_set_enable_plugins is deprecated and does nothing. Plugins are no longer supported.");
+    WebKitSettingsPrivate* priv = settings->priv;
+    bool currentValue = priv->preferences->pluginsEnabled();
+    if (currentValue == enabled)
+        return;
+
+    priv->preferences->setPluginsEnabled(enabled);
+    g_object_notify(G_OBJECT(settings), "enable-plugins");
 }
 
 /**
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp	2022-03-22 16:35:20.172433411 -0500
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp	2022-03-22 16:38:57.385580173 -0500
@@ -42,6 +42,7 @@
 #include "WebKitMemoryPressureSettings.h"
 #include "WebKitMemoryPressureSettingsPrivate.h"
 #include "WebKitNotificationProvider.h"
+#include "WebKitPluginPrivate.h"
 #include "WebKitPrivate.h"
 #include "WebKitProtocolHandler.h"
 #include "WebKitSecurityManagerPrivate.h"
@@ -1153,12 +1154,31 @@ WebKitSecurityManager* webkit_web_contex
  * @directory: the directory to add
  *
  * Set an additional directory where WebKit will look for plugins.
- *
- * Deprecated: 2.32
  */
-void webkit_web_context_set_additional_plugins_directory(WebKitWebContext*, const char*)
+void webkit_web_context_set_additional_plugins_directory(WebKitWebContext* context, const char* directory)
+{
+    g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context));
+    g_return_if_fail(directory);
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    context->priv->processPool->setAdditionalPluginsDirectory(FileSystem::stringFromFileSystemRepresentation(directory));
+#endif
+}
+
+static void destroyPluginList(GList* plugins)
+{
+    g_list_free_full(plugins, g_object_unref);
+}
+
+static void webkitWebContextGetPluginThread(GTask* task, gpointer object, gpointer /* taskData */, GCancellable*)
 {
-    g_warning("webkit_web_context_set_additional_plugins_directory is deprecated and does nothing. Netscape plugins are no longer supported.");
+    GList* returnValue = 0;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    Vector<PluginModuleInfo> plugins = WEBKIT_WEB_CONTEXT(object)->priv->processPool->pluginInfoStore().plugins();
+    for (size_t i = 0; i < plugins.size(); ++i)
+        returnValue = g_list_prepend(returnValue, webkitPluginCreate(plugins[i]));
+#endif
+    g_task_return_pointer(task, returnValue, reinterpret_cast<GDestroyNotify>(destroyPluginList));
 }
 
 /**
@@ -1172,17 +1192,13 @@ void webkit_web_context_set_additional_p
  *
  * When the operation is finished, @callback will be called. You can then call
  * webkit_web_context_get_plugins_finish() to get the result of the operation.
- *
- * Deprecated: 2.32
  */
 void webkit_web_context_get_plugins(WebKitWebContext* context, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
 {
     g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context));
 
-    g_warning("webkit_web_context_get_plugins is deprecated and always returns an empty list. Netscape plugins are no longer supported.");
-
     GRefPtr<GTask> task = adoptGRef(g_task_new(context, cancellable, callback, userData));
-    g_task_return_pointer(task.get(), nullptr, nullptr);
+    g_task_run_in_thread(task.get(), webkitWebContextGetPluginThread);
 }
 
 /**
@@ -1195,13 +1211,11 @@ void webkit_web_context_get_plugins(WebK
  *
  * Returns: (element-type WebKitPlugin) (transfer full): a #GList of #WebKitPlugin. You must free the #GList with
  *    g_list_free() and unref the #WebKitPlugin<!-- -->s with g_object_unref() when you're done with them.
- *
- * Deprecated: 2.32
  */
 GList* webkit_web_context_get_plugins_finish(WebKitWebContext* context, GAsyncResult* result, GError** error)
 {
-    g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr);
-    g_return_val_if_fail(g_task_is_valid(result, context), nullptr);
+    g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0);
+    g_return_val_if_fail(g_task_is_valid(result, context), 0);
 
     return static_cast<GList*>(g_task_propagate_pointer(G_TASK(result), error));
 }
@@ -1232,7 +1246,9 @@ GList* webkit_web_context_get_plugins_fi
  *     const gchar  *path;
  *
  *     path = webkit_uri_scheme_request_get_path (request);
- *     if (!g_strcmp0 (path, "memory")) {
+ *     if (!g_strcmp0 (path, "plugins")) {
+ *         /<!-- -->* Create a GInputStream with the contents of plugins about page, and set its length to stream_length *<!-- -->/
+ *     } else if (!g_strcmp0 (path, "memory")) {
  *         /<!-- -->* Create a GInputStream with the contents of memory about page, and set its length to stream_length *<!-- -->/
  *     } else if (!g_strcmp0 (path, "applications")) {
  *         /<!-- -->* Create a GInputStream with the contents of applications about page, and set its length to stream_length *<!-- -->/
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitWebsiteData.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitWebsiteData.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitWebsiteData.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitWebsiteData.cpp	2022-03-22 16:38:57.385580173 -0500
@@ -74,6 +74,9 @@ static bool recordContainsSupportedDataT
         WebsiteDataType::WebSQLDatabases,
         WebsiteDataType::IndexedDBDatabases,
         WebsiteDataType::HSTSCache,
+#if ENABLE(NETSCAPE_PLUGIN_API)
+        WebsiteDataType::PlugInData,
+#endif
         WebsiteDataType::Cookies,
         WebsiteDataType::DeviceIdHashSalt,
         WebsiteDataType::ResourceLoadStatistics,
@@ -103,6 +106,10 @@ static WebKitWebsiteDataTypes toWebKitWe
         returnValue |= WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES;
     if (types.contains(WebsiteDataType::HSTSCache))
         returnValue |= WEBKIT_WEBSITE_DATA_HSTS_CACHE;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    if (types.contains(WebsiteDataType::PlugInData))
+        returnValue |= WEBKIT_WEBSITE_DATA_PLUGIN_DATA;
+#endif
     if (types.contains(WebsiteDataType::Cookies))
         returnValue |= WEBKIT_WEBSITE_DATA_COOKIES;
     if (types.contains(WebsiteDataType::DeviceIdHashSalt))
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitWebsiteDataManager.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitWebsiteDataManager.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitWebsiteDataManager.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitWebsiteDataManager.cpp	2022-03-22 16:38:57.385580173 -0500
@@ -993,6 +993,10 @@ static OptionSet<WebsiteDataType> toWebs
         returnValue.add(WebsiteDataType::IndexedDBDatabases);
     if (types & WEBKIT_WEBSITE_DATA_HSTS_CACHE)
         returnValue.add(WebsiteDataType::HSTSCache);
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    if (types & WEBKIT_WEBSITE_DATA_PLUGIN_DATA)
+        returnValue.add(WebsiteDataType::PlugInData);
+#endif
     if (types & WEBKIT_WEBSITE_DATA_COOKIES)
         returnValue.add(WebsiteDataType::Cookies);
     if (types & WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp	2022-03-22 16:38:57.385580173 -0500
@@ -501,7 +501,8 @@ static gboolean webkitWebViewLoadFail(We
 {
     if (g_error_matches(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED)
         || g_error_matches(error, WEBKIT_PLUGIN_ERROR, WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD)
-        || g_error_matches(error, WEBKIT_POLICY_ERROR, WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE))
+        || g_error_matches(error, WEBKIT_POLICY_ERROR, WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE)
+        || g_error_matches(error, WEBKIT_PLUGIN_ERROR, WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD))
         return FALSE;
 
     GUniquePtr<char> htmlString(g_strdup_printf("<html><body>%s</body></html>", error->message));
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/gtk/WebKitError.h webkitgtk-2.36.0/Source/WebKit/UIProcess/API/gtk/WebKitError.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/gtk/WebKitError.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/gtk/WebKitError.h	2022-03-22 16:38:57.385580173 -0500
@@ -41,6 +41,12 @@ G_BEGIN_DECLS
 /**
  * WebKitNetworkError:
  * @WEBKIT_NETWORK_ERROR_FAILED: Generic load failure
+ * @WEBKIT_PLUGIN_ERROR_FAILED: Generic plugin load failure
+ * @WEBKIT_PLUGIN_ERROR_CANNOT_FIND_PLUGIN: Load failure due to missing plugin
+ * @WEBKIT_PLUGIN_ERROR_CANNOT_LOAD_PLUGIN: Load failure due to inability to load plugin
+ * @WEBKIT_PLUGIN_ERROR_JAVA_UNAVAILABLE: Load failure due to missing Java support that is required to load plugin
+ * @WEBKIT_PLUGIN_ERROR_CONNECTION_CANCELLED: Load failure due to connection cancellation
+ * @WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD: Load failure since plugin handles the load
  * @WEBKIT_NETWORK_ERROR_TRANSPORT: Load failure due to transport error
  * @WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL: Load failure due to unknown protocol
  * @WEBKIT_NETWORK_ERROR_CANCELLED: Load failure due to cancellation
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/gtk/WebKitMimeInfo.h webkitgtk-2.36.0/Source/WebKit/UIProcess/API/gtk/WebKitMimeInfo.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/gtk/WebKitMimeInfo.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/gtk/WebKitMimeInfo.h	2022-03-22 16:38:57.385580173 -0500
@@ -34,22 +34,22 @@ G_BEGIN_DECLS
 typedef struct _WebKitMimeInfo WebKitMimeInfo;
 
 
-WEBKIT_DEPRECATED GType
+WEBKIT_API GType
 webkit_mime_info_get_type        (void);
 
-WEBKIT_DEPRECATED WebKitMimeInfo *
+WEBKIT_API WebKitMimeInfo *
 webkit_mime_info_ref             (WebKitMimeInfo *info);
 
-WEBKIT_DEPRECATED void
+WEBKIT_API void
 webkit_mime_info_unref           (WebKitMimeInfo *info);
 
-WEBKIT_DEPRECATED const gchar *
+WEBKIT_API const gchar *
 webkit_mime_info_get_mime_type   (WebKitMimeInfo *info);
 
-WEBKIT_DEPRECATED const gchar *
+WEBKIT_API const gchar *
 webkit_mime_info_get_description (WebKitMimeInfo *info);
 
-WEBKIT_DEPRECATED const gchar * const *
+WEBKIT_API const gchar * const *
 webkit_mime_info_get_extensions  (WebKitMimeInfo *info);
 
 G_END_DECLS
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/gtk/WebKitPlugin.h webkitgtk-2.36.0/Source/WebKit/UIProcess/API/gtk/WebKitPlugin.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/gtk/WebKitPlugin.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/gtk/WebKitPlugin.h	2022-03-22 16:38:57.385580173 -0500
@@ -55,19 +55,19 @@ struct _WebKitPluginClass {
     void (*_webkit_reserved3) (void);
 };
 
-WEBKIT_DEPRECATED GType
+WEBKIT_API GType
 webkit_plugin_get_type           (void);
 
-WEBKIT_DEPRECATED const gchar *
+WEBKIT_API const gchar *
 webkit_plugin_get_name           (WebKitPlugin *plugin);
 
-WEBKIT_DEPRECATED const gchar *
+WEBKIT_API const gchar *
 webkit_plugin_get_description    (WebKitPlugin *plugin);
 
-WEBKIT_DEPRECATED const gchar *
+WEBKIT_API const gchar *
 webkit_plugin_get_path           (WebKitPlugin *plugin);
 
-WEBKIT_DEPRECATED GList *
+WEBKIT_API GList *
 webkit_plugin_get_mime_info_list (WebKitPlugin *plugin);
 
 G_END_DECLS
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/gtk/WebKitSettings.h webkitgtk-2.36.0/Source/WebKit/UIProcess/API/gtk/WebKitSettings.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/gtk/WebKitSettings.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/gtk/WebKitSettings.h	2022-03-22 16:38:57.385580173 -0500
@@ -147,10 +147,10 @@ WEBKIT_API void
 webkit_settings_set_enable_frame_flattening                    (WebKitSettings *settings,
                                                                 gboolean        enabled);
 
-WEBKIT_DEPRECATED gboolean
+WEBKIT_API gboolean
 webkit_settings_get_enable_plugins                             (WebKitSettings *settings);
 
-WEBKIT_DEPRECATED void
+WEBKIT_API void
 webkit_settings_set_enable_plugins                             (WebKitSettings *settings,
                                                                 gboolean        enabled);
 
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/gtk/WebKitWebContext.h webkitgtk-2.36.0/Source/WebKit/UIProcess/API/gtk/WebKitWebContext.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/gtk/WebKitWebContext.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/gtk/WebKitWebContext.h	2022-03-22 16:38:57.385580173 -0500
@@ -197,17 +197,17 @@ webkit_web_context_get_favicon_database_
 WEBKIT_API WebKitSecurityManager *
 webkit_web_context_get_security_manager             (WebKitWebContext              *context);
 
-WEBKIT_DEPRECATED void
+WEBKIT_API void
 webkit_web_context_set_additional_plugins_directory (WebKitWebContext              *context,
                                                      const gchar                   *directory);
 
-WEBKIT_DEPRECATED void
+WEBKIT_API void
 webkit_web_context_get_plugins                      (WebKitWebContext              *context,
                                                      GCancellable                  *cancellable,
                                                      GAsyncReadyCallback            callback,
                                                      gpointer                       user_data);
 
-WEBKIT_DEPRECATED GList *
+WEBKIT_API GList *
 webkit_web_context_get_plugins_finish               (WebKitWebContext              *context,
                                                      GAsyncResult                  *result,
                                                      GError                       **error);
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/gtk/WebKitWebsiteData.h webkitgtk-2.36.0/Source/WebKit/UIProcess/API/gtk/WebKitWebsiteData.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/API/gtk/WebKitWebsiteData.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/API/gtk/WebKitWebsiteData.h	2022-03-22 16:38:57.385580173 -0500
@@ -42,7 +42,7 @@ typedef struct _WebKitWebsiteData WebKit
  * @WEBKIT_WEBSITE_DATA_LOCAL_STORAGE: Local storage data.
  * @WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES: WebSQL databases. Deprecated 2.24
  * @WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES: IndexedDB databases.
- * @WEBKIT_WEBSITE_DATA_PLUGIN_DATA: Plugins data. Deprecated 2.32
+ * @WEBKIT_WEBSITE_DATA_PLUGIN_DATA: Plugins data.
  * @WEBKIT_WEBSITE_DATA_COOKIES: Cookies.
  * @WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT: Hash salt used to generate the device ids used by webpages. Since 2.24
  * @WEBKIT_WEBSITE_DATA_HSTS_CACHE: HSTS cache. Since 2.26
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp	2022-03-22 16:38:57.385580173 -0500
@@ -78,6 +78,11 @@ void AuxiliaryProcessProxy::getLaunchOpt
     case ProcessLauncher::ProcessType::Web:
         varname = "WEB_PROCESS_CMD_PREFIX";
         break;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    case ProcessLauncher::ProcessType::Plugin:
+        varname = "PLUGIN_PROCESS_CMD_PREFIX";
+        break;
+#endif
     case ProcessLauncher::ProcessType::Network:
         varname = "NETWORK_PROCESS_CMD_PREFIX";
         break;
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/gtk/WebPageProxyGtk.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/gtk/WebPageProxyGtk.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/gtk/WebPageProxyGtk.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/gtk/WebPageProxyGtk.cpp	2022-03-22 16:38:57.385580173 -0500
@@ -38,6 +38,10 @@
 #include <WebCore/PlatformDisplay.h>
 #include <wtf/NeverDestroyed.h>
 
+#if PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
+#include <gtk/gtkx.h>
+#endif
+
 namespace WebKit {
 
 void WebPageProxy::platformInitialize()
@@ -70,6 +74,62 @@ void WebPageProxy::didUpdateEditorState(
     pageClient().selectionDidChange();
 }
 
+#if PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
+typedef HashMap<uint64_t, GtkWidget* > PluginWindowMap;
+static PluginWindowMap& pluginWindowMap()
+{
+    static NeverDestroyed<PluginWindowMap> map;
+    return map;
+}
+
+static gboolean pluginContainerPlugRemoved(GtkSocket* socket)
+{
+    uint64_t windowID = static_cast<uint64_t>(gtk_socket_get_id(socket));
+    pluginWindowMap().remove(windowID);
+    return FALSE;
+}
+
+void WebPageProxy::createPluginContainer(CompletionHandler<void(uint64_t)>&& completionHandler)
+{
+    RELEASE_ASSERT(WebCore::PlatformDisplay::sharedDisplay().type() == WebCore::PlatformDisplay::Type::X11);
+    GtkWidget* socket = gtk_socket_new();
+    g_signal_connect(socket, "plug-removed", G_CALLBACK(pluginContainerPlugRemoved), 0);
+    gtk_container_add(GTK_CONTAINER(viewWidget()), socket);
+
+    uint64_t windowID = static_cast<uint64_t>(gtk_socket_get_id(GTK_SOCKET(socket)));
+    pluginWindowMap().set(windowID, socket);
+    completionHandler(windowID);
+}
+
+void WebPageProxy::windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID)
+{
+    GtkWidget* plugin = pluginWindowMap().get(windowID);
+    if (!plugin)
+        return;
+
+    if (gtk_widget_get_realized(plugin)) {
+        GdkRectangle clip = clipRect;
+        cairo_region_t* clipRegion = cairo_region_create_rectangle(&clip);
+        gdk_window_shape_combine_region(gtk_widget_get_window(plugin), clipRegion, 0, 0);
+        cairo_region_destroy(clipRegion);
+    }
+
+    webkitWebViewBaseChildMoveResize(WEBKIT_WEB_VIEW_BASE(viewWidget()), plugin, frameRect);
+}
+
+void WebPageProxy::windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID)
+{
+    GtkWidget* plugin = pluginWindowMap().get(windowID);
+    if (!plugin)
+        return;
+
+    if (isVisible)
+        gtk_widget_show(plugin);
+    else
+        gtk_widget_hide(plugin);
+}
+#endif // PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
+
 void WebPageProxy::setInputMethodState(std::optional<InputMethodState>&& state)
 {
     webkitWebViewBaseSetInputMethodState(WEBKIT_WEB_VIEW_BASE(viewWidget()), WTFMove(state));
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp	2022-03-16 08:48:02.000000000 -0500
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp	2022-03-22 16:38:57.385580173 -0500
@@ -636,6 +636,13 @@ GRefPtr<GSubprocess> bubblewrapSpawn(GSu
 {
     ASSERT(launcher);
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    // It is impossible to know what access arbitrary plugins need and since it is for legacy
+    // reasons lets just leave it unsandboxed.
+    if (launchOptions.processType == ProcessLauncher::ProcessType::Plugin)
+        return adoptGRef(g_subprocess_launcher_spawnv(launcher, argv, error));
+#endif
+
     // For now we are just considering the network process trusted as it
     // requires a lot of access but doesn't execute arbitrary code like
     // the WebProcess where our focus lies.
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Launcher/glib/ProcessLauncherGLib.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/Launcher/glib/ProcessLauncherGLib.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Launcher/glib/ProcessLauncherGLib.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Launcher/glib/ProcessLauncherGLib.cpp	2022-03-22 16:38:57.385580173 -0500
@@ -74,10 +74,21 @@ void ProcessLauncher::launchProcess()
 
     String executablePath;
     CString realExecutablePath;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    String pluginPath;
+    CString realPluginPath;
+#endif
     switch (m_launchOptions.processType) {
     case ProcessLauncher::ProcessType::Web:
         executablePath = executablePathOfWebProcess();
         break;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    case ProcessLauncher::ProcessType::Plugin:
+        executablePath = executablePathOfPluginProcess();
+        pluginPath = m_launchOptions.extraInitializationData.get("plugin-path");
+        realPluginPath = FileSystem::fileSystemRepresentation(pluginPath);
+        break;
+#endif
     case ProcessLauncher::ProcessType::Network:
         executablePath = executablePathOfNetworkProcess();
         break;
@@ -125,7 +136,11 @@ void ProcessLauncher::launchProcess()
     if (configureJSCForTesting)
         argv[i++] = const_cast<char*>("--configure-jsc-for-testing");
 #endif
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    argv[i++] = const_cast<char*>(realPluginPath.data());
+#else
     argv[i++] = nullptr;
+#endif
 
     // Warning: do not set a child setup function, because we want GIO to be able to spawn with
     // posix_spawn() rather than fork()/exec(), in order to better accomodate applications that use
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Launcher/ProcessLauncher.h webkitgtk-2.36.0/Source/WebKit/UIProcess/Launcher/ProcessLauncher.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Launcher/ProcessLauncher.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Launcher/ProcessLauncher.h	2022-03-22 16:38:57.385580173 -0500
@@ -70,6 +70,9 @@ public:
     
     enum class ProcessType {
         Web,
+#if ENABLE(NETSCAPE_PLUGIN_API)
+        Plugin,
+#endif
         Network,
 #if ENABLE(GPU_PROCESS)
         GPU,
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/PageClient.h webkitgtk-2.36.0/Source/WebKit/UIProcess/PageClient.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/PageClient.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/PageClient.h	2022-03-22 16:38:57.385580173 -0500
@@ -56,6 +56,7 @@
 #include <wtf/WeakPtr.h>
 
 #if PLATFORM(COCOA)
+#include "PluginComplexTextInputState.h"
 #include "RemoteLayerTreeNode.h"
 #include "WKFoundation.h"
 
@@ -423,6 +424,8 @@ public:
 #endif
 
 #if PLATFORM(MAC)
+    virtual void pluginFocusOrWindowFocusChanged(uint64_t pluginComplexTextInputIdentifier, bool pluginHasFocusAndWindowHasFocus) = 0;
+    virtual void setPluginComplexTextInputState(uint64_t pluginComplexTextInputIdentifier, PluginComplexTextInputState) = 0;
     virtual void showCorrectionPanel(WebCore::AlternativeTextType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) = 0;
     virtual void dismissCorrectionPanel(WebCore::ReasonForDismissingAlternativeText) = 0;
     virtual String dismissCorrectionPanelSoon(WebCore::ReasonForDismissingAlternativeText) = 0;
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/gtk/PluginInfoCache.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/gtk/PluginInfoCache.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/gtk/PluginInfoCache.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/gtk/PluginInfoCache.cpp	2022-03-22 16:38:57.385580173 -0500
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginInfoCache.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NetscapePluginModule.h"
+#include <WebCore/PlatformDisplay.h>
+#include <wtf/FileSystem.h>
+#include <wtf/text/CString.h>
+
+namespace WebKit {
+
+static const unsigned gSchemaVersion = 3;
+
+PluginInfoCache& PluginInfoCache::singleton()
+{
+    static NeverDestroyed<PluginInfoCache> pluginInfoCache;
+    return pluginInfoCache;
+}
+
+static inline const char* cacheFilenameForCurrentDisplay()
+{
+#if PLATFORM(X11)
+    if (WebCore::PlatformDisplay::sharedDisplay().type() == WebCore::PlatformDisplay::Type::X11)
+        return "plugins-x11";
+#endif
+#if PLATFORM(WAYLAND)
+    if (WebCore::PlatformDisplay::sharedDisplay().type() == WebCore::PlatformDisplay::Type::Wayland)
+        return "plugins-wayland";
+#endif
+
+    ASSERT_NOT_REACHED();
+    return "plugins";
+}
+
+PluginInfoCache::PluginInfoCache()
+    : m_cacheFile(g_key_file_new())
+    , m_saveToFileIdle(RunLoop::main(), this, &PluginInfoCache::saveToFile)
+    , m_readOnlyMode(false)
+{
+    m_saveToFileIdle.setPriority(G_PRIORITY_DEFAULT_IDLE);
+
+    GUniquePtr<char> cacheDirectory(g_build_filename(g_get_user_cache_dir(), "webkitgtk", nullptr));
+    if (FileSystem::makeAllDirectories(cacheDirectory.get())) {
+        // Delete old cache file.
+        GUniquePtr<char> oldCachePath(g_build_filename(cacheDirectory.get(), "plugins", nullptr));
+        FileSystem::deleteFile(FileSystem::stringFromFileSystemRepresentation(oldCachePath.get()));
+
+        m_cachePath.reset(g_build_filename(cacheDirectory.get(), cacheFilenameForCurrentDisplay(), nullptr));
+        g_key_file_load_from_file(m_cacheFile.get(), m_cachePath.get(), G_KEY_FILE_NONE, nullptr);
+    }
+
+    if (g_key_file_has_group(m_cacheFile.get(), "schema")) {
+        unsigned schemaVersion = static_cast<unsigned>(g_key_file_get_integer(m_cacheFile.get(), "schema", "version", nullptr));
+        if (schemaVersion < gSchemaVersion) {
+            // Cache file using an old schema, create a new empty file.
+            m_cacheFile.reset(g_key_file_new());
+        } else if (schemaVersion > gSchemaVersion) {
+            // Cache file using a newer schema, use the cache in read only mode.
+            m_readOnlyMode = true;
+        } else {
+            // Same schema version, we don't need to update it.
+            return;
+        }
+    }
+
+    g_key_file_set_integer(m_cacheFile.get(), "schema", "version", static_cast<unsigned>(gSchemaVersion));
+}
+
+PluginInfoCache::~PluginInfoCache()
+{
+}
+
+void PluginInfoCache::saveToFile()
+{
+    gsize dataLength;
+    GUniquePtr<char> data(g_key_file_to_data(m_cacheFile.get(), &dataLength, nullptr));
+    if (!data)
+        return;
+
+    g_file_set_contents(m_cachePath.get(), data.get(), dataLength, nullptr);
+}
+
+bool PluginInfoCache::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
+{
+    CString pluginGroup = pluginPath.utf8();
+    if (!g_key_file_has_group(m_cacheFile.get(), pluginGroup.data()))
+        return false;
+
+    auto lastModifiedTime = FileSystem::fileModificationTime(pluginPath);
+    if (!lastModifiedTime)
+        return false;
+    time_t cachedLastModified = static_cast<time_t>(g_key_file_get_uint64(m_cacheFile.get(), pluginGroup.data(), "mtime", nullptr));
+    if (lastModifiedTime->secondsSinceEpoch().secondsAs<time_t>() != cachedLastModified)
+        return false;
+
+    plugin.path = pluginPath;
+    plugin.info.file = FileSystem::pathFileName(pluginPath);
+
+    GUniquePtr<char> stringValue(g_key_file_get_string(m_cacheFile.get(), pluginGroup.data(), "name", nullptr));
+    plugin.info.name = String::fromUTF8(stringValue.get());
+
+    stringValue.reset(g_key_file_get_string(m_cacheFile.get(), pluginGroup.data(), "description", nullptr));
+    plugin.info.desc = String::fromUTF8(stringValue.get());
+
+#if PLUGIN_ARCHITECTURE(UNIX)
+    stringValue.reset(g_key_file_get_string(m_cacheFile.get(), pluginGroup.data(), "mime-description", nullptr));
+    NetscapePluginModule::parseMIMEDescription(String::fromUTF8(stringValue.get()), plugin.info.mimes);
+#endif
+
+    return true;
+}
+
+void PluginInfoCache::updatePluginInfo(const String& pluginPath, const PluginModuleInfo& plugin)
+{
+    auto lastModifiedTime = FileSystem::fileModificationTime(pluginPath);
+    if (!lastModifiedTime)
+        return;
+
+    CString pluginGroup = pluginPath.utf8();
+    g_key_file_set_uint64(m_cacheFile.get(), pluginGroup.data(), "mtime", lastModifiedTime->secondsSinceEpoch().secondsAs<guint64>());
+    g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "name", plugin.info.name.utf8().data());
+    g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "description", plugin.info.desc.utf8().data());
+
+#if PLUGIN_ARCHITECTURE(UNIX)
+    String mimeDescription = NetscapePluginModule::buildMIMEDescription(plugin.info.mimes);
+    g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "mime-description", mimeDescription.utf8().data());
+#endif
+
+    if (m_cachePath && !m_readOnlyMode) {
+        // Save the cache file in an idle to make sure it happens in the main thread and
+        // it's done only once when this is called multiple times in a very short time.
+        if (m_saveToFileIdle.isActive())
+            return;
+
+        m_saveToFileIdle.startOneShot(0_s);
+    }
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/gtk/PluginInfoCache.h webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/gtk/PluginInfoCache.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/gtk/PluginInfoCache.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/gtk/PluginInfoCache.h	2022-03-22 16:38:57.385580173 -0500
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PluginInfoCache_h
+#define PluginInfoCache_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "PluginModuleInfo.h"
+#include <wtf/NeverDestroyed.h>
+#include <wtf/RunLoop.h>
+#include <wtf/glib/GUniquePtr.h>
+
+namespace WebKit {
+
+class PluginInfoCache {
+    WTF_MAKE_NONCOPYABLE(PluginInfoCache);
+    friend NeverDestroyed<PluginInfoCache>;
+public:
+    static PluginInfoCache& singleton();
+
+    bool getPluginInfo(const String& pluginPath, PluginModuleInfo&);
+    void updatePluginInfo(const String& pluginPath, const PluginModuleInfo&);
+
+private:
+    PluginInfoCache();
+    ~PluginInfoCache();
+
+    void saveToFile();
+
+    GUniquePtr<GKeyFile> m_cacheFile;
+    GUniquePtr<char> m_cachePath;
+    RunLoop::Timer<PluginInfoCache> m_saveToFileIdle;
+    bool m_readOnlyMode;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // PluginInfoCache_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginInfoStore.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginInfoStore.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginInfoStore.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginInfoStore.cpp	2022-03-22 16:38:57.385580173 -0500
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2010, 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginInfoStore.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "PluginModuleInfo.h"
+#include <WebCore/MIMETypeRegistry.h>
+#include <WebCore/SecurityOrigin.h>
+#include <algorithm>
+#include <wtf/ListHashSet.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/URL.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+PluginInfoStore::PluginInfoStore()
+    : m_pluginListIsUpToDate(false)
+{
+}
+
+void PluginInfoStore::setAdditionalPluginsDirectories(const Vector<String>& directories)
+{
+    m_additionalPluginsDirectories = directories;
+    refresh();
+}
+
+void PluginInfoStore::refresh()
+{
+    m_pluginListIsUpToDate = false;
+}
+
+template <typename T, typename U>
+static void addFromVector(T& hashSet, const U& vector)
+{
+    for (size_t i = 0; i < vector.size(); ++i)
+        hashSet.add(vector[i]);
+}
+
+void PluginInfoStore::loadPluginsIfNecessary()
+{
+    if (m_pluginListIsUpToDate)
+        return;
+
+    ListHashSet<String> uniquePluginPaths;
+
+    // First, load plug-ins from the additional plug-ins directories specified.
+    for (size_t i = 0; i < m_additionalPluginsDirectories.size(); ++i)
+        addFromVector(uniquePluginPaths, pluginPathsInDirectory(m_additionalPluginsDirectories[i]));
+
+    // Then load plug-ins from the standard plug-ins directories.
+    Vector<String> directories = pluginsDirectories();
+    for (size_t i = 0; i < directories.size(); ++i)
+        addFromVector(uniquePluginPaths, pluginPathsInDirectory(directories[i]));
+
+    // Then load plug-ins that are not in the standard plug-ins directories.
+    addFromVector(uniquePluginPaths, individualPluginPaths());
+
+    m_plugins.clear();
+
+    for (const auto& pluginPath : uniquePluginPaths)
+        loadPlugin(m_plugins, pluginPath);
+
+    m_pluginListIsUpToDate = true;
+}
+
+void PluginInfoStore::loadPlugin(Vector<PluginModuleInfo>& plugins, const String& pluginPath)
+{
+    PluginModuleInfo plugin;
+    
+    if (!getPluginInfo(pluginPath, plugin))
+        return;
+
+    if (!shouldUsePlugin(plugins, plugin))
+        return;
+    
+    plugins.append(plugin);
+}
+
+Vector<PluginModuleInfo> PluginInfoStore::plugins()
+{
+    loadPluginsIfNecessary();
+    return m_plugins;
+}
+
+PluginModuleInfo PluginInfoStore::findPluginForMIMEType(const String& mimeType, PluginData::AllowedPluginTypes allowedPluginTypes) const
+{
+    ASSERT(!mimeType.isNull());
+
+    for (const auto& plugin : m_plugins) {
+        if (allowedPluginTypes == PluginData::OnlyApplicationPlugins && !plugin.info.isApplicationPlugin)
+            continue;
+
+        for (const auto& mimeClassInfo : plugin.info.mimes) {
+            if (mimeClassInfo.type == mimeType)
+                return plugin;
+        }
+    }
+    
+    return PluginModuleInfo();
+}
+
+PluginModuleInfo PluginInfoStore::findPluginForExtension(const String& extension, String& mimeType, PluginData::AllowedPluginTypes allowedPluginTypes) const
+{
+    ASSERT(!extension.isNull());
+
+    for (const auto& plugin : m_plugins) {
+        if (allowedPluginTypes == PluginData::OnlyApplicationPlugins && !plugin.info.isApplicationPlugin)
+            continue;
+
+        for (const auto& mimeClassInfo : plugin.info.mimes) {
+            if (mimeClassInfo.extensions.contains(extension)) {
+                // We found a supported extension, set the correct MIME type.
+                mimeType = mimeClassInfo.type;
+                return plugin;
+            }
+        }
+    }
+    
+    return PluginModuleInfo();
+}
+
+static String pathExtension(const URL& url)
+{
+    auto filename = url.lastPathComponent();
+    if (filename.endsWith('/'))
+        return { };
+    size_t lastDotPosition = filename.reverseFind('.');
+    if (lastDotPosition == notFound)
+        return { };
+    return filename.substring(lastDotPosition + 1).convertToASCIILowercase();
+}
+
+#if !PLATFORM(COCOA)
+
+PluginModuleLoadPolicy PluginInfoStore::defaultLoadPolicyForPlugin(const PluginModuleInfo&)
+{
+    return PluginModuleLoadNormally;
+}
+    
+PluginModuleInfo PluginInfoStore::findPluginWithBundleIdentifier(const String&)
+{
+    ASSERT_NOT_REACHED();
+    return PluginModuleInfo();
+}
+
+#endif
+
+PluginModuleInfo PluginInfoStore::findPlugin(String& mimeType, const URL& url, PluginData::AllowedPluginTypes allowedPluginTypes)
+{
+    loadPluginsIfNecessary();
+    
+    // First, check if we can get the plug-in based on its MIME type.
+    if (!mimeType.isNull()) {
+        PluginModuleInfo plugin = findPluginForMIMEType(mimeType, allowedPluginTypes);
+        if (!plugin.path.isNull())
+            return plugin;
+    }
+
+    // Next, check if any plug-ins claim to support the URL extension.
+    String extension = pathExtension(url);
+    if (!extension.isNull() && mimeType.isEmpty()) {
+        PluginModuleInfo plugin = findPluginForExtension(extension, mimeType, allowedPluginTypes);
+        if (!plugin.path.isNull())
+            return plugin;
+        
+        // Finally, try to get the MIME type from the extension in a platform specific manner and use that.
+        String extensionMimeType = MIMETypeRegistry::mimeTypeForExtension(extension);
+        if (!extensionMimeType.isNull()) {
+            PluginModuleInfo plugin = findPluginForMIMEType(extensionMimeType, allowedPluginTypes);
+            if (!plugin.path.isNull()) {
+                mimeType = extensionMimeType;
+                return plugin;
+            }
+        }
+    }
+    
+    return PluginModuleInfo();
+}
+
+bool PluginInfoStore::isSupportedPlugin(const PluginInfoStore::SupportedPlugin& plugin, const String& mimeType, const URL& pluginURL)
+{
+    if (!mimeType.isEmpty() && plugin.mimeTypes.contains(mimeType))
+        return true;
+    auto extension = pathExtension(pluginURL);
+    return extension.isEmpty() ? false : plugin.extensions.contains(extension);
+}
+
+bool PluginInfoStore::isSupportedPlugin(const String& mimeType, const URL& pluginURL, const String&, const URL& pageURL)
+{
+    // We check only pageURL for consistency with WebProcess visible plugins.
+    if (!m_supportedPlugins)
+        return true;
+
+    return m_supportedPlugins->findIf([&] (auto&& plugin) {
+        return pageURL.isMatchingDomain(plugin.matchingDomain) && isSupportedPlugin(plugin, mimeType, pluginURL);
+    }) != notFound;
+}
+
+std::optional<Vector<SupportedPluginIdentifier>> PluginInfoStore::supportedPluginIdentifiers()
+{
+    if (!m_supportedPlugins)
+        return std::nullopt;
+
+    return WTF::map(*m_supportedPlugins, [] (auto&& item) {
+        return SupportedPluginIdentifier { item.matchingDomain, item.identifier };
+    });
+}
+
+void PluginInfoStore::addSupportedPlugin(String&& domainName, String&& identifier, HashSet<String>&& mimeTypes, HashSet<String> extensions)
+{
+    if (!m_supportedPlugins)
+        m_supportedPlugins = Vector<SupportedPlugin> { };
+
+    m_supportedPlugins->append(SupportedPlugin { WTFMove(domainName), WTFMove(identifier), WTFMove(mimeTypes), WTFMove(extensions) });
+}
+
+PluginModuleInfo PluginInfoStore::infoForPluginWithPath(const String& pluginPath) const
+{
+    for (const auto& plugin : m_plugins) {
+        if (plugin.path == pluginPath)
+            return plugin;
+    }
+
+    ASSERT_NOT_REACHED();
+    return PluginModuleInfo();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginInfoStore.h webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginInfoStore.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginInfoStore.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginInfoStore.h	2022-03-22 16:38:57.389580195 -0500
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2010, 2012, 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "PluginModuleInfo.h"
+
+#include <WebCore/PluginData.h>
+#include <wtf/HashSet.h>
+
+namespace WebKit {
+
+class PluginInfoStore;
+
+class PluginInfoStore {
+    WTF_MAKE_NONCOPYABLE(PluginInfoStore);
+
+public:
+    PluginInfoStore();
+
+    void setAdditionalPluginsDirectories(const Vector<String>&);
+
+    void refresh();
+    Vector<PluginModuleInfo> plugins();
+
+    // Returns the info for a plug-in that can handle the given MIME type.
+    // If the MIME type is null, the file extension of the given url will be used to infer the
+    // plug-in type. In that case, mimeType will be filled in with the right MIME type.
+    PluginModuleInfo findPlugin(String& mimeType, const URL&, WebCore::PluginData::AllowedPluginTypes = WebCore::PluginData::AllPlugins);
+
+    // Returns the info for the plug-in with the given bundle identifier.
+    PluginModuleInfo findPluginWithBundleIdentifier(const String& bundleIdentifier);
+
+    // Returns the info for the plug-in with the given path.
+    PluginModuleInfo infoForPluginWithPath(const String& pluginPath) const;
+
+    static PluginModuleLoadPolicy defaultLoadPolicyForPlugin(const PluginModuleInfo&);
+
+    bool isSupportedPlugin(const String& mimeType, const URL& pluginURL, const String& frameURLString, const URL& pageURL);
+    std::optional<Vector<WebCore::SupportedPluginIdentifier>> supportedPluginIdentifiers();
+    void addSupportedPlugin(String&& matchingDomain, String&& identifier, HashSet<String>&& mimeTypes, HashSet<String> extensions);
+    void clearSupportedPlugins() { m_supportedPlugins = std::nullopt; }
+
+private:
+    PluginModuleInfo findPluginForMIMEType(const String& mimeType, WebCore::PluginData::AllowedPluginTypes) const;
+    PluginModuleInfo findPluginForExtension(const String& extension, String& mimeType, WebCore::PluginData::AllowedPluginTypes) const;
+
+    void loadPluginsIfNecessary();
+    static void loadPlugin(Vector<PluginModuleInfo>& plugins, const String& pluginPath);
+    
+    // Platform-specific member functions:
+
+    // Returns paths to directories that should be searched for plug-ins (via pluginPathsInDirectory).
+    static Vector<String> pluginsDirectories();
+
+    // Returns paths to all plug-ins in the specified directory.
+    static Vector<String> pluginPathsInDirectory(const String& directory);
+
+    // Returns paths to individual plug-ins that won't be found via pluginsDirectories/pluginPathsInDirectory.
+    static Vector<String> individualPluginPaths();
+
+    // Load plug-in info for the plug-in with the specified path.
+    static bool getPluginInfo(const String& pluginPath, PluginModuleInfo&);
+
+    // Return whether this plug-in should be used (added to the list of plug-ins) or not.
+    static bool shouldUsePlugin(Vector<PluginModuleInfo>& alreadyLoadedPlugins, const PluginModuleInfo&);
+
+    Vector<String> m_additionalPluginsDirectories;
+    Vector<PluginModuleInfo> m_plugins;
+    bool m_pluginListIsUpToDate;
+
+    struct SupportedPlugin {
+        String matchingDomain;
+        String identifier;
+        HashSet<String> mimeTypes;
+        HashSet<String> extensions;
+    };
+    static bool isSupportedPlugin(const SupportedPlugin&, const String& mimeType, const URL& pluginURL);
+
+    std::optional<Vector<SupportedPlugin>> m_supportedPlugins;
+};
+    
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginProcessManager.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginProcessManager.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginProcessManager.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginProcessManager.cpp	2022-03-22 16:38:57.389580195 -0500
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginProcessManager.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "PluginProcessProxy.h"
+#include "WebProcessProxyMessages.h"
+#include "WebsiteDataFetchOption.h"
+#include <wtf/CryptographicallyRandomNumber.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+PluginProcessManager& PluginProcessManager::singleton()
+{
+    static NeverDestroyed<PluginProcessManager> pluginProcessManager;
+    return pluginProcessManager;
+}
+
+PluginProcessManager::PluginProcessManager()
+#if PLATFORM(COCOA)
+    : m_processSuppressionDisabledForPageCounter([this](RefCounterEvent event) { updateProcessSuppressionDisabled(event); })
+#endif
+{
+}
+
+uint64_t PluginProcessManager::pluginProcessToken(const PluginModuleInfo& pluginModuleInfo, PluginProcessSandboxPolicy pluginProcessSandboxPolicy)
+{
+    // See if we know this token already.
+    for (size_t i = 0; i < m_pluginProcessTokens.size(); ++i) {
+        const PluginProcessAttributes& attributes = m_pluginProcessTokens[i].first;
+
+        if (attributes.moduleInfo.path == pluginModuleInfo.path
+            && attributes.sandboxPolicy == pluginProcessSandboxPolicy)
+            return m_pluginProcessTokens[i].second;
+    }
+
+    uint64_t token;
+    while (true) {
+        cryptographicallyRandomValues(&token, sizeof(token));
+
+        if (m_knownTokens.isValidValue(token) && !m_knownTokens.contains(token))
+            break;
+    }
+
+    PluginProcessAttributes attributes;
+    attributes.moduleInfo = pluginModuleInfo;
+    attributes.sandboxPolicy = pluginProcessSandboxPolicy;
+
+    m_pluginProcessTokens.append(std::make_pair(WTFMove(attributes), token));
+    m_knownTokens.add(token);
+
+    return token;
+}
+
+bool PluginProcessManager::getPluginProcessConnection(uint64_t pluginProcessToken, Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply&& reply)
+{
+    ASSERT(pluginProcessToken);
+
+    auto* pluginProcess = getOrCreatePluginProcess(pluginProcessToken);
+    ASSERT(pluginProcess);
+    if (!pluginProcess)
+        return false;
+
+    pluginProcess->getPluginProcessConnection(WTFMove(reply));
+    return true;
+}
+
+void PluginProcessManager::removePluginProcessProxy(PluginProcessProxy* pluginProcessProxy)
+{
+    size_t vectorIndex = m_pluginProcesses.find(pluginProcessProxy);
+    ASSERT(vectorIndex != notFound);
+
+    m_pluginProcesses.remove(vectorIndex);
+}
+
+void PluginProcessManager::fetchWebsiteData(const PluginModuleInfo& plugin, OptionSet<WebsiteDataFetchOption> fetchOptions, WTF::Function<void (Vector<String>)>&& completionHandler)
+{
+    auto token = pluginProcessToken(plugin, PluginProcessSandboxPolicy::Normal);
+    auto pluginProcess = fetchOptions.contains(WebsiteDataFetchOption::DoNotCreateProcesses) ? getPluginProcess(token) : getOrCreatePluginProcess(token);
+    if (!pluginProcess) {
+        completionHandler({ });
+        return;
+    }
+
+    pluginProcess->fetchWebsiteData(WTFMove(completionHandler));
+}
+
+void PluginProcessManager::deleteWebsiteData(const PluginModuleInfo& plugin, WallTime modifiedSince, WTF::Function<void ()>&& completionHandler)
+{
+    PluginProcessProxy* pluginProcess = getOrCreatePluginProcess(pluginProcessToken(plugin, PluginProcessSandboxPolicy::Normal));
+    pluginProcess->deleteWebsiteData(modifiedSince, WTFMove(completionHandler));
+}
+
+void PluginProcessManager::deleteWebsiteDataForHostNames(const PluginModuleInfo& plugin, const Vector<String>& hostNames,WTF::Function<void ()>&& completionHandler)
+{
+    PluginProcessProxy* pluginProcess = getOrCreatePluginProcess(pluginProcessToken(plugin, PluginProcessSandboxPolicy::Normal));
+    pluginProcess->deleteWebsiteDataForHostNames(hostNames, WTFMove(completionHandler));
+}
+
+PluginProcessProxy* PluginProcessManager::getPluginProcess(uint64_t pluginProcessToken)
+{
+    for (const auto& pluginProcess : m_pluginProcesses) {
+        if (pluginProcess->pluginProcessToken() == pluginProcessToken)
+            return pluginProcess.get();
+    }
+
+    return nullptr;
+}
+
+#if OS(LINUX)
+void PluginProcessManager::sendMemoryPressureEvent(bool isCritical)
+{
+    for (auto& pluginProcess : m_pluginProcesses)
+        pluginProcess->sendMemoryPressureEvent(isCritical);
+}
+#endif
+
+PluginProcessProxy* PluginProcessManager::getOrCreatePluginProcess(uint64_t pluginProcessToken)
+{
+    if (auto existingProcess = getPluginProcess(pluginProcessToken))
+        return existingProcess;
+
+    for (auto& attributesAndToken : m_pluginProcessTokens) {
+        if (attributesAndToken.second == pluginProcessToken) {
+            auto pluginProcess = PluginProcessProxy::create(this, attributesAndToken.first, attributesAndToken.second);
+            PluginProcessProxy* pluginProcessPtr = pluginProcess.ptr();
+            m_pluginProcesses.append(WTFMove(pluginProcess));
+            return pluginProcessPtr;
+        }
+    }
+
+    return nullptr;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginProcessManager.h webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginProcessManager.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginProcessManager.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginProcessManager.h	2022-03-22 16:38:57.389580195 -0500
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "PluginModuleInfo.h"
+#include "PluginProcess.h"
+#include "PluginProcessAttributes.h"
+#include "ProcessThrottler.h"
+#include "WebProcessProxyMessagesReplies.h"
+#include <wtf/Forward.h>
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/RefCounter.h>
+#include <wtf/Vector.h>
+
+namespace IPC {
+class Encoder;
+}
+
+namespace WebKit {
+
+class PluginInfoStore;
+class PluginProcessProxy;
+class WebProcessProxy;
+enum class WebsiteDataFetchOption : uint8_t;
+
+class PluginProcessManager {
+    WTF_MAKE_NONCOPYABLE(PluginProcessManager);
+    friend NeverDestroyed<PluginProcessManager>;
+public:
+    static PluginProcessManager& singleton();
+
+    uint64_t pluginProcessToken(const PluginModuleInfo&, PluginProcessSandboxPolicy);
+
+    bool getPluginProcessConnection(uint64_t pluginProcessToken, Messages::WebProcessProxy::GetPluginProcessConnectionDelayedReply&&);
+    void removePluginProcessProxy(PluginProcessProxy*);
+
+    void fetchWebsiteData(const PluginModuleInfo&, OptionSet<WebsiteDataFetchOption>, WTF::Function<void (Vector<String>)>&& completionHandler);
+    void deleteWebsiteData(const PluginModuleInfo&, WallTime modifiedSince, WTF::Function<void ()>&& completionHandler);
+    void deleteWebsiteDataForHostNames(const PluginModuleInfo&, const Vector<String>& hostNames, WTF::Function<void ()>&& completionHandler);
+
+#if OS(LINUX)
+    void sendMemoryPressureEvent(bool isCritical);
+#endif
+
+#if PLATFORM(COCOA)
+    inline ProcessSuppressionDisabledToken processSuppressionDisabledToken();
+    inline bool processSuppressionDisabled() const;
+    void updateProcessSuppressionDisabled(RefCounterEvent);
+#endif
+
+    const Vector<RefPtr<PluginProcessProxy>>& pluginProcesses() const { return m_pluginProcesses; }
+
+#if PLATFORM(MAC)
+    void setExperimentalPlugInSandboxProfilesEnabled(bool);
+    bool experimentalPlugInSandboxProfilesEnabled() const { return m_experimentalPlugInSandboxProfilesEnabled; }
+#endif
+
+private:
+    PluginProcessManager();
+
+    PluginProcessProxy* getPluginProcess(uint64_t pluginProcessToken);
+    PluginProcessProxy* getOrCreatePluginProcess(uint64_t pluginProcessToken);
+
+    Vector<std::pair<PluginProcessAttributes, uint64_t>> m_pluginProcessTokens;
+    HashSet<uint64_t> m_knownTokens;
+
+    Vector<RefPtr<PluginProcessProxy>> m_pluginProcesses;
+
+#if PLATFORM(COCOA)
+    ProcessSuppressionDisabledCounter m_processSuppressionDisabledForPageCounter;
+#endif
+#if PLATFORM(MAC)
+    bool m_experimentalPlugInSandboxProfilesEnabled { false };
+#endif
+};
+
+#if PLATFORM(COCOA)
+inline ProcessSuppressionDisabledToken PluginProcessManager::processSuppressionDisabledToken()
+{
+    return m_processSuppressionDisabledForPageCounter.count();
+}
+
+inline bool PluginProcessManager::processSuppressionDisabled() const
+{
+    return m_processSuppressionDisabledForPageCounter.value();
+}
+#endif
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginProcessProxy.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginProcessProxy.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginProcessProxy.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginProcessProxy.cpp	2022-03-22 16:38:57.389580195 -0500
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2010-2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginProcessProxy.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "AuxiliaryProcessMessages.h"
+#include "PluginProcessConnectionManagerMessages.h"
+#include "PluginProcessCreationParameters.h"
+#include "PluginProcessManager.h"
+#include "PluginProcessMessages.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebProcessPool.h"
+#include "WebProcessProxy.h"
+#include "WebProcessProxyMessages.h"
+#include <WebCore/NotImplemented.h>
+#include <wtf/RunLoop.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+static const Seconds minimumLifetime { 2_min };
+static const Seconds snapshottingMinimumLifetime { 30_s };
+
+static const Seconds shutdownTimeout { 1_min };
+static const Seconds snapshottingShutdownTimeout { 15_s };
+
+static uint64_t generatePluginProcessCallbackID()
+{
+    static uint64_t callbackID;
+
+    return ++callbackID;
+}
+
+Ref<PluginProcessProxy> PluginProcessProxy::create(PluginProcessManager* PluginProcessManager, const PluginProcessAttributes& pluginProcessAttributes, uint64_t pluginProcessToken)
+{
+    return adoptRef(*new PluginProcessProxy(PluginProcessManager, pluginProcessAttributes, pluginProcessToken));
+}
+
+PluginProcessProxy::PluginProcessProxy(PluginProcessManager* PluginProcessManager, const PluginProcessAttributes& pluginProcessAttributes, uint64_t pluginProcessToken)
+    : m_throttler(*this, false)
+    , m_pluginProcessManager(PluginProcessManager)
+    , m_pluginProcessAttributes(pluginProcessAttributes)
+    , m_pluginProcessToken(pluginProcessToken)
+    , m_numPendingConnectionRequests(0)
+#if PLATFORM(COCOA)
+    , m_modalWindowIsShowing(false)
+    , m_fullscreenWindowIsShowing(false)
+    , m_preFullscreenAppPresentationOptions(0)
+#endif
+{
+    connect();
+}
+
+PluginProcessProxy::~PluginProcessProxy()
+{
+    if (m_connection)
+        m_connection->invalidate();
+
+    ASSERT(m_pendingFetchWebsiteDataRequests.isEmpty());
+    ASSERT(m_pendingFetchWebsiteDataCallbacks.isEmpty());
+    ASSERT(m_pendingDeleteWebsiteDataRequests.isEmpty());
+    ASSERT(m_pendingDeleteWebsiteDataCallbacks.isEmpty());
+}
+
+void PluginProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions)
+{
+    platformGetLaunchOptionsWithAttributes(launchOptions, m_pluginProcessAttributes);
+    AuxiliaryProcessProxy::getLaunchOptions(launchOptions);
+}
+
+void PluginProcessProxy::processWillShutDown(IPC::Connection& connection)
+{
+    ASSERT_UNUSED(connection, this->connection() == &connection);
+}
+
+// Asks the plug-in process to create a new connection to a web process. The connection identifier will be 
+// encoded in the given argument encoder and sent back to the connection of the given web process.
+void PluginProcessProxy::getPluginProcessConnection(Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply&& reply)
+{
+    m_pendingConnectionReplies.append(WTFMove(reply));
+
+    if (state() == State::Launching) {
+        m_numPendingConnectionRequests++;
+        return;
+    }
+    
+    // Ask the plug-in process to create a connection. Since the plug-in can be waiting for a synchronous reply
+    // we need to make sure that this message is always processed, even when the plug-in is waiting for a synchronus reply.
+    m_connection->send(Messages::PluginProcess::CreateWebProcessConnection(), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
+}
+
+void PluginProcessProxy::fetchWebsiteData(CompletionHandler<void (Vector<String>)>&& completionHandler)
+{
+    uint64_t callbackID = generatePluginProcessCallbackID();
+    m_pendingFetchWebsiteDataCallbacks.set(callbackID, WTFMove(completionHandler));
+
+    if (state() == State::Launching) {
+        m_pendingFetchWebsiteDataRequests.append(callbackID);
+        return;
+    }
+
+    m_connection->send(Messages::PluginProcess::GetSitesWithData(callbackID), 0);
+}
+
+void PluginProcessProxy::deleteWebsiteData(WallTime modifiedSince, CompletionHandler<void ()>&& completionHandler)
+{
+    uint64_t callbackID = generatePluginProcessCallbackID();
+    m_pendingDeleteWebsiteDataCallbacks.set(callbackID, WTFMove(completionHandler));
+
+    if (state() == State::Launching) {
+        m_pendingDeleteWebsiteDataRequests.append({ modifiedSince, callbackID });
+        return;
+    }
+
+    m_connection->send(Messages::PluginProcess::DeleteWebsiteData(modifiedSince, callbackID), 0);
+}
+
+void PluginProcessProxy::deleteWebsiteDataForHostNames(const Vector<String>& hostNames, CompletionHandler<void ()>&& completionHandler)
+{
+    uint64_t callbackID = generatePluginProcessCallbackID();
+    m_pendingDeleteWebsiteDataForHostNamesCallbacks.set(callbackID, WTFMove(completionHandler));
+
+    if (state() == State::Launching) {
+        m_pendingDeleteWebsiteDataForHostNamesRequests.append({ hostNames, callbackID });
+        return;
+    }
+
+    m_connection->send(Messages::PluginProcess::DeleteWebsiteDataForHostNames(hostNames, callbackID), 0);
+}
+
+#if OS(LINUX)
+void PluginProcessProxy::sendMemoryPressureEvent(bool isCritical)
+{
+    if (state() == State::Launching)
+        return;
+
+    m_connection->send(Messages::AuxiliaryProcess::DidReceiveMemoryPressureEvent(isCritical), 0);
+}
+#endif
+
+void PluginProcessProxy::pluginProcessCrashedOrFailedToLaunch()
+{
+    // The plug-in process must have crashed or exited, send any pending sync replies we might have.
+    while (!m_pendingConnectionReplies.isEmpty()) {
+        auto reply = m_pendingConnectionReplies.takeFirst();
+
+#if USE(UNIX_DOMAIN_SOCKETS)
+        reply(IPC::Attachment(), false);
+#elif OS(DARWIN)
+        reply(IPC::Attachment(0, MACH_MSG_TYPE_MOVE_SEND), false);
+#else
+        notImplemented();
+#endif
+    }
+
+    m_pendingFetchWebsiteDataRequests.clear();
+    for (auto&& callback : m_pendingFetchWebsiteDataCallbacks.values())
+        callback({ });
+    m_pendingFetchWebsiteDataCallbacks.clear();
+
+    m_pendingDeleteWebsiteDataRequests.clear();
+    for (auto&& callback : m_pendingDeleteWebsiteDataCallbacks.values())
+        callback();
+    m_pendingDeleteWebsiteDataRequests.clear();
+
+    m_pendingDeleteWebsiteDataForHostNamesRequests.clear();
+    for (auto&& callback : m_pendingDeleteWebsiteDataForHostNamesCallbacks.values())
+        callback();
+    m_pendingDeleteWebsiteDataForHostNamesCallbacks.clear();
+
+    // Tell the plug-in process manager to forget about this plug-in process proxy. This may cause us to be deleted.
+    m_pluginProcessManager->removePluginProcessProxy(this);
+}
+
+void PluginProcessProxy::didClose(IPC::Connection&)
+{
+#if PLATFORM(COCOA)
+    if (m_modalWindowIsShowing)
+        endModal();
+
+    if (m_fullscreenWindowIsShowing)
+        exitFullscreen();
+#endif
+
+    for (auto& processPool : WebProcessPool::allProcessPools())
+        processPool->sendToAllProcesses(Messages::PluginProcessConnectionManager::PluginProcessCrashed(m_pluginProcessToken));
+
+    // This will cause us to be deleted.
+    pluginProcessCrashedOrFailedToLaunch();
+}
+
+void PluginProcessProxy::didReceiveInvalidMessage(IPC::Connection& connection, IPC::MessageName messageName)
+{
+    logInvalidMessage(connection, messageName);
+    terminate();
+}
+
+void PluginProcessProxy::didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier connectionIdentifier)
+{
+    ASSERT(!m_connection);
+
+    if (!IPC::Connection::identifierIsValid(connectionIdentifier)) {
+        pluginProcessCrashedOrFailedToLaunch();
+        return;
+    }
+
+    m_connection = IPC::Connection::createServerConnection(connectionIdentifier, *this);
+
+    m_connection->open();
+    
+    PluginProcessCreationParameters parameters;
+    parameters.minimumLifetime = minimumLifetime;
+    parameters.terminationTimeout = shutdownTimeout;
+
+    platformInitializePluginProcess(parameters);
+
+    // Initialize the plug-in host process.
+    m_connection->send(Messages::PluginProcess::InitializePluginProcess(parameters), 0);
+
+#if PLATFORM(COCOA)
+    m_connection->send(Messages::PluginProcess::SetQOS(pluginProcessLatencyQOS(), pluginProcessThroughputQOS()), 0);
+#endif
+
+    for (auto callbackID : m_pendingFetchWebsiteDataRequests)
+        m_connection->send(Messages::PluginProcess::GetSitesWithData(callbackID), 0);
+    m_pendingFetchWebsiteDataRequests.clear();
+
+    for (auto& request : m_pendingDeleteWebsiteDataRequests)
+        m_connection->send(Messages::PluginProcess::DeleteWebsiteData(request.modifiedSince, request.callbackID), 0);
+    m_pendingDeleteWebsiteDataRequests.clear();
+
+    for (auto& request : m_pendingDeleteWebsiteDataForHostNamesRequests)
+        m_connection->send(Messages::PluginProcess::DeleteWebsiteDataForHostNames(request.hostNames, request.callbackID), 0);
+    m_pendingDeleteWebsiteDataForHostNamesRequests.clear();
+
+    for (unsigned i = 0; i < m_numPendingConnectionRequests; ++i)
+        m_connection->send(Messages::PluginProcess::CreateWebProcessConnection(), 0);
+    
+    m_numPendingConnectionRequests = 0;
+
+#if PLATFORM(COCOA)
+    if (!PluginProcessManager::singleton().processSuppressionDisabled())
+        setProcessSuppressionEnabled(true);
+#endif
+}
+
+void PluginProcessProxy::didCreateWebProcessConnection(const IPC::Attachment& connectionIdentifier, bool supportsAsynchronousPluginInitialization)
+{
+    ASSERT(!m_pendingConnectionReplies.isEmpty());
+
+    // Grab the first pending connection reply.
+    auto reply = m_pendingConnectionReplies.takeFirst();
+
+#if USE(UNIX_DOMAIN_SOCKETS)
+    reply(connectionIdentifier, supportsAsynchronousPluginInitialization);
+#elif OS(DARWIN)
+    reply(IPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND), supportsAsynchronousPluginInitialization);
+#else
+    notImplemented();
+#endif
+}
+
+void PluginProcessProxy::didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID)
+{
+    auto callback = m_pendingFetchWebsiteDataCallbacks.take(callbackID);
+    callback(sites);
+}
+
+void PluginProcessProxy::didDeleteWebsiteData(uint64_t callbackID)
+{
+    auto callback = m_pendingDeleteWebsiteDataCallbacks.take(callbackID);
+    callback();
+}
+
+void PluginProcessProxy::didDeleteWebsiteDataForHostNames(uint64_t callbackID)
+{
+    auto callback = m_pendingDeleteWebsiteDataForHostNamesCallbacks.take(callbackID);
+    callback();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginProcessProxy.h webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginProcessProxy.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginProcessProxy.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginProcessProxy.h	2022-03-22 16:38:57.389580195 -0500
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "AuxiliaryProcessProxy.h"
+#include "Connection.h"
+#include "PluginModuleInfo.h"
+#include "PluginProcess.h"
+#include "PluginProcessAttributes.h"
+#include "ProcessLauncher.h"
+#include "ProcessThrottler.h"
+#include "ProcessThrottlerClient.h"
+#include "WebProcessProxyMessagesReplies.h"
+#include <wtf/Deque.h>
+
+#if PLATFORM(COCOA)
+#include <wtf/RetainPtr.h>
+OBJC_CLASS NSObject;
+OBJC_CLASS WKPlaceholderModalWindow;
+#endif
+
+namespace WebKit {
+
+class PluginProcessManager;
+class WebProcessProxy;
+struct PluginProcessCreationParameters;
+
+#if PLUGIN_ARCHITECTURE(UNIX)
+struct RawPluginMetaData {
+    String name;
+    String description;
+    String mimeDescription;
+};
+#endif
+
+#if PLATFORM(COCOA)
+int pluginProcessLatencyQOS();
+int pluginProcessThroughputQOS();
+#endif
+
+class PluginProcessProxy final : public AuxiliaryProcessProxy, private ProcessThrottlerClient {
+public:
+    static Ref<PluginProcessProxy> create(PluginProcessManager*, const PluginProcessAttributes&, uint64_t pluginProcessToken);
+    ~PluginProcessProxy();
+
+    const PluginProcessAttributes& pluginProcessAttributes() const { return m_pluginProcessAttributes; }
+    uint64_t pluginProcessToken() const { return m_pluginProcessToken; }
+
+    // Asks the plug-in process to create a new connection to a web process. The connection identifier will be
+    // encoded in the given argument encoder and sent back to the connection of the given web process.
+    void getPluginProcessConnection(Messages::WebProcessProxy::GetPluginProcessConnectionDelayedReply&&);
+
+    void fetchWebsiteData(CompletionHandler<void (Vector<String>)>&&);
+    void deleteWebsiteData(WallTime modifiedSince, CompletionHandler<void ()>&&);
+    void deleteWebsiteDataForHostNames(const Vector<String>& hostNames, CompletionHandler<void ()>&&);
+
+#if OS(LINUX)
+    void sendMemoryPressureEvent(bool isCritical);
+#endif
+
+    bool isValid() const { return m_connection; }
+
+#if PLUGIN_ARCHITECTURE(UNIX)
+    static bool scanPlugin(const String& pluginPath, RawPluginMetaData& result);
+#endif
+
+    ProcessThrottler& throttler() final { return m_throttler; }
+
+private:
+    PluginProcessProxy(PluginProcessManager*, const PluginProcessAttributes&, uint64_t pluginProcessToken);
+
+    // AuxiliaryProcessProxy
+    ASCIILiteral processName() const final { return "Plugin"_s; }
+
+    void getLaunchOptions(ProcessLauncher::LaunchOptions&) override;
+    void platformGetLaunchOptionsWithAttributes(ProcessLauncher::LaunchOptions&, const PluginProcessAttributes&);
+    void processWillShutDown(IPC::Connection&) override;
+
+    void pluginProcessCrashedOrFailedToLaunch();
+
+    // ProcessThrottlerClient
+    void sendPrepareToSuspend(IsSuspensionImminent, CompletionHandler<void()>&& completionHandler) final { completionHandler(); }
+    void sendProcessDidResume() final { }
+    ASCIILiteral clientName() const final { return "PluginProcess"_s; }
+
+    // IPC::Connection::Client
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+    bool didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&) override;
+
+    void didClose(IPC::Connection&) override;
+    void didReceiveInvalidMessage(IPC::Connection&, IPC::MessageName) override;
+
+    // ProcessLauncher::Client
+    void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override;
+
+    // Message handlers
+    void didCreateWebProcessConnection(const IPC::Attachment&, bool supportsAsynchronousPluginInitialization);
+    void didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID);
+    void didDeleteWebsiteData(uint64_t callbackID);
+    void didDeleteWebsiteDataForHostNames(uint64_t callbackID);
+
+#if PLATFORM(COCOA)
+    bool getPluginProcessSerialNumber(ProcessSerialNumber&);
+    void makePluginProcessTheFrontProcess();
+    void makeUIProcessTheFrontProcess();
+
+    void setFullscreenWindowIsShowing(bool);
+    void enterFullscreen();
+    void exitFullscreen();
+
+    void setModalWindowIsShowing(bool);
+    void beginModal();
+    void endModal();
+
+    void applicationDidBecomeActive();
+    void launchProcess(const String& launchPath, const Vector<String>& arguments, CompletionHandler<void(bool)>&&);
+    void launchApplicationAtURL(const String& urlString, const Vector<String>& arguments, CompletionHandler<void(bool)>&&);
+    void openURL(const String& url, CompletionHandler<void(bool result, int32_t status, String launchedURLString)>&&);
+    void openFile(const String& fullPath, CompletionHandler<void(bool)>&&);
+#endif
+
+    void platformInitializePluginProcess(PluginProcessCreationParameters& parameters);
+
+    ProcessThrottler m_throttler;
+
+    // The plug-in host process manager.
+    PluginProcessManager* m_pluginProcessManager;
+
+    PluginProcessAttributes m_pluginProcessAttributes;
+    uint64_t m_pluginProcessToken;
+
+    // The connection to the plug-in host process.
+    RefPtr<IPC::Connection> m_connection;
+
+    Deque<Messages::WebProcessProxy::GetPluginProcessConnectionDelayedReply> m_pendingConnectionReplies;
+
+    Vector<uint64_t> m_pendingFetchWebsiteDataRequests;
+    HashMap<uint64_t, CompletionHandler<void (Vector<String>)>> m_pendingFetchWebsiteDataCallbacks;
+
+    struct DeleteWebsiteDataRequest {
+        WallTime modifiedSince;
+        uint64_t callbackID;
+    };
+    Vector<DeleteWebsiteDataRequest> m_pendingDeleteWebsiteDataRequests;
+    HashMap<uint64_t, CompletionHandler<void ()>> m_pendingDeleteWebsiteDataCallbacks;
+
+    struct DeleteWebsiteDataForHostNamesRequest {
+        Vector<String> hostNames;
+        uint64_t callbackID;
+    };
+    Vector<DeleteWebsiteDataForHostNamesRequest> m_pendingDeleteWebsiteDataForHostNamesRequests;
+    HashMap<uint64_t, CompletionHandler<void ()>> m_pendingDeleteWebsiteDataForHostNamesCallbacks;
+
+    // If createPluginConnection is called while the process is still launching we'll keep count of it and send a bunch of requests
+    // when the process finishes launching.
+    unsigned m_numPendingConnectionRequests;
+
+#if PLATFORM(COCOA)
+    RetainPtr<NSObject> m_activationObserver;
+    RetainPtr<WKPlaceholderModalWindow> m_placeholderWindow;
+    bool m_modalWindowIsShowing;
+    bool m_fullscreenWindowIsShowing;
+    unsigned m_preFullscreenAppPresentationOptions;
+#endif
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginProcessProxy.messages.in webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginProcessProxy.messages.in
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/PluginProcessProxy.messages.in	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/PluginProcessProxy.messages.in	2022-03-22 16:38:57.389580195 -0500
@@ -0,0 +1,50 @@
+# Copyright (C) 2010 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+messages -> PluginProcessProxy {
+    DidCreateWebProcessConnection(IPC::Attachment connectionIdentifier, bool supportsAsynchronousPluginInitialization)
+
+    DidGetSitesWithData(Vector<String> sites, uint64_t callbackID)
+    DidDeleteWebsiteData(uint64_t callbackID)
+    DidDeleteWebsiteDataForHostNames(uint64_t callbackID)
+
+#if PLATFORM(COCOA)
+    SetModalWindowIsShowing(bool modalWindowIsShowing)
+    SetFullscreenWindowIsShowing(bool fullscreenWindowIsShowing)
+    
+    # Returns true if the UI process launched the process.
+    LaunchProcess(String launchPath, Vector<String> arguments) -> (bool result) Synchronous
+
+    # Returns true if the UI process launched the application.
+    LaunchApplicationAtURL(String url, Vector<String> arguments) -> (bool result) Synchronous
+
+    # Returns true if the UI process did open the URL.
+    OpenURL(String urlString) -> (bool result, int32_t status, String launchedURLString) Synchronous
+    
+    # Returns true if the UI process did open the file.
+    OpenFile(String fullPath) -> (bool result) Synchronous
+#endif
+}
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp	2022-03-22 16:38:57.389580195 -0500
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Note: this file is only for UNIX. On other platforms we can reuse the native implementation.
+
+#include "config.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "PluginInfoStore.h"
+
+#include "NetscapePluginModule.h"
+#include "PluginSearchPath.h"
+#include "ProcessExecutablePath.h"
+#include <WebCore/PlatformDisplay.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <wtf/FileSystem.h>
+
+#if PLATFORM(GTK)
+#include "PluginInfoCache.h"
+#endif
+#include <fnmatch.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+Vector<String> PluginInfoStore::pluginsDirectories()
+{
+    return WebKit::pluginsDirectories();
+}
+
+Vector<String> PluginInfoStore::pluginPathsInDirectory(const String& directory)
+{
+    Vector<String> result;
+    char normalizedPath[PATH_MAX];
+    CString cpath = FileSystem::fileSystemRepresentation(directory);
+    for (const auto& path : FileSystem::listDirectory(directory)) {
+        CString filename = FileSystem::fileSystemRepresentation(path);
+        if (fnmatch(filename.data(), "*.so", 0))
+            continue;
+        char filePath[PATH_MAX];
+        if (static_cast<int>(sizeof(filePath) - 1) < snprintf(filePath, sizeof(filePath), "%s/%s", cpath.data(), filename.data()))
+            continue; // buffer overflow
+        if (realpath(filePath, normalizedPath))
+            result.append(FileSystem::stringFromFileSystemRepresentation(normalizedPath));
+    }
+
+    return result;
+}
+
+Vector<String> PluginInfoStore::individualPluginPaths()
+{
+    return Vector<String>();
+}
+
+bool PluginInfoStore::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin)
+{
+#if PLATFORM(GTK)
+    if (PluginInfoCache::singleton().getPluginInfo(pluginPath, plugin))
+        return true;
+
+    if (NetscapePluginModule::getPluginInfo(pluginPath, plugin)) {
+        PluginInfoCache::singleton().updatePluginInfo(pluginPath, plugin);
+        return true;
+    }
+    return false;
+#else
+    return NetscapePluginModule::getPluginInfo(pluginPath, plugin);
+#endif
+}
+
+bool PluginInfoStore::shouldUsePlugin(Vector<PluginModuleInfo>& /*alreadyLoadedPlugins*/, const PluginModuleInfo& /*plugin*/)
+{
+    // We do not do any black-listing presently.
+    return true;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp	2022-03-22 16:38:57.389580195 -0500
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2011, 2014 Igalia S.L.
+ * Copyright (C) 2011 Apple Inc.
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginProcessProxy.h"
+
+#if ENABLE(PLUGIN_PROCESS)
+
+#include "PluginProcessCreationParameters.h"
+#include "ProcessExecutablePath.h"
+#include <WebCore/PlatformDisplay.h>
+#include <sys/wait.h>
+#include <wtf/FileSystem.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+#if PLATFORM(GTK)
+#include <glib.h>
+#include <wtf/glib/GUniquePtr.h>
+#endif
+
+#if PLATFORM(GTK)
+#include "Module.h"
+#endif
+
+namespace WebKit {
+using namespace WebCore;
+
+void PluginProcessProxy::platformGetLaunchOptionsWithAttributes(ProcessLauncher::LaunchOptions& launchOptions, const PluginProcessAttributes& pluginProcessAttributes)
+{
+    launchOptions.processType = ProcessLauncher::ProcessType::Plugin;
+    launchOptions.extraInitializationData.add("plugin-path", pluginProcessAttributes.moduleInfo.path);
+}
+
+void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationParameters&)
+{
+}
+
+#if PLATFORM(GTK)
+static bool pluginRequiresGtk2(const String& pluginPath)
+{
+    std::unique_ptr<Module> module = makeUnique<Module>(pluginPath);
+    if (!module->load())
+        return false;
+    return module->functionPointer<gpointer>("gtk_object_get_type");
+}
+#endif
+
+#if PLUGIN_ARCHITECTURE(UNIX)
+bool PluginProcessProxy::scanPlugin(const String& pluginPath, RawPluginMetaData& result)
+{
+    String pluginProcessPath = executablePathOfPluginProcess();
+
+#if PLATFORM(GTK)
+    if (pluginRequiresGtk2(pluginPath))
+        return false;
+#endif
+
+    CString binaryPath = FileSystem::fileSystemRepresentation(pluginProcessPath);
+    CString pluginPathCString = FileSystem::fileSystemRepresentation(pluginPath);
+    char* argv[4];
+    argv[0] = const_cast<char*>(binaryPath.data());
+    argv[1] = const_cast<char*>("-scanPlugin");
+    argv[2] = const_cast<char*>(pluginPathCString.data());
+    argv[3] = nullptr;
+
+    // If the disposition of SIGCLD signal is set to SIG_IGN (default)
+    // then the signal will be ignored and g_spawn_sync() will not be
+    // able to return the status.
+    // As a consequence, we make sure that the disposition is set to
+    // SIG_DFL before calling g_spawn_sync().
+#if defined(SIGCLD)
+    struct sigaction action;
+    sigaction(SIGCLD, 0, &action);
+    if (action.sa_handler == SIG_IGN) {
+        action.sa_handler = SIG_DFL;
+        sigaction(SIGCLD, &action, 0);
+    }
+#endif
+
+    int status;
+    GUniqueOutPtr<char> stdOut;
+    GUniqueOutPtr<GError> error;
+    if (!g_spawn_sync(nullptr, argv, nullptr, G_SPAWN_STDERR_TO_DEV_NULL, nullptr, nullptr, &stdOut.outPtr(), nullptr, &status, &error.outPtr())) {
+        WTFLogAlways("Failed to launch %s: %s", argv[0], error->message);
+        return false;
+    }
+
+    if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS) {
+        WTFLogAlways("Error scanning plugin %s, %s returned %d exit status", argv[2], argv[0], status);
+        return false;
+    }
+
+    if (!stdOut) {
+        WTFLogAlways("Error scanning plugin %s, %s didn't write any output to stdout", argv[2], argv[0]);
+        return false;
+    }
+
+    Vector<String> lines = String::fromUTF8(stdOut.get()).splitAllowingEmptyEntries('\n');
+
+    if (lines.size() < 3) {
+        WTFLogAlways("Error scanning plugin %s, too few lines of output provided", argv[2]);
+        return false;
+    }
+
+    result.name.swap(lines[0]);
+    result.description.swap(lines[1]);
+    result.mimeDescription.swap(lines[2]);
+    return !result.mimeDescription.isEmpty();
+}
+#endif // PLUGIN_ARCHITECTURE(UNIX)
+
+} // namespace WebKit
+
+#endif // ENABLE(PLUGIN_PROCESS)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebPageProxy.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/WebPageProxy.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-03-22 16:38:57.389580195 -0500
@@ -81,6 +81,8 @@
 #include "NotificationPermissionRequest.h"
 #include "NotificationPermissionRequestManager.h"
 #include "PageClient.h"
+#include "PluginInformation.h"
+#include "PluginProcessManager.h"
 #include "PrintInfo.h"
 #include "ProcessThrottler.h"
 #include "ProvisionalPageProxy.h"
@@ -1905,6 +1907,13 @@ bool WebPageProxy::canShowMIMEType(const
     if (MIMETypeRegistry::canShowMIMEType(mimeType))
         return true;
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    String newMimeType = mimeType;
+    PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL());
+    if (!plugin.path.isNull() && m_preferences->pluginsEnabled())
+        return true;
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
 #if PLATFORM(COCOA)
     // On Mac, we can show PDFs.
     if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebProcessPool::omitPDFSupport())
@@ -3026,6 +3035,64 @@ WebPreferencesStore WebPageProxy::prefer
     return m_preferences->store();
 }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+void WebPageProxy::findPlugin(const String& mimeType, const String& urlString, const String& frameURLString, const String& pageURLString, bool allowOnlyApplicationPlugins, Messages::WebPageProxy::FindPlugin::DelayedReply&& reply)
+{
+    PageClientProtector protector(pageClient());
+
+    MESSAGE_CHECK_URL(m_process, urlString);
+
+    URL pluginURL = URL { URL(), urlString };
+    String newMimeType = mimeType.convertToASCIILowercase();
+
+    PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins;
+
+    URL pageURL = URL { URL(), pageURLString };
+    if (!m_process->processPool().pluginInfoStore().isSupportedPlugin(mimeType, pluginURL, frameURLString, pageURL)) {
+        reply(0, newMimeType, PluginModuleLoadNormally, { }, true);
+        return;
+    }
+
+    PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, pluginURL, allowedPluginTypes);
+    if (!plugin.path) {
+        reply(0, newMimeType, PluginModuleLoadNormally, { }, false);
+        return;
+    }
+
+    uint32_t pluginLoadPolicy = PluginInfoStore::defaultLoadPolicyForPlugin(plugin);
+
+#if PLATFORM(COCOA)
+    auto pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String());
+#endif
+
+    auto findPluginCompletion = [reply = WTFMove(reply), newMimeType = WTFMove(newMimeType), plugin = WTFMove(plugin)] (uint32_t pluginLoadPolicy, const String& unavailabilityDescription) mutable {
+        PluginProcessSandboxPolicy pluginProcessSandboxPolicy = PluginProcessSandboxPolicy::Normal;
+        switch (pluginLoadPolicy) {
+        case PluginModuleLoadNormally:
+            pluginProcessSandboxPolicy = PluginProcessSandboxPolicy::Normal;
+            break;
+        case PluginModuleLoadUnsandboxed:
+            pluginProcessSandboxPolicy = PluginProcessSandboxPolicy::Unsandboxed;
+            break;
+
+        case PluginModuleBlockedForSecurity:
+        case PluginModuleBlockedForCompatibility:
+            reply(0, newMimeType, pluginLoadPolicy, unavailabilityDescription, false);
+            return;
+        }
+
+        reply(PluginProcessManager::singleton().pluginProcessToken(plugin, pluginProcessSandboxPolicy), newMimeType, pluginLoadPolicy, unavailabilityDescription, false);
+    };
+
+#if PLATFORM(COCOA)
+    m_navigationClient->decidePolicyForPluginLoad(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), WTFMove(findPluginCompletion));
+#else
+    findPluginCompletion(pluginLoadPolicy, { });
+#endif
+}
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
 #if ENABLE(TOUCH_EVENTS)
 
 static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b)
@@ -6109,6 +6176,39 @@ void WebPageProxy::mouseDidMoveOverEleme
     setToolTip(hitTestResultData.toolTipText);
 }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginspageAttributeURLString, const String& frameURLString, const String& pageURLString)
+{
+    MESSAGE_CHECK_URL(m_process, pluginURLString);
+    MESSAGE_CHECK_URL(m_process, pluginspageAttributeURLString);
+    MESSAGE_CHECK_URL(m_process, frameURLString);
+    MESSAGE_CHECK_URL(m_process, pageURLString);
+
+    String newMimeType = mimeType;
+    PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
+    auto pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, pluginspageAttributeURLString, pluginURLString);
+
+    WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
+    switch (static_cast<RenderEmbeddedObject::PluginUnavailabilityReason>(opaquePluginUnavailabilityReason)) {
+    case RenderEmbeddedObject::PluginMissing:
+        pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
+        break;
+    case RenderEmbeddedObject::InsecurePluginVersion:
+        pluginUnavailabilityReason = kWKPluginUnavailabilityReasonInsecurePluginVersion;
+        break;
+    case RenderEmbeddedObject::PluginCrashed:
+        pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginCrashed;
+        break;
+    case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
+    case RenderEmbeddedObject::UnsupportedPlugin:
+    case RenderEmbeddedObject::PluginTooSmall:
+        ASSERT_NOT_REACHED();
+    }
+
+    m_uiClient->unavailablePluginButtonClicked(*this, pluginUnavailabilityReason, pluginInformation.get());
+}
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
 #if ENABLE(WEBGL)
 void WebPageProxy::webGLPolicyForURL(URL&& url, Messages::WebPageProxy::WebGLPolicyForURL::DelayedReply&& reply)
 {
@@ -8951,6 +9051,22 @@ Color WebPageProxy::platformUnderPageBac
 
 #endif // !PLATFORM(COCOA)
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+void WebPageProxy::didFailToInitializePlugin(const String& mimeType, const String& frameURLString, const String& pageURLString)
+{
+    m_navigationClient->didFailToInitializePlugIn(*this, createPluginInformationDictionary(mimeType, frameURLString, pageURLString).get());
+}
+
+void WebPageProxy::didBlockInsecurePluginVersion(const String& mimeType, const String& pluginURLString, const String& frameURLString, const String& pageURLString, bool replacementObscured)
+{
+    String newMimeType = mimeType;
+    PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
+    auto pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, String(), String(), replacementObscured);
+
+    m_navigationClient->didBlockInsecurePluginVersion(*this, pluginInformation.get());
+}
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
 bool WebPageProxy::willHandleHorizontalScrollEvents() const
 {
     return !m_canShortCircuitHorizontalWheelEvents;
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebPageProxy.h webkitgtk-2.36.0/Source/WebKit/UIProcess/WebPageProxy.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebPageProxy.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/WebPageProxy.h	2022-03-22 16:38:57.389580195 -0500
@@ -47,6 +47,7 @@
 #include "PDFPluginIdentifier.h"
 #include "PageLoadState.h"
 #include "PasteboardAccessIntent.h"
+#include "PluginProcessAttributes.h"
 #include "PolicyDecision.h"
 #include "ProcessTerminationReason.h"
 #include "ProcessThrottler.h"
@@ -962,6 +963,8 @@ public:
 #if PLATFORM(COCOA)
     void windowAndViewFramesChanged(const WebCore::FloatRect& viewFrameInWindowCoordinates, const WebCore::FloatPoint& accessibilityViewCoordinates);
     void setMainFrameIsScrollable(bool);
+        
+    void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput);
     bool shouldDelayWindowOrderingForEvent(const WebMouseEvent&);
 
     void setRemoteLayerTreeRootNode(RemoteLayerTreeNode*);
@@ -2193,6 +2196,9 @@ private:
     void setStatusText(const String&);
     void mouseDidMoveOverElement(WebHitTestResultData&&, uint32_t modifiers, UserData&&);
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    void unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginsPageURLString, const String& frameURLString, const String& pageURLString);
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
 #if ENABLE(WEBGL)
     void webGLPolicyForURL(URL&&, Messages::WebPageProxy::WebGLPolicyForURLDelayedReply&&);
     void resolveWebGLPolicyForURL(URL&&, Messages::WebPageProxy::ResolveWebGLPolicyForURLDelayedReply&&);
@@ -2251,6 +2257,10 @@ private:
     void pageExtendedBackgroundColorDidChange(const WebCore::Color&);
     void sampledPageTopColorChanged(const WebCore::Color&);
     WebCore::Color platformUnderPageBackgroundColor() const;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    void didFailToInitializePlugin(const String& mimeType, const String& frameURLString, const String& pageURLString);
+    void didBlockInsecurePluginVersion(const String& mimeType, const String& pluginURLString, const String& frameURLString, const String& pageURLString, bool replacementObscured);
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
     void setCanShortCircuitHorizontalWheelEvents(bool canShortCircuitHorizontalWheelEvents) { m_canShortCircuitHorizontalWheelEvents = canShortCircuitHorizontalWheelEvents; }
 
     enum class ProcessLaunchReason {
@@ -2398,6 +2408,11 @@ private:
 
     void didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference&);
 
+#if PLATFORM(COCOA)
+    void pluginFocusOrWindowFocusChanged(uint64_t pluginComplexTextInputIdentifier, bool pluginHasFocusAndWindowHasFocus);
+    void setPluginComplexTextInputState(uint64_t pluginComplexTextInputIdentifier, uint64_t complexTextInputState);
+#endif
+
 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
     void toggleSmartInsertDelete();
     void toggleAutomaticQuoteSubstitution();
@@ -2457,6 +2472,12 @@ private:
 
     void setRenderTreeSize(uint64_t treeSize) { m_renderTreeSize = treeSize; }
 
+#if PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
+    void createPluginContainer(CompletionHandler<void(uint64_t)>&&);
+    void windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID);
+    void windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID);
+#endif
+
     void sendWheelEvent(const WebWheelEvent&);
 
     WebWheelEventCoalescer& wheelEventCoalescer();
@@ -2472,6 +2493,10 @@ private:
     WebCore::TrackingType touchEventTrackingType(const WebTouchEvent&) const;
 #endif
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    void findPlugin(const String& mimeType, const String& urlString, const String& frameURLString, const String& pageURLString, bool allowOnlyApplicationPlugins, Messages::WebPageProxy::FindPluginDelayedReply&&);
+#endif
+
 #if USE(QUICK_LOOK)
     void didStartLoadForQuickLookDocumentInMainFrame(const String& fileName, const String& uti);
     void didFinishLoadForQuickLookDocumentInMainFrame(const ShareableResource::Handle&);
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebPageProxy.messages.in webkitgtk-2.36.0/Source/WebKit/UIProcess/WebPageProxy.messages.in
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebPageProxy.messages.in	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/WebPageProxy.messages.in	2022-03-22 16:38:57.389580195 -0500
@@ -30,6 +30,9 @@ messages -> WebPageProxy {
     RunJavaScriptPrompt(WebCore::FrameIdentifier frameID, struct WebKit::FrameInfoData frameInfo, String message, String defaultValue) -> (String result) Synchronous
     MouseDidMoveOverElement(struct WebKit::WebHitTestResultData hitTestResultData, uint32_t modifiers, WebKit::UserData userData)
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    UnavailablePluginButtonClicked(uint32_t pluginUnavailabilityReason, String mimeType, String pluginURLString, String pluginspageAttributeURLString, String frameURLString, String pageURLString)
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
 #if ENABLE(WEBGL)
     WebGLPolicyForURL(URL url) -> (enum:uint8_t WebCore::WebGLLoadPolicy loadPolicy) Synchronous
     ResolveWebGLPolicyForURL(URL url) -> (enum:uint8_t WebCore::WebGLLoadPolicy loadPolicy) Synchronous
@@ -78,6 +81,10 @@ messages -> WebPageProxy {
     ThemeColorChanged(WebCore::Color themeColor)
     PageExtendedBackgroundColorDidChange(WebCore::Color backgroundColor)
     SampledPageTopColorChanged(WebCore::Color sampledPageTopColor)
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    DidFailToInitializePlugin(String mimeType, String frameURLString, String pageURLString)
+    DidBlockInsecurePluginVersion(String mimeType, String pluginURLString, String frameURLString, String pageURLString, bool replacementObscured)
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
     SetCanShortCircuitHorizontalWheelEvents(bool canShortCircuitHorizontalWheelEvents)
 
     DidChangeContentSize(WebCore::IntSize newSize)
@@ -327,6 +334,10 @@ messages -> WebPageProxy {
     # Remote accessibility messages
     RegisterWebProcessAccessibilityToken(IPC::DataReference data)
 
+    # Plug-in complex text input support messages
+    PluginFocusOrWindowFocusChanged(uint64_t pluginComplexTextInputIdentifier, bool pluginHasFocusAndWindowHasFocus)
+    SetPluginComplexTextInputState(uint64_t pluginComplexTextInputIdentifier, uint64_t complexTextInputState)
+
     # Speech messages
     GetIsSpeaking() -> (bool isSpeaking) Synchronous
     Speak(String string)
@@ -377,6 +388,13 @@ messages -> WebPageProxy {
     DictationAlternatives(WebCore::DictationContext dictationContext) -> (Vector<String> alternatives) Synchronous
 #endif
 
+#if PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
+    # X11 windowed plugin messages
+    CreatePluginContainer() -> (uint64_t windowID) Synchronous
+    WindowedPluginGeometryDidChange(WebCore::IntRect frameRect, WebCore::IntRect clipRect, uint64_t windowID)
+    WindowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID)
+#endif
+
 #if PLATFORM(IOS_FAMILY)
     CouldNotRestorePageState()
     RestorePageState(std::optional<WebCore::FloatPoint> scrollPosition, WebCore::FloatPoint scrollOrigin, WebCore::RectEdges<float> obscuredInsetsOnSave, double scale)
@@ -424,6 +442,10 @@ messages -> WebPageProxy {
     ShowPDFContextMenu(struct WebKit::PDFContextMenu contextMenu, WebKit::PDFPluginIdentifier identifier) -> (std::optional<int32_t> selectedItem) Synchronous
 #endif
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    FindPlugin(String mimeType, String urlString, String frameURLString, String pageURLString, bool allowOnlyApplicationPlugins) -> (uint64_t pluginProcessToken, String newMIMEType, uint32_t pluginLoadPolicy, String unavailabilityDescription, bool isUnsupported) Synchronous
+#endif
+
     DidUpdateActivityState()
 
 #if ENABLE(WEB_CRYPTO)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebProcessPool.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/WebProcessPool.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebProcessPool.cpp	2022-03-18 07:53:19.000000000 -0500
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/WebProcessPool.cpp	2022-03-22 16:43:52.295137293 -0500
@@ -51,6 +51,7 @@
 #include "NetworkProcessMessages.h"
 #include "NetworkProcessProxy.h"
 #include "PerActivityStateCPUUsageSampler.h"
+#include "PluginProcessManager.h"
 #include "SandboxExtension.h"
 #include "TextChecker.h"
 #include "UIGamepad.h"
@@ -403,6 +404,9 @@ void WebProcessPool::sendMemoryPressureE
     sendToAllProcesses(Messages::AuxiliaryProcess::DidReceiveMemoryPressureEvent(isCritical));
     for (auto networkProcess : NetworkProcessProxy::allNetworkProcesses())
         networkProcess->send(Messages::AuxiliaryProcess::DidReceiveMemoryPressureEvent(isCritical), 0);
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    PluginProcessManager::singleton().sendMemoryPressureEvent(isCritical);
+#endif
 }
 #endif
 
@@ -877,6 +881,8 @@ void WebProcessPool::initializeNewWebPro
     parameters.shouldAlwaysUseComplexTextCodePath = m_alwaysUsesComplexTextCodePath;
     parameters.shouldUseFontSmoothing = m_shouldUseFontSmoothing;
 
+    parameters.terminationTimeout = 0_s;
+
     parameters.textCheckerState = TextChecker::state();
 
     parameters.fullKeyboardAccessEnabled = WebProcessProxy::fullKeyboardAccessEnabled();
@@ -1328,6 +1334,23 @@ void WebProcessPool::handleMemoryPressur
     ASSERT(!m_prewarmedProcess);
 }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+void WebProcessPool::setAdditionalPluginsDirectory(const String& directory)
+{
+    Vector<String> directories;
+    directories.append(directory);
+
+    m_pluginInfoStore.setAdditionalPluginsDirectories(directories);
+}
+
+void WebProcessPool::refreshPlugins()
+{
+    m_pluginInfoStore.refresh();
+    sendToAllProcesses(Messages::WebProcess::RefreshPlugins());
+}
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
 ProcessID WebProcessPool::prewarmedProcessIdentifier()
 {
     return m_prewarmedProcess ? m_prewarmedProcess->processIdentifier() : 0;
@@ -1761,14 +1784,21 @@ void WebProcessPool::setJavaScriptGarbag
 
 void WebProcessPool::addSupportedPlugin(String&& matchingDomain, String&& name, HashSet<String>&& mimeTypes, HashSet<String> extensions)
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    m_pluginInfoStore.addSupportedPlugin(WTFMove(matchingDomain), WTFMove(name), WTFMove(mimeTypes), WTFMove(extensions));
+#else
     UNUSED_PARAM(matchingDomain);
     UNUSED_PARAM(name);
     UNUSED_PARAM(mimeTypes);
     UNUSED_PARAM(extensions);
+#endif
 }
 
 void WebProcessPool::clearSupportedPlugins()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    m_pluginInfoStore.clearSupportedPlugins();
+#endif
 }
 
 void WebProcessPool::setMemoryCacheDisabled(bool disabled)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebProcessPool.h webkitgtk-2.36.0/Source/WebKit/UIProcess/WebProcessPool.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebProcessPool.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/WebProcessPool.h	2022-03-22 16:38:57.389580195 -0500
@@ -34,6 +34,7 @@
 #include "MessageReceiver.h"
 #include "MessageReceiverMap.h"
 #include "NetworkProcessProxy.h"
+#include "PluginInfoStore.h"
 #include "ProcessThrottler.h"
 #include "VisitedLinkStore.h"
 #include "WebContextClient.h"
@@ -240,6 +241,13 @@ public:
 
     void handleMemoryPressureWarning(Critical);
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    void setAdditionalPluginsDirectory(const String&);
+    void refreshPlugins();
+
+    PluginInfoStore& pluginInfoStore() { return m_pluginInfoStore; }
+#endif
+
 #if HAVE(CVDISPLAYLINK)
     std::optional<WebCore::FramesPerSecond> nominalFramesPerSecondForDisplay(WebCore::PlatformDisplayID);
     void startDisplayLink(IPC::Connection&, DisplayLinkObserverID, WebCore::PlatformDisplayID, WebCore::FramesPerSecond);
@@ -650,6 +658,9 @@ private:
 
     RefPtr<WebAutomationSession> m_automationSession;
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    PluginInfoStore m_pluginInfoStore;
+#endif
     Ref<VisitedLinkStore> m_visitedLinkStore;
     bool m_visitedLinksPopulated { false };
 
@@ -727,6 +738,7 @@ private:
 
 #if PLATFORM(COCOA)
     RetainPtr<NSMutableDictionary> m_bundleParameters;
+    ProcessSuppressionDisabledToken m_pluginProcessManagerProcessSuppressionDisabledToken;
     mutable RetainPtr<NSSet> m_classesForParameterCoder;
 #endif
 
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebProcessProxy.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/WebProcessProxy.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebProcessProxy.cpp	2022-03-16 05:48:52.000000000 -0500
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/WebProcessProxy.cpp	2022-03-22 16:38:57.393580216 -0500
@@ -34,6 +34,8 @@
 #include "LoadParameters.h"
 #include "Logging.h"
 #include "NotificationManagerMessageHandlerMessages.h"
+#include "PluginInfoStore.h"
+#include "PluginProcessManager.h"
 #include "ProvisionalPageProxy.h"
 #include "ServiceWorkerNotificationHandler.h"
 #include "SpeechRecognitionPermissionRequest.h"
@@ -812,6 +814,40 @@ void WebProcessProxy::updateBackForwardI
     }
 }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+void WebProcessProxy::getPlugins(bool refresh, CompletionHandler<void(Vector<PluginInfo>&& plugins, Vector<PluginInfo>&& applicationPlugins, std::optional<Vector<WebCore::SupportedPluginIdentifier>>&& supportedPluginIdentifiers)>&& completionHandler)
+{
+    if (refresh)
+        m_processPool->pluginInfoStore().refresh();
+
+    auto supportedPluginIdentifiers = m_processPool->pluginInfoStore().supportedPluginIdentifiers();
+
+    Vector<PluginInfo> plugins;
+    Vector<PluginModuleInfo> pluginModules = m_processPool->pluginInfoStore().plugins();
+    for (size_t i = 0; i < pluginModules.size(); ++i)
+        plugins.append(pluginModules[i].info);
+
+    Vector<PluginInfo> applicationPlugins;
+#if ENABLE(PDFKIT_PLUGIN)
+    // Add built-in PDF last, so that it's not used when a real plug-in is installed.
+    if (!m_processPool->omitPDFSupport()) {
+        plugins.append(PDFPlugin::pluginInfo());
+        applicationPlugins.append(PDFPlugin::pluginInfo());
+    }
+#endif
+    completionHandler(WTFMove(plugins), WTFMove(applicationPlugins), WTFMove(supportedPluginIdentifiers));
+}
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+void WebProcessProxy::getPluginProcessConnection(uint64_t pluginProcessToken, Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply&& reply)
+{
+    MESSAGE_CHECK(HashSet<uint64_t>::isValidValue(pluginProcessToken));
+    bool success = PluginProcessManager::singleton().getPluginProcessConnection(pluginProcessToken, WTFMove(reply));
+    MESSAGE_CHECK(success);
+}
+#endif
+
 void WebProcessProxy::getNetworkProcessConnection(Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply&& reply)
 {
     websiteDataStore().getNetworkProcessConnection(*this, WTFMove(reply));
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebProcessProxy.h webkitgtk-2.36.0/Source/WebKit/UIProcess/WebProcessProxy.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebProcessProxy.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/WebProcessProxy.h	2022-03-22 16:38:57.393580216 -0500
@@ -31,6 +31,7 @@
 #include "DisplayLinkObserverID.h"
 #include "MessageReceiverMap.h"
 #include "NetworkProcessProxy.h"
+#include "PluginInfoStore.h"
 #include "ProcessLauncher.h"
 #include "ProcessTerminationReason.h"
 #include "ProcessThrottler.h"
@@ -474,6 +475,14 @@ private:
 
     bool hasProvisionalPageWithID(WebPageProxyIdentifier) const;
     bool isAllowedToUpdateBackForwardItem(WebBackForwardListItem&) const;
+
+    // Plugins
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    void getPlugins(bool refresh, CompletionHandler<void(Vector<WebCore::PluginInfo>&& plugins, Vector<WebCore::PluginInfo>&& applicationPlugins, std::optional<Vector<WebCore::SupportedPluginIdentifier>>&&)>&&);
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    void getPluginProcessConnection(uint64_t pluginProcessToken, Messages::WebProcessProxy::GetPluginProcessConnectionDelayedReply&&);
+#endif
     
     void getNetworkProcessConnection(Messages::WebProcessProxy::GetNetworkProcessConnectionDelayedReply&&);
 
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebProcessProxy.messages.in webkitgtk-2.36.0/Source/WebKit/UIProcess/WebProcessProxy.messages.in
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebProcessProxy.messages.in	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/WebProcessProxy.messages.in	2022-03-22 16:38:57.393580216 -0500
@@ -31,6 +31,11 @@ messages -> WebProcessProxy LegacyReceiv
     EnableSuddenTermination()
     DisableSuddenTermination()
 
+    # Plugin messages.
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    GetPlugins(bool refresh) -> (Vector<WebCore::PluginInfo> plugins, Vector<WebCore::PluginInfo> applicationPlugins, struct std::optional<Vector<WebCore::SupportedPluginIdentifier>> supportedPluginIdentifiers) Synchronous
+    GetPluginProcessConnection(uint64_t pluginProcessToken) -> (IPC::Attachment connectionHandle, bool supportsAsynchronousInitialization) Synchronous
+#endif
     GetNetworkProcessConnection() -> (struct WebKit::NetworkProcessConnectionInfo connectionInfo) Synchronous
 
 #if ENABLE(GPU_PROCESS)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.cpp	2022-03-22 16:38:57.393580216 -0500
@@ -90,6 +90,14 @@ void WebsiteDataRecord::addCookieHostNam
     cookieHostNames.add(hostName);
 }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+void WebsiteDataRecord::addPluginDataHostName(const String& hostName)
+{
+    types.add(WebsiteDataType::PlugInData);
+    pluginDataHostNames.add(hostName);
+}
+#endif
+
 void WebsiteDataRecord::addHSTSCacheHostname(const String& hostName)
 {
     types.add(WebsiteDataType::HSTSCache);
@@ -152,6 +160,12 @@ String WebsiteDataRecord::topPrivatelyCo
     
     if (!origins.isEmpty())
         return WebCore::topPrivatelyControlledDomain(origins.takeAny().securityOrigin().get().host());
+    
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    if (!pluginDataHostNames.isEmpty())
+        return WebCore::topPrivatelyControlledDomain(pluginDataHostNames.takeAny());
+#endif
+    
 #endif // ENABLE(PUBLIC_SUFFIX_LIST)
     
     return emptyString();
@@ -165,6 +179,9 @@ WebsiteDataRecord WebsiteDataRecord::iso
         size,
         crossThreadCopy(origins),
         crossThreadCopy(cookieHostNames),
+#if ENABLE(NETSCAPE_PLUGIN_API)
+        crossThreadCopy(pluginDataHostNames),
+#endif
         crossThreadCopy(HSTSCacheHostNames),
         crossThreadCopy(alternativeServicesHostNames),
 #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.h webkitgtk-2.36.0/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/WebsiteData/WebsiteDataRecord.h	2022-03-22 16:38:57.393580216 -0500
@@ -49,6 +49,9 @@ struct WebsiteDataRecord {
 
     void add(WebsiteDataType, const WebCore::SecurityOriginData&);
     void addCookieHostName(const String& hostName);
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    void addPluginDataHostName(const String& hostName);
+#endif
     void addHSTSCacheHostname(const String& hostName);
     void addAlternativeServicesHostname(const String& hostName);
 #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
@@ -71,6 +74,9 @@ struct WebsiteDataRecord {
 
     HashSet<WebCore::SecurityOriginData> origins;
     HashSet<String> cookieHostNames;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    HashSet<String> pluginDataHostNames;
+#endif
     HashSet<String> HSTSCacheHostNames;
     HashSet<String> alternativeServicesHostNames;
 #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp webkitgtk-2.36.0/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp	2022-03-22 16:38:57.393580216 -0500
@@ -72,6 +72,10 @@
 #include <wtf/spi/darwin/OSVariantSPI.h>
 #endif
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+#include "PluginProcessManager.h"
+#endif
+
 #if HAVE(SEC_KEY_PROXY)
 #include "SecKeyProxyStore.h"
 #endif
@@ -380,6 +384,20 @@ void WebsiteDataStore::fetchDataAndApply
                 record.addCookieHostName(hostName);
             }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+            for (auto& hostName : websiteData.hostNamesWithPluginData) {
+                auto displayName = WebsiteDataRecord::displayNameForHostName(hostName);
+                if (!displayName)
+                    continue;
+
+                auto& record = m_websiteDataRecords.add(displayName, WebsiteDataRecord { }).iterator->value;
+                if (!record.displayName)
+                    record.displayName = WTFMove(displayName);
+
+                record.addPluginDataHostName(hostName);
+            }
+#endif
+
             for (auto& hostName : websiteData.hostNamesWithHSTSCache) {
                 auto displayName = WebsiteDataRecord::displayNameForHostName(hostName);
                 if (!displayName)
@@ -504,6 +522,57 @@ private:
             callbackAggregator->addWebsiteData(WTFMove(websiteData));
         });
     }
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    if (dataTypes.contains(WebsiteDataType::PlugInData) && isPersistent()) {
+        class State {
+        public:
+            static void fetchData(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins)
+            {
+                new State(WTFMove(callbackAggregator), WTFMove(plugins));
+            }
+
+        private:
+            State(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins)
+                : m_callbackAggregator(WTFMove(callbackAggregator))
+                , m_plugins(WTFMove(plugins))
+            {
+                fetchWebsiteDataForNextPlugin();
+            }
+
+            ~State()
+            {
+                ASSERT(m_plugins.isEmpty());
+            }
+
+            void fetchWebsiteDataForNextPlugin()
+            {
+                if (m_plugins.isEmpty()) {
+                    WebsiteData websiteData;
+                    websiteData.hostNamesWithPluginData = WTFMove(m_hostNames);
+
+                    m_callbackAggregator->addWebsiteData(WTFMove(websiteData));
+
+                    delete this;
+                    return;
+                }
+
+                auto plugin = m_plugins.takeLast();
+                PluginProcessManager::singleton().fetchWebsiteData(plugin, m_callbackAggregator->fetchOptions(), [this](Vector<String> hostNames) {
+                    for (auto& hostName : hostNames)
+                        m_hostNames.add(WTFMove(hostName));
+                    fetchWebsiteDataForNextPlugin();
+                });
+            }
+
+            Ref<CallbackAggregator> m_callbackAggregator;
+            Vector<PluginModuleInfo> m_plugins;
+            HashSet<String> m_hostNames;
+        };
+
+        State::fetchData(callbackAggregator.copyRef(), plugins());
+    }
+#endif
 }
 
 #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
@@ -652,6 +721,51 @@ void WebsiteDataStore::removeData(Option
         });
     }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    if (dataTypes.contains(WebsiteDataType::PlugInData) && isPersistent()) {
+        class State {
+        public:
+            static void deleteData(Ref<RemovalCallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins, WallTime modifiedSince)
+            {
+                new State(WTFMove(callbackAggregator), WTFMove(plugins), modifiedSince);
+            }
+
+        private:
+            State(Ref<RemovalCallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins, WallTime modifiedSince)
+                : m_callbackAggregator(WTFMove(callbackAggregator))
+                , m_plugins(WTFMove(plugins))
+                , m_modifiedSince(modifiedSince)
+            {
+                deleteWebsiteDataForNextPlugin();
+            }
+
+            ~State()
+            {
+                ASSERT(m_plugins.isEmpty());
+            }
+
+            void deleteWebsiteDataForNextPlugin()
+            {
+                if (m_plugins.isEmpty()) {
+                    delete this;
+                    return;
+                }
+
+                auto plugin = m_plugins.takeLast();
+                PluginProcessManager::singleton().deleteWebsiteData(plugin, m_modifiedSince, [this] {
+                    deleteWebsiteDataForNextPlugin();
+                });
+            }
+
+            Ref<RemovalCallbackAggregator> m_callbackAggregator;
+            Vector<PluginModuleInfo> m_plugins;
+            WallTime m_modifiedSince;
+        };
+
+        State::deleteData(callbackAggregator.copyRef(), plugins(), modifiedSince);
+    }
+#endif
+
 #if ENABLE(INTELLIGENT_TRACKING_PREVENTION)
     if (dataTypes.contains(WebsiteDataType::ResourceLoadStatistics)) {
         if (!didNotifyNetworkProcessToDeleteWebsiteData)
@@ -773,6 +887,59 @@ void WebsiteDataStore::removeData(Option
             removeMediaKeys(mediaKeysStorageDirectory, origins);
         });
     }
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    if (dataTypes.contains(WebsiteDataType::PlugInData) && isPersistent()) {
+        Vector<String> hostNames;
+        for (const auto& dataRecord : dataRecords) {
+            for (const auto& hostName : dataRecord.pluginDataHostNames)
+                hostNames.append(hostName);
+        }
+
+
+        class State {
+        public:
+            static void deleteData(Ref<RemovalCallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins, Vector<String>&& hostNames)
+            {
+                new State(WTFMove(callbackAggregator), WTFMove(plugins), WTFMove(hostNames));
+            }
+
+        private:
+            State(Ref<RemovalCallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins, Vector<String>&& hostNames)
+                : m_callbackAggregator(WTFMove(callbackAggregator))
+                , m_plugins(WTFMove(plugins))
+                , m_hostNames(WTFMove(hostNames))
+            {
+                deleteWebsiteDataForNextPlugin();
+            }
+
+            ~State()
+            {
+                ASSERT(m_plugins.isEmpty());
+            }
+
+            void deleteWebsiteDataForNextPlugin()
+            {
+                if (m_plugins.isEmpty()) {
+                    delete this;
+                    return;
+                }
+
+                auto plugin = m_plugins.takeLast();
+                PluginProcessManager::singleton().deleteWebsiteDataForHostNames(plugin, m_hostNames, [this] {
+                    deleteWebsiteDataForNextPlugin();
+                });
+            }
+
+            Ref<RemovalCallbackAggregator> m_callbackAggregator;
+            Vector<PluginModuleInfo> m_plugins;
+            Vector<String> m_hostNames;
+        };
+
+        if (!hostNames.isEmpty())
+            State::deleteData(callbackAggregator.copyRef(), plugins(), WTFMove(hostNames));
+    }
+#endif
 }
 
 void WebsiteDataStore::setServiceWorkerTimeoutForTesting(Seconds seconds)
@@ -1440,6 +1607,20 @@ HashSet<RefPtr<WebProcessPool>> WebsiteD
     return processPools;
 }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+Vector<PluginModuleInfo> WebsiteDataStore::plugins() const
+{
+    Vector<PluginModuleInfo> plugins;
+
+    for (auto& processPool : ensureProcessPools()) {
+        for (auto& plugin : processPool->pluginInfoStore().plugins())
+            plugins.append(plugin);
+    }
+
+    return plugins;
+}
+#endif
+
 static String computeMediaKeyFile(const String& mediaKeyDirectory)
 {
     return FileSystem::pathByAppendingComponent(mediaKeyDirectory, "SecureStop.plist");
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h webkitgtk-2.36.0/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
--- webkitgtk-2.36.0.orig/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h	2022-03-22 16:38:57.393580216 -0500
@@ -108,6 +108,10 @@ enum class StorageAccessStatus : uint8_t
 enum class StorageAccessPromptStatus;
 #endif
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+struct PluginModuleInfo;
+#endif
+
 class WebsiteDataStore : public API::ObjectImpl<API::Object::Type::WebsiteDataStore>, public Identified<WebsiteDataStore>, public CanMakeWeakPtr<WebsiteDataStore>  {
 public:
     static Ref<WebsiteDataStore> defaultDataStore();
@@ -403,6 +407,10 @@ private:
     // Will create a temporary process pool is none exists yet.
     HashSet<RefPtr<WebProcessPool>> ensureProcessPools() const;
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    Vector<PluginModuleInfo> plugins() const;
+#endif
+
     static Vector<WebCore::SecurityOriginData> mediaKeyOrigins(const String& mediaKeysStorageDirectory);
     static void removeMediaKeys(const String& mediaKeysStorageDirectory, WallTime modifiedSince);
     static void removeMediaKeys(const String& mediaKeysStorageDirectory, const HashSet<WebCore::SecurityOriginData>&);
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/webkitglib-symbols.map webkitgtk-2.36.0/Source/WebKit/webkitglib-symbols.map
--- webkitgtk-2.36.0.orig/Source/WebKit/webkitglib-symbols.map	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/webkitglib-symbols.map	2022-03-22 16:38:57.393580216 -0500
@@ -5,6 +5,7 @@ global:
   extern "C++" {
     "bmalloc::vmPageSize()::cached";
     "WebKit::NetworkProcessMain(int, char**)";
+    "WebKit::PluginProcessMain(int, char**)";
     "WebKit::WebKitExtensionManager::initialize(WebKit::InjectedBundle*, API::Object*)";
     "WebKit::WebKitExtensionManager::singleton()";
     "WebKit::WebProcessMain(int, char**)";
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/JSNPMethod.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/JSNPMethod.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/JSNPMethod.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/JSNPMethod.cpp	2022-03-22 16:38:57.393580216 -0500
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSNPMethod.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "JSNPObject.h"
+#include <JavaScriptCore/Error.h>
+#include <JavaScriptCore/FunctionPrototype.h>
+#include <JavaScriptCore/IsoSubspacePerVM.h>
+#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
+#include <JavaScriptCore/JSGlobalObjectInlines.h>
+#include <JavaScriptCore/JSObject.h>
+#include <WebCore/JSHTMLElement.h>
+#include <WebCore/JSPluginElementFunctions.h>
+
+namespace WebKit {
+using namespace JSC;
+using namespace WebCore;
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSNPMethod);
+
+const ClassInfo JSNPMethod::s_info = { "NPMethod", &InternalFunction::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSNPMethod) };
+
+static JSC_DECLARE_HOST_FUNCTION(callMethod);
+
+JSNPMethod::JSNPMethod(JSGlobalObject* globalObject, Structure* structure, NPIdentifier npIdentifier)
+    : InternalFunction(globalObject->vm(), structure, callMethod, nullptr)
+    , m_npIdentifier(npIdentifier)
+{
+}
+
+void JSNPMethod::finishCreation(VM& vm, const String& name)
+{
+    Base::finishCreation(vm, 0, name);
+    ASSERT(inherits(vm, info()));
+}
+
+GCClient::IsoSubspace* JSNPMethod::subspaceForImpl(VM& vm)
+{
+    static NeverDestroyed<IsoSubspacePerVM> perVM([] (Heap& heap) { return ISO_SUBSPACE_PARAMETERS(heap.cellHeapCellType, JSNPMethod); });
+    return &perVM.get().clientIsoSubspaceforVM(vm);
+}
+
+JSC_DEFINE_HOST_FUNCTION(callMethod, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSNPMethod* jsNPMethod = jsCast<JSNPMethod*>(callFrame->jsCallee());
+
+    JSValue thisValue = callFrame->thisValue();
+
+    // Check if we're calling a method on the plug-in script object.
+    if (thisValue.inherits<JSHTMLElement>(vm)) {
+        JSHTMLElement* element = jsCast<JSHTMLElement*>(asObject(thisValue));
+
+        // Try to get the script object from the element
+        if (JSObject* scriptObject = pluginScriptObject(globalObject, element))
+            thisValue = scriptObject;
+    }
+
+    if (thisValue.inherits<JSNPObject>(vm)) {
+        JSNPObject* jsNPObject = jsCast<JSNPObject*>(asObject(thisValue));
+
+        return JSValue::encode(jsNPObject->callMethod(globalObject, callFrame, jsNPMethod->npIdentifier()));
+    }
+
+    return throwVMTypeError(globalObject, scope);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/JSNPMethod.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/JSNPMethod.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/JSNPMethod.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/JSNPMethod.h	2022-03-22 16:38:57.393580216 -0500
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSNPMethod_h
+#define JSNPMethod_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <JavaScriptCore/FunctionPrototype.h>
+#include <JavaScriptCore/InternalFunction.h>
+#include <JavaScriptCore/JSGlobalObject.h>
+
+typedef void* NPIdentifier;
+
+namespace WebKit {
+
+// A JSObject that wraps an NPMethod.
+class JSNPMethod final : public JSC::InternalFunction {
+public:
+    using Base = JSC::InternalFunction;
+
+    template<typename CellType, JSC::SubspaceAccess>
+    static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+    {
+        return subspaceForImpl(vm);
+    }
+
+    static JSNPMethod* create(JSC::JSGlobalObject* globalObject, const String& name, NPIdentifier npIdent)
+    {
+        JSC::VM& vm = globalObject->vm();
+        JSC::Structure* structure = createStructure(globalObject->vm(), globalObject, globalObject->functionPrototype());
+        JSNPMethod* method = new (JSC::allocateCell<JSNPMethod>(vm)) JSNPMethod(globalObject, structure, npIdent);
+        method->finishCreation(vm, name);
+        return method;
+    }
+
+    DECLARE_INFO;
+
+    NPIdentifier npIdentifier() const { return m_npIdentifier; }
+
+private:
+    static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM&);
+    
+    JSNPMethod(JSC::JSGlobalObject*, JSC::Structure*, NPIdentifier);
+    void finishCreation(JSC::VM&, const String& name);
+
+    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+    {
+        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
+    }
+
+    NPIdentifier m_npIdentifier;
+};
+
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // JSNPMethod_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/JSNPObject.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/JSNPObject.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/JSNPObject.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/JSNPObject.cpp	2022-03-22 16:38:57.393580216 -0500
@@ -0,0 +1,549 @@
+/*
+ * Copyright (C) 2010-2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSNPObject.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "JSNPMethod.h"
+#include "NPJSObject.h"
+#include "NPRuntimeObjectMap.h"
+#include "NPRuntimeUtilities.h"
+#include <JavaScriptCore/AuxiliaryBarrierInlines.h>
+#include <JavaScriptCore/Error.h>
+#include <JavaScriptCore/IdentifierInlines.h>
+#include <JavaScriptCore/IsoSubspacePerVM.h>
+#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
+#include <JavaScriptCore/JSGlobalObject.h>
+#include <JavaScriptCore/JSLock.h>
+#include <JavaScriptCore/ObjectPrototype.h>
+#include <WebCore/CommonVM.h>
+#include <WebCore/DOMWindow.h>
+#include <WebCore/IdentifierRep.h>
+#include <WebCore/JSDOMWindowBase.h>
+#include <wtf/Assertions.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+using namespace JSC;
+using namespace WebCore;
+
+static JSC_DECLARE_CUSTOM_GETTER(propertyGetter);
+static JSC_DECLARE_CUSTOM_GETTER(methodGetter);
+
+static NPIdentifier npIdentifierFromIdentifier(PropertyName propertyName)
+{
+    String name(propertyName.publicName());
+    // If the propertyName is Symbol.
+    if (name.isNull())
+        return nullptr;
+    return static_cast<NPIdentifier>(IdentifierRep::get(name.utf8().data()));
+}
+
+static JSC::Exception* throwInvalidAccessError(JSGlobalObject* lexicalGlobalObject, ThrowScope& scope)
+{
+    return throwException(lexicalGlobalObject, scope, createReferenceError(lexicalGlobalObject, "Trying to access object from destroyed plug-in."));
+}
+
+const ClassInfo JSNPObject::s_info = { "NPObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSNPObject) };
+
+JSNPObject::JSNPObject(JSGlobalObject* globalObject, Structure* structure, NPRuntimeObjectMap* objectMap, NPObject* npObject)
+    : JSDestructibleObject(globalObject->vm(), structure)
+    , m_objectMap(objectMap)
+    , m_npObject(npObject)
+{
+    ASSERT(globalObject == structure->globalObject());
+}
+
+void JSNPObject::finishCreation(JSGlobalObject* globalObject)
+{
+    VM& vm = globalObject->vm();
+    Base::finishCreation(vm);
+    ASSERT(inherits(vm, info()));
+
+    // We should never have an NPJSObject inside a JSNPObject.
+    ASSERT(!NPJSObject::isNPJSObject(m_npObject));
+
+    retainNPObject(m_npObject);
+}
+
+JSNPObject::~JSNPObject()
+{
+    if (m_npObject)
+        invalidate();
+}
+
+void JSNPObject::destroy(JSCell* cell)
+{
+    static_cast<JSNPObject*>(cell)->JSNPObject::~JSNPObject();
+}
+
+void JSNPObject::invalidate()
+{
+    ASSERT(m_npObject);
+
+    releaseNPObject(m_npObject);
+    m_npObject = 0;
+}
+
+NPObject* JSNPObject::leakNPObject()
+{
+    ASSERT(m_npObject);
+
+    NPObject* object = m_npObject;
+    m_npObject = 0;
+    return object;
+}
+
+JSValue JSNPObject::callMethod(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame, NPIdentifier methodName)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    ASSERT_THIS_GC_OBJECT_INHERITS(info());
+    if (!m_npObject)
+        return throwInvalidAccessError(lexicalGlobalObject, scope);
+
+    // If the propertyName is symbol.
+    if (!methodName)
+        return jsUndefined();
+
+    size_t argumentCount = callFrame->argumentCount();
+    Vector<NPVariant, 8> arguments(argumentCount);
+
+    // Convert all arguments to NPVariants.
+    for (size_t i = 0; i < argumentCount; ++i)
+        m_objectMap->convertJSValueToNPVariant(lexicalGlobalObject, callFrame->uncheckedArgument(i), arguments[i]);
+
+    // Calling NPClass::invoke will call into plug-in code, and there's no telling what the plug-in can do.
+    // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until 
+    // the call has finished.
+    NPRuntimeObjectMap::PluginProtector protector(m_objectMap);
+
+    bool returnValue;
+    NPVariant result;
+    VOID_TO_NPVARIANT(result);
+    
+    {
+        JSLock::DropAllLocks dropAllLocks(commonVM());
+        returnValue = m_npObject->_class->invoke(m_npObject, methodName, arguments.data(), argumentCount, &result);
+        NPRuntimeObjectMap::moveGlobalExceptionToExecState(lexicalGlobalObject);
+    }
+
+    // Release all arguments.
+    for (size_t i = 0; i < argumentCount; ++i)
+        releaseNPVariantValue(&arguments[i]);
+
+    if (!returnValue)
+        throwException(lexicalGlobalObject, scope, createError(lexicalGlobalObject, "Error calling method on NPObject."));
+
+    JSValue propertyValue = m_objectMap->convertNPVariantToJSValue(globalObject(), result);
+    releaseNPVariantValue(&result);
+    return propertyValue;
+}
+
+JSC::JSValue JSNPObject::callObject(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    ASSERT_THIS_GC_OBJECT_INHERITS(info());
+    if (!m_npObject)
+        return throwInvalidAccessError(lexicalGlobalObject, scope);
+
+    size_t argumentCount = callFrame->argumentCount();
+    Vector<NPVariant, 8> arguments(argumentCount);
+    
+    // Convert all arguments to NPVariants.
+    for (size_t i = 0; i < argumentCount; ++i)
+        m_objectMap->convertJSValueToNPVariant(lexicalGlobalObject, callFrame->uncheckedArgument(i), arguments[i]);
+
+    // Calling NPClass::invokeDefault will call into plug-in code, and there's no telling what the plug-in can do.
+    // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until 
+    // the call has finished.
+    NPRuntimeObjectMap::PluginProtector protector(m_objectMap);
+    
+    bool returnValue;
+    NPVariant result;
+    VOID_TO_NPVARIANT(result);
+
+    {
+        JSLock::DropAllLocks dropAllLocks(commonVM());
+        returnValue = m_npObject->_class->invokeDefault(m_npObject, arguments.data(), argumentCount, &result);
+        NPRuntimeObjectMap::moveGlobalExceptionToExecState(lexicalGlobalObject);
+    }
+
+    // Release all arguments;
+    for (size_t i = 0; i < argumentCount; ++i)
+        releaseNPVariantValue(&arguments[i]);
+
+    if (!returnValue)
+        throwException(lexicalGlobalObject, scope, createError(lexicalGlobalObject, "Error calling method on NPObject."));
+
+    JSValue propertyValue = m_objectMap->convertNPVariantToJSValue(globalObject(), result);
+    releaseNPVariantValue(&result);
+    return propertyValue;
+}
+
+JSValue JSNPObject::callConstructor(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    ASSERT_THIS_GC_OBJECT_INHERITS(info());
+    if (!m_npObject)
+        return throwInvalidAccessError(lexicalGlobalObject, scope);
+
+    size_t argumentCount = callFrame->argumentCount();
+    Vector<NPVariant, 8> arguments(argumentCount);
+
+    // Convert all arguments to NPVariants.
+    for (size_t i = 0; i < argumentCount; ++i)
+        m_objectMap->convertJSValueToNPVariant(lexicalGlobalObject, callFrame->uncheckedArgument(i), arguments[i]);
+
+    // Calling NPClass::construct will call into plug-in code, and there's no telling what the plug-in can do.
+    // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until 
+    // the call has finished.
+    NPRuntimeObjectMap::PluginProtector protector(m_objectMap);
+    
+    bool returnValue;
+    NPVariant result;
+    VOID_TO_NPVARIANT(result);
+    
+    {
+        JSLock::DropAllLocks dropAllLocks(commonVM());
+        returnValue = m_npObject->_class->construct(m_npObject, arguments.data(), argumentCount, &result);
+        NPRuntimeObjectMap::moveGlobalExceptionToExecState(lexicalGlobalObject);
+    }
+
+    if (!returnValue)
+        throwException(lexicalGlobalObject, scope, createError(lexicalGlobalObject, "Error calling method on NPObject."));
+    
+    JSValue value = m_objectMap->convertNPVariantToJSValue(globalObject(), result);
+    releaseNPVariantValue(&result);
+    return value;
+}
+
+static JSC_DECLARE_HOST_FUNCTION(callNPJSObject);
+static JSC_DECLARE_HOST_FUNCTION(constructWithConstructor);
+
+JSC_DEFINE_HOST_FUNCTION(callNPJSObject, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+    JSObject* object = callFrame->jsCallee();
+    ASSERT_UNUSED(globalObject, object->inherits<JSNPObject>(globalObject->vm()));
+
+    return JSValue::encode(jsCast<JSNPObject*>(object)->callObject(globalObject, callFrame));
+}
+
+CallData JSNPObject::getCallData(JSCell* cell)
+{
+    CallData callData;
+    JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    if (thisObject->m_npObject && thisObject->m_npObject->_class->invokeDefault) {
+        callData.type = CallData::Type::Native;
+        callData.native.function = callNPJSObject;
+    }
+    return callData;
+}
+
+JSC_DEFINE_HOST_FUNCTION(constructWithConstructor, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+    JSObject* constructor = callFrame->jsCallee();
+    ASSERT_UNUSED(globalObject, constructor->inherits<JSNPObject>(globalObject->vm()));
+
+    return JSValue::encode(jsCast<JSNPObject*>(constructor)->callConstructor(globalObject, callFrame));
+}
+
+CallData JSNPObject::getConstructData(JSCell* cell)
+{
+    CallData constructData;
+
+    JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    if (thisObject->m_npObject && thisObject->m_npObject->_class->construct) {
+        constructData.type = CallData::Type::Native;
+        constructData.native.function = constructWithConstructor;
+    }
+
+    return constructData;
+}
+
+bool JSNPObject::getOwnPropertySlot(JSObject* object, JSGlobalObject* lexicalGlobalObject, PropertyName propertyName, PropertySlot& slot)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(object);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    if (!thisObject->m_npObject) {
+        throwInvalidAccessError(lexicalGlobalObject, scope);
+        return false;
+    }
+    
+    NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName);
+    // If the propertyName is symbol.
+    if (!npIdentifier)
+        return false;
+
+    // Calling NPClass::invoke will call into plug-in code, and there's no telling what the plug-in can do.
+    // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until 
+    // the call has finished.
+    NPRuntimeObjectMap::PluginProtector protector(thisObject->m_objectMap);
+
+    // First, check if the NPObject has a property with this name.
+    if (thisObject->m_npObject->_class->hasProperty && thisObject->m_npObject->_class->hasProperty(thisObject->m_npObject, npIdentifier)) {
+        slot.setCustom(thisObject, static_cast<unsigned>(JSC::PropertyAttribute::DontDelete), propertyGetter);
+        return true;
+    }
+
+    // Second, check if the NPObject has a method with this name.
+    if (thisObject->m_npObject->_class->hasMethod && thisObject->m_npObject->_class->hasMethod(thisObject->m_npObject, npIdentifier)) {
+        slot.setCustom(thisObject, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly, methodGetter);
+        return true;
+    }
+    
+    return false;
+}
+
+bool JSNPObject::put(JSCell* cell, JSGlobalObject* lexicalGlobalObject, PropertyName propertyName, JSValue value, PutPropertySlot&)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    if (!thisObject->m_npObject) {
+        throwInvalidAccessError(lexicalGlobalObject, scope);
+        return false;
+    }
+
+    NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName);
+    // If the propertyName is symbol.
+    if (!npIdentifier)
+        return false;
+    
+    if (!thisObject->m_npObject->_class->hasProperty || !thisObject->m_npObject->_class->hasProperty(thisObject->m_npObject, npIdentifier)) {
+        // FIXME: Should we throw an exception here?
+        return false;
+    }
+
+    if (!thisObject->m_npObject->_class->setProperty)
+        return false;
+
+    NPVariant variant;
+    thisObject->m_objectMap->convertJSValueToNPVariant(lexicalGlobalObject, value, variant);
+
+    // Calling NPClass::setProperty will call into plug-in code, and there's no telling what the plug-in can do.
+    // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until 
+    // the call has finished.
+    NPRuntimeObjectMap::PluginProtector protector(thisObject->m_objectMap);
+
+    bool result = false;
+    {
+        JSLock::DropAllLocks dropAllLocks(commonVM());
+        result = thisObject->m_npObject->_class->setProperty(thisObject->m_npObject, npIdentifier, &variant);
+
+        NPRuntimeObjectMap::moveGlobalExceptionToExecState(lexicalGlobalObject);
+
+        // FIXME: Should we throw an exception if setProperty returns false?
+    }
+
+    releaseNPVariantValue(&variant);
+    return result;
+}
+
+bool JSNPObject::deleteProperty(JSCell* cell, JSGlobalObject* lexicalGlobalObject, PropertyName propertyName, DeletePropertySlot& slot)
+{
+    return jsCast<JSNPObject*>(cell)->deleteProperty(lexicalGlobalObject, npIdentifierFromIdentifier(propertyName));
+}
+
+bool JSNPObject::deletePropertyByIndex(JSCell* cell, JSGlobalObject* lexicalGlobalObject, unsigned propertyName)
+{
+    return jsCast<JSNPObject*>(cell)->deleteProperty(lexicalGlobalObject, static_cast<NPIdentifier>(IdentifierRep::get(propertyName)));
+}
+
+bool JSNPObject::deleteProperty(JSGlobalObject* lexicalGlobalObject, NPIdentifier propertyName)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    ASSERT_THIS_GC_OBJECT_INHERITS(info());
+
+    // If the propertyName is symbol.
+    if (!propertyName)
+        return false;
+
+    if (!m_npObject) {
+        throwInvalidAccessError(lexicalGlobalObject, scope);
+        return false;
+    }
+
+    if (!m_npObject->_class->removeProperty) {
+        // FIXME: Should we throw an exception here?
+        return false;
+    }
+
+    // Calling NPClass::setProperty will call into plug-in code, and there's no telling what the plug-in can do.
+    // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until 
+    // the call has finished.
+    NPRuntimeObjectMap::PluginProtector protector(m_objectMap);
+
+    {
+        JSLock::DropAllLocks dropAllLocks(commonVM());
+
+        // FIXME: Should we throw an exception if removeProperty returns false?
+        if (!m_npObject->_class->removeProperty(m_npObject, propertyName))
+            return false;
+
+        NPRuntimeObjectMap::moveGlobalExceptionToExecState(lexicalGlobalObject);
+    }
+
+    return true;
+}
+
+void JSNPObject::getOwnPropertyNames(JSObject* object, JSGlobalObject* lexicalGlobalObject, PropertyNameArray& propertyNameArray, DontEnumPropertiesMode)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSNPObject* thisObject = jsCast<JSNPObject*>(object);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    if (!thisObject->m_npObject) {
+        throwInvalidAccessError(lexicalGlobalObject, scope);
+        return;
+    }
+
+    if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(thisObject->m_npObject->_class) || !thisObject->m_npObject->_class->enumerate)
+        return;
+
+    NPIdentifier* identifiers = 0;
+    uint32_t identifierCount = 0;
+    
+    // Calling NPClass::enumerate will call into plug-in code, and there's no telling what the plug-in can do.
+    // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until 
+    // the call has finished.
+    NPRuntimeObjectMap::PluginProtector protector(thisObject->m_objectMap);
+    
+    {
+        JSLock::DropAllLocks dropAllLocks(commonVM());
+
+        // FIXME: Should we throw an exception if enumerate returns false?
+        if (!thisObject->m_npObject->_class->enumerate(thisObject->m_npObject, &identifiers, &identifierCount))
+            return;
+
+        NPRuntimeObjectMap::moveGlobalExceptionToExecState(lexicalGlobalObject);
+    }
+
+    for (uint32_t i = 0; i < identifierCount; ++i) {
+        IdentifierRep* identifierRep = static_cast<IdentifierRep*>(identifiers[i]);
+        
+        Identifier identifier;
+        if (identifierRep->isString()) {
+            const char* string = identifierRep->string();
+            int length = strlen(string);
+            
+            identifier = Identifier::fromString(vm, String::fromUTF8WithLatin1Fallback(string, length));
+        } else
+            identifier = Identifier::from(vm, identifierRep->number());
+
+        propertyNameArray.add(identifier);
+    }
+
+    npnMemFree(identifiers);
+}
+
+JSC_DEFINE_CUSTOM_GETTER(propertyGetter, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName propertyName))
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSNPObject* thisObj = jsCast<JSNPObject*>(JSValue::decode(thisValue));
+    ASSERT_GC_OBJECT_INHERITS(thisObj, JSNPObject::info());
+    
+    if (!thisObj->npObject())
+        return JSValue::encode(throwInvalidAccessError(lexicalGlobalObject, scope));
+
+    if (!thisObj->npObject()->_class->getProperty)
+        return JSValue::encode(jsUndefined());
+
+    NPVariant result;
+    VOID_TO_NPVARIANT(result);
+
+    // Calling NPClass::getProperty will call into plug-in code, and there's no telling what the plug-in can do.
+    // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until 
+    // the call has finished.
+    NPRuntimeObjectMap::PluginProtector protector(thisObj->objectMap());
+    
+    bool returnValue;
+    {
+        JSLock::DropAllLocks dropAllLocks(commonVM());
+        NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName);
+        // If the propertyName is symbol.
+        if (!npIdentifier)
+            return JSValue::encode(jsUndefined());
+
+        returnValue = thisObj->npObject()->_class->getProperty(thisObj->npObject(), npIdentifier, &result);
+        
+        NPRuntimeObjectMap::moveGlobalExceptionToExecState(lexicalGlobalObject);
+    }
+
+    if (!returnValue)
+        return JSValue::encode(jsUndefined());
+
+    JSValue propertyValue = thisObj->objectMap()->convertNPVariantToJSValue(thisObj->globalObject(), result);
+    releaseNPVariantValue(&result);
+    return JSValue::encode(propertyValue);
+}
+
+JSC_DEFINE_CUSTOM_GETTER(methodGetter, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName propertyName))
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSNPObject* thisObj = jsCast<JSNPObject*>(JSValue::decode(thisValue));
+    ASSERT_GC_OBJECT_INHERITS(thisObj, JSNPObject::info());
+    
+    if (!thisObj->npObject())
+        return JSValue::encode(throwInvalidAccessError(lexicalGlobalObject, scope));
+
+    NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName);
+    // If the propertyName is symbol.
+    if (!npIdentifier)
+        return JSValue::encode(throwInvalidAccessError(lexicalGlobalObject, scope));
+
+    return JSValue::encode(JSNPMethod::create(thisObj->globalObject(), propertyName.publicName(), npIdentifier));
+}
+
+GCClient::IsoSubspace* JSNPObject::subspaceForImpl(VM& vm)
+{
+    static NeverDestroyed<IsoSubspacePerVM> perVM([] (Heap& heap) { return ISO_SUBSPACE_PARAMETERS(heap.destructibleObjectHeapCellType, JSNPObject); });
+    return &perVM.get().clientIsoSubspaceforVM(vm);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/JSNPObject.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/JSNPObject.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/JSNPObject.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/JSNPObject.h	2022-03-22 16:38:57.393580216 -0500
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010-2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSNPObject_h
+#define JSNPObject_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <JavaScriptCore/JSGlobalObject.h>
+#include <JavaScriptCore/JSObject.h>
+#include <JavaScriptCore/ObjectPrototype.h>
+
+typedef void* NPIdentifier;
+struct NPObject;
+
+namespace WebKit {
+
+class NPRuntimeObjectMap;
+    
+// JSNPObject is a JSObject that wraps an NPObject.
+
+class JSNPObject final : public JSC::JSDestructibleObject {
+public:
+    using Base = JSC::JSDestructibleObject;
+    static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetOwnPropertyNames | JSC::OverridesGetCallData | JSC::OverridesPut | JSC::GetOwnPropertySlotMayBeWrongAboutDontEnum;
+
+    template<typename CellType, JSC::SubspaceAccess>
+    static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+    {
+        return subspaceForImpl(vm);
+    }
+
+    static JSNPObject* create(JSC::JSGlobalObject* globalObject, NPRuntimeObjectMap* objectMap, NPObject* npObject)
+    {
+        JSC::Structure* structure = createStructure(globalObject->vm(), globalObject, globalObject->objectPrototype());
+        JSNPObject* object = new (JSC::allocateCell<JSNPObject>(globalObject->vm())) JSNPObject(globalObject, structure, objectMap, npObject);
+        object->finishCreation(globalObject);
+        return object;
+    }
+
+    ~JSNPObject();
+    static void destroy(JSCell*);
+
+    void invalidate();
+
+    // Used to invalidate an NPObject asynchronously.
+    NPObject* leakNPObject();
+
+    JSC::JSValue callMethod(JSC::JSGlobalObject*, JSC::CallFrame*, NPIdentifier methodName);
+    JSC::JSValue callObject(JSC::JSGlobalObject*, JSC::CallFrame*);
+    JSC::JSValue callConstructor(JSC::JSGlobalObject*, JSC::CallFrame*);
+
+    DECLARE_INFO;
+
+    NPObject* npObject() const { return m_npObject; }
+    NPRuntimeObjectMap* objectMap() const { return m_objectMap; }
+
+private:
+    static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM&);
+    
+    JSNPObject(JSC::JSGlobalObject*, JSC::Structure*, NPRuntimeObjectMap*, NPObject*);
+    void finishCreation(JSC::JSGlobalObject*);
+    
+    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+    {
+        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+    }
+
+    static JSC::CallData getCallData(JSC::JSCell*);
+    static JSC::CallData getConstructData(JSC::JSCell*);
+
+    static bool getOwnPropertySlot(JSC::JSObject*, JSC::JSGlobalObject*, JSC::PropertyName, JSC::PropertySlot&);
+    static bool put(JSC::JSCell*, JSC::JSGlobalObject*, JSC::PropertyName, JSC::JSValue, JSC::PutPropertySlot&);
+
+    static bool deleteProperty(JSC::JSCell*, JSC::JSGlobalObject*, JSC::PropertyName, JSC::DeletePropertySlot&);
+    static bool deletePropertyByIndex(JSC::JSCell*, JSC::JSGlobalObject*, unsigned propertyName);
+
+    bool deleteProperty(JSC::JSGlobalObject*, NPIdentifier propertyName);
+
+    static void getOwnPropertyNames(JSC::JSObject*, JSC::JSGlobalObject*, JSC::PropertyNameArray&, JSC::DontEnumPropertiesMode);
+
+    NPRuntimeObjectMap* m_objectMap;
+    NPObject* m_npObject;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // JSNPObject_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp	2022-03-22 16:38:57.393580216 -0500
@@ -0,0 +1,1049 @@
+/*
+ * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NetscapeBrowserFuncs.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NPRuntimeUtilities.h"
+#include "NetscapePlugin.h"
+#include "PluginController.h"
+#include <WebCore/HTTPHeaderMap.h>
+#include <WebCore/HTTPHeaderNames.h>
+#include <WebCore/IdentifierRep.h>
+#include <WebCore/NotImplemented.h>
+#include <WebCore/ProtectionSpace.h>
+#include <WebCore/SharedBuffer.h>
+#include <memory>
+#include <utility>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringToIntegerConversion.h>
+
+#if PLATFORM(COCOA)
+#include <wtf/MachSendRight.h>
+#endif
+
+#if PLATFORM(X11)
+#include <WebCore/PlatformDisplayX11.h>
+#endif
+
+namespace WebKit {
+using namespace WebCore;
+
+// Helper class for delaying destruction of a plug-in.
+class PluginDestructionProtector {
+public:
+    explicit PluginDestructionProtector(NetscapePlugin* plugin)
+    {
+        if (plugin)
+            m_protector = makeUnique<PluginController::PluginDestructionProtector>(static_cast<Plugin*>(plugin)->controller());
+    }
+    
+private:
+    std::unique_ptr<PluginController::PluginDestructionProtector> m_protector;
+};
+
+static bool startsWithBlankLine(const char* bytes, unsigned length)
+{
+    return length > 0 && bytes[0] == '\n';
+}
+
+static int locationAfterFirstBlankLine(const char* bytes, unsigned length)
+{
+    for (unsigned i = 0; i < length - 4; i++) {
+        // Support for Acrobat. It sends "\n\n".
+        if (bytes[i] == '\n' && bytes[i + 1] == '\n')
+            return i + 2;
+        
+        // Returns the position after 2 CRLF's or 1 CRLF if it is the first line.
+        if (bytes[i] == '\r' && bytes[i + 1] == '\n') {
+            i += 2;
+            if (i == 2)
+                return i;
+
+            if (bytes[i] == '\n') {
+                // Support for Director. It sends "\r\n\n" (3880387).
+                return i + 1;
+            }
+
+            if (bytes[i] == '\r' && bytes[i + 1] == '\n') {
+                // Support for Flash. It sends "\r\n\r\n" (3758113).
+                return i + 2;
+            }
+        }
+    }
+
+    return -1;
+}
+
+static const char* findEndOfLine(const char* bytes, unsigned length)
+{
+    // According to the HTTP specification EOL is defined as
+    // a CRLF pair. Unfortunately, some servers will use LF
+    // instead. Worse yet, some servers will use a combination
+    // of both (e.g. <header>CRLFLF<body>), so findEOL needs
+    // to be more forgiving. It will now accept CRLF, LF or
+    // CR.
+    //
+    // It returns 0 if EOLF is not found or it will return
+    // a pointer to the first terminating character.
+    for (unsigned i = 0; i < length; i++) {
+        if (bytes[i] == '\n')
+            return bytes + i;
+        if (bytes[i] == '\r') {
+            // Check to see if spanning buffer bounds
+            // (CRLF is across reads). If so, wait for
+            // next read.
+            if (i + 1 == length)
+                break;
+
+            return bytes + i;
+        }
+    }
+
+    return 0;
+}
+
+static String capitalizeRFC822HeaderFieldName(const String& name)
+{
+    bool capitalizeCharacter = true;
+    StringBuilder result;
+    for (unsigned i = 0; i < name.length(); i++) {
+        result.append(capitalizeCharacter ? toASCIIUpper(name[i]) : toASCIILower(name[i]));
+        if (name[i] == '-')
+            capitalizeCharacter = true;
+        else
+            capitalizeCharacter = false;
+    }
+    return result.toString();
+}
+
+static HTTPHeaderMap parseRFC822HeaderFields(const char* bytes, unsigned length)
+{
+    String lastHeaderKey;
+    HTTPHeaderMap headerFields;
+
+    // Loop over lines until we're past the header, or we can't find any more end-of-lines
+    while (const char* endOfLine = findEndOfLine(bytes, length)) {
+        const char* line = bytes;
+        int lineLength = endOfLine - bytes;
+
+        // Move bytes to the character after the terminator as returned by findEndOfLine.
+        bytes = endOfLine + 1;
+        if ((*endOfLine == '\r') && (*bytes == '\n'))
+            bytes++; // Safe since findEndOfLine won't return a spanning CRLF.
+
+        length -= (bytes - line);
+        if (!lineLength) {
+            // Blank line; we're at the end of the header
+            break;
+        }
+
+        if (*line == ' ' || *line == '\t') {
+            // Continuation of the previous header
+            if (lastHeaderKey.isNull()) {
+                // malformed header; ignore it and continue
+                continue;
+            } 
+            
+            // Merge the continuation of the previous header
+            String currentValue = headerFields.get(lastHeaderKey);
+            String newValue(line, lineLength);
+            
+            headerFields.set(lastHeaderKey, currentValue + newValue);
+        } else {
+            // Brand new header
+            const char* colon = line;
+            while (*colon != ':' && colon != endOfLine)
+                colon++;
+
+            if (colon == endOfLine) {
+                // malformed header; ignore it and continue
+                continue;
+            }
+
+            lastHeaderKey = capitalizeRFC822HeaderFieldName(String(line, colon - line));
+            String value;
+            
+            for (colon++; colon != endOfLine; colon++) {
+                if (*colon != ' ' && *colon != '\t')
+                    break;
+            }
+            if (colon == endOfLine)
+                value = emptyString();
+            else
+                value = String(colon, endOfLine - colon);
+            
+            String oldValue = headerFields.get(lastHeaderKey);
+            if (!oldValue.isNull())
+                value = oldValue + ", " + value;
+            
+            headerFields.set(lastHeaderKey, value);
+        }
+    }
+
+    return headerFields;
+}
+    
+static NPError parsePostBuffer(bool isFile, const char *buffer, uint32_t length, bool parseHeaders, HTTPHeaderMap& headerFields, Vector<uint8_t>& bodyData)
+{
+    RefPtr<SharedBuffer> fileContents;
+    const char* postBuffer = 0;
+    uint32_t postBufferSize = 0;
+
+    if (isFile) {
+        fileContents = SharedBuffer::createWithContentsOfFile(String::fromUTF8(buffer));
+        if (!fileContents)
+            return NPERR_FILE_NOT_FOUND;
+
+        postBuffer = fileContents->dataAsCharPtr();
+        postBufferSize = fileContents->size();
+
+        // FIXME: The NPAPI spec states that the file should be deleted here.
+    } else {
+        postBuffer = buffer;
+        postBufferSize = length;
+    }
+
+    if (parseHeaders) {
+        if (startsWithBlankLine(postBuffer, postBufferSize)) {
+            postBuffer++;
+            postBufferSize--;
+        } else {
+            int location = locationAfterFirstBlankLine(postBuffer, postBufferSize);
+            if (location != -1) {
+                // If the blank line is somewhere in the middle of the buffer, everything before is the header
+                headerFields = parseRFC822HeaderFields(postBuffer, location);
+                unsigned dataLength = postBufferSize - location;
+
+                // Sometimes plugins like to set Content-Length themselves when they post,
+                // but WebFoundation does not like that. So we will remove the header
+                // and instead truncate the data to the requested length.
+                String contentLength = headerFields.get(HTTPHeaderName::ContentLength);
+
+                if (!contentLength.isNull())
+                    dataLength = std::min(parseIntegerAllowingTrailingJunk<unsigned>(contentLength).value_or(0), dataLength);
+                headerFields.remove(HTTPHeaderName::ContentLength);
+
+                postBuffer += location;
+                postBufferSize = dataLength;
+            }
+        }
+    }
+
+    ASSERT(bodyData.isEmpty());
+    bodyData.append(postBuffer, postBufferSize);
+
+    return NPERR_NO_ERROR;
+}
+
+static String makeURLString(const char* url)
+{
+    String urlString(url);
+    
+    // Strip return characters.
+    urlString.replaceWithLiteral('\r', "");
+    urlString.replaceWithLiteral('\n', "");
+
+    return urlString;
+}
+
+static NPError NPN_GetURL(NPP npp, const char* url, const char* target)
+{
+    if (!url)
+        return NPERR_GENERIC_ERROR;
+    
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    plugin->loadURL("GET", makeURLString(url), target, HTTPHeaderMap(), Vector<uint8_t>(), false, 0);
+    
+    return NPERR_GENERIC_ERROR;
+}
+
+static NPError NPN_PostURL(NPP npp, const char* url, const char* target, uint32_t len, const char* buf, NPBool file)
+{
+    HTTPHeaderMap headerFields;
+    Vector<uint8_t> postData;
+    
+    // NPN_PostURL only allows headers if the post buffer points to a file.
+    bool parseHeaders = file;
+
+    NPError error = parsePostBuffer(file, buf, len, parseHeaders, headerFields, postData);
+    if (error != NPERR_NO_ERROR)
+        return error;
+
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    plugin->loadURL("POST", makeURLString(url), target, WTFMove(headerFields), postData, false, 0);
+    return NPERR_NO_ERROR;
+}
+
+static NPError NPN_RequestRead(NPStream*, NPByteRange*)
+{
+    notImplemented();
+    return NPERR_GENERIC_ERROR;
+}
+
+static NPError NPN_NewStream(NPP, NPMIMEType, const char*, NPStream**)
+{
+    notImplemented();
+    return NPERR_GENERIC_ERROR;
+}
+    
+static int32_t NPN_Write(NPP, NPStream*, int32_t, void*)
+{
+    notImplemented();    
+    return -1;
+}
+    
+static NPError NPN_DestroyStream(NPP npp, NPStream* stream, NPReason reason)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    
+    return plugin->destroyStream(stream, reason);
+}
+
+static void NPN_Status(NPP npp, const char* message)
+{
+    String statusbarText;
+    if (!message)
+        statusbarText = emptyString();
+    else
+        statusbarText = String::fromUTF8WithLatin1Fallback(message, strlen(message));
+
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    plugin->setStatusbarText(statusbarText);
+}
+    
+static const char* NPN_UserAgent(NPP npp)
+{
+    return NetscapePlugin::userAgent(npp);
+}
+
+static void* NPN_MemAlloc(uint32_t size)
+{
+    return npnMemAlloc(size);
+}
+
+static void NPN_MemFree(void* ptr)
+{
+    npnMemFree(ptr);
+}
+
+static uint32_t NPN_MemFlush(uint32_t)
+{
+    return 0;
+}
+
+static void NPN_ReloadPlugins(NPBool)
+{
+    notImplemented();
+}
+
+static JRIEnv* NPN_GetJavaEnv(void)
+{
+    notImplemented();
+    return 0;
+}
+
+static jref NPN_GetJavaPeer(NPP)
+{
+    notImplemented();
+    return 0;
+}
+
+static NPError NPN_GetURLNotify(NPP npp, const char* url, const char* target, void* notifyData)
+{
+    if (!url)
+        return NPERR_GENERIC_ERROR;
+
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    plugin->loadURL("GET", makeURLString(url), target, HTTPHeaderMap(), Vector<uint8_t>(), true, notifyData);
+    
+    return NPERR_NO_ERROR;
+}
+
+static NPError NPN_PostURLNotify(NPP npp, const char* url, const char* target, uint32_t len, const char* buf, NPBool file, void* notifyData)
+{
+    HTTPHeaderMap headerFields;
+    Vector<uint8_t> postData;
+    NPError error = parsePostBuffer(file, buf, len, true, headerFields, postData);
+    if (error != NPERR_NO_ERROR)
+        return error;
+
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    plugin->loadURL("POST", makeURLString(url), target, headerFields, postData, true, notifyData);
+    return NPERR_NO_ERROR;
+}
+
+#if PLATFORM(COCOA)
+// Whether the browser supports compositing of Core Animation plug-ins.
+static const unsigned WKNVSupportsCompositingCoreAnimationPluginsBool = 74656;
+
+// Whether the browser expects a non-retained Core Animation layer.
+static const unsigned WKNVExpectsNonretainedLayer = 74657;
+
+// 74658 and 74659 are no longer implemented.
+
+#endif
+
+static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value)
+{
+    switch (static_cast<unsigned>(variable)) {
+        case NPNVWindowNPObject: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+            PluginDestructionProtector protector(plugin.get());
+
+            NPObject* windowNPObject = plugin->windowScriptNPObject();
+            if (!windowNPObject)
+                return NPERR_GENERIC_ERROR;
+
+            *(NPObject**)value = windowNPObject;
+            break;
+        }
+        case NPNVPluginElementNPObject: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+            PluginDestructionProtector protector(plugin.get());
+
+            NPObject* pluginElementNPObject = plugin->pluginElementNPObject();
+            *(NPObject**)value = pluginElementNPObject;
+            break;
+        }
+        case NPNVprivateModeBool: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+
+            *(NPBool*)value = plugin->isPrivateBrowsingEnabled();
+            break;
+        }
+
+        case NPNVmuteAudioBool: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+            *(NPBool*)value = plugin->isMuted();
+            break;
+        }
+#if PLATFORM(COCOA)
+        case NPNVsupportsCoreGraphicsBool:
+            // Always claim to support the Core Graphics drawing model.
+            *(NPBool*)value = true;
+            break;
+
+        case WKNVSupportsCompositingCoreAnimationPluginsBool:
+        case NPNVsupportsCoreAnimationBool: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+            
+            *(NPBool*)value = plugin->isAcceleratedCompositingEnabled();
+            break;
+        }
+        case NPNVcontentsScaleFactor: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+
+            *(double*)value = plugin->contentsScaleFactor();
+            break;
+        }
+        case NPNVsupportsCocoaBool:
+            // Always claim to support the Cocoa event model.
+            *(NPBool*)value = true;
+            break;
+
+        case NPNVsupportsUpdatedCocoaTextInputBool: {
+            // The plug-in is asking whether we support the updated Cocoa text input model.
+            // If we haven't yet delivered a key down event to the plug-in, we can opt into the updated
+            // model and say that we support it. Otherwise, we'll just fall back and say that we don't support it.
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+
+            bool supportsUpdatedTextInput = !plugin->hasHandledAKeyDownEvent();
+            if (supportsUpdatedTextInput)
+                plugin->setPluginWantsLegacyCocoaTextInput(false);
+
+            *reinterpret_cast<NPBool*>(value) = supportsUpdatedTextInput;
+            break;
+        }
+
+        case WKNVCALayerRenderServerPort: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+
+            *(mach_port_t*)value = plugin->compositingRenderServerPort().sendRight();
+            break;
+        }
+
+        case WKNVExpectsNonretainedLayer: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+
+            // Asking for this will make us expect a non-retained layer from the plug-in.
+            plugin->setPluginReturnsNonretainedLayer(true);
+            *(NPBool*)value = true;
+            break;
+        }
+#elif PLATFORM(X11)
+        case NPNVxDisplay: {
+            if (!npp)
+                return NPERR_GENERIC_ERROR;
+            auto& display = PlatformDisplay::sharedDisplay();
+            if (display.type() != PlatformDisplay::Type::X11)
+                return NPERR_GENERIC_ERROR;
+            *reinterpret_cast<Display**>(value) = downcast<PlatformDisplayX11>(display).native();
+            break;
+        }
+        case NPNVSupportsXEmbedBool:
+            *static_cast<NPBool*>(value) = PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11;
+            break;
+        case NPNVSupportsWindowless:
+            *static_cast<NPBool*>(value) = true;
+            break;
+
+       case NPNVToolkit: {
+           // Gtk based plugins need to be assured about the toolkit version.
+           const uint32_t expectedGtkToolKitVersion = 2;
+           *reinterpret_cast<uint32_t*>(value) = expectedGtkToolKitVersion;
+           break;
+       }
+
+       // TODO: implement NPNVnetscapeWindow once we want to support windowed plugins.
+#endif
+        default:
+            notImplemented();
+            return NPERR_GENERIC_ERROR;
+    }
+
+    return NPERR_NO_ERROR;
+}
+
+static NPError NPN_SetValue(NPP npp, NPPVariable variable, void *value)
+{
+    switch (variable) {
+#if PLATFORM(COCOA)
+        case NPPVpluginDrawingModel: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+            
+            NPDrawingModel drawingModel = static_cast<NPDrawingModel>(reinterpret_cast<uintptr_t>(value));
+            return plugin->setDrawingModel(drawingModel);
+        }
+
+        case NPPVpluginEventModel: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+            
+            NPEventModel eventModel = static_cast<NPEventModel>(reinterpret_cast<uintptr_t>(value));
+            return plugin->setEventModel(eventModel);
+        }
+#endif
+
+        case NPPVpluginWindowBool: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+            plugin->setIsWindowed(value);
+            return NPERR_NO_ERROR;
+        }
+
+        case NPPVpluginTransparentBool: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+            plugin->setIsTransparent(value);
+            return NPERR_NO_ERROR;
+        }
+
+        case NPPVpluginIsPlayingAudio: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+            plugin->setIsPlayingAudio(value);
+            return NPERR_NO_ERROR;
+        }
+
+        default:
+            notImplemented();
+            return NPERR_GENERIC_ERROR;
+    }
+}
+
+static void NPN_InvalidateRect(NPP npp, NPRect* invalidRect)
+{
+#if PLUGIN_ARCHITECTURE(UNIX)
+    // NSPluginWrapper, a plugin wrapper binary that allows running 32-bit plugins
+    // on 64-bit architectures typically used in X11, will sometimes give us a null NPP here.
+    if (!npp)
+        return;
+#endif
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    plugin->invalidate(invalidRect);
+}
+
+static void NPN_InvalidateRegion(NPP npp, NPRegion)
+{
+    // FIXME: We could at least figure out the bounding rectangle of the invalid region.
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    plugin->invalidate(0);
+}
+
+static void NPN_ForceRedraw(NPP)
+{
+    notImplemented();
+}
+
+static NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name)
+{
+    return static_cast<NPIdentifier>(IdentifierRep::get(name));
+}
+    
+static void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers)
+{
+    ASSERT(names);
+    ASSERT(identifiers);
+
+    if (!names || !identifiers)
+        return;
+
+    for (int32_t i = 0; i < nameCount; ++i)
+        identifiers[i] = NPN_GetStringIdentifier(names[i]);
+}
+
+static NPIdentifier NPN_GetIntIdentifier(int32_t intid)
+{
+    return static_cast<NPIdentifier>(IdentifierRep::get(intid));
+}
+
+static bool NPN_IdentifierIsString(NPIdentifier identifier)
+{
+    return static_cast<IdentifierRep*>(identifier)->isString();
+}
+
+static NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier)
+{
+    const char* string = static_cast<IdentifierRep*>(identifier)->string();
+    if (!string)
+        return 0;
+
+    uint32_t stringLength = strlen(string);
+    char* utf8String = npnMemNewArray<char>(stringLength + 1);
+    memcpy(utf8String, string, stringLength);
+    utf8String[stringLength] = '\0';
+    
+    return utf8String;
+}
+
+static int32_t NPN_IntFromIdentifier(NPIdentifier identifier)
+{
+    return static_cast<IdentifierRep*>(identifier)->number();
+}
+
+static NPObject* NPN_CreateObject(NPP npp, NPClass *npClass)
+{
+    return createNPObject(npp, npClass);
+}
+
+static NPObject *NPN_RetainObject(NPObject *npObject)
+{
+    retainNPObject(npObject);
+    return npObject;
+}
+
+static void NPN_ReleaseObject(NPObject *npObject)
+{
+    releaseNPObject(npObject);
+}
+
+static bool NPN_Invoke(NPP npp, NPObject *npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    PluginDestructionProtector protector(plugin.get());
+
+    if (npObject->_class->invoke)
+        return npObject->_class->invoke(npObject, methodName, arguments, argumentCount, result);
+
+    return false;
+}
+
+static bool NPN_InvokeDefault(NPP npp, NPObject *npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    PluginDestructionProtector protector(plugin.get());
+
+    if (npObject->_class->invokeDefault)
+        return npObject->_class->invokeDefault(npObject, arguments, argumentCount, result);
+
+    return false;
+}
+
+static bool NPN_Evaluate(NPP npp, NPObject *npObject, NPString *script, NPVariant* result)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    PluginDestructionProtector protector(plugin.get());
+    
+    String scriptString = String::fromUTF8WithLatin1Fallback(script->UTF8Characters, script->UTF8Length);
+    
+    return plugin->evaluate(npObject, scriptString, result);
+}
+
+static bool NPN_GetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, NPVariant* result)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    PluginDestructionProtector protector(plugin.get());
+    
+    if (npObject->_class->getProperty)
+        return npObject->_class->getProperty(npObject, propertyName, result);
+    
+    return false;
+}
+
+static bool NPN_SetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, const NPVariant* value)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    PluginDestructionProtector protector(plugin.get());
+    
+    if (npObject->_class->setProperty)
+        return npObject->_class->setProperty(npObject, propertyName, value);
+
+    return false;
+}
+
+static bool NPN_RemoveProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    PluginDestructionProtector protector(plugin.get());
+    
+    if (npObject->_class->removeProperty)
+        return npObject->_class->removeProperty(npObject, propertyName);
+
+    return false;
+}
+
+static bool NPN_HasProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    PluginDestructionProtector protector(plugin.get());
+    
+    if (npObject->_class->hasProperty)
+        return npObject->_class->hasProperty(npObject, propertyName);
+
+    return false;
+}
+
+static bool NPN_HasMethod(NPP npp, NPObject* npObject, NPIdentifier methodName)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    PluginDestructionProtector protector(plugin.get());
+    
+    if (npObject->_class->hasMethod)
+        return npObject->_class->hasMethod(npObject, methodName);
+
+    return false;
+}
+
+static void NPN_ReleaseVariantValue(NPVariant* variant)
+{
+    releaseNPVariantValue(variant);
+}
+
+static void NPN_SetException(NPObject*, const NPUTF8* message)
+{
+    NetscapePlugin::setException(message);
+}
+
+static void NPN_PushPopupsEnabledState(NPP npp, NPBool enabled)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    plugin->pushPopupsEnabledState(enabled);
+}
+    
+static void NPN_PopPopupsEnabledState(NPP npp)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    plugin->popPopupsEnabledState();
+}
+    
+static bool NPN_Enumerate(NPP npp, NPObject* npObject, NPIdentifier** identifiers, uint32_t* identifierCount)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    PluginDestructionProtector protector(plugin.get());
+    
+    if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(npObject->_class) && npObject->_class->enumerate)
+        return npObject->_class->enumerate(npObject, identifiers, identifierCount);
+
+    return false;
+}
+
+static void NPN_PluginThreadAsyncCall(NPP npp, void (*function)(void*), void* userData)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+
+    plugin->pluginThreadAsyncCall(function, userData);
+}
+
+static bool NPN_Construct(NPP npp, NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    PluginDestructionProtector protector(plugin.get());
+    
+    if (NP_CLASS_STRUCT_VERSION_HAS_CTOR(npObject->_class) && npObject->_class->construct)
+        return npObject->_class->construct(npObject, arguments, argumentCount, result);
+
+    return false;
+}
+
+static NPError copyCString(const CString& string, char** value, uint32_t* len)
+{
+    ASSERT(!string.isNull());
+    ASSERT(value);
+    ASSERT(len);
+
+    *value = npnMemNewArray<char>(string.length());
+    if (!*value)
+        return NPERR_GENERIC_ERROR;
+
+    memcpy(*value, string.data(), string.length());
+    *len = string.length();
+    return NPERR_NO_ERROR;
+}
+
+static NPError NPN_GetValueForURL(NPP npp, NPNURLVariable variable, const char* url, char** value, uint32_t* len)
+{
+    if (!value || !len)
+        return NPERR_GENERIC_ERROR;
+    
+    switch (variable) {
+        case NPNURLVCookie: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+            PluginDestructionProtector protector(plugin.get());
+            
+            String cookies = plugin->cookiesForURL(makeURLString(url));
+            if (cookies.isNull())
+                return NPERR_GENERIC_ERROR;
+
+            return copyCString(cookies.utf8(), value, len);
+        }
+
+        case NPNURLVProxy: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+            PluginDestructionProtector protector(plugin.get());
+            
+            String proxies = plugin->proxiesForURL(makeURLString(url));
+            if (proxies.isNull())
+                return NPERR_GENERIC_ERROR;
+
+            return copyCString(proxies.utf8(), value, len);
+        }
+        default:
+            notImplemented();
+            return NPERR_GENERIC_ERROR;
+    }
+}
+
+static NPError NPN_SetValueForURL(NPP npp, NPNURLVariable variable, const char* url, const char* value, uint32_t len)
+{
+    switch (variable) {
+        case NPNURLVCookie: {
+            RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+            PluginDestructionProtector protector(plugin.get());
+            
+            plugin->setCookiesForURL(makeURLString(url), String(value, len));
+            return NPERR_NO_ERROR;
+        }
+
+        case NPNURLVProxy:
+            // Can't set the proxy for a URL.
+            return NPERR_GENERIC_ERROR;
+
+        default:
+            notImplemented();
+            return NPERR_GENERIC_ERROR;
+    }
+}
+
+static bool initializeProtectionSpace(const char* protocol, const char* host, int port, const char* scheme, const char* realm, ProtectionSpace& protectionSpace)
+{
+    ProtectionSpace::ServerType serverType;
+    if (equalLettersIgnoringASCIICase(protocol, "http"))
+        serverType = ProtectionSpace::ServerType::HTTP;
+    else if (equalLettersIgnoringASCIICase(protocol, "https"))
+        serverType = ProtectionSpace::ServerType::HTTPS;
+    else {
+        // We only care about http and https.
+        return false;
+    }
+
+    ProtectionSpace::AuthenticationScheme authenticationScheme = ProtectionSpace::AuthenticationScheme::Default;
+    if (serverType == ProtectionSpace::ServerType::HTTP) {
+        if (equalLettersIgnoringASCIICase(scheme, "basic"))
+            authenticationScheme = ProtectionSpace::AuthenticationScheme::HTTPBasic;
+        else if (equalLettersIgnoringASCIICase(scheme, "digest"))
+            authenticationScheme = ProtectionSpace::AuthenticationScheme::HTTPDigest;
+    }
+
+    protectionSpace = ProtectionSpace(host, port, serverType, realm, authenticationScheme);
+    return true;
+}
+
+static NPError NPN_GetAuthenticationInfo(NPP npp, const char* protocol, const char* host, int32_t port, const char* scheme, 
+                                         const char* realm, char** username, uint32_t* usernameLength, char** password, uint32_t* passwordLength)
+{
+    if (!protocol || !host || !scheme || !realm || !username || !usernameLength || !password || !passwordLength)
+        return NPERR_GENERIC_ERROR;
+
+    ProtectionSpace protectionSpace;
+    if (!initializeProtectionSpace(protocol, host, port, scheme, realm, protectionSpace))
+        return NPERR_GENERIC_ERROR;
+
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    String usernameString;
+    String passwordString;
+    if (!plugin->getAuthenticationInfo(protectionSpace, usernameString, passwordString))
+        return NPERR_GENERIC_ERROR;
+
+    NPError result = copyCString(usernameString.utf8(), username, usernameLength);
+    if (result != NPERR_NO_ERROR)
+        return result;
+
+    result = copyCString(passwordString.utf8(), password, passwordLength);
+    if (result != NPERR_NO_ERROR) {
+        npnMemFree(*username);
+        return result;
+    }
+
+    return NPERR_NO_ERROR;
+}
+
+static uint32_t NPN_ScheduleTimer(NPP npp, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID))
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+
+    return plugin->scheduleTimer(interval, repeat, timerFunc);
+}
+
+static void NPN_UnscheduleTimer(NPP npp, uint32_t timerID)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+
+    plugin->unscheduleTimer(timerID);
+}
+
+#if PLATFORM(COCOA)
+static NPError NPN_PopUpContextMenu(NPP npp, NPMenu* menu)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+
+    return plugin->popUpContextMenu(menu);
+}
+
+static NPBool NPN_ConvertPoint(NPP npp, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double* destX, double* destY, NPCoordinateSpace destSpace)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+
+    double destinationX;
+    double destinationY;
+
+    bool returnValue = plugin->convertPoint(sourceX, sourceY, sourceSpace, destinationX, destinationY, destSpace);
+
+    if (destX)
+        *destX = destinationX;
+    if (destY)
+        *destY = destinationY;
+
+    return returnValue;
+}
+#endif
+
+static void NPN_URLRedirectResponse(NPP npp, void* notifyData, NPBool allow)
+{
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+
+    plugin->urlRedirectResponse(notifyData, allow);
+}
+
+static void initializeBrowserFuncs(NPNetscapeFuncs &netscapeFuncs)
+{
+    netscapeFuncs.size = sizeof(NPNetscapeFuncs);
+    netscapeFuncs.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
+    
+    netscapeFuncs.geturl = NPN_GetURL;
+    netscapeFuncs.posturl = NPN_PostURL;
+    netscapeFuncs.requestread = NPN_RequestRead;
+    netscapeFuncs.newstream = NPN_NewStream;
+    netscapeFuncs.write = NPN_Write;
+    netscapeFuncs.destroystream = NPN_DestroyStream;
+    netscapeFuncs.status = NPN_Status;
+    netscapeFuncs.uagent = NPN_UserAgent;
+    netscapeFuncs.memalloc = NPN_MemAlloc;
+    netscapeFuncs.memfree = NPN_MemFree;
+    netscapeFuncs.memflush = NPN_MemFlush;
+    netscapeFuncs.reloadplugins = NPN_ReloadPlugins;
+    netscapeFuncs.getJavaEnv = NPN_GetJavaEnv;
+    netscapeFuncs.getJavaPeer = NPN_GetJavaPeer;
+    netscapeFuncs.geturlnotify = NPN_GetURLNotify;
+    netscapeFuncs.posturlnotify = NPN_PostURLNotify;
+    netscapeFuncs.getvalue = NPN_GetValue;
+    netscapeFuncs.setvalue = NPN_SetValue;
+    netscapeFuncs.invalidaterect = NPN_InvalidateRect;
+    netscapeFuncs.invalidateregion = NPN_InvalidateRegion;
+    netscapeFuncs.forceredraw = NPN_ForceRedraw;
+    
+    netscapeFuncs.getstringidentifier = NPN_GetStringIdentifier;
+    netscapeFuncs.getstringidentifiers = NPN_GetStringIdentifiers;
+    netscapeFuncs.getintidentifier = NPN_GetIntIdentifier;
+    netscapeFuncs.identifierisstring = NPN_IdentifierIsString;
+    netscapeFuncs.utf8fromidentifier = NPN_UTF8FromIdentifier;
+    netscapeFuncs.intfromidentifier = NPN_IntFromIdentifier;
+    netscapeFuncs.createobject = NPN_CreateObject;
+    netscapeFuncs.retainobject = NPN_RetainObject;
+    netscapeFuncs.releaseobject = NPN_ReleaseObject;
+    netscapeFuncs.invoke = NPN_Invoke;
+    netscapeFuncs.invokeDefault = NPN_InvokeDefault;
+    netscapeFuncs.evaluate = NPN_Evaluate;
+    netscapeFuncs.getproperty = NPN_GetProperty;
+    netscapeFuncs.setproperty = NPN_SetProperty;
+    netscapeFuncs.removeproperty = NPN_RemoveProperty;
+    netscapeFuncs.hasproperty = NPN_HasProperty;
+    netscapeFuncs.hasmethod = NPN_HasMethod;
+    netscapeFuncs.releasevariantvalue = NPN_ReleaseVariantValue;
+    netscapeFuncs.setexception = NPN_SetException;
+    netscapeFuncs.pushpopupsenabledstate = NPN_PushPopupsEnabledState;
+    netscapeFuncs.poppopupsenabledstate = NPN_PopPopupsEnabledState;
+    netscapeFuncs.enumerate = NPN_Enumerate;
+    netscapeFuncs.pluginthreadasynccall = NPN_PluginThreadAsyncCall;
+    netscapeFuncs.construct = NPN_Construct;
+    netscapeFuncs.getvalueforurl = NPN_GetValueForURL;
+    netscapeFuncs.setvalueforurl = NPN_SetValueForURL;
+    netscapeFuncs.getauthenticationinfo = NPN_GetAuthenticationInfo;
+    netscapeFuncs.scheduletimer = NPN_ScheduleTimer;
+    netscapeFuncs.unscheduletimer = NPN_UnscheduleTimer;
+#if PLATFORM(COCOA)
+    netscapeFuncs.popupcontextmenu = NPN_PopUpContextMenu;
+    netscapeFuncs.convertpoint = NPN_ConvertPoint;
+#else
+    netscapeFuncs.popupcontextmenu = 0;
+    netscapeFuncs.convertpoint = 0;
+#endif
+    netscapeFuncs.urlredirectresponse = NPN_URLRedirectResponse;
+}
+    
+NPNetscapeFuncs* netscapeBrowserFuncs()
+{
+    static NPNetscapeFuncs netscapeFuncs;
+    static bool initialized = false;
+    
+    if (!initialized) {
+        initializeBrowserFuncs(netscapeFuncs);
+        initialized = true;
+    }
+
+    return &netscapeFuncs;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h	2022-03-22 16:38:57.393580216 -0500
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NetscapeBrowserFuncs_h
+#define NetscapeBrowserFuncs_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <WebCore/npfunctions.h>
+
+namespace WebKit {
+
+#if PLUGIN_ARCHITECTURE(MAC)
+// The Core Animation render server port.
+static const unsigned WKNVCALayerRenderServerPort = 71879;
+#endif
+
+NPNetscapeFuncs* netscapeBrowserFuncs();
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // NetscapeBrowserFuncs_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePlugin.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePlugin.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePlugin.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePlugin.cpp	2022-03-22 16:38:57.393580216 -0500
@@ -0,0 +1,1149 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NetscapePlugin.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NPRuntimeObjectMap.h"
+#include "NPRuntimeUtilities.h"
+#include "NetscapePluginStream.h"
+#include "PluginController.h"
+#include "ShareableBitmap.h"
+#include <JavaScriptCore/JSObject.h>
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/HTTPHeaderMap.h>
+#include <WebCore/IntRect.h>
+#include <WebCore/SharedBuffer.h>
+#include <utility>
+#include <wtf/URL.h>
+#include <wtf/text/CString.h>
+
+#if PLUGIN_ARCHITECTURE(UNIX)
+#include "NetscapePluginUnix.h"
+#endif
+
+#if PLATFORM(COCOA)
+#include "LayerHostingContext.h"
+#include "LayerTreeContext.h"
+#endif
+
+namespace WebKit {
+using namespace WebCore;
+
+// The plug-in that we're currently calling NPP_New for.
+static NetscapePlugin* currentNPPNewPlugin;
+
+RefPtr<NetscapePlugin> NetscapePlugin::create(RefPtr<NetscapePluginModule>&& pluginModule)
+{
+    if (!pluginModule)
+        return nullptr;
+
+    return adoptRef(*new NetscapePlugin(pluginModule.releaseNonNull()));
+}
+    
+NetscapePlugin::NetscapePlugin(Ref<NetscapePluginModule>&& pluginModule)
+    : Plugin(NetscapePluginType)
+    , m_nextRequestID(0)
+    , m_pluginModule(WTFMove(pluginModule))
+    , m_npWindow()
+    , m_isStarted(false)
+#if PLATFORM(COCOA)
+    , m_isWindowed(false)
+#else
+    , m_isWindowed(true)
+#endif
+    , m_isTransparent(false)
+    , m_inNPPNew(false)
+    , m_shouldUseManualLoader(false)
+    , m_hasCalledSetWindow(false)
+    , m_isVisible(false)
+    , m_nextTimerID(0)
+#if PLATFORM(COCOA)
+    , m_drawingModel(static_cast<NPDrawingModel>(-1))
+    , m_eventModel(static_cast<NPEventModel>(-1))
+    , m_pluginReturnsNonretainedLayer(!m_pluginModule->pluginQuirks().contains(PluginQuirks::ReturnsRetainedCoreAnimationLayer))
+    , m_layerHostingMode(LayerHostingMode::InProcess)
+    , m_currentMouseEvent(0)
+    , m_pluginHasFocus(false)
+    , m_windowHasFocus(false)
+    , m_pluginWantsLegacyCocoaTextInput(true)
+    , m_isComplexTextInputEnabled(false)
+    , m_hasHandledAKeyDownEvent(false)
+    , m_ignoreNextKeyUpEventCounter(0)
+#endif
+{
+    m_npp.ndata = this;
+    m_npp.pdata = 0;
+    
+    m_pluginModule->incrementLoadCount();
+}
+
+NetscapePlugin::~NetscapePlugin()
+{
+    ASSERT(!m_isStarted);
+    ASSERT(m_timers.isEmpty());
+
+    m_pluginModule->decrementLoadCount();
+}
+
+RefPtr<NetscapePlugin> NetscapePlugin::fromNPP(NPP npp)
+{
+    if (!npp)
+        return nullptr;
+
+    return static_cast<NetscapePlugin*>(npp->ndata);
+}
+
+void NetscapePlugin::invalidate(const NPRect* invalidRect)
+{
+    IntRect rect;
+    
+    if (!invalidRect)
+        rect = IntRect(0, 0, m_pluginSize.width(), m_pluginSize.height());
+    else
+        rect = IntRect(invalidRect->left, invalidRect->top, invalidRect->right - invalidRect->left, invalidRect->bottom - invalidRect->top);
+    
+    if (platformInvalidate(rect))
+        return;
+
+    controller()->invalidate(rect);
+}
+
+const char* NetscapePlugin::userAgent(NPP npp)
+{
+    if (npp)
+        return fromNPP(npp)->userAgent();
+
+    if (currentNPPNewPlugin)
+        return currentNPPNewPlugin->userAgent();
+
+    return 0;
+}
+
+const char* NetscapePlugin::userAgent()
+{
+    if (m_userAgent.isNull()) {
+        String userAgent = controller()->userAgent();
+        ASSERT(!userAgent.isNull());
+
+#if PLUGIN_ARCHITECTURE(MAC)
+        if (quirks().contains(PluginQuirks::AppendVersion3UserAgent))
+            userAgent.append(" Version/3.2.1");
+#endif
+
+        m_userAgent = userAgent.utf8();
+    }
+    return m_userAgent.data();
+}
+
+void NetscapePlugin::loadURL(const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody,
+                             bool sendNotification, void* notificationData)
+{
+    uint64_t requestID = ++m_nextRequestID;
+    
+    controller()->loadURL(requestID, method, urlString, target, headerFields, httpBody, allowPopups());
+
+    if (target.isNull()) {
+        // The browser is going to send the data in a stream, create a plug-in stream.
+        auto pluginStream = NetscapePluginStream::create(*this, requestID, urlString, sendNotification, notificationData);
+        ASSERT(!m_streams.contains(requestID));
+
+        m_streams.set(requestID, WTFMove(pluginStream));
+        return;
+    }
+
+    if (sendNotification) {
+        // Eventually we are going to get a frameDidFinishLoading or frameDidFail call for this request.
+        // Keep track of the notification data so we can call NPP_URLNotify.
+        ASSERT(!m_pendingURLNotifications.contains(requestID));
+        m_pendingURLNotifications.set(requestID, std::make_pair(urlString, notificationData));
+    }
+}
+
+NPError NetscapePlugin::destroyStream(NPStream* stream, NPReason reason)
+{
+    NetscapePluginStream* pluginStream = 0;
+
+    for (StreamsMap::const_iterator it = m_streams.begin(), end = m_streams.end(); it != end; ++it) {
+        if (it->value->npStream() == stream) {
+            pluginStream = it->value.get();
+            break;
+        }
+    }
+
+    if (!pluginStream)
+        return NPERR_INVALID_INSTANCE_ERROR;
+
+    return pluginStream->destroy(reason);
+}
+
+void NetscapePlugin::setIsWindowed(bool isWindowed)
+{
+    // Once the plugin has started, it's too late to change whether the plugin is windowed or not.
+    // (This is true in Firefox and Chrome, too.) Disallow setting m_isWindowed in that case to
+    // keep our internal state consistent.
+    if (m_isStarted)
+        return;
+
+    m_isWindowed = isWindowed;
+}
+
+void NetscapePlugin::setIsTransparent(bool isTransparent)
+{
+    m_isTransparent = isTransparent;
+}
+
+void NetscapePlugin::setStatusbarText(const String& statusbarText)
+{
+    controller()->setStatusbarText(statusbarText);
+}
+
+static void (*setExceptionFunction)(const String&);
+
+void NetscapePlugin::setSetExceptionFunction(void (*function)(const String&))
+{
+    ASSERT(!setExceptionFunction || setExceptionFunction == function);
+    setExceptionFunction = function;
+}
+
+void NetscapePlugin::setException(const String& exceptionString)
+{
+    ASSERT(setExceptionFunction);
+    setExceptionFunction(exceptionString);
+}
+
+bool NetscapePlugin::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result)
+{
+    return controller()->evaluate(npObject, scriptString, result, allowPopups());
+}
+
+bool NetscapePlugin::isPrivateBrowsingEnabled()
+{
+    return controller()->isPrivateBrowsingEnabled();
+}
+
+bool NetscapePlugin::isMuted() const
+{
+    return controller()->isMuted();
+}
+
+NPObject* NetscapePlugin::windowScriptNPObject()
+{
+    return controller()->windowScriptNPObject();
+}
+
+NPObject* NetscapePlugin::pluginElementNPObject()
+{
+    return controller()->pluginElementNPObject();
+}
+
+void NetscapePlugin::cancelStreamLoad(NetscapePluginStream* pluginStream)
+{
+    if (pluginStream == m_manualStream) {
+        controller()->cancelManualStreamLoad();
+        return;
+    }
+
+    // Ask the plug-in controller to cancel this stream load.
+    controller()->cancelStreamLoad(pluginStream->streamID());
+}
+
+void NetscapePlugin::removePluginStream(NetscapePluginStream* pluginStream)
+{
+    if (pluginStream == m_manualStream) {
+        m_manualStream = nullptr;
+        return;
+    }
+
+    ASSERT(m_streams.get(pluginStream->streamID()) == pluginStream);
+    m_streams.remove(pluginStream->streamID());
+}
+
+bool NetscapePlugin::isAcceleratedCompositingEnabled()
+{
+    return controller()->isAcceleratedCompositingEnabled();
+}
+
+void NetscapePlugin::pushPopupsEnabledState(bool state)
+{
+    m_popupEnabledStates.append(state);
+}
+ 
+void NetscapePlugin::popPopupsEnabledState()
+{
+    ASSERT(!m_popupEnabledStates.isEmpty());
+
+    m_popupEnabledStates.removeLast();
+}
+
+void NetscapePlugin::pluginThreadAsyncCall(void (*function)(void*), void* userData)
+{
+    RunLoop::main().dispatch([protectedThis = Ref { *this }, function, userData] {
+        if (!protectedThis->m_isStarted)
+            return;
+
+        function(userData);
+    });
+}
+
+NetscapePlugin::Timer::Timer(NetscapePlugin* netscapePlugin, unsigned timerID, unsigned interval, bool repeat, TimerFunc timerFunc)
+    : m_netscapePlugin(netscapePlugin)
+    , m_timerID(timerID)
+    , m_interval(interval)
+    , m_repeat(repeat)
+    , m_timerFunc(timerFunc)
+    , m_timer(RunLoop::main(), this, &Timer::timerFired)
+{
+}
+
+NetscapePlugin::Timer::~Timer()
+{
+}
+
+void NetscapePlugin::Timer::start()
+{
+    Seconds timeInterval = 1_ms * m_interval;
+
+    if (m_repeat)
+        m_timer.startRepeating(timeInterval);
+    else
+        m_timer.startOneShot(timeInterval);
+}
+
+void NetscapePlugin::Timer::stop()
+{
+    m_timer.stop();
+}
+
+void NetscapePlugin::Timer::timerFired()
+{
+    m_timerFunc(&m_netscapePlugin->m_npp, m_timerID);
+
+    if (!m_repeat)
+        m_netscapePlugin->unscheduleTimer(m_timerID);
+}
+
+uint32_t NetscapePlugin::scheduleTimer(unsigned interval, bool repeat, void (*timerFunc)(NPP, unsigned timerID))
+{
+    if (!timerFunc)
+        return 0;
+
+    // FIXME: Handle wrapping around.
+    unsigned timerID = ++m_nextTimerID;
+
+    auto timer = makeUnique<Timer>(this, timerID, interval, repeat, timerFunc);
+    
+    // FIXME: Based on the plug-in visibility, figure out if we should throttle the timer, or if we should start it at all.
+    timer->start();
+    m_timers.set(timerID, WTFMove(timer));
+
+    return timerID;
+}
+
+void NetscapePlugin::unscheduleTimer(unsigned timerID)
+{
+    if (auto timer = m_timers.take(timerID))
+        timer->stop();
+}
+
+double NetscapePlugin::contentsScaleFactor()
+{
+    return controller()->contentsScaleFactor();
+}
+
+String NetscapePlugin::proxiesForURL(const String& urlString)
+{
+    return controller()->proxiesForURL(urlString);
+}
+    
+String NetscapePlugin::cookiesForURL(const String& urlString)
+{
+    return controller()->cookiesForURL(urlString);
+}
+
+void NetscapePlugin::setCookiesForURL(const String& urlString, const String& cookieString)
+{
+    controller()->setCookiesForURL(urlString, cookieString);
+}
+
+bool NetscapePlugin::getAuthenticationInfo(const ProtectionSpace& protectionSpace, String& username, String& password)
+{
+    return controller()->getAuthenticationInfo(protectionSpace, username, password);
+}
+
+void NetscapePlugin::registerRedirect(NetscapePluginStream* stream, const URL& requestURL, int redirectResponseStatus, void* notificationData)
+{
+    // NPP_URLRedirectNotify may synchronously request this stream back out, so set it first
+    m_redirects.set(notificationData, std::make_pair(stream, requestURL.string()));
+    if (!NPP_URLRedirectNotify(requestURL.string().utf8().data(), redirectResponseStatus, notificationData)) {
+        m_redirects.take(notificationData);
+        controller()->continueStreamLoad(stream->streamID());
+    }
+}
+
+void NetscapePlugin::urlRedirectResponse(void* notifyData, bool allow)
+{
+    if (!m_redirects.contains(notifyData))
+        return;
+
+    auto redirect = m_redirects.take(notifyData);
+    if (!redirect.first)
+        return;
+
+    RefPtr<NetscapePluginStream> stream = redirect.first;
+    if (!allow) {
+        controller()->cancelStreamLoad(stream->streamID());
+        stream->stop(NPRES_USER_BREAK);
+    } else {
+        stream->setURL(redirect.second);
+        controller()->continueStreamLoad(stream->streamID());
+    }
+}
+
+void NetscapePlugin::setIsPlayingAudio(bool isPlayingAudio)
+{
+    controller()->setPluginIsPlayingAudio(isPlayingAudio);
+}
+
+NPError NetscapePlugin::NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* savedData)
+{
+    return m_pluginModule->pluginFuncs().newp(pluginType, &m_npp, mode, argc, argn, argv, savedData);
+}
+    
+NPError NetscapePlugin::NPP_Destroy(NPSavedData** savedData)
+{
+    return m_pluginModule->pluginFuncs().destroy(&m_npp, savedData);
+}
+
+NPError NetscapePlugin::NPP_SetWindow(NPWindow* npWindow)
+{
+    return m_pluginModule->pluginFuncs().setwindow(&m_npp, npWindow);
+}
+
+NPError NetscapePlugin::NPP_NewStream(NPMIMEType mimeType, NPStream* stream, NPBool seekable, uint16_t* streamType)
+{
+    return m_pluginModule->pluginFuncs().newstream(&m_npp, mimeType, stream, seekable, streamType);
+}
+
+NPError NetscapePlugin::NPP_DestroyStream(NPStream* stream, NPReason reason)
+{
+    return m_pluginModule->pluginFuncs().destroystream(&m_npp, stream, reason);
+}
+
+void NetscapePlugin::NPP_StreamAsFile(NPStream* stream, const char* filename)
+{
+    return m_pluginModule->pluginFuncs().asfile(&m_npp, stream, filename);
+}
+
+int32_t NetscapePlugin::NPP_WriteReady(NPStream* stream)
+{
+    return m_pluginModule->pluginFuncs().writeready(&m_npp, stream);
+}
+
+int32_t NetscapePlugin::NPP_Write(NPStream* stream, int32_t offset, int32_t len, void* buffer)
+{
+    return m_pluginModule->pluginFuncs().write(&m_npp, stream, offset, len, buffer);
+}
+
+int16_t NetscapePlugin::NPP_HandleEvent(void* event)
+{
+    return m_pluginModule->pluginFuncs().event(&m_npp, event);
+}
+
+void NetscapePlugin::NPP_URLNotify(const char* url, NPReason reason, void* notifyData)
+{
+    m_pluginModule->pluginFuncs().urlnotify(&m_npp, url, reason, notifyData);
+}
+
+bool NetscapePlugin::NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData)
+{
+    if (!m_pluginModule->pluginFuncs().urlredirectnotify)
+        return false;
+
+    m_pluginModule->pluginFuncs().urlredirectnotify(&m_npp, url, status, notifyData);
+    return true;
+}
+
+NPError NetscapePlugin::NPP_GetValue(NPPVariable variable, void *value)
+{
+    if (!m_pluginModule->pluginFuncs().getvalue)
+        return NPERR_GENERIC_ERROR;
+
+    return m_pluginModule->pluginFuncs().getvalue(&m_npp, variable, value);
+}
+
+NPError NetscapePlugin::NPP_SetValue(NPNVariable variable, void *value)
+{
+    if (!m_pluginModule->pluginFuncs().setvalue)
+        return NPERR_GENERIC_ERROR;
+
+    return m_pluginModule->pluginFuncs().setvalue(&m_npp, variable, value);
+}
+
+void NetscapePlugin::callSetWindow()
+{
+    if (wantsPluginRelativeNPWindowCoordinates()) {
+        m_npWindow.x = 0;
+        m_npWindow.y = 0;
+        m_npWindow.clipRect.top = m_clipRect.y();
+        m_npWindow.clipRect.left = m_clipRect.x();
+    } else {
+        IntPoint pluginLocationInRootViewCoordinates = convertToRootView(IntPoint());
+        IntPoint clipRectInRootViewCoordinates = convertToRootView(m_clipRect.location());
+
+        m_npWindow.x = pluginLocationInRootViewCoordinates.x();
+        m_npWindow.y = pluginLocationInRootViewCoordinates.y();
+        m_npWindow.clipRect.top = clipRectInRootViewCoordinates.y();
+        m_npWindow.clipRect.left = clipRectInRootViewCoordinates.x();
+    }
+
+    m_npWindow.width = m_pluginSize.width();
+    m_npWindow.height = m_pluginSize.height();
+    m_npWindow.clipRect.right = m_npWindow.clipRect.left + m_clipRect.width();
+    m_npWindow.clipRect.bottom = m_npWindow.clipRect.top + m_clipRect.height();
+
+    NPP_SetWindow(&m_npWindow);
+    m_hasCalledSetWindow = true;
+}
+
+void NetscapePlugin::callSetWindowInvisible()
+{
+    NPWindow invisibleWindow = m_npWindow;
+    
+    invisibleWindow.window = 0;
+    invisibleWindow.clipRect.top = 0;
+    invisibleWindow.clipRect.left = 0;
+    invisibleWindow.clipRect.bottom = 0;
+    invisibleWindow.clipRect.right = 0;
+    
+    NPP_SetWindow(&invisibleWindow);
+    m_hasCalledSetWindow = true;
+}
+
+bool NetscapePlugin::shouldLoadSrcURL()
+{
+#if PLATFORM(X11)
+    // Flash crashes when NPP_GetValue is called for NPPVpluginCancelSrcStream in windowed mode.
+    if (m_isWindowed && m_pluginModule->pluginQuirks().contains(PluginQuirks::DoNotCancelSrcStreamInWindowedMode))
+        return true;
+#endif
+
+    // Check if we should cancel the load
+    NPBool cancelSrcStream = false;
+
+    if (NPP_GetValue(NPPVpluginCancelSrcStream, &cancelSrcStream) != NPERR_NO_ERROR)
+        return true;
+
+    return !cancelSrcStream;
+}
+
+NetscapePluginStream* NetscapePlugin::streamFromID(uint64_t streamID)
+{
+    return m_streams.get(streamID);
+}
+
+void NetscapePlugin::stopAllStreams()
+{
+    for (auto& stream : copyToVector(m_streams.values()))
+        stream->stop(NPRES_USER_BREAK);
+}
+
+bool NetscapePlugin::allowPopups() const
+{
+    if (m_pluginModule->pluginFuncs().version >= NPVERS_HAS_POPUPS_ENABLED_STATE) {
+        if (!m_popupEnabledStates.isEmpty())
+            return m_popupEnabledStates.last();
+    }
+
+    // FIXME: Check if the current event is a user gesture.
+    // Really old versions of Flash required this for popups to work, but all newer versions
+    // support NPN_PushPopupEnabledState/NPN_PopPopupEnabledState.
+    return false;
+}
+
+#if PLUGIN_ARCHITECTURE(MAC)
+static bool isTransparentSilverlightBackgroundValue(const String& lowercaseBackgroundValue)
+{
+    // This checks if the background color value is transparent, according to
+    // the format documented at http://msdn.microsoft.com/en-us/library/cc838148(VS.95).aspx
+    if (lowercaseBackgroundValue.startsWith('#')) {
+        if (lowercaseBackgroundValue.length() == 5 && lowercaseBackgroundValue[1] != 'f') {
+            // An 8-bit RGB value with alpha transparency, in the form #ARGB.
+            return true;
+        }
+
+        if (lowercaseBackgroundValue.length() == 9 && !(lowercaseBackgroundValue[1] == 'f' && lowercaseBackgroundValue[2] == 'f')) {
+            // A 16-bit RGB value with alpha transparency, in the form #AARRGGBB.
+            return true;
+        }
+    } else if (lowercaseBackgroundValue.startsWith("sc#")) {
+        Vector<String> components = lowercaseBackgroundValue.substring(3).split(',');
+
+        // An ScRGB value with alpha transparency, in the form sc#A,R,G,B.
+        if (components.size() == 4) {
+            if (components[0].toDouble() < 1)
+                return true;
+        }
+    } else if (lowercaseBackgroundValue == "transparent")
+        return true;
+
+    // This is an opaque color.
+    return false;
+}
+#endif
+
+bool NetscapePlugin::initialize(const Parameters& parameters)
+{
+    uint16_t mode = parameters.isFullFramePlugin ? NP_FULL : NP_EMBED;
+    
+    m_shouldUseManualLoader = parameters.shouldUseManualLoader;
+
+    CString mimeTypeCString = parameters.mimeType.utf8();
+
+    ASSERT(parameters.names.size() == parameters.values.size());
+
+    Vector<CString> paramNames;
+    Vector<CString> paramValues;
+    for (size_t i = 0; i < parameters.names.size(); ++i) {
+        String parameterName = parameters.names[i];
+
+#if PLUGIN_ARCHITECTURE(MAC)
+        if (m_pluginModule->pluginQuirks().contains(PluginQuirks::WantsLowercaseParameterNames))
+            parameterName = parameterName.convertToASCIILowercase();
+#endif
+
+        paramNames.append(parameterName.utf8());
+        paramValues.append(parameters.values[i].utf8());
+    }
+
+#if PLATFORM(X11)
+    if (equalLettersIgnoringASCIICase(parameters.mimeType, "application/x-shockwave-flash")) {
+        size_t wmodeIndex = parameters.names.find("wmode");
+        if (wmodeIndex != notFound) {
+            // Transparent window mode is not supported by X11 backend.
+            if (equalLettersIgnoringASCIICase(parameters.values[wmodeIndex], "transparent")
+                || (m_pluginModule->pluginQuirks().contains(PluginQuirks::ForceFlashWindowlessMode) && equalLettersIgnoringASCIICase(parameters.values[wmodeIndex], "window")))
+                paramValues[wmodeIndex] = "opaque";
+        } else if (m_pluginModule->pluginQuirks().contains(PluginQuirks::ForceFlashWindowlessMode)) {
+            paramNames.append("wmode");
+            paramValues.append("opaque");
+        }
+    }
+#endif
+
+    if (equalLettersIgnoringASCIICase(parameters.mimeType, "application/x-webkit-test-netscape")) {
+        paramNames.append("windowedPlugin");
+        paramValues.append("false");
+    }
+
+    // The strings that these pointers point to are kept alive by paramNames and paramValues.
+    Vector<const char*> names;
+    Vector<const char*> values;
+    for (size_t i = 0; i < paramNames.size(); ++i) {
+        names.append(paramNames[i].data());
+        values.append(paramValues[i].data());
+    }
+
+#if PLUGIN_ARCHITECTURE(MAC)
+    if (m_pluginModule->pluginQuirks().contains(PluginQuirks::MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists)) {
+        for (size_t i = 0; i < parameters.names.size(); ++i) {
+            if (equalLettersIgnoringASCIICase(parameters.names[i], "background")) {
+                setIsTransparent(isTransparentSilverlightBackgroundValue(parameters.values[i].convertToASCIILowercase()));
+                break;
+            }
+        }
+    }
+
+    m_layerHostingMode = parameters.layerHostingMode;
+#endif
+
+    platformPreInitialize();
+
+    NetscapePlugin* previousNPPNewPlugin = currentNPPNewPlugin;
+    
+    m_inNPPNew = true;
+    currentNPPNewPlugin = this;
+
+    NPError error = NPP_New(const_cast<char*>(mimeTypeCString.data()), mode, names.size(),
+                            const_cast<char**>(names.data()), const_cast<char**>(values.data()), 0);
+
+    m_inNPPNew = false;
+    currentNPPNewPlugin = previousNPPNewPlugin;
+
+    if (error != NPERR_NO_ERROR)
+        return false;
+
+    m_isStarted = true;
+
+    // FIXME: This is not correct in all cases.
+    m_npWindow.type = NPWindowTypeDrawable;
+
+    if (!platformPostInitialize()) {
+        destroy();
+        return false;
+    }
+
+    // Load the src URL if needed.
+    if (!parameters.shouldUseManualLoader && !parameters.url.isEmpty() && shouldLoadSrcURL())
+        loadURL("GET", parameters.url.string(), String(), HTTPHeaderMap(), Vector<uint8_t>(), false, 0);
+    
+    return true;
+}
+    
+void NetscapePlugin::destroy()
+{
+    ASSERT(m_isStarted);
+
+    // Stop all streams.
+    stopAllStreams();
+
+#if !PLUGIN_ARCHITECTURE(MAC) && !PLUGIN_ARCHITECTURE(UNIX)
+    m_npWindow.window = 0;
+    callSetWindow();
+#endif
+
+    NPP_Destroy(0);
+
+    m_isStarted = false;
+
+    platformDestroy();
+
+    m_timers.clear();
+}
+    
+void NetscapePlugin::paint(GraphicsContext& context, const IntRect& dirtyRect)
+{
+    ASSERT(m_isStarted);
+    
+    platformPaint(context, dirtyRect);
+}
+
+RefPtr<ShareableBitmap> NetscapePlugin::snapshot()
+{
+    if (!supportsSnapshotting() || m_pluginSize.isEmpty())
+        return nullptr;
+
+    ASSERT(m_isStarted);
+
+    IntSize backingStoreSize = m_pluginSize;
+    backingStoreSize.scale(contentsScaleFactor());
+
+    auto bitmap = ShareableBitmap::createShareable(backingStoreSize, { });
+    auto context = bitmap->createGraphicsContext();
+    if (!context)
+        return nullptr;
+
+    // FIXME: We should really call applyDeviceScaleFactor instead of scale, but that ends up calling into WKSI
+    // which we currently don't have initiated in the plug-in process.
+    context->scale(contentsScaleFactor());
+
+    platformPaint(*context, IntRect(IntPoint(), m_pluginSize), true);
+
+    return bitmap;
+}
+
+bool NetscapePlugin::isTransparent()
+{
+    return m_isTransparent;
+}
+
+bool NetscapePlugin::wantsWheelEvents()
+{
+    return m_pluginModule->pluginQuirks().contains(PluginQuirks::WantsWheelEvents);
+}
+
+void NetscapePlugin::geometryDidChange(const IntSize& pluginSize, const IntRect& clipRect, const AffineTransform& pluginToRootViewTransform)
+{
+    ASSERT(m_isStarted);
+
+    if (pluginSize == m_pluginSize && m_clipRect == clipRect && m_pluginToRootViewTransform == pluginToRootViewTransform) {
+        // Nothing to do.
+        return;
+    }
+
+    bool shouldCallSetWindow = true;
+
+    // If the plug-in doesn't want window relative coordinates, we don't need to call setWindow unless its size or clip rect changes.
+    if (m_hasCalledSetWindow && wantsPluginRelativeNPWindowCoordinates() && m_pluginSize == pluginSize && m_clipRect == clipRect)
+        shouldCallSetWindow = false;
+
+    m_pluginSize = pluginSize;
+    m_clipRect = clipRect;
+    m_pluginToRootViewTransform = pluginToRootViewTransform;
+
+#if PLUGIN_ARCHITECTURE(UNIX)
+    IntPoint frameRectLocationInWindowCoordinates = m_pluginToRootViewTransform.mapPoint(IntPoint());
+    m_frameRectInWindowCoordinates = IntRect(frameRectLocationInWindowCoordinates, m_pluginSize);
+#endif
+
+    platformGeometryDidChange();
+
+    if (!shouldCallSetWindow)
+        return;
+
+    callSetWindow();
+}
+
+void NetscapePlugin::visibilityDidChange(bool isVisible)
+{
+    ASSERT(m_isStarted);
+
+    if (m_isVisible == isVisible)
+        return;
+
+    m_isVisible = isVisible;
+    platformVisibilityDidChange();
+}
+
+void NetscapePlugin::frameDidFinishLoading(uint64_t requestID)
+{
+    ASSERT(m_isStarted);
+    
+    auto notification = m_pendingURLNotifications.take(requestID);
+    if (notification.first.isEmpty())
+        return;
+
+    NPP_URLNotify(notification.first.utf8().data(), NPRES_DONE, notification.second);
+}
+
+void NetscapePlugin::frameDidFail(uint64_t requestID, bool wasCancelled)
+{
+    ASSERT(m_isStarted);
+    
+    auto notification = m_pendingURLNotifications.take(requestID);
+    if (notification.first.isNull())
+        return;
+    
+    NPP_URLNotify(notification.first.utf8().data(), wasCancelled ? NPRES_USER_BREAK : NPRES_NETWORK_ERR, notification.second);
+}
+
+void NetscapePlugin::didEvaluateJavaScript(uint64_t requestID, const String& result)
+{
+    ASSERT(m_isStarted);
+    
+    if (NetscapePluginStream* pluginStream = streamFromID(requestID))
+        pluginStream->sendJavaScriptStream(result);
+}
+
+void NetscapePlugin::streamWillSendRequest(uint64_t streamID, const URL& requestURL, const URL& redirectResponseURL, int redirectResponseStatus)
+{
+    ASSERT(m_isStarted);
+
+    if (NetscapePluginStream* pluginStream = streamFromID(streamID))
+        pluginStream->willSendRequest(requestURL, redirectResponseURL, redirectResponseStatus);
+}
+
+void NetscapePlugin::streamDidReceiveResponse(uint64_t streamID, const URL& responseURL, uint32_t streamLength, 
+                                              uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& /* suggestedFileName */)
+{
+    ASSERT(m_isStarted);
+    
+    if (NetscapePluginStream* pluginStream = streamFromID(streamID))
+        pluginStream->didReceiveResponse(responseURL, streamLength, lastModifiedTime, mimeType, headers);
+}
+
+void NetscapePlugin::streamDidReceiveData(uint64_t streamID, const WebCore::SharedBuffer& buffer)
+{
+    ASSERT(m_isStarted);
+    
+    if (NetscapePluginStream* pluginStream = streamFromID(streamID))
+        pluginStream->didReceiveData(buffer.data(), buffer.size());
+}
+
+void NetscapePlugin::streamDidFinishLoading(uint64_t streamID)
+{
+    ASSERT(m_isStarted);
+    
+    if (NetscapePluginStream* pluginStream = streamFromID(streamID))
+        pluginStream->didFinishLoading();
+}
+
+void NetscapePlugin::streamDidFail(uint64_t streamID, bool wasCancelled)
+{
+    ASSERT(m_isStarted);
+    
+    if (NetscapePluginStream* pluginStream = streamFromID(streamID))
+        pluginStream->didFail(wasCancelled);
+}
+
+void NetscapePlugin::manualStreamDidReceiveResponse(const URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, 
+                                                    const String& mimeType, const String& headers, const String& /* suggestedFileName */)
+{
+    ASSERT(m_isStarted);
+    ASSERT(m_shouldUseManualLoader);
+    ASSERT(!m_manualStream);
+    
+    m_manualStream = NetscapePluginStream::create(*this, 0, responseURL.string(), false, 0);
+    m_manualStream->didReceiveResponse(responseURL, streamLength, lastModifiedTime, mimeType, headers);
+}
+
+void NetscapePlugin::manualStreamDidReceiveData(const WebCore::SharedBuffer& buffer)
+{
+    ASSERT(m_isStarted);
+    ASSERT(m_shouldUseManualLoader);
+    ASSERT(m_manualStream);
+
+    m_manualStream->didReceiveData(buffer.data(), buffer.size());
+}
+
+void NetscapePlugin::manualStreamDidFinishLoading()
+{
+    ASSERT(m_isStarted);
+    ASSERT(m_shouldUseManualLoader);
+    ASSERT(m_manualStream);
+
+    m_manualStream->didFinishLoading();
+}
+
+void NetscapePlugin::manualStreamDidFail(bool wasCancelled)
+{
+    ASSERT(m_isStarted);
+    ASSERT(m_shouldUseManualLoader);
+
+    if (!m_manualStream)
+        return;
+    m_manualStream->didFail(wasCancelled);
+}
+
+bool NetscapePlugin::handleMouseEvent(const WebMouseEvent& mouseEvent)
+{
+    ASSERT(m_isStarted);
+    
+    return platformHandleMouseEvent(mouseEvent);
+}
+    
+bool NetscapePlugin::handleWheelEvent(const WebWheelEvent& wheelEvent)
+{
+    ASSERT(m_isStarted);
+
+    return platformHandleWheelEvent(wheelEvent);
+}
+
+bool NetscapePlugin::handleMouseEnterEvent(const WebMouseEvent& mouseEvent)
+{
+    ASSERT(m_isStarted);
+
+    return platformHandleMouseEnterEvent(mouseEvent);
+}
+
+bool NetscapePlugin::handleMouseLeaveEvent(const WebMouseEvent& mouseEvent)
+{
+    ASSERT(m_isStarted);
+
+    return platformHandleMouseLeaveEvent(mouseEvent);
+}
+
+bool NetscapePlugin::handleContextMenuEvent(const WebMouseEvent&)
+{
+    // We don't know if the plug-in has handled mousedown event by displaying a context menu, so we never want WebKit to show a default one.
+    return true;
+}
+
+bool NetscapePlugin::handleKeyboardEvent(const WebKeyboardEvent& keyboardEvent)
+{
+    ASSERT(m_isStarted);
+
+    return platformHandleKeyboardEvent(keyboardEvent);
+}
+
+bool NetscapePlugin::handleEditingCommand(const String& /* commandName */, const String& /* argument */)
+{
+    return false;
+}
+
+bool NetscapePlugin::isEditingCommandEnabled(const String& /* commandName */)
+{
+    return false;
+}
+
+bool NetscapePlugin::shouldAllowScripting()
+{
+    return true;
+}
+
+bool NetscapePlugin::shouldAllowNavigationFromDrags()
+{
+    return false;
+}
+
+bool NetscapePlugin::handlesPageScaleFactor() const
+{
+    return false;
+}
+
+void NetscapePlugin::setFocus(bool hasFocus)
+{
+    ASSERT(m_isStarted);
+
+    platformSetFocus(hasFocus);
+}
+
+NPObject* NetscapePlugin::pluginScriptableNPObject()
+{
+    ASSERT(m_isStarted);
+    NPObject* scriptableNPObject = 0;
+    
+    if (NPP_GetValue(NPPVpluginScriptableNPObject, &scriptableNPObject) != NPERR_NO_ERROR)
+        return 0;
+
+#if PLUGIN_ARCHITECTURE(MAC)
+    if (m_pluginModule->pluginQuirks().contains(PluginQuirks::ReturnsNonRetainedScriptableNPObject))
+        retainNPObject(scriptableNPObject);        
+#endif    
+
+    return scriptableNPObject;
+}
+    
+unsigned NetscapePlugin::countFindMatches(const String&, WebCore::FindOptions, unsigned)
+{
+    return 0;
+}
+
+bool NetscapePlugin::findString(const String&, WebCore::FindOptions, unsigned)
+{
+    return false;
+}
+
+void NetscapePlugin::contentsScaleFactorChanged(float scaleFactor)
+{
+    ASSERT(m_isStarted);
+
+#if PLUGIN_ARCHITECTURE(MAC)
+    double contentsScaleFactor = scaleFactor;
+    NPP_SetValue(NPNVcontentsScaleFactor, &contentsScaleFactor);
+#else
+    UNUSED_PARAM(scaleFactor);
+#endif
+}
+
+void NetscapePlugin::storageBlockingStateChanged(bool storageBlockingEnabled)
+{
+    if (m_storageBlockingState != storageBlockingEnabled) {
+        m_storageBlockingState = storageBlockingEnabled;
+        updateNPNPrivateMode();
+    }
+}
+
+void NetscapePlugin::privateBrowsingStateChanged(bool privateBrowsingEnabled)
+{
+    if (m_privateBrowsingState != privateBrowsingEnabled) {
+        m_privateBrowsingState = privateBrowsingEnabled;
+        updateNPNPrivateMode();
+    }
+}
+
+void NetscapePlugin::updateNPNPrivateMode()
+{
+    ASSERT(m_isStarted);
+
+    // From https://wiki.mozilla.org/Plugins:PrivateMode
+    //   When the browser turns private mode on or off it will call NPP_SetValue for "NPNVprivateModeBool" 
+    //   (assigned enum value 18) with a pointer to an NPBool value on all applicable instances.
+    //   Plugins should check the boolean value pointed to, not the pointer itself. 
+    //   The value will be true when private mode is on.
+    NPBool value = m_privateBrowsingState || m_storageBlockingState;
+    NPP_SetValue(NPNVprivateModeBool, &value);
+}
+
+bool NetscapePlugin::getFormValue(String& formValue)
+{
+    ASSERT(m_isStarted);
+
+    char* formValueString = 0;
+    if (NPP_GetValue(NPPVformValue, &formValueString) != NPERR_NO_ERROR)
+        return false;
+
+    formValue = String::fromUTF8(formValueString);
+
+    // The plug-in allocates the form value string with NPN_MemAlloc so it needs to be freed with NPN_MemFree.
+    npnMemFree(formValueString);
+    return true;
+}
+
+bool NetscapePlugin::handleScroll(ScrollDirection, ScrollGranularity)
+{
+    return false;
+}
+
+Scrollbar* NetscapePlugin::horizontalScrollbar()
+{
+    return 0;
+}
+
+Scrollbar* NetscapePlugin::verticalScrollbar()
+{
+    return 0;
+}
+
+bool NetscapePlugin::supportsSnapshotting() const
+{
+#if PLATFORM(COCOA)
+    return m_pluginModule->pluginQuirks().contains(PluginQuirks::SupportsSnapshotting);
+#endif
+    return false;
+}
+
+RefPtr<WebCore::FragmentedSharedBuffer> NetscapePlugin::liveResourceData() const
+{
+    return nullptr;
+}
+
+IntPoint NetscapePlugin::convertToRootView(const IntPoint& pointInPluginCoordinates) const
+{
+    return m_pluginToRootViewTransform.mapPoint(pointInPluginCoordinates);
+}
+
+bool NetscapePlugin::convertFromRootView(const IntPoint& pointInRootViewCoordinates, IntPoint& pointInPluginCoordinates)
+{
+    if (auto inverse = m_pluginToRootViewTransform.inverse()) {
+        pointInPluginCoordinates = inverse.value().mapPoint(pointInRootViewCoordinates);
+        return true;
+    }
+    return false;
+}
+
+void NetscapePlugin::mutedStateChanged(bool muted)
+{
+    NPBool value = muted;
+    NPP_SetValue(NPNVmuteAudioBool, &value);
+}
+
+#if !PLATFORM(COCOA)
+    
+void NetscapePlugin::windowFocusChanged(bool)
+{
+}
+
+void NetscapePlugin::windowVisibilityChanged(bool)
+{
+}
+
+#endif
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePlugin.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePlugin.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePlugin.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePlugin.h	2022-03-22 16:38:57.393580216 -0500
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NetscapePluginModule.h"
+#include "Plugin.h"
+#include <WebCore/AffineTransform.h>
+#include <WebCore/GraphicsLayer.h>
+#include <WebCore/IntRect.h>
+#include <wtf/HashMap.h>
+#include <wtf/RunLoop.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringHash.h>
+
+namespace WTF {
+class MachSendRight;
+}
+
+namespace WebCore {
+class Element;
+class HTTPHeaderMap;
+class ProtectionSpace;
+class SharedBuffer;
+}
+
+namespace WebKit {
+
+class NetscapePluginStream;
+class NetscapePluginUnix;
+
+class NetscapePlugin : public Plugin {
+public:
+    static RefPtr<NetscapePlugin> create(RefPtr<NetscapePluginModule>&&);
+    virtual ~NetscapePlugin();
+
+    static RefPtr<NetscapePlugin> fromNPP(NPP);
+
+#if PLATFORM(COCOA)
+    NPError setDrawingModel(NPDrawingModel);
+    NPError setEventModel(NPEventModel);
+    NPBool convertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double& destX, double& destY, NPCoordinateSpace destSpace);
+    NPError popUpContextMenu(NPMenu*);
+
+    void setPluginReturnsNonretainedLayer(bool pluginReturnsNonretainedLayer) { m_pluginReturnsNonretainedLayer = pluginReturnsNonretainedLayer; }
+    void setPluginWantsLegacyCocoaTextInput(bool pluginWantsLegacyCocoaTextInput) { m_pluginWantsLegacyCocoaTextInput = pluginWantsLegacyCocoaTextInput; }
+
+    bool hasHandledAKeyDownEvent() const { return m_hasHandledAKeyDownEvent; }
+
+    const WTF::MachSendRight& compositingRenderServerPort();
+
+    // Computes an affine transform from the given coordinate space to the screen coordinate space.
+    bool getScreenTransform(NPCoordinateSpace sourceSpace, WebCore::AffineTransform&);
+#endif
+
+#if PLUGIN_ARCHITECTURE(UNIX)
+    const WebCore::IntRect& frameRectInWindowCoordinates() const { return m_frameRectInWindowCoordinates; }
+#endif
+    const WebCore::IntRect& clipRect() const { return m_clipRect; }
+    const WebCore::IntSize& size() const { return m_pluginSize; }
+
+    PluginQuirks quirks() const { return m_pluginModule->pluginQuirks(); }
+
+    void invalidate(const NPRect*);
+    static const char* userAgent(NPP);
+    void loadURL(const String& method, const String& urlString, const String& target, const WebCore::HTTPHeaderMap& headerFields,
+                 const Vector<uint8_t>& httpBody, bool sendNotification, void* notificationData);
+    NPError destroyStream(NPStream*, NPReason);
+    void setIsWindowed(bool);
+    void setIsTransparent(bool);
+    void setStatusbarText(const String&);
+    static void setException(const String&);
+    bool evaluate(NPObject*, const String&scriptString, NPVariant* result);
+    bool isPrivateBrowsingEnabled();
+    bool isMuted() const;
+    bool isWindowed() const { return m_isWindowed; }
+    bool isVisible() const { return m_isVisible; }
+
+    static void setSetExceptionFunction(void (*)(const String&));
+
+    // These return retained objects.
+    NPObject* windowScriptNPObject();
+    NPObject* pluginElementNPObject();
+
+    void cancelStreamLoad(NetscapePluginStream*);
+    void removePluginStream(NetscapePluginStream*);
+
+    bool isAcceleratedCompositingEnabled();
+
+    void pushPopupsEnabledState(bool enabled);
+    void popPopupsEnabledState();
+
+    void pluginThreadAsyncCall(void (*function)(void*), void* userData);
+
+    unsigned scheduleTimer(unsigned interval, bool repeat, void (*timerFunc)(NPP, unsigned timerID));
+    void unscheduleTimer(unsigned timerID);
+
+    double contentsScaleFactor();
+    String proxiesForURL(const String& urlString);
+    String cookiesForURL(const String& urlString);
+    void setCookiesForURL(const String& urlString, const String& cookieString);
+    bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password);
+
+    void setIsPlayingAudio(bool);
+
+    void registerRedirect(NetscapePluginStream*, const URL& requestURL, int redirectResponseStatus, void* notificationData);
+    void urlRedirectResponse(void* notifyData, bool allow);
+
+    // Member functions for calling into the plug-in.
+    NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData*);
+    NPError NPP_Destroy(NPSavedData**);
+    NPError NPP_SetWindow(NPWindow*);
+    NPError NPP_NewStream(NPMIMEType, NPStream*, NPBool seekable, uint16_t* stype);
+    NPError NPP_DestroyStream(NPStream*, NPReason);
+    void NPP_StreamAsFile(NPStream*, const char* filename);
+    int32_t NPP_WriteReady(NPStream*);
+    int32_t NPP_Write(NPStream*, int32_t offset, int32_t len, void* buffer);
+    int16_t NPP_HandleEvent(void* event);
+    void NPP_URLNotify(const char* url, NPReason, void* notifyData);
+    bool NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData);
+    NPError NPP_GetValue(NPPVariable, void *value);
+    NPError NPP_SetValue(NPNVariable, void *value);
+
+    // Convert the given point from plug-in coordinates to root view coordinates.
+    WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const override;
+
+private:
+    explicit NetscapePlugin(Ref<NetscapePluginModule>&&);
+
+    void callSetWindow();
+    void callSetWindowInvisible();
+    bool shouldLoadSrcURL();
+    NetscapePluginStream* streamFromID(uint64_t streamID);
+    void stopAllStreams();
+    bool allowPopups() const;
+
+    const char* userAgent();
+
+    void platformPreInitialize();
+    bool platformPostInitialize();
+    void platformDestroy();
+    bool platformInvalidate(const WebCore::IntRect&);
+    void platformGeometryDidChange();
+    void platformVisibilityDidChange();
+    void platformPaint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect, bool isSnapshot = false);
+
+    bool platformHandleMouseEvent(const WebMouseEvent&);
+    bool platformHandleWheelEvent(const WebWheelEvent&);
+    bool platformHandleMouseEnterEvent(const WebMouseEvent&);
+    bool platformHandleMouseLeaveEvent(const WebMouseEvent&);
+    bool platformHandleKeyboardEvent(const WebKeyboardEvent&);
+    void platformSetFocus(bool);
+
+    static bool wantsPluginRelativeNPWindowCoordinates();
+
+    // Plugin
+    bool initialize(const Parameters&) override;
+    void destroy() override;
+    void paint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override;
+    RefPtr<ShareableBitmap> snapshot() override;
+#if PLATFORM(COCOA)
+    PlatformLayer* pluginLayer() override;
+#endif
+    bool isTransparent() override;
+    bool wantsWheelEvents() override;
+    void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) override;
+    void visibilityDidChange(bool isVisible) override;
+    void frameDidFinishLoading(uint64_t requestID) override;
+    void frameDidFail(uint64_t requestID, bool wasCancelled) override;
+    void didEvaluateJavaScript(uint64_t requestID, const String& result) override;
+    void streamWillSendRequest(uint64_t streamID, const URL& requestURL, const URL& responseURL, int responseStatus) override;
+    void streamDidReceiveResponse(uint64_t streamID, const URL& responseURL, uint32_t streamLength,
+                                          uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) override;
+    void streamDidReceiveData(uint64_t streamID, const WebCore::SharedBuffer& buffer) override;
+    void streamDidFinishLoading(uint64_t streamID) override;
+    void streamDidFail(uint64_t streamID, bool wasCancelled) override;
+    void manualStreamDidReceiveResponse(const URL& responseURL, uint32_t streamLength, 
+                                                uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) override;
+    void manualStreamDidReceiveData(const WebCore::SharedBuffer& buffer) override;
+    void manualStreamDidFinishLoading() override;
+    void manualStreamDidFail(bool wasCancelled) override;
+    
+    bool handleMouseEvent(const WebMouseEvent&) override;
+    bool handleWheelEvent(const WebWheelEvent&) override;
+    bool handleMouseEnterEvent(const WebMouseEvent&) override;
+    bool handleMouseLeaveEvent(const WebMouseEvent&) override;
+    bool handleContextMenuEvent(const WebMouseEvent&) override;
+    bool handleKeyboardEvent(const WebKeyboardEvent&) override;
+    void setFocus(bool) override;
+
+    bool handleEditingCommand(const String& commandName, const String& argument) override;
+    bool isEditingCommandEnabled(const String&) override;
+
+    bool shouldAllowScripting() override;
+    bool shouldAllowNavigationFromDrags() override;
+    
+    bool handlesPageScaleFactor() const override;
+
+    NPObject* pluginScriptableNPObject() override;
+    
+    unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned maxMatchCount) override;
+    bool findString(const String&, WebCore::FindOptions, unsigned maxMatchCount) override;
+
+    void windowFocusChanged(bool) override;
+    void windowVisibilityChanged(bool) override;
+
+#if PLATFORM(COCOA)
+    void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) override;
+
+    uint64_t pluginComplexTextInputIdentifier() const override;
+    void sendComplexTextInput(const String& textInput) override;
+    void setLayerHostingMode(LayerHostingMode) override;
+
+    void pluginFocusOrWindowFocusChanged();
+    void setComplexTextInputEnabled(bool);
+
+    void updatePluginLayer();
+#endif
+
+    void contentsScaleFactorChanged(float) override;
+    void storageBlockingStateChanged(bool) override;
+    void privateBrowsingStateChanged(bool) override;
+    bool getFormValue(String& formValue) override;
+    bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) override;
+    WebCore::Scrollbar* horizontalScrollbar() override;
+    WebCore::Scrollbar* verticalScrollbar() override;
+
+    bool supportsSnapshotting() const override;
+
+    // Convert the given point from root view coordinates to plug-in coordinates. Returns false if the point can't be
+    // converted (if the transformation matrix isn't invertible).
+    bool convertFromRootView(const WebCore::IntPoint& pointInRootViewCoordinates, WebCore::IntPoint& pointInPluginCoordinates);
+
+    RefPtr<WebCore::FragmentedSharedBuffer> liveResourceData() const override;
+
+    bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) override { return false; }
+
+    String getSelectionString() const override { return String(); }
+    String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const override { return String(); }
+    bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const override { return false; }
+
+    void mutedStateChanged(bool) override;
+
+    void updateNPNPrivateMode();
+
+    uint64_t m_nextRequestID;
+
+    typedef HashMap<uint64_t, std::pair<String, void*>> PendingURLNotifyMap;
+    PendingURLNotifyMap m_pendingURLNotifications;
+
+    typedef HashMap<uint64_t, RefPtr<NetscapePluginStream>> StreamsMap;
+    StreamsMap m_streams;
+    HashMap<void*, std::pair<RefPtr<NetscapePluginStream>, String>> m_redirects;
+
+    Ref<NetscapePluginModule> m_pluginModule;
+    NPP_t m_npp;
+    NPWindow m_npWindow;
+
+    WebCore::IntSize m_pluginSize;
+
+    // The clip rect in plug-in coordinates.
+    WebCore::IntRect m_clipRect;
+
+    // A transform that can be used to convert from root view coordinates to plug-in coordinates.
+    WebCore::AffineTransform m_pluginToRootViewTransform;
+
+#if PLUGIN_ARCHITECTURE(UNIX)
+    WebCore::IntRect m_frameRectInWindowCoordinates;
+#endif
+
+    CString m_userAgent;
+
+    bool m_isStarted;
+    bool m_isWindowed;
+    bool m_isTransparent;
+    bool m_inNPPNew;
+    bool m_shouldUseManualLoader;
+    bool m_hasCalledSetWindow;
+    bool m_isVisible;
+
+    RefPtr<NetscapePluginStream> m_manualStream;
+    Vector<bool, 8> m_popupEnabledStates;
+
+    class Timer {
+        WTF_MAKE_FAST_ALLOCATED;
+        WTF_MAKE_NONCOPYABLE(Timer);
+
+    public:
+        typedef void (*TimerFunc)(NPP, uint32_t timerID);
+
+        Timer(NetscapePlugin*, unsigned timerID, unsigned interval, bool repeat, TimerFunc);
+        ~Timer();
+
+        void start();
+        void stop();
+
+    private:
+        void timerFired();
+
+        // This is a weak pointer since Timer objects are destroyed before the NetscapePlugin object itself is destroyed.
+        NetscapePlugin* m_netscapePlugin;
+
+        unsigned m_timerID;
+        unsigned m_interval;
+        bool m_repeat;
+        TimerFunc m_timerFunc;
+
+        RunLoop::Timer<Timer> m_timer;
+    };
+    typedef HashMap<unsigned, std::unique_ptr<Timer>> TimerMap;
+    TimerMap m_timers;
+    unsigned m_nextTimerID;
+
+    bool m_privateBrowsingState { false };
+    bool m_storageBlockingState { false };
+
+#if PLUGIN_ARCHITECTURE(MAC)
+    NPDrawingModel m_drawingModel;
+    NPEventModel m_eventModel;
+
+    RetainPtr<PlatformLayer> m_pluginLayer;
+    bool m_pluginReturnsNonretainedLayer;
+    LayerHostingMode m_layerHostingMode;
+
+    NPCocoaEvent* m_currentMouseEvent;
+
+    bool m_pluginHasFocus;
+    bool m_windowHasFocus;
+
+    // Whether the plug-in wants to use the legacy Cocoa text input handling that
+    // existed in WebKit1, or the updated Cocoa text input handling specified on
+    // https://wiki.mozilla.org/NPAPI:CocoaEventModel#Text_Input
+    bool m_pluginWantsLegacyCocoaTextInput;
+
+    // Whether complex text input is enabled.
+    bool m_isComplexTextInputEnabled;
+
+    // Whether the plug-in has handled a keydown event. This is used to determine
+    // if we can tell the plug-in that we support the updated Cocoa text input specification.
+    bool m_hasHandledAKeyDownEvent;
+
+    // The number of NPCocoaEventKeyUp events that should be ignored.
+    unsigned m_ignoreNextKeyUpEventCounter;
+
+    WebCore::IntRect m_windowFrameInScreenCoordinates;
+    WebCore::IntRect m_viewFrameInWindowCoordinates;
+#elif PLUGIN_ARCHITECTURE(UNIX)
+    std::unique_ptr<NetscapePluginUnix> m_impl;
+#endif
+};
+
+} // namespace WebKit
+
+SPECIALIZE_TYPE_TRAITS_PLUGIN(NetscapePlugin, isNetscapePlugin())
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp	2022-03-22 16:38:57.393580216 -0500
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#if ENABLE(NETSCAPE_PLUGIN_API) && PLUGIN_ARCHITECTURE(UNSUPPORTED)
+
+#include "NetscapePlugin.h"
+
+namespace WebKit {
+using namespace WebCore;
+
+void NetscapePlugin::platformPreInitialize()
+{
+}
+
+bool NetscapePlugin::platformPostInitialize()
+{
+    return false;
+}
+
+void NetscapePlugin::platformDestroy()
+{
+}
+
+bool NetscapePlugin::platformInvalidate(const IntRect&)
+{
+    return false;
+}
+
+void NetscapePlugin::platformGeometryDidChange()
+{
+}
+
+void NetscapePlugin::platformVisibilityDidChange()
+{
+}
+
+void NetscapePlugin::platformPaint(GraphicsContext&, const IntRect&, bool)
+{
+}
+
+bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent&)
+{
+    return false;
+}
+
+bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent&)
+{
+    return false;
+}
+
+void NetscapePlugin::platformSetFocus(bool)
+{
+}
+
+bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent&)
+{
+    return false;
+}
+
+bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent&)
+{
+    return false;
+}
+
+bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& event)
+{
+    return false;
+}
+
+bool NetscapePlugin::wantsPluginRelativeNPWindowCoordinates()
+{
+    return true;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API) && PLUGIN_ARCHITECTURE(UNSUPPORTED)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp	2022-03-22 16:38:57.393580216 -0500
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NetscapePluginStream.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NetscapePlugin.h"
+#include <utility>
+#include <wtf/Vector.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+NetscapePluginStream::NetscapePluginStream(Ref<NetscapePlugin>&& plugin, uint64_t streamID, const String& requestURLString, bool sendNotification, void* notificationData)
+    : m_plugin(WTFMove(plugin))
+    , m_streamID(streamID)
+    , m_requestURLString(requestURLString)
+    , m_sendNotification(sendNotification)
+    , m_notificationData(notificationData)
+    , m_npStream()
+    , m_transferMode(NP_NORMAL)
+    , m_offset(0)
+    , m_fileHandle(FileSystem::invalidPlatformFileHandle)
+    , m_isStarted(false)
+#if ASSERT_ENABLED
+    , m_urlNotifyHasBeenCalled(false)
+#endif    
+    , m_deliveryDataTimer(RunLoop::main(), this, &NetscapePluginStream::deliverDataToPlugin)
+    , m_stopStreamWhenDoneDelivering(false)
+{
+}
+
+NetscapePluginStream::~NetscapePluginStream()
+{
+    ASSERT(!m_isStarted);
+    ASSERT(!m_sendNotification || m_urlNotifyHasBeenCalled);
+    ASSERT(m_fileHandle == FileSystem::invalidPlatformFileHandle);
+}
+
+void NetscapePluginStream::willSendRequest(const URL& requestURL, const URL& redirectResponseURL, int redirectResponseStatus)
+{
+    Ref<NetscapePluginStream> protect(*this);
+
+    if (redirectResponseStatus >= 300 && redirectResponseStatus < 400)
+        m_plugin->registerRedirect(this, requestURL, redirectResponseStatus, m_notificationData);
+}
+
+void NetscapePluginStream::didReceiveResponse(const URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers)
+{
+    // Starting the stream could cause the plug-in stream to go away so we keep a reference to it here.
+    Ref<NetscapePluginStream> protect(*this);
+
+    start(responseURL.string(), streamLength, lastModifiedTime, mimeType, headers);
+}
+
+void NetscapePluginStream::didReceiveData(const uint8_t* bytes, int length)
+{
+    // Delivering the data could cause the plug-in stream to go away so we keep a reference to it here.
+    Ref<NetscapePluginStream> protect(*this);
+
+    deliverData(bytes, length);
+}
+
+void NetscapePluginStream::didFinishLoading()
+{
+    // Stopping the stream could cause the plug-in stream to go away so we keep a reference to it here.
+    Ref<NetscapePluginStream> protect(*this);
+
+    stop(NPRES_DONE);
+}
+
+void NetscapePluginStream::didFail(bool wasCancelled)
+{
+    // Stopping the stream could cause the plug-in stream to go away so we keep a reference to it here.
+    Ref<NetscapePluginStream> protect(*this);
+
+    stop(wasCancelled ? NPRES_USER_BREAK : NPRES_NETWORK_ERR);
+}
+    
+void NetscapePluginStream::sendJavaScriptStream(const String& result)
+{
+    // starting the stream or delivering the data to it might cause the plug-in stream to go away, so we keep
+    // a reference to it here.
+    Ref<NetscapePluginStream> protect(*this);
+
+    CString resultCString = result.utf8();
+    if (resultCString.isNull()) {
+        // There was an error evaluating the JavaScript, call NPP_URLNotify if needed and then destroy the stream.
+        notifyAndDestroyStream(NPRES_NETWORK_ERR);
+        return;
+    }
+
+    if (!start(m_requestURLString, resultCString.length(), 0, "text/plain", ""))
+        return;
+
+    deliverData(resultCString.dataAsUInt8Ptr(), resultCString.length());
+    stop(NPRES_DONE);
+}
+
+NPError NetscapePluginStream::destroy(NPReason reason)
+{
+    // It doesn't make sense to call NPN_DestroyStream on a stream that hasn't been started yet.
+    if (!m_isStarted)
+        return NPERR_GENERIC_ERROR;
+
+    // It isn't really valid for a plug-in to call NPN_DestroyStream with NPRES_DONE.
+    // (At least not for browser initiated streams, and we don't support plug-in initiated streams).
+    if (reason == NPRES_DONE)
+        return NPERR_INVALID_PARAM;
+
+    cancel();
+    stop(reason);
+    return NPERR_NO_ERROR;
+}
+
+static bool isSupportedTransferMode(uint16_t transferMode)
+{
+    switch (transferMode) {
+    case NP_ASFILEONLY:
+    case NP_ASFILE:
+    case NP_NORMAL:
+        return true;
+    // FIXME: We don't support seekable streams.
+    case NP_SEEK:
+        return false;
+    }
+
+    ASSERT_NOT_REACHED();
+    return false;
+}
+    
+bool NetscapePluginStream::start(const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers)
+{
+    m_responseURL = responseURLString.utf8();
+    m_mimeType = mimeType.utf8();
+    m_headers = headers.utf8();
+
+    m_npStream.ndata = this;
+    m_npStream.url = m_responseURL.data();
+    m_npStream.end = streamLength;
+    m_npStream.lastmodified = lastModifiedTime;
+    m_npStream.notifyData = m_notificationData;
+    m_npStream.headers = m_headers.length() == 0 ? 0 : m_headers.data();
+
+    NPError error = m_plugin->NPP_NewStream(const_cast<char*>(m_mimeType.data()), &m_npStream, false, &m_transferMode);
+    if (error != NPERR_NO_ERROR) {
+        // We failed to start the stream, cancel the load and destroy it.
+        cancel();
+        notifyAndDestroyStream(NPRES_NETWORK_ERR);
+        return false;
+    }
+
+    // We successfully started the stream.
+    m_isStarted = true;
+
+    if (!isSupportedTransferMode(m_transferMode)) {
+        // Cancel the load and stop the stream.
+        cancel();
+        stop(NPRES_NETWORK_ERR);
+        return false;
+    }
+
+    return true;
+}
+
+void NetscapePluginStream::deliverData(const uint8_t* bytes, int length)
+{
+    ASSERT(m_isStarted);
+
+    if (m_transferMode != NP_ASFILEONLY) {
+        if (!m_deliveryData)
+            m_deliveryData = makeUnique<Vector<uint8_t>>();
+
+        m_deliveryData->reserveCapacity(m_deliveryData->size() + length);
+        m_deliveryData->append(bytes, length);
+        
+        deliverDataToPlugin();
+    }
+
+    if (m_transferMode == NP_ASFILE || m_transferMode == NP_ASFILEONLY)
+        deliverDataToFile(bytes, length);
+}
+
+void NetscapePluginStream::deliverDataToPlugin()
+{
+    ASSERT(m_isStarted);
+
+    int32_t numBytesToDeliver = m_deliveryData->size();
+    int32_t numBytesDelivered = 0;
+
+    while (numBytesDelivered < numBytesToDeliver) {
+        int32_t numBytesPluginCanHandle = m_plugin->NPP_WriteReady(&m_npStream);
+        
+        // NPP_WriteReady could call NPN_DestroyStream and destroy the stream.
+        if (!m_isStarted)
+            return;
+
+        if (numBytesPluginCanHandle <= 0) {
+            // The plug-in can't handle more data, we'll send the rest later
+            m_deliveryDataTimer.startOneShot(0_s);
+            break;
+        }
+
+        // Figure out how much data to send to the plug-in.
+        int32_t dataLength = std::min(numBytesPluginCanHandle, numBytesToDeliver - numBytesDelivered);
+        uint8_t* data = m_deliveryData->data() + numBytesDelivered;
+
+        int32_t numBytesWritten = m_plugin->NPP_Write(&m_npStream, m_offset, dataLength, data);
+        if (numBytesWritten < 0) {
+            cancel();
+            stop(NPRES_NETWORK_ERR);
+            return;
+        }
+
+        // NPP_Write could call NPN_DestroyStream and destroy the stream.
+        if (!m_isStarted)
+            return;
+
+        numBytesWritten = std::min(numBytesWritten, dataLength);
+        m_offset += numBytesWritten;
+        numBytesDelivered += numBytesWritten;
+    }
+
+    // We didn't write anything.
+    if (!numBytesDelivered)
+        return;
+
+    if (numBytesDelivered < numBytesToDeliver) {
+        // Remove the bytes that we actually delivered.
+        m_deliveryData->remove(0, numBytesDelivered);
+    } else {
+        m_deliveryData->clear();
+
+        if (m_stopStreamWhenDoneDelivering)
+            stop(NPRES_DONE);
+    }
+}
+
+void NetscapePluginStream::deliverDataToFile(const uint8_t* bytes, int length)
+{
+    if (m_fileHandle == FileSystem::invalidPlatformFileHandle && m_filePath.isNull()) {
+        // Create a temporary file.
+        m_filePath = FileSystem::openTemporaryFile("WebKitPluginStream", m_fileHandle);
+
+        // We failed to open the file, stop the stream.
+        if (m_fileHandle == FileSystem::invalidPlatformFileHandle) {
+            stop(NPRES_NETWORK_ERR);
+            return;
+        }
+    }
+
+    if (!length)
+        return;
+
+    int byteCount = FileSystem::writeToFile(m_fileHandle, bytes, length);
+    if (byteCount != length) {
+        // This happens only rarely, when we are out of disk space or have a disk I/O error.
+        FileSystem::closeFile(m_fileHandle);
+
+        stop(NPRES_NETWORK_ERR);
+    }
+}
+
+void NetscapePluginStream::stop(NPReason reason)
+{
+    // The stream was stopped before it got a chance to start. This can happen if a stream is cancelled by
+    // WebKit before it received a response.
+    if (!m_isStarted) {
+        ASSERT(reason != NPRES_DONE);
+        notifyAndDestroyStream(reason);
+        return;
+    }
+
+    if (reason == NPRES_DONE && m_deliveryData && !m_deliveryData->isEmpty()) {
+        // There is still data left that the plug-in hasn't been able to consume yet.
+        ASSERT(m_deliveryDataTimer.isActive());
+        
+        // Set m_stopStreamWhenDoneDelivering to true so that the next time the delivery timer fires
+        // and calls deliverDataToPlugin the stream will be closed if all the remaining data was
+        // successfully delivered.
+        m_stopStreamWhenDoneDelivering = true;
+        return;
+    }
+
+    m_deliveryData = nullptr;
+    m_deliveryDataTimer.stop();
+
+    if (m_transferMode == NP_ASFILE || m_transferMode == NP_ASFILEONLY) {
+        if (reason == NPRES_DONE) {
+            // Ensure that the file is created.
+            deliverDataToFile(0, 0);
+            if (m_fileHandle != FileSystem::invalidPlatformFileHandle)
+                FileSystem::closeFile(m_fileHandle);
+            
+            ASSERT(!m_filePath.isNull());
+            
+            m_plugin->NPP_StreamAsFile(&m_npStream, m_filePath.utf8().data());
+        } else {
+            // Just close the file.
+            if (m_fileHandle != FileSystem::invalidPlatformFileHandle)
+                FileSystem::closeFile(m_fileHandle);
+        }
+
+        // Delete the file after calling NPP_StreamAsFile(), instead of in the destructor.  It should be OK
+        // to delete the file here -- NPP_StreamAsFile() is always called immediately before NPP_DestroyStream()
+        // (the stream destruction function), so there can be no expectation that a plugin will read the stream
+        // file asynchronously after NPP_StreamAsFile() is called.
+        FileSystem::deleteFile(m_filePath);
+        m_filePath = String();
+
+        // NPP_StreamAsFile could call NPN_DestroyStream and destroy the stream.
+        if (!m_isStarted)
+            return;
+    }
+
+    // Set m_isStarted to false before calling NPP_DestroyStream in case NPP_DestroyStream calls NPN_DestroyStream.
+    m_isStarted = false;
+
+    m_plugin->NPP_DestroyStream(&m_npStream, reason);
+
+    notifyAndDestroyStream(reason);
+}
+
+void NetscapePluginStream::setURL(const String& newURLString)
+{
+    m_requestURLString = newURLString;
+}
+
+void NetscapePluginStream::cancel()
+{
+    m_plugin->cancelStreamLoad(this);
+}
+
+void NetscapePluginStream::notifyAndDestroyStream(NPReason reason)
+{
+    ASSERT(!m_isStarted);
+    ASSERT(!m_deliveryDataTimer.isActive());
+    ASSERT(!m_urlNotifyHasBeenCalled);
+    
+    if (m_sendNotification) {
+        m_plugin->NPP_URLNotify(m_requestURLString.utf8().data(), reason, m_notificationData);
+    
+#if ASSERT_ENABLED
+        m_urlNotifyHasBeenCalled = true;
+#endif    
+    }
+
+    m_plugin->removePluginStream(this);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePluginStream.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePluginStream.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePluginStream.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NetscapePluginStream.h	2022-03-22 16:38:57.393580216 -0500
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <WebCore/npruntime_internal.h>
+#include <memory>
+#include <wtf/FileSystem.h>
+#include <wtf/Forward.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/RunLoop.h>
+#include <wtf/text/CString.h>
+
+namespace WebKit {
+
+class NetscapePlugin;
+
+class NetscapePluginStream : public RefCounted<NetscapePluginStream> {
+public:
+    static Ref<NetscapePluginStream> create(Ref<NetscapePlugin>&& plugin, uint64_t streamID, const String& requestURLString, bool sendNotification, void* notificationData)
+    {
+        return adoptRef(*new NetscapePluginStream(WTFMove(plugin), streamID, requestURLString, sendNotification, notificationData));
+    }
+    ~NetscapePluginStream();
+
+    uint64_t streamID() const { return m_streamID; }
+    const NPStream* npStream() const { return &m_npStream; }
+
+    void willSendRequest(const URL& requestURL, const URL& redirectResponseURL, int redirectResponseStatus);
+    void didReceiveResponse(const URL& responseURL, uint32_t streamLength,
+                            uint32_t lastModifiedTime, const String& mimeType, const String& headers);
+    void didReceiveData(const uint8_t* bytes, int length);
+    void didFinishLoading();
+    void didFail(bool wasCancelled);
+
+    void sendJavaScriptStream(const String& result);
+
+    void stop(NPReason);
+    NPError destroy(NPReason);
+    void setURL(const String& newURLString);
+
+private:
+    NetscapePluginStream(Ref<NetscapePlugin>&&, uint64_t streamID, const String& requestURLString, bool sendNotification, void* notificationData);
+
+    bool start(const String& responseURLString, uint32_t streamLength, 
+               uint32_t lastModifiedTime, const String& mimeType, const String& headers);
+
+    void cancel();
+    void notifyAndDestroyStream(NPReason);
+
+    void deliverData(const uint8_t* bytes, int length);
+    void deliverDataToPlugin();
+    void deliverDataToFile(const uint8_t* bytes, int length);
+
+    Ref<NetscapePlugin> m_plugin;
+    uint64_t m_streamID;
+
+    String m_requestURLString;
+    bool m_sendNotification;
+    void* m_notificationData;
+
+    NPStream m_npStream;
+    uint16_t m_transferMode;
+    int32_t m_offset;
+
+    String m_filePath;
+    FileSystem::PlatformFileHandle m_fileHandle;
+    
+    // Whether NPP_NewStream has successfully been called.
+    bool m_isStarted;
+
+#if ASSERT_ENABLED
+    bool m_urlNotifyHasBeenCalled;
+#endif
+
+    CString m_responseURL;
+    CString m_mimeType;
+    CString m_headers;
+
+    RunLoop::Timer<NetscapePluginStream> m_deliveryDataTimer;
+    std::unique_ptr<Vector<uint8_t>> m_deliveryData;
+    bool m_stopStreamWhenDoneDelivering;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NPJSObject.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NPJSObject.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NPJSObject.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NPJSObject.cpp	2022-03-22 16:38:57.393580216 -0500
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2010-2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NPJSObject.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "JSNPObject.h"
+#include "NPRuntimeObjectMap.h"
+#include "NPRuntimeUtilities.h"
+#include <JavaScriptCore/CatchScope.h>
+#include <JavaScriptCore/JSCInlines.h>
+#include <JavaScriptCore/JSCellInlines.h>
+#include <JavaScriptCore/JSLock.h>
+#include <JavaScriptCore/JSObject.h>
+#include <JavaScriptCore/StrongInlines.h>
+#include <WebCore/Frame.h>
+#include <WebCore/IdentifierRep.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+using namespace JSC;
+using namespace WebCore;
+
+NPJSObject* NPJSObject::create(VM& vm, NPRuntimeObjectMap* objectMap, JSObject* jsObject)
+{
+    // We should never have a JSNPObject inside an NPJSObject.
+    ASSERT(!jsObject->inherits<JSNPObject>(vm));
+
+    NPJSObject* npJSObject = toNPJSObject(createNPObject(0, npClass()));
+    npJSObject->initialize(vm, objectMap, jsObject);
+
+    return npJSObject;
+}
+
+NPJSObject::NPJSObject()
+    : m_objectMap(0)
+{
+}
+
+NPJSObject::~NPJSObject()
+{
+    m_objectMap->npJSObjectDestroyed(this);
+}
+
+bool NPJSObject::isNPJSObject(NPObject* npObject)
+{
+    return npObject->_class == npClass();
+}
+
+void NPJSObject::initialize(VM& vm, NPRuntimeObjectMap* objectMap, JSObject* jsObject)
+{
+    ASSERT(!m_objectMap);
+    ASSERT(!m_jsObject);
+
+    m_objectMap = objectMap;
+    m_jsObject.set(vm, jsObject);
+}
+
+static Identifier identifierFromIdentifierRep(JSGlobalObject* lexicalGlobalObject, IdentifierRep* identifierRep)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    ASSERT(identifierRep->isString());
+
+    const char* string = identifierRep->string();
+    int length = strlen(string);
+
+    return Identifier::fromString(vm, String::fromUTF8WithLatin1Fallback(string, length));
+}
+
+bool NPJSObject::hasMethod(NPIdentifier methodName)
+{
+    IdentifierRep* identifierRep = static_cast<IdentifierRep*>(methodName);
+
+    if (!identifierRep->isString())
+        return false;
+
+    JSGlobalObject* lexicalGlobalObject = m_objectMap->globalObject();
+    if (!lexicalGlobalObject)
+        return false;
+
+    VM& vm = lexicalGlobalObject->vm();
+    JSLockHolder lock(vm);
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+
+    JSValue value = m_jsObject->get(lexicalGlobalObject, identifierFromIdentifierRep(lexicalGlobalObject, identifierRep));    
+    scope.clearException();
+
+    return value.isCallable(vm);
+}
+
+bool NPJSObject::invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    IdentifierRep* identifierRep = static_cast<IdentifierRep*>(methodName);
+    
+    if (!identifierRep->isString())
+        return false;
+    
+    JSGlobalObject* lexicalGlobalObject = m_objectMap->globalObject();
+    if (!lexicalGlobalObject)
+        return false;
+    
+    JSLockHolder lock(lexicalGlobalObject);
+
+    JSValue function = m_jsObject->get(lexicalGlobalObject, identifierFromIdentifierRep(lexicalGlobalObject, identifierRep));
+    return invoke(lexicalGlobalObject, function, arguments, argumentCount, result);
+}
+
+bool NPJSObject::invokeDefault(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    JSGlobalObject* lexicalGlobalObject = m_objectMap->globalObject();
+    if (!lexicalGlobalObject)
+        return false;
+
+    JSLockHolder lock(lexicalGlobalObject);
+
+    JSValue function = m_jsObject.get();
+    return invoke(lexicalGlobalObject, function, arguments, argumentCount, result);
+}
+
+bool NPJSObject::hasProperty(NPIdentifier identifier)
+{
+    IdentifierRep* identifierRep = static_cast<IdentifierRep*>(identifier);
+    
+    JSGlobalObject* lexicalGlobalObject = m_objectMap->globalObject();
+    if (!lexicalGlobalObject)
+        return false;
+    
+    VM& vm = lexicalGlobalObject->vm();
+    JSLockHolder lock(vm);
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+
+    bool result;
+    if (identifierRep->isString())
+        result = m_jsObject->hasProperty(lexicalGlobalObject, identifierFromIdentifierRep(lexicalGlobalObject, identifierRep));
+    else
+        result = m_jsObject->hasProperty(lexicalGlobalObject, static_cast<uint32_t>(identifierRep->number()));
+
+    scope.clearException();
+    return result;
+}
+
+bool NPJSObject::getProperty(NPIdentifier propertyName, NPVariant* result)
+{
+    IdentifierRep* identifierRep = static_cast<IdentifierRep*>(propertyName);
+    
+    JSGlobalObject* lexicalGlobalObject = m_objectMap->globalObject();
+    if (!lexicalGlobalObject)
+        return false;
+
+    VM& vm = lexicalGlobalObject->vm();
+    JSLockHolder lock(vm);
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+
+    JSValue jsResult;
+    if (identifierRep->isString())
+        jsResult = m_jsObject->get(lexicalGlobalObject, identifierFromIdentifierRep(lexicalGlobalObject, identifierRep));
+    else
+        jsResult = m_jsObject->get(lexicalGlobalObject, static_cast<uint32_t>(identifierRep->number()));
+    
+    m_objectMap->convertJSValueToNPVariant(lexicalGlobalObject, jsResult, *result);
+    scope.clearException();
+    return true;
+}
+
+bool NPJSObject::setProperty(NPIdentifier propertyName, const NPVariant* value)
+{
+    IdentifierRep* identifierRep = static_cast<IdentifierRep*>(propertyName);
+    
+    JSGlobalObject* lexicalGlobalObject = m_objectMap->globalObject();
+    if (!lexicalGlobalObject)
+        return false;
+    
+    VM& vm = lexicalGlobalObject->vm();
+    JSLockHolder lock(vm);
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+
+    JSValue jsValue = m_objectMap->convertNPVariantToJSValue(m_objectMap->globalObject(), *value);
+    if (identifierRep->isString()) {
+        PutPropertySlot slot(m_jsObject.get());
+        m_jsObject->methodTable(vm)->put(m_jsObject.get(), lexicalGlobalObject, identifierFromIdentifierRep(lexicalGlobalObject, identifierRep), jsValue, slot);
+    } else
+        m_jsObject->methodTable(vm)->putByIndex(m_jsObject.get(), lexicalGlobalObject, identifierRep->number(), jsValue, false);
+    scope.clearException();
+    
+    return true;
+}
+
+bool NPJSObject::removeProperty(NPIdentifier propertyName)
+{
+    IdentifierRep* identifierRep = static_cast<IdentifierRep*>(propertyName);
+    
+    JSGlobalObject* lexicalGlobalObject = m_objectMap->globalObject();
+    if (!lexicalGlobalObject)
+        return false;
+
+    VM& vm = lexicalGlobalObject->vm();
+    JSLockHolder lock(vm);
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+
+    if (identifierRep->isString()) {
+        Identifier identifier = identifierFromIdentifierRep(lexicalGlobalObject, identifierRep);
+        
+        if (!m_jsObject->hasProperty(lexicalGlobalObject, identifier)) {
+            scope.clearException();
+            return false;
+        }
+
+        JSCell::deleteProperty(m_jsObject.get(), lexicalGlobalObject, identifier);
+    } else {
+        if (!m_jsObject->hasProperty(lexicalGlobalObject, static_cast<uint32_t>(identifierRep->number()))) {
+            scope.clearException();
+            return false;
+        }
+
+        m_jsObject->methodTable(vm)->deletePropertyByIndex(m_jsObject.get(), lexicalGlobalObject, identifierRep->number());
+    }
+
+    scope.clearException();
+    return true;
+}
+
+bool NPJSObject::enumerate(NPIdentifier** identifiers, uint32_t* identifierCount)
+{
+    JSGlobalObject* lexicalGlobalObject = m_objectMap->globalObject();
+    if (!lexicalGlobalObject)
+        return false;
+
+    VM& vm = lexicalGlobalObject->vm();
+    JSLockHolder lock(vm);
+
+    PropertyNameArray propertyNames(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
+    m_jsObject->getPropertyNames(lexicalGlobalObject, propertyNames, DontEnumPropertiesMode::Exclude);
+
+    NPIdentifier* nameIdentifiers = npnMemNewArray<NPIdentifier>(propertyNames.size());
+
+    for (size_t i = 0; i < propertyNames.size(); ++i)
+        nameIdentifiers[i] = static_cast<NPIdentifier>(IdentifierRep::get(propertyNames[i].string().utf8().data()));
+
+    *identifiers = nameIdentifiers;
+    *identifierCount = propertyNames.size();
+
+    return true;
+}
+
+bool NPJSObject::construct(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    JSGlobalObject* lexicalGlobalObject = m_objectMap->globalObject();
+    if (!lexicalGlobalObject)
+        return false;
+
+    VM& vm = lexicalGlobalObject->vm();
+    JSLockHolder lock(vm);
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+
+    auto constructData = getConstructData(vm, m_jsObject.get());
+    if (constructData.type == CallData::Type::None)
+        return false;
+
+    // Convert the passed in arguments.
+    MarkedArgumentBuffer argumentList;
+    for (uint32_t i = 0; i < argumentCount; ++i)
+        argumentList.append(m_objectMap->convertNPVariantToJSValue(m_objectMap->globalObject(), arguments[i]));
+    RELEASE_ASSERT(!argumentList.hasOverflowed());
+
+    JSValue value = JSC::construct(lexicalGlobalObject, m_jsObject.get(), constructData, argumentList);
+    
+    // Convert and return the new object.
+    m_objectMap->convertJSValueToNPVariant(lexicalGlobalObject, value, *result);
+    scope.clearException();
+
+    return true;
+}
+
+bool NPJSObject::invoke(JSGlobalObject* lexicalGlobalObject, JSValue function, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+
+    auto callData = getCallData(vm, function);
+    if (callData.type == CallData::Type::None)
+        return false;
+
+    // Convert the passed in arguments.
+    MarkedArgumentBuffer argumentList;
+    for (uint32_t i = 0; i < argumentCount; ++i)
+        argumentList.append(m_objectMap->convertNPVariantToJSValue(lexicalGlobalObject, arguments[i]));
+    RELEASE_ASSERT(!argumentList.hasOverflowed());
+
+    JSValue value = JSC::call(lexicalGlobalObject, function, callData, m_jsObject.get(), argumentList);
+
+    if (UNLIKELY(scope.exception())) {
+        scope.clearException();
+        return false;
+    }
+
+    // Convert and return the result of the function call.
+    m_objectMap->convertJSValueToNPVariant(lexicalGlobalObject, value, *result);
+
+    if (UNLIKELY(scope.exception())) {
+        scope.clearException();
+        return false;
+    }
+    
+    return true;
+}
+
+NPClass* NPJSObject::npClass()
+{
+    static NPClass npClass = {
+        NP_CLASS_STRUCT_VERSION,
+        NP_Allocate,
+        NP_Deallocate,
+        0,
+        NP_HasMethod,
+        NP_Invoke,
+        NP_InvokeDefault,
+        NP_HasProperty,
+        NP_GetProperty,
+        NP_SetProperty,
+        NP_RemoveProperty,
+        NP_Enumerate,
+        NP_Construct
+    };
+
+    return &npClass;
+}
+    
+NPObject* NPJSObject::NP_Allocate(NPP npp, NPClass*)
+{
+    ASSERT_UNUSED(npp, !npp);
+
+    return new NPJSObject;
+}
+
+void NPJSObject::NP_Deallocate(NPObject* npObject)
+{
+    NPJSObject* npJSObject = toNPJSObject(npObject);
+    delete npJSObject;
+}
+
+bool NPJSObject::NP_HasMethod(NPObject* npObject, NPIdentifier methodName)
+{
+    return toNPJSObject(npObject)->hasMethod(methodName);
+}
+    
+bool NPJSObject::NP_Invoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    return toNPJSObject(npObject)->invoke(methodName, arguments, argumentCount, result);
+}
+    
+bool NPJSObject::NP_InvokeDefault(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    return toNPJSObject(npObject)->invokeDefault(arguments, argumentCount, result);
+}
+    
+bool NPJSObject::NP_HasProperty(NPObject* npObject, NPIdentifier propertyName)
+{
+    return toNPJSObject(npObject)->hasProperty(propertyName);
+}
+
+bool NPJSObject::NP_GetProperty(NPObject* npObject, NPIdentifier propertyName, NPVariant* result)
+{
+    return toNPJSObject(npObject)->getProperty(propertyName, result);
+}
+
+bool NPJSObject::NP_SetProperty(NPObject* npObject, NPIdentifier propertyName, const NPVariant* value)
+{
+    return toNPJSObject(npObject)->setProperty(propertyName, value);
+}
+
+bool NPJSObject::NP_RemoveProperty(NPObject* npObject, NPIdentifier propertyName)
+{
+    return toNPJSObject(npObject)->removeProperty(propertyName);
+}
+
+bool NPJSObject::NP_Enumerate(NPObject* npObject, NPIdentifier** identifiers, uint32_t* identifierCount)
+{
+    return toNPJSObject(npObject)->enumerate(identifiers, identifierCount);
+}
+
+bool NPJSObject::NP_Construct(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+    return toNPJSObject(npObject)->construct(arguments, argumentCount, result);
+}
+    
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NPJSObject.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NPJSObject.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NPJSObject.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NPJSObject.h	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NPJSObject_h
+#define NPJSObject_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <JavaScriptCore/Strong.h>
+#include <WebCore/npruntime_internal.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+
+class VM;
+class JSGlobalObject;
+class JSObject;
+
+}
+
+namespace WebKit {
+
+class NPRuntimeObjectMap;
+    
+// NPJSObject is an NPObject that wraps a JSObject.
+class NPJSObject : public NPObject {
+    WTF_MAKE_NONCOPYABLE(NPJSObject);
+public:
+    static NPJSObject* create(JSC::VM&, NPRuntimeObjectMap*, JSC::JSObject*);
+
+    JSC::JSObject* jsObject() const { return m_jsObject.get(); }
+
+    static bool isNPJSObject(NPObject*);
+
+    static NPJSObject* toNPJSObject(NPObject* npObject)
+    {
+        RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(isNPJSObject(npObject));
+        return static_cast<NPJSObject*>(npObject);
+    }
+
+private:
+    NPJSObject();
+    ~NPJSObject();
+
+    void initialize(JSC::VM&, NPRuntimeObjectMap*, JSC::JSObject*);
+
+    bool hasMethod(NPIdentifier methodName);
+    bool invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+    bool invokeDefault(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+    bool hasProperty(NPIdentifier propertyName);
+    bool getProperty(NPIdentifier propertyName, NPVariant* result);
+    bool setProperty(NPIdentifier propertyName, const NPVariant* value);
+    bool removeProperty(NPIdentifier propertyName);
+    bool enumerate(NPIdentifier** identifiers, uint32_t* identifierCount);
+    bool construct(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+
+    bool invoke(JSC::JSGlobalObject*, JSC::JSValue function, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+
+    static NPClass* npClass();
+    static NPObject* NP_Allocate(NPP, NPClass*);
+    static void NP_Deallocate(NPObject*);
+    static bool NP_HasMethod(NPObject*, NPIdentifier methodName);
+    static bool NP_Invoke(NPObject*, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+    static bool NP_InvokeDefault(NPObject*, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+    static bool NP_HasProperty(NPObject*, NPIdentifier propertyName);
+    static bool NP_GetProperty(NPObject*, NPIdentifier propertyName, NPVariant* result);
+    static bool NP_SetProperty(NPObject*, NPIdentifier propertyName, const NPVariant* value);
+    static bool NP_RemoveProperty(NPObject*, NPIdentifier propertyName);
+    static bool NP_Enumerate(NPObject*, NPIdentifier** identifiers, uint32_t* identifierCount);
+    static bool NP_Construct(NPObject*, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+    
+    NPRuntimeObjectMap* m_objectMap;
+    JSC::Strong<JSC::JSObject> m_jsObject;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // NPJSObject_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2010-2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NPRuntimeObjectMap.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "JSNPObject.h"
+#include "NPJSObject.h"
+#include "NPRuntimeUtilities.h"
+#include "PluginView.h"
+#include "WebProcess.h"
+#include <JavaScriptCore/Completion.h>
+#include <JavaScriptCore/Error.h>
+#include <JavaScriptCore/JSGlobalObjectInlines.h>
+#include <JavaScriptCore/JSLock.h>
+#include <JavaScriptCore/SourceCode.h>
+#include <JavaScriptCore/Strong.h>
+#include <JavaScriptCore/StrongInlines.h>
+#include <WebCore/DOMWrapperWorld.h>
+#include <WebCore/Frame.h>
+#include <WebCore/ScriptController.h>
+#include <wtf/NeverDestroyed.h>
+
+namespace WebKit {
+using namespace JSC;
+using namespace WebCore;
+
+
+NPRuntimeObjectMap::NPRuntimeObjectMap(PluginView* pluginView)
+    : m_pluginView(pluginView)
+    , m_finalizationTimer(RunLoop::main(), this, &NPRuntimeObjectMap::invalidateQueuedObjects)
+{
+}
+
+NPRuntimeObjectMap::PluginProtector::PluginProtector(NPRuntimeObjectMap* npRuntimeObjectMap)
+{
+    // If we're already in the plug-in view destructor, we shouldn't try to keep it alive.
+    if (!npRuntimeObjectMap->m_pluginView->isBeingDestroyed())
+        m_pluginView = npRuntimeObjectMap->m_pluginView;
+}
+
+NPRuntimeObjectMap::PluginProtector::~PluginProtector()
+{
+}
+
+NPObject* NPRuntimeObjectMap::getOrCreateNPObject(VM& vm, JSObject* jsObject)
+{
+    // If this is a JSNPObject, we can just get its underlying NPObject.
+    if (jsObject->classInfo(vm) == JSNPObject::info()) {
+        JSNPObject* jsNPObject = jsCast<JSNPObject*>(jsObject);
+        NPObject* npObject = jsNPObject->npObject();
+        
+        retainNPObject(npObject);
+        return npObject;
+    }
+    
+    // First, check if we already know about this object.
+    if (NPJSObject* npJSObject = m_npJSObjects.get(jsObject)) {
+        retainNPObject(npJSObject);
+        return npJSObject;
+    }
+
+    NPJSObject* npJSObject = NPJSObject::create(vm, this, jsObject);
+    m_npJSObjects.set(jsObject, npJSObject);
+
+    return npJSObject;
+}
+
+void NPRuntimeObjectMap::npJSObjectDestroyed(NPJSObject* npJSObject)
+{
+    // Remove the object from the map.
+    ASSERT(m_npJSObjects.contains(npJSObject->jsObject()));
+    m_npJSObjects.remove(npJSObject->jsObject());
+}
+
+JSObject* NPRuntimeObjectMap::getOrCreateJSObject(JSGlobalObject* globalObject, NPObject* npObject)
+{
+    // If this is an NPJSObject, we can just get the JSObject that it's wrapping.
+    if (NPJSObject::isNPJSObject(npObject))
+        return NPJSObject::toNPJSObject(npObject)->jsObject();
+    
+    if (JSNPObject* jsNPObject = m_jsNPObjects.get(npObject))
+        return jsNPObject;
+
+    JSNPObject* jsNPObject = JSNPObject::create(globalObject, this, npObject);
+    weakAdd(m_jsNPObjects, npObject, JSC::Weak<JSNPObject>(jsNPObject, this, npObject));
+    return jsNPObject;
+}
+
+JSValue NPRuntimeObjectMap::convertNPVariantToJSValue(JSC::JSGlobalObject* globalObject, const NPVariant& variant)
+{
+    switch (variant.type) {
+    case NPVariantType_Void:
+        return jsUndefined();
+
+    case NPVariantType_Null:
+        return jsNull();
+
+    case NPVariantType_Bool:
+        return jsBoolean(variant.value.boolValue);
+
+    case NPVariantType_Int32:
+        return jsNumber(variant.value.intValue);
+
+    case NPVariantType_Double:
+        return jsNumber(variant.value.doubleValue);
+
+    case NPVariantType_String:
+        return jsString(globalObject->vm(), String::fromUTF8WithLatin1Fallback(variant.value.stringValue.UTF8Characters,
+                                                                 variant.value.stringValue.UTF8Length));
+    case NPVariantType_Object:
+        return getOrCreateJSObject(globalObject, variant.value.objectValue);
+    }
+
+    ASSERT_NOT_REACHED();
+    return jsUndefined();
+}
+
+void NPRuntimeObjectMap::convertJSValueToNPVariant(JSGlobalObject* lexicalGlobalObject, JSValue value, NPVariant& variant)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    JSLockHolder lock(lexicalGlobalObject);
+
+    VOID_TO_NPVARIANT(variant);
+    
+    if (value.isNull()) {
+        NULL_TO_NPVARIANT(variant);
+        return;
+    }
+
+    if (value.isUndefined()) {
+        VOID_TO_NPVARIANT(variant);
+        return;
+    }
+
+    if (value.isBoolean()) {
+        BOOLEAN_TO_NPVARIANT(value.toBoolean(lexicalGlobalObject), variant);
+        return;
+    }
+
+    if (value.isNumber()) {
+        DOUBLE_TO_NPVARIANT(value.toNumber(lexicalGlobalObject), variant);
+        return;
+    }
+
+    if (value.isString()) {
+        NPString npString = createNPString(value.toString(lexicalGlobalObject)->value(lexicalGlobalObject).utf8());
+        STRINGN_TO_NPVARIANT(npString.UTF8Characters, npString.UTF8Length, variant);
+        return;
+    }
+
+    if (value.isObject()) {
+        NPObject* npObject = getOrCreateNPObject(vm, asObject(value));
+        OBJECT_TO_NPVARIANT(npObject, variant);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
+}
+
+bool NPRuntimeObjectMap::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result)
+{
+    Strong<JSGlobalObject> globalObject(this->globalObject()->vm(), this->globalObject());
+    if (!globalObject)
+        return false;
+
+    JSLockHolder lock(globalObject.get());
+    JSValue thisValue = getOrCreateJSObject(globalObject.get(), npObject);
+
+    JSValue resultValue = JSC::evaluate(globalObject.get(), makeSource(scriptString, { }), thisValue);
+
+    convertJSValueToNPVariant(globalObject.get(), resultValue, *result);
+    return true;
+}
+
+void NPRuntimeObjectMap::invalidate()
+{
+    // Deallocate all the object wrappers so we won't leak any JavaScript objects.
+    for (auto& npJSObject : copyToVector(m_npJSObjects.values()))
+        deallocateNPObject(npJSObject);
+    
+    // We shouldn't have any NPJSObjects left now.
+    ASSERT(m_npJSObjects.isEmpty());
+
+    Vector<NPObject*> objects;
+
+    for (HashMap<NPObject*, JSC::Weak<JSNPObject>>::iterator ptr = m_jsNPObjects.begin(), end = m_jsNPObjects.end(); ptr != end; ++ptr) {
+        JSNPObject* jsNPObject = ptr->value.get();
+        if (!jsNPObject) // Skip zombies.
+            continue;
+        objects.append(jsNPObject->leakNPObject());
+    }
+
+    m_jsNPObjects.clear();
+
+    for (size_t i = 0; i < objects.size(); ++i)
+        releaseNPObject(objects[i]);
+    
+    // Deal with any objects that were scheduled for delayed destruction
+    if (m_npObjectsToFinalize.isEmpty())
+        return;
+    ASSERT(m_finalizationTimer.isActive());
+    m_finalizationTimer.stop();
+    invalidateQueuedObjects();
+}
+
+JSGlobalObject* NPRuntimeObjectMap::globalObject() const
+{
+    Frame* frame = m_pluginView->frame();
+    if (!frame)
+        return 0;
+
+    return frame->script().globalObject(pluginWorld());
+}
+
+static String& globalExceptionString()
+{
+    static NeverDestroyed<String> exceptionString;
+    return exceptionString;
+}
+
+void NPRuntimeObjectMap::setGlobalException(const String& exceptionString)
+{
+    globalExceptionString() = exceptionString;
+}
+    
+void NPRuntimeObjectMap::moveGlobalExceptionToExecState(JSGlobalObject* lexicalGlobalObject)
+{
+    VM& vm = lexicalGlobalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (globalExceptionString().isNull())
+        return;
+
+    {
+        JSLockHolder lock(vm);
+        throwException(lexicalGlobalObject, scope, createError(lexicalGlobalObject, globalExceptionString()));
+    }
+    
+    globalExceptionString() = String();
+}
+
+void NPRuntimeObjectMap::invalidateQueuedObjects()
+{
+    ASSERT(m_npObjectsToFinalize.size());
+    // We deliberately re-request m_npObjectsToFinalize.size() as custom dealloc
+    // functions may execute JS and so get more objects added to the dealloc queue
+    for (size_t i = 0; i < m_npObjectsToFinalize.size(); ++i)
+        deallocateNPObject(m_npObjectsToFinalize[i]);
+    m_npObjectsToFinalize.clear();
+}
+
+void NPRuntimeObjectMap::addToInvalidationQueue(NPObject* npObject)
+{
+    if (trySafeReleaseNPObject(npObject))
+        return;
+    if (m_npObjectsToFinalize.isEmpty())
+        m_finalizationTimer.startOneShot(0_s);
+    ASSERT(m_finalizationTimer.isActive());
+    m_npObjectsToFinalize.append(npObject);
+}
+
+void NPRuntimeObjectMap::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
+{
+    JSNPObject* object = static_cast<JSNPObject*>(handle.get().asCell());
+    weakRemove(m_jsNPObjects, static_cast<NPObject*>(context), object);
+    addToInvalidationQueue(object->leakNPObject());
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NPJSObjectWrapperMap_h
+#define NPJSObjectWrapperMap_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <JavaScriptCore/Weak.h>
+#include <JavaScriptCore/WeakInlines.h>
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/RunLoop.h>
+
+struct NPObject;
+typedef struct _NPVariant NPVariant;
+
+namespace JSC {
+    class CallFrame;
+    class VM;
+    class JSGlobalObject;
+    class JSObject;
+    class JSValue;
+}
+
+namespace WebKit {
+
+class JSNPObject;
+class NPJSObject;
+class PluginView;
+
+// A per plug-in map of NPObjects that wrap JavaScript objects.
+class NPRuntimeObjectMap : private JSC::WeakHandleOwner {
+public:
+    explicit NPRuntimeObjectMap(PluginView*);
+
+    class PluginProtector {
+    public:
+        explicit PluginProtector(NPRuntimeObjectMap* npRuntimeObjectMap);
+        ~PluginProtector();
+        
+    private:
+        RefPtr<PluginView> m_pluginView;
+    };
+
+    // Returns an NPObject that wraps the given JSObject object. If there is already an NPObject that wraps this JSObject, it will
+    // retain it and return it.
+    NPObject* getOrCreateNPObject(JSC::VM&, JSC::JSObject*);
+    void npJSObjectDestroyed(NPJSObject*);
+
+    // Returns a JSObject object that wraps the given NPObject.
+    JSC::JSObject* getOrCreateJSObject(JSC::JSGlobalObject*, NPObject*);
+    void jsNPObjectDestroyed(JSNPObject*);
+
+    void convertJSValueToNPVariant(JSC::JSGlobalObject*, JSC::JSValue, NPVariant&);
+    JSC::JSValue convertNPVariantToJSValue(JSC::JSGlobalObject*, const NPVariant&);
+
+    bool evaluate(NPObject*, const String& scriptString, NPVariant* result);
+
+    // Called when the plug-in is destroyed. Will invalidate all the NPObjects.
+    void invalidate();
+
+    JSC::JSGlobalObject* globalObject() const;
+
+    static void setGlobalException(const String& exceptionString);
+    static void moveGlobalExceptionToExecState(JSC::JSGlobalObject*);
+
+private:
+    // WeakHandleOwner
+    void finalize(JSC::Handle<JSC::Unknown>, void* context) override;
+    void addToInvalidationQueue(NPObject*);
+    void invalidateQueuedObjects();
+
+    PluginView* m_pluginView;
+    HashMap<JSC::JSObject*, NPJSObject*> m_npJSObjects;
+    HashMap<NPObject*, JSC::Weak<JSNPObject>> m_jsNPObjects;
+    Vector<NPObject*> m_npObjectsToFinalize;
+    RunLoop::Timer<NPRuntimeObjectMap> m_finalizationTimer;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // NPJSObjectWrapperMap_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeUtilities.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeUtilities.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeUtilities.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeUtilities.cpp	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NPRuntimeUtilities.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <string.h>
+#include <wtf/text/CString.h>
+
+namespace WebKit {
+
+void* npnMemAlloc(uint32_t size)
+{
+    // We could use fastMalloc here, but there might be plug-ins that mix NPN_MemAlloc/NPN_MemFree with malloc and free,
+    // so having them be equivalent seems like a good idea.
+    return malloc(size);
+}
+
+void npnMemFree(void* ptr)
+{
+    // We could use fastFree here, but there might be plug-ins that mix NPN_MemAlloc/NPN_MemFree with malloc and free,
+    // so having them be equivalent seems like a good idea.
+    free(ptr);
+}
+
+NPString createNPString(const CString& string)
+{
+    char* utf8Characters = npnMemNewArray<char>(string.length());
+    memcpy(utf8Characters, string.data(), string.length());
+
+    NPString npString;
+    npString.UTF8Characters = utf8Characters;
+    npString.UTF8Length = string.length();
+
+    return npString;
+}
+
+NPObject* createNPObject(NPP npp, NPClass* npClass)
+{
+    ASSERT(npClass);
+    
+    NPObject* npObject;
+    if (npClass->allocate)
+        npObject = npClass->allocate(npp, npClass);
+    else
+        npObject = npnMemNew<NPObject>();
+
+    npObject->_class = npClass;
+    npObject->referenceCount = 1;
+    
+    return npObject;
+}
+
+void deallocateNPObject(NPObject* npObject)
+{
+    ASSERT(npObject);
+    if (!npObject)
+        return;
+
+    if (npObject->_class->deallocate)
+        npObject->_class->deallocate(npObject);
+    else
+        npnMemFree(npObject);
+}
+
+void retainNPObject(NPObject* npObject)
+{
+    ASSERT(npObject);
+    if (!npObject)
+        return;
+
+    npObject->referenceCount++;
+}
+
+bool trySafeReleaseNPObject(NPObject* npObject)
+{
+    ASSERT(npObject);
+    if (!npObject)
+        return true;
+    
+    ASSERT(npObject->referenceCount >= 1);
+
+    npObject->referenceCount--;
+    if (npObject->referenceCount)
+        return true;
+    if (npObject->_class->deallocate)
+        return false;
+    deallocateNPObject(npObject);
+    return true;
+}
+
+void releaseNPObject(NPObject* npObject)
+{
+    ASSERT(npObject);
+    if (!npObject)
+        return;
+    
+    ASSERT(npObject->referenceCount >= 1);
+    npObject->referenceCount--;
+    if (!npObject->referenceCount)
+        deallocateNPObject(npObject);
+}
+
+void releaseNPVariantValue(NPVariant* variant)
+{
+    ASSERT(variant);
+    
+    switch (variant->type) {
+    case NPVariantType_Void:
+    case NPVariantType_Null:
+    case NPVariantType_Bool:
+    case NPVariantType_Int32:
+    case NPVariantType_Double:
+        // Nothing to do.
+        break;
+        
+    case NPVariantType_String:
+        npnMemFree(const_cast<NPUTF8*>(variant->value.stringValue.UTF8Characters));
+        variant->value.stringValue.UTF8Characters = 0;
+        variant->value.stringValue.UTF8Length = 0;
+        break;
+    case NPVariantType_Object:
+        releaseNPObject(variant->value.objectValue);
+        variant->value.objectValue = 0;
+        break;
+    }
+
+    variant->type = NPVariantType_Void;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeUtilities.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeUtilities.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeUtilities.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/NPRuntimeUtilities.h	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NPRuntimeUtilities_h
+#define NPRuntimeUtilities_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <WebCore/npruntime_internal.h>
+#include <wtf/Forward.h>
+
+struct NPClass;
+struct NPObject;
+
+namespace WebKit {
+
+void* npnMemAlloc(uint32_t);
+void npnMemFree(void*);
+
+template<typename T> T* npnMemNew()
+{
+    return static_cast<T*>(npnMemAlloc(sizeof(T)));
+}
+
+template<typename T> T* npnMemNewArray(size_t count)
+{
+    return static_cast<T*>(npnMemAlloc(sizeof(T) * count));
+}
+
+NPString createNPString(const CString&);
+
+NPObject* createNPObject(NPP, NPClass*);
+void deallocateNPObject(NPObject*);
+
+void retainNPObject(NPObject*);
+void releaseNPObject(NPObject*);
+    
+// This function decrements the refcount of the specified object. If the
+// refcount reaches 0 it will attempt to destroy the object. If the object has
+// a custom deallocate function it will fail and return false, so it will be
+// up to the caller to call deallocateNPObject.
+// This function is used to implement the delayed finalization of NPObjects
+// released during GC.
+bool trySafeReleaseNPObject(NPObject*);
+
+void releaseNPVariantValue(NPVariant*);
+
+}
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // NPRuntimeUtilities_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.cpp	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NetscapePluginUnix.h"
+
+#if PLUGIN_ARCHITECTURE(UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NetscapePlugin.h"
+#include "WebEvent.h"
+#include "WebMouseEvent.h"
+#include "WebWheelEvent.h"
+#include <WebCore/NotImplemented.h>
+#include <WebCore/PlatformDisplay.h>
+
+#if PLATFORM(X11)
+#include "NetscapePluginX11.h"
+#endif
+
+namespace WebKit {
+using namespace WebCore;
+
+void NetscapePlugin::platformPreInitialize()
+{
+}
+
+bool NetscapePlugin::platformPostInitialize()
+{
+#if PLATFORM(X11)
+    if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) {
+        m_impl = NetscapePluginX11::create(*this);
+        if (!m_impl)
+            return false;
+    }
+#endif
+
+    // Windowed plugins need a platform implementation.
+    if (!m_impl)
+        return !m_isWindowed;
+
+    m_npWindow.type = m_impl->windowType();
+    m_npWindow.window = m_impl->window();
+    m_npWindow.ws_info = m_impl->windowSystemInfo();
+    callSetWindow();
+    return true;
+}
+
+void NetscapePlugin::platformDestroy()
+{
+    m_impl = nullptr;
+}
+
+bool NetscapePlugin::platformInvalidate(const IntRect&)
+{
+    notImplemented();
+    return false;
+}
+
+void NetscapePlugin::platformGeometryDidChange()
+{
+    if (!m_impl)
+        return;
+    m_impl->geometryDidChange();
+}
+
+void NetscapePlugin::platformVisibilityDidChange()
+{
+    if (!m_isWindowed || !m_impl)
+        return;
+
+    m_impl->visibilityDidChange();
+}
+
+void NetscapePlugin::platformPaint(GraphicsContext& context, const IntRect& dirtyRect, bool /*isSnapshot*/)
+{
+    if (m_isWindowed || !m_impl)
+        return;
+
+    if (!m_isStarted) {
+        // FIXME: we should paint a missing plugin icon.
+        return;
+    }
+
+    m_impl->paint(context, dirtyRect);
+}
+
+bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event)
+{
+    if (m_isWindowed || !m_impl)
+        return false;
+
+#if PLATFORM(X11)
+    if ((event.type() == WebEvent::MouseDown || event.type() == WebEvent::MouseUp)
+        && event.button() == WebMouseEvent::RightButton
+        && quirks().contains(PluginQuirks::IgnoreRightClickInWindowlessMode))
+        return false;
+#endif
+
+    return m_impl->handleMouseEvent(event);
+}
+
+bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent& event)
+{
+    if (m_isWindowed || !m_impl)
+        return false;
+
+    return m_impl->handleWheelEvent(event);
+}
+
+void NetscapePlugin::platformSetFocus(bool focusIn)
+{
+    if (m_isWindowed || !m_impl)
+        return;
+
+    m_impl->setFocus(focusIn);
+}
+
+bool NetscapePlugin::wantsPluginRelativeNPWindowCoordinates()
+{
+    return true;
+}
+
+bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& event)
+{
+    if (m_isWindowed || !m_impl)
+        return false;
+
+    return m_impl->handleMouseEnterEvent(event);
+}
+
+bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& event)
+{
+    if (m_isWindowed || !m_impl)
+        return false;
+
+    return m_impl->handleMouseLeaveEvent(event);
+}
+
+bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& event)
+{
+    // We don't generate other types of keyboard events via WebEventFactory.
+    ASSERT(event.type() == WebEvent::KeyDown || event.type() == WebEvent::KeyUp);
+
+    if (m_isWindowed || !m_impl)
+        return false;
+
+    return m_impl->handleKeyboardEvent(event);
+}
+
+} // namespace WebKit
+
+#endif // PLUGIN_ARCHITECTURE(UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.h	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NetscapePluginUnix_h
+#define NetscapePluginUnix_h
+
+#if PLUGIN_ARCHITECTURE(UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
+
+#include <WebCore/npruntime_internal.h>
+
+namespace WebCore {
+class GraphicsContext;
+class IntRect;
+}
+
+namespace WebKit {
+
+class WebKeyboardEvent;
+class WebMouseEvent;
+class WebWheelEvent;
+
+class NetscapePluginUnix {
+public:
+    virtual ~NetscapePluginUnix() { }
+    virtual NPWindowType windowType() const = 0;
+    virtual void* window() const = 0;
+    virtual NPSetWindowCallbackStruct* windowSystemInfo() = 0;
+    virtual void geometryDidChange() = 0;
+    virtual void visibilityDidChange() = 0;
+    virtual void paint(WebCore::GraphicsContext&, const WebCore::IntRect&) = 0;
+    virtual bool handleMouseEvent(const WebMouseEvent&) = 0;
+    virtual bool handleWheelEvent(const WebWheelEvent&) = 0;
+    virtual bool handleMouseEnterEvent(const WebMouseEvent&) = 0;
+    virtual bool handleMouseLeaveEvent(const WebMouseEvent&) = 0;
+    virtual bool handleKeyboardEvent(const WebKeyboardEvent&) = 0;
+    virtual void setFocus(bool) = 0;
+};
+
+} // namespace WebKit
+
+#endif // PLUGIN_ARCHITECTURE(UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // NetscapePluginUnix_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/unix/PluginProxyUnix.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/unix/PluginProxyUnix.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/unix/PluginProxyUnix.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/unix/PluginProxyUnix.cpp	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginProxy.h"
+
+#if ENABLE(PLUGIN_PROCESS)
+
+#include <WebCore/NotImplemented.h>
+
+namespace WebKit {
+
+bool PluginProxy::needsBackingStore() const
+{
+    notImplemented();
+    return true;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(PLUGIN_PROCESS)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,542 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 University of Szeged
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NetscapePluginX11.h"
+
+#if PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NetscapePlugin.h"
+#include "PluginController.h"
+#include "WebEvent.h"
+#include "WebMouseEvent.h"
+#include "WebWheelEvent.h"
+#include "WebKeyboardEvent.h"
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/NotImplemented.h>
+#include <WebCore/PlatformDisplayX11.h>
+#include <WebCore/XUniquePtr.h>
+
+#if PLATFORM(GTK)
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+#include <gtk/gtkx.h>
+#endif
+
+#if USE(CAIRO)
+#include <WebCore/GraphicsContextCairo.h>
+#include <WebCore/RefPtrCairo.h>
+#include <cairo/cairo-xlib.h>
+#endif
+
+namespace WebKit {
+using namespace WebCore;
+
+static inline Display* x11HostDisplay()
+{
+    return downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native();
+}
+
+static Display* getPluginDisplay()
+{
+#if PLATFORM(GTK)
+    // Since we're a gdk/gtk app, we'll (probably?) have the same X connection as any gdk-based
+    // plugins, so we can return that. We might want to add other implementations here later.
+    return gdk_x11_get_default_xdisplay();
+#else
+    return nullptr;
+#endif
+}
+
+static inline int x11Screen()
+{
+#if PLATFORM(GTK)
+    return gdk_x11_screen_get_screen_number(gdk_screen_get_default());
+#else
+    return 0;
+#endif
+}
+
+static inline int displayDepth()
+{
+#if PLATFORM(GTK)
+    return gdk_visual_get_depth(gdk_screen_get_system_visual(gdk_screen_get_default()));
+#else
+    return 0;
+#endif
+}
+
+static inline unsigned long rootWindowID()
+{
+#if PLATFORM(GTK)
+    return GDK_ROOT_WINDOW();
+#else
+    return 0;
+#endif
+}
+
+#if PLATFORM(GTK)
+static gboolean socketPlugRemovedCallback(GtkSocket*)
+{
+    // Default action is to destroy the GtkSocket, so we just return TRUE here
+    // to be able to reuse the socket. For some obscure reason, newer versions
+    // of flash plugin remove the plug from the socket, probably because the plug
+    // created by the plugin is re-parented.
+    return TRUE;
+}
+#endif
+
+std::unique_ptr<NetscapePluginX11> NetscapePluginX11::create(NetscapePlugin& plugin)
+{
+#if PLATFORM(GTK)
+    uint64_t windowID = 0;
+#endif
+    if (plugin.isWindowed()) {
+#if PLATFORM(GTK)
+        // NPPVplugiNeedsXEmbed is a boolean value, but at least the
+        // Flash player plugin is using an 'int' instead.
+        int needsXEmbed = 0;
+        plugin.NPP_GetValue(NPPVpluginNeedsXEmbed, &needsXEmbed);
+        if (needsXEmbed) {
+            windowID = plugin.controller()->createPluginContainer();
+            if (!windowID)
+                return nullptr;
+        } else {
+            notImplemented();
+            return nullptr;
+        }
+#else
+        notImplemented();
+        return nullptr;
+#endif
+    }
+
+    Display* display = getPluginDisplay();
+    if (!display)
+        return nullptr;
+
+#if PLATFORM(GTK)
+    if (plugin.isWindowed())
+        return makeUnique<NetscapePluginX11>(plugin, display, windowID);
+#endif
+
+    return makeUnique<NetscapePluginX11>(plugin, display);
+}
+
+NetscapePluginX11::NetscapePluginX11(NetscapePlugin& plugin, Display* display)
+    : m_plugin(plugin)
+    , m_pluginDisplay(display)
+{
+    Display* hostDisplay = x11HostDisplay();
+    int depth = displayDepth();
+    m_setWindowCallbackStruct.display = hostDisplay;
+    m_setWindowCallbackStruct.depth = depth;
+
+    XVisualInfo visualTemplate;
+    visualTemplate.screen = x11Screen();
+    visualTemplate.depth = depth;
+    visualTemplate.c_class = TrueColor;
+    int numMatching;
+    XUniquePtr<XVisualInfo> visualInfo(XGetVisualInfo(hostDisplay, VisualScreenMask | VisualDepthMask | VisualClassMask, &visualTemplate, &numMatching));
+    ASSERT(visualInfo);
+    Visual* visual = visualInfo.get()[0].visual;
+    ASSERT(visual);
+
+    m_setWindowCallbackStruct.type = NP_SETWINDOW;
+    m_setWindowCallbackStruct.visual = visual;
+    m_setWindowCallbackStruct.colormap = XCreateColormap(hostDisplay, rootWindowID(), visual, AllocNone);
+}
+
+#if PLATFORM(GTK)
+NetscapePluginX11::NetscapePluginX11(NetscapePlugin& plugin, Display* display, uint64_t windowID)
+    : m_plugin(plugin)
+    , m_pluginDisplay(display)
+{
+    // It seems flash needs the socket to be in the same process,
+    // I guess it uses gdk_window_lookup(), so we create a new socket here
+    // containing a plug with the UI process socket embedded.
+    m_platformPluginWidget = gtk_plug_new(static_cast<Window>(windowID));
+
+    // Hide the GtkPlug on delete-event since we assume the widget is valid while the plugin is active.
+    // platformDestroy() will be called anyway right after the delete-event.
+    g_signal_connect(m_platformPluginWidget, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), nullptr);
+
+    GtkWidget* socket = gtk_socket_new();
+    // Do not show the plug widget until the socket is connected.
+    g_signal_connect_swapped(socket, "plug-added", G_CALLBACK(gtk_widget_show), m_platformPluginWidget);
+    g_signal_connect(socket, "plug-removed", G_CALLBACK(socketPlugRemovedCallback), nullptr);
+    gtk_container_add(GTK_CONTAINER(m_platformPluginWidget), socket);
+    gtk_widget_show(socket);
+
+    Display* hostDisplay = x11HostDisplay();
+    m_npWindowID = gtk_socket_get_id(GTK_SOCKET(socket));
+    GdkWindow* window = gtk_widget_get_window(socket);
+    m_setWindowCallbackStruct.type = NP_SETWINDOW;
+    m_setWindowCallbackStruct.display = GDK_WINDOW_XDISPLAY(window);
+    m_setWindowCallbackStruct.visual = GDK_VISUAL_XVISUAL(gdk_window_get_visual(window));
+    m_setWindowCallbackStruct.depth = gdk_visual_get_depth(gdk_window_get_visual(window));
+    m_setWindowCallbackStruct.colormap = XCreateColormap(hostDisplay, GDK_ROOT_WINDOW(), m_setWindowCallbackStruct.visual, AllocNone);
+
+    XFlush(hostDisplay);
+}
+#endif
+
+NetscapePluginX11::~NetscapePluginX11()
+{
+    XFreeColormap(x11HostDisplay(), m_setWindowCallbackStruct.colormap);
+
+    m_drawable.reset();
+
+#if PLATFORM(GTK)
+    if (m_platformPluginWidget)
+        gtk_widget_destroy(m_platformPluginWidget);
+#endif
+}
+
+NPWindowType NetscapePluginX11::windowType() const
+{
+    return m_plugin.isWindowed() ? NPWindowTypeWindow : NPWindowTypeDrawable;
+}
+
+void* NetscapePluginX11::window() const
+{
+#if PLATFORM(GTK)
+    return m_plugin.isWindowed() ? GINT_TO_POINTER(m_npWindowID) : nullptr;
+#else
+    return nullptr;
+#endif
+}
+
+void NetscapePluginX11::geometryDidChange()
+{
+    if (m_plugin.isWindowed()) {
+        uint64_t windowID = 0;
+#if PLATFORM(GTK)
+        if (!gtk_plug_get_embedded(GTK_PLUG(m_platformPluginWidget)))
+            return;
+        windowID = static_cast<uint64_t>(GDK_WINDOW_XID(gtk_plug_get_socket_window(GTK_PLUG(m_platformPluginWidget))));
+#endif
+        m_plugin.controller()->windowedPluginGeometryDidChange(m_plugin.frameRectInWindowCoordinates(), m_plugin.clipRect(), windowID);
+        return;
+    }
+
+    m_drawable.reset();
+    if (m_plugin.size().isEmpty())
+        return;
+
+    m_drawable = XCreatePixmap(x11HostDisplay(), rootWindowID(), m_plugin.size().width(), m_plugin.size().height(), displayDepth());
+    XSync(x11HostDisplay(), false); // Make sure that the server knows about the Drawable.
+}
+
+void NetscapePluginX11::visibilityDidChange()
+{
+    ASSERT(m_plugin.isWindowed());
+    uint64_t windowID = 0;
+#if PLATFORM(GTK)
+    if (!gtk_plug_get_embedded(GTK_PLUG(m_platformPluginWidget)))
+        return;
+    windowID = static_cast<uint64_t>(GDK_WINDOW_XID(gtk_plug_get_socket_window(GTK_PLUG(m_platformPluginWidget))));
+#endif
+    m_plugin.controller()->windowedPluginVisibilityDidChange(m_plugin.isVisible(), windowID);
+    m_plugin.controller()->windowedPluginGeometryDidChange(m_plugin.frameRectInWindowCoordinates(), m_plugin.clipRect(), windowID);
+}
+
+void NetscapePluginX11::paint(GraphicsContext& context, const IntRect& dirtyRect)
+{
+    ASSERT(!m_plugin.isWindowed());
+
+    if (context.paintingDisabled() || !m_drawable)
+        return;
+
+    XEvent xevent;
+    memset(&xevent, 0, sizeof(XEvent));
+    XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose;
+    exposeEvent.type = GraphicsExpose;
+    exposeEvent.display = x11HostDisplay();
+    exposeEvent.drawable = m_drawable.get();
+
+    IntRect exposedRect(dirtyRect);
+    exposeEvent.x = exposedRect.x();
+    exposeEvent.y = exposedRect.y();
+
+    // Note: in transparent mode Flash thinks width is the right and height is the bottom.
+    // We should take it into account if we want to support transparency.
+    exposeEvent.width = exposedRect.width();
+    exposeEvent.height = exposedRect.height();
+
+    m_plugin.NPP_HandleEvent(&xevent);
+
+    if (m_pluginDisplay != x11HostDisplay())
+        XSync(m_pluginDisplay, false);
+
+#if PLATFORM(GTK)
+    RefPtr<cairo_surface_t> drawableSurface = adoptRef(cairo_xlib_surface_create(m_pluginDisplay, m_drawable.get(),
+        m_setWindowCallbackStruct.visual, m_plugin.size().width(), m_plugin.size().height()));
+    cairo_t* cr = context.platformContext()->cr();
+    cairo_save(cr);
+
+    cairo_set_source_surface(cr, drawableSurface.get(), 0, 0);
+
+    cairo_rectangle(cr, exposedRect.x(), exposedRect.y(), exposedRect.width(), exposedRect.height());
+    cairo_clip(cr);
+    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+    cairo_paint(cr);
+
+    cairo_restore(cr);
+#else
+    notImplemented();
+#endif
+}
+
+static inline void initializeXEvent(XEvent& event)
+{
+    memset(&event, 0, sizeof(XEvent));
+    event.xany.serial = 0;
+    event.xany.send_event = false;
+    event.xany.display = x11HostDisplay();
+    event.xany.window = 0;
+}
+
+static inline uint64_t xTimeStamp(WallTime timestamp)
+{
+    return timestamp.secondsSinceEpoch().milliseconds();
+}
+
+static inline unsigned xKeyModifiers(const WebEvent& event)
+{
+    unsigned xModifiers = 0;
+    if (event.controlKey())
+        xModifiers |= ControlMask;
+    if (event.shiftKey())
+        xModifiers |= ShiftMask;
+    if (event.altKey())
+        xModifiers |= Mod1Mask;
+    if (event.metaKey())
+        xModifiers |= Mod4Mask;
+
+    return xModifiers;
+}
+
+template <typename XEventType, typename WebEventType>
+static inline void setCommonMouseEventFields(XEventType& xEvent, const WebEventType& webEvent, const WebCore::IntPoint& pluginLocation)
+{
+    xEvent.root = rootWindowID();
+    xEvent.subwindow = 0;
+    xEvent.time = xTimeStamp(webEvent.timestamp());
+    xEvent.x = webEvent.position().x() - pluginLocation.x();
+    xEvent.y = webEvent.position().y() - pluginLocation.y();
+    xEvent.x_root = webEvent.globalPosition().x();
+    xEvent.y_root = webEvent.globalPosition().y();
+    xEvent.state = xKeyModifiers(webEvent);
+    xEvent.same_screen = true;
+}
+
+static inline void setXMotionEventFields(XEvent& xEvent, const WebMouseEvent& webEvent, const WebCore::IntPoint& pluginLocation)
+{
+    XMotionEvent& xMotion = xEvent.xmotion;
+    setCommonMouseEventFields(xMotion, webEvent, pluginLocation);
+    xMotion.type = MotionNotify;
+}
+
+static inline void setXButtonEventFields(XEvent& xEvent, const WebMouseEvent& webEvent, const WebCore::IntPoint& pluginLocation)
+{
+    XButtonEvent& xButton = xEvent.xbutton;
+    setCommonMouseEventFields(xButton, webEvent, pluginLocation);
+
+    xButton.type = (webEvent.type() == WebEvent::MouseDown) ? ButtonPress : ButtonRelease;
+    switch (webEvent.button()) {
+    case WebMouseEvent::LeftButton:
+        xButton.button = Button1;
+        break;
+    case WebMouseEvent::MiddleButton:
+        xButton.button = Button2;
+        break;
+    case WebMouseEvent::RightButton:
+        xButton.button = Button3;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+}
+
+static inline void setXButtonEventFieldsByWebWheelEvent(XEvent& xEvent, const WebWheelEvent& webEvent, const WebCore::IntPoint& pluginLocation)
+{
+    XButtonEvent& xButton = xEvent.xbutton;
+    setCommonMouseEventFields(xButton, webEvent, pluginLocation);
+
+    xButton.type = ButtonPress;
+    FloatSize ticks = webEvent.wheelTicks();
+    if (ticks.height()) {
+        if (ticks.height() > 0)
+            xButton.button = 4; // up
+        else
+            xButton.button = 5; // down
+    } else {
+        if (ticks.width() > 0)
+            xButton.button = 6; // left
+        else
+            xButton.button = 7; // right
+    }
+}
+
+static inline void setXCrossingEventFields(XEvent& xEvent, const WebMouseEvent& webEvent, const WebCore::IntPoint& pluginLocation, int type)
+{
+    XCrossingEvent& xCrossing = xEvent.xcrossing;
+    setCommonMouseEventFields(xCrossing, webEvent, pluginLocation);
+
+    xCrossing.type = type;
+    xCrossing.mode = NotifyNormal;
+    xCrossing.detail = NotifyDetailNone;
+    xCrossing.focus = false;
+}
+
+bool NetscapePluginX11::handleMouseEvent(const WebMouseEvent& event)
+{
+    ASSERT(!m_plugin.isWindowed());
+
+    XEvent xEvent;
+    initializeXEvent(xEvent);
+
+    switch (event.type()) {
+    case WebEvent::MouseDown:
+    case WebEvent::MouseUp:
+        setXButtonEventFields(xEvent, event, m_plugin.convertToRootView(IntPoint()));
+        break;
+    case WebEvent::MouseMove:
+        setXMotionEventFields(xEvent, event, m_plugin.convertToRootView(IntPoint()));
+        break;
+    case WebEvent::MouseForceChanged:
+    case WebEvent::MouseForceDown:
+    case WebEvent::MouseForceUp:
+    case WebEvent::NoType:
+    case WebEvent::Wheel:
+    case WebEvent::KeyDown:
+    case WebEvent::KeyUp:
+    case WebEvent::RawKeyDown:
+    case WebEvent::Char:
+#if ENABLE(TOUCH_EVENTS)
+    case WebEvent::TouchStart:
+    case WebEvent::TouchMove:
+    case WebEvent::TouchEnd:
+    case WebEvent::TouchCancel:
+#endif
+        return false;
+    }
+
+    return !m_plugin.NPP_HandleEvent(&xEvent);
+}
+
+// We undefine these constants in npruntime_internal.h to avoid collision
+// with WebKit and platform headers. Values are defined in X.h.
+const int kKeyPressType = 2;
+const int kKeyReleaseType = 3;
+const int kFocusInType = 9;
+const int kFocusOutType = 10;
+
+bool NetscapePluginX11::handleWheelEvent(const WebWheelEvent& event)
+{
+    ASSERT(!m_plugin.isWindowed());
+
+    XEvent xEvent;
+    initializeXEvent(xEvent);
+    setXButtonEventFieldsByWebWheelEvent(xEvent, event, m_plugin.convertToRootView(IntPoint()));
+
+    return !m_plugin.NPP_HandleEvent(&xEvent);
+}
+
+void NetscapePluginX11::setFocus(bool focusIn)
+{
+    ASSERT(!m_plugin.isWindowed());
+
+    XEvent xEvent;
+    initializeXEvent(xEvent);
+    XFocusChangeEvent& focusEvent = xEvent.xfocus;
+    focusEvent.type = focusIn ? kFocusInType : kFocusOutType;
+    focusEvent.mode = NotifyNormal;
+    focusEvent.detail = NotifyDetailNone;
+
+    m_plugin.NPP_HandleEvent(&xEvent);
+}
+
+bool NetscapePluginX11::handleMouseEnterEvent(const WebMouseEvent& event)
+{
+    ASSERT(!m_plugin.isWindowed());
+
+    XEvent xEvent;
+    initializeXEvent(xEvent);
+    setXCrossingEventFields(xEvent, event, m_plugin.convertToRootView(IntPoint()), EnterNotify);
+
+    return !m_plugin.NPP_HandleEvent(&xEvent);
+}
+
+bool NetscapePluginX11::handleMouseLeaveEvent(const WebMouseEvent& event)
+{
+    ASSERT(!m_plugin.isWindowed());
+
+    XEvent xEvent;
+    initializeXEvent(xEvent);
+    setXCrossingEventFields(xEvent, event, m_plugin.convertToRootView(IntPoint()), LeaveNotify);
+
+    return !m_plugin.NPP_HandleEvent(&xEvent);
+}
+
+static inline void setXKeyEventFields(XEvent& xEvent, const WebKeyboardEvent& webEvent)
+{
+    xEvent.xany.type = (webEvent.type() == WebEvent::KeyDown) ? kKeyPressType : kKeyReleaseType;
+    XKeyEvent& xKey = xEvent.xkey;
+    xKey.root = rootWindowID();
+    xKey.subwindow = 0;
+    xKey.time = xTimeStamp(webEvent.timestamp());
+    xKey.state = xKeyModifiers(webEvent);
+    xKey.keycode = webEvent.nativeVirtualKeyCode();
+
+    xKey.same_screen = true;
+
+    // Key events propagated to the plugin does not need to have position.
+    // source: https://developer.mozilla.org/en/NPEvent
+    xKey.x = 0;
+    xKey.y = 0;
+    xKey.x_root = 0;
+    xKey.y_root = 0;
+}
+
+bool NetscapePluginX11::handleKeyboardEvent(const WebKeyboardEvent& event)
+{
+    ASSERT(!m_plugin.isWindowed());
+    // We don't generate other types of keyboard events via WebEventFactory.
+    ASSERT(event.type() == WebEvent::KeyDown || event.type() == WebEvent::KeyUp);
+
+    XEvent xEvent;
+    initializeXEvent(xEvent);
+    setXKeyEventFields(xEvent, event);
+
+    return !m_plugin.NPP_HandleEvent(&xEvent);
+}
+
+} // namespace WebKit
+
+#endif // PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.h	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 University of Szeged
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NetscapePluginX11_h
+#define NetscapePluginX11_h
+
+#if PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NetscapePluginUnix.h"
+#include <WebCore/XUniqueResource.h>
+
+namespace WebKit {
+
+class NetscapePlugin;
+
+class NetscapePluginX11 final : public NetscapePluginUnix {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static std::unique_ptr<NetscapePluginX11> create(NetscapePlugin&);
+    NetscapePluginX11(NetscapePlugin&, Display*);
+#if PLATFORM(GTK)
+    NetscapePluginX11(NetscapePlugin&, Display*, uint64_t windowID);
+#endif
+    virtual ~NetscapePluginX11();
+
+private:
+    NPWindowType windowType() const override;
+    void* window() const override;
+    NPSetWindowCallbackStruct* windowSystemInfo() override { return &m_setWindowCallbackStruct; }
+    void geometryDidChange() override;
+    void visibilityDidChange() override;
+    void paint(WebCore::GraphicsContext&, const WebCore::IntRect&) override;
+    bool handleMouseEvent(const WebMouseEvent&) override;
+    bool handleWheelEvent(const WebWheelEvent&) override;
+    bool handleMouseEnterEvent(const WebMouseEvent&) override;
+    bool handleMouseLeaveEvent(const WebMouseEvent&) override;
+    bool handleKeyboardEvent(const WebKeyboardEvent&) override;
+    void setFocus(bool) override;
+
+    NetscapePlugin& m_plugin;
+    Display* m_pluginDisplay { nullptr };
+    WebCore::XUniquePixmap m_drawable;
+    NPSetWindowCallbackStruct m_setWindowCallbackStruct;
+#if PLATFORM(GTK)
+    unsigned long m_npWindowID { 0 };
+    GtkWidget* m_platformPluginWidget { nullptr };
+#endif
+};
+} // namespace WebKit
+
+#endif // PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // NetscapePluginX11_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h	2022-03-22 16:38:57.397580237 -0500
@@ -195,14 +195,18 @@ private:
     bool handlesPageScaleFactor() const final;
     bool requiresUnifiedScaleFactor() const final { return true; }
     void setFocus(bool) final { }
+    NPObject* pluginScriptableNPObject() final { return nullptr; }
     void windowFocusChanged(bool) final { }
     void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) final { }
     void windowVisibilityChanged(bool) final { }
+    uint64_t pluginComplexTextInputIdentifier() const final { return 0; }
     void sendComplexTextInput(const String& textInput) final { }
     void setLayerHostingMode(LayerHostingMode) final { }
     WebCore::Scrollbar* horizontalScrollbar() final { return m_horizontalScrollbar.get(); }
     WebCore::Scrollbar* verticalScrollbar() final { return m_verticalScrollbar.get(); }
     void storageBlockingStateChanged(bool) final { }
+    void privateBrowsingStateChanged(bool) final { }
+    bool getFormValue(String& formValue) final { return false; }
     bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) final;
     RefPtr<WebCore::FragmentedSharedBuffer> liveResourceData() const final;
     void willDetachRenderer() final;
@@ -221,6 +225,7 @@ private:
 
     bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) final;
     String getSelectionString() const final;
+    String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const final;
     bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const final;
 
     bool shouldAllowScripting() final { return false; }
@@ -429,7 +434,7 @@ private:
 } // namespace WebKit
 
 SPECIALIZE_TYPE_TRAITS_BEGIN(WebKit::PDFPlugin)
-    static bool isType(const WebKit::Plugin&) { return true; } // FIXME: Consolidate PDFPlugin and Plugin into one class.
+    static bool isType(const WebKit::Plugin& plugin) { return plugin.isPDFPlugin(); }
     static bool isType(const WebCore::ScrollableArea& area) { return area.isPDFPlugin(); }
 SPECIALIZE_TYPE_TRAITS_END()
 
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginController.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginController.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginController.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginController.h	2022-03-22 16:38:57.397580237 -0500
@@ -28,6 +28,18 @@
 #include <wtf/Forward.h>
 #include <wtf/WeakPtr.h>
 
+#if PLATFORM(COCOA)
+#include "PluginComplexTextInputState.h"
+#endif
+
+struct NPObject;
+typedef struct _NPVariant NPVariant;
+typedef void* NPIdentifier;
+
+namespace WTF {
+class MachSendRight;
+}
+
 namespace WebCore {
 class HTTPHeaderMap;
 class IntRect;
@@ -38,6 +50,12 @@ namespace WebKit {
 
 class PluginController : public CanMakeWeakPtr<PluginController> {
 public:
+    // Tells the controller that the plug-in wants the given rect to be repainted. The rect is in the plug-in's coordinate system.
+    virtual void invalidate(const WebCore::IntRect&) = 0;
+
+    // Returns the user agent string.
+    virtual String userAgent() = 0;
+
     // Loads the given URL and associates it with the request ID.
     // 
     // If a target is specified, then the URL will be loaded in the window or frame that the target refers to.
@@ -48,12 +66,117 @@ public:
     virtual void loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, 
                          const WebCore::HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups) = 0;
 
+    // Continues the load of a stream that was requested by loadURL.
+    virtual void continueStreamLoad(uint64_t streamID) = 0;
+
+    // Cancels the load of a stream that was requested by loadURL.
+    virtual void cancelStreamLoad(uint64_t streamID) = 0;
+
+    // Cancels the load of the manual stream.
+    virtual void cancelManualStreamLoad() = 0;
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    // Get the NPObject that corresponds to the window JavaScript object. Returns a retained object.
+    virtual NPObject* windowScriptNPObject() = 0;
+
+    // Get the NPObject that corresponds to the plug-in's element. Returns a retained object.
+    virtual NPObject* pluginElementNPObject() = 0;
+
+    // Evaluates the given script string in the context of the given NPObject.
+    virtual bool evaluate(NPObject*, const String& scriptString, NPVariant* result, bool allowPopups) = 0;
+
+    // Called by the Netscape plug-in when it starts or stops playing audio.
+    virtual void setPluginIsPlayingAudio(bool) = 0;
+
+    // Returns whether the plugin should be muted.
+    virtual bool isMuted() const = 0;
+#endif
+
+    // Set the statusbar text.
+    virtual void setStatusbarText(const String&) = 0;
+
+    // Return whether accelerated compositing is enabled.
+    virtual bool isAcceleratedCompositingEnabled() = 0;
+
+    // Tells the controller that the plug-in process has crashed.
+    virtual void pluginProcessCrashed() = 0;
+
+#if PLATFORM(COCOA)
+    // Tells the controller that the plug-in focus or window focus did change.
+    virtual void pluginFocusOrWindowFocusChanged(bool) = 0;
+
+    // Tells the controller that complex text input be enabled or disabled for the plug-in.
+    virtual void setComplexTextInputState(PluginComplexTextInputState) = 0;
+
+    // Returns the mach port of the compositing render server.
+    virtual const WTF::MachSendRight& compositingRenderServerPort() = 0;
+#endif
+
     // Returns the contents scale factor.
     virtual float contentsScaleFactor() = 0;
 
+    // Returns the proxies for the given URL or null on failure.
+    virtual String proxiesForURL(const String&) = 0;
+
+    // Returns the cookies for the given URL or null on failure.
+    virtual String cookiesForURL(const String&) = 0;
+
+    // Sets the cookies for the given URL.
+    virtual void setCookiesForURL(const String& urlString, const String& cookieString) = 0;
+
+    // Get authentication credentials for the given protection space.
+    virtual bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password) = 0;
+
+    // Returns whether private browsing is enabled.
+    virtual bool isPrivateBrowsingEnabled() = 0;
+    
+    // Returns whether or not asynchronous plugin initialization is enabled.
+    virtual bool asynchronousPluginInitializationEnabled() const { return false; }
+    
+    // Returns whether or not asynchronous plugin initialization should be attempted for all plugins.
+    virtual bool asynchronousPluginInitializationEnabledForAllPlugins() const { return false; }
+    
+    // Returns the articifical plugin delay to use for testing of asynchronous plugin initialization.
+    virtual bool artificialPluginInitializationDelayEnabled() const { return false; }
+
+    // Increments a counter that prevents the plug-in from being destroyed.
+    virtual void protectPluginFromDestruction() = 0;
+
+    // Decrements a counter that, when it reaches 0, stops preventing the plug-in from being destroyed.
+    virtual void unprotectPluginFromDestruction() = 0;
+
+#if PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
+    // Create a plugin container for windowed plugins
+    virtual uint64_t createPluginContainer() = 0;
+    virtual void windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID) = 0;
+    virtual void windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID) = 0;
+#endif
+
     // Called when the a plug-in instance is successfully initialized, either synchronously or asynchronously.
     virtual void didInitializePlugin() = 0;
     
+    // Called when the a plug-in instance fails to initialized, either synchronously or asynchronously.
+    virtual void didFailToInitializePlugin() = 0;
+
+    // Helper class for delaying destruction of a plug-in.
+    class PluginDestructionProtector {
+        WTF_MAKE_FAST_ALLOCATED;
+    public:
+        explicit PluginDestructionProtector(PluginController* pluginController)
+            : m_pluginController(pluginController)
+        {
+            m_pluginController->protectPluginFromDestruction();
+        }
+        
+        ~PluginDestructionProtector()
+        {
+            m_pluginController->unprotectPluginFromDestruction();
+        }
+        
+    private:
+        PluginController* m_pluginController;
+    };
+    
 protected:
     virtual ~PluginController() { }
 };
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Plugin.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Plugin.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Plugin.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Plugin.cpp	2022-03-22 16:38:57.397580237 -0500
@@ -79,7 +79,11 @@ bool Plugin::Parameters::decode(IPC::Dec
     return true;
 }
 
-Plugin::Plugin() = default;
+Plugin::Plugin(PluginType type)
+    : m_type(type)
+{
+}
+
 Plugin::~Plugin() = default;
 
 bool Plugin::initialize(PluginController& pluginController, const Parameters& parameters)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Plugin.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Plugin.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/Plugin.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/Plugin.h	2022-03-22 16:38:57.397580237 -0500
@@ -44,6 +44,8 @@ OBJC_CLASS PDFDocument;
 OBJC_CLASS PDFSelection;
 #endif
 
+struct NPObject;
+
 namespace IPC {
 class Encoder;
 class Decoder;
@@ -72,6 +74,12 @@ class WebWheelEvent;
     
 class PluginController;
 
+enum PluginType {
+    PluginProxyType,
+    NetscapePluginType,
+    PDFPluginType,
+};
+
 enum class LayerHostingMode : uint8_t;
 
 class Plugin : public ThreadSafeRefCounted<Plugin> {
@@ -102,6 +110,12 @@ public:
 
     virtual ~Plugin();
 
+    PluginType type() const { return m_type; }
+
+    bool isPluginProxy() const { return m_type == PluginProxyType; }
+    bool isNetscapePlugin() const { return m_type == NetscapePluginType; }
+    bool isPDFPlugin() const { return m_type == PDFPluginType; }
+
 private:
     // Initializes the plug-in. If the plug-in fails to initialize this should return false.
     // This is only called by the other initialize overload so it can be made private.
@@ -218,6 +232,9 @@ public:
     // Tells the plug-in about focus changes.
     virtual void setFocus(bool) = 0;
 
+    // Get the NPObject that corresponds to the plug-in's scriptable object. Returns a retained object.
+    virtual NPObject* pluginScriptableNPObject() = 0;
+
     // Tells the plug-in about window focus changes.
     virtual void windowFocusChanged(bool) = 0;
     
@@ -228,6 +245,9 @@ public:
     // Tells the plug-in about window and plug-in frame changes.
     virtual void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) = 0;
 
+    // Get the per complex text input identifier.
+    virtual uint64_t pluginComplexTextInputIdentifier() const = 0;
+
     // Send the complex text input to the plug-in.
     virtual void sendComplexTextInput(const String& textInput) = 0;
 
@@ -241,6 +261,12 @@ public:
     // Called when the storage blocking policy for this plug-in changes.
     virtual void storageBlockingStateChanged(bool) = 0;
 
+    // Called when the private browsing state for this plug-in changes.
+    virtual void privateBrowsingStateChanged(bool) = 0;
+
+    // Gets the form value representation for the plug-in, letting plug-ins participate in form submission.
+    virtual bool getFormValue(String& formValue) = 0;
+
     // Tells the plug-in that it should scroll. The plug-in should return true if it did scroll.
     virtual bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) = 0;
 
@@ -268,10 +294,13 @@ public:
     virtual bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) = 0;
 
     virtual String getSelectionString() const = 0;
+    virtual String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const = 0;
     virtual bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const = 0;
 
     virtual void mutedStateChanged(bool) { }
 
+    virtual bool canCreateTransientPaintingSnapshot() const { return true; }
+
     virtual bool requiresUnifiedScaleFactor() const { return false; }
 
     virtual void willDetachRenderer() { }
@@ -279,7 +308,9 @@ public:
     virtual bool pluginHandlesContentOffsetForAccessibilityHitTest() const { return false; }
 
 protected:
-    Plugin();
+    Plugin(PluginType);
+
+    PluginType m_type;
 
     bool m_isBeingDestroyed { false };
 
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProcessConnection.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProcessConnection.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProcessConnection.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProcessConnection.cpp	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginProcessConnection.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "NPObjectMessageReceiverMessages.h"
+#include "NPRemoteObjectMap.h"
+#include "NPRuntimeObjectMap.h"
+#include "PluginProcessConnectionManager.h"
+#include "PluginProxy.h"
+#include "WebProcess.h"
+#include "WebProcessProxyMessages.h"
+#include <JavaScriptCore/JSObject.h>
+#include <wtf/FileSystem.h>
+
+namespace WebKit {
+
+PluginProcessConnection::PluginProcessConnection(PluginProcessConnectionManager* pluginProcessConnectionManager, uint64_t pluginProcessToken, IPC::Connection::Identifier connectionIdentifier, bool supportsAsynchronousPluginInitialization)
+    : m_pluginProcessConnectionManager(pluginProcessConnectionManager)
+    , m_pluginProcessToken(pluginProcessToken)
+    , m_supportsAsynchronousPluginInitialization(supportsAsynchronousPluginInitialization)
+{
+    m_connection = IPC::Connection::createClientConnection(connectionIdentifier, *this);
+
+    m_npRemoteObjectMap = NPRemoteObjectMap::create(m_connection.get());
+
+    m_connection->open();
+}
+
+PluginProcessConnection::~PluginProcessConnection()
+{
+    ASSERT(!m_connection);
+    ASSERT(!m_npRemoteObjectMap);
+}
+
+void PluginProcessConnection::addPluginProxy(PluginProxy* plugin)
+{
+    ASSERT(!m_plugins.contains(plugin->pluginInstanceID()));
+    m_plugins.set(plugin->pluginInstanceID(), plugin);
+}
+
+void PluginProcessConnection::removePluginProxy(PluginProxy* plugin)
+{
+    ASSERT(m_plugins.contains(plugin->pluginInstanceID()));
+    m_plugins.remove(plugin->pluginInstanceID());
+
+    // Invalidate all objects related to this plug-in.
+    m_npRemoteObjectMap->pluginDestroyed(plugin);
+
+    if (!m_plugins.isEmpty())
+        return;
+
+    m_npRemoteObjectMap = nullptr;
+
+    // We have no more plug-ins, invalidate the connection to the plug-in process.
+    ASSERT(m_connection);
+    m_connection->invalidate();
+    m_connection = nullptr;
+
+    // This will cause us to be deleted.
+    m_pluginProcessConnectionManager->removePluginProcessConnection(this);
+}
+
+void PluginProcessConnection::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
+{
+    ASSERT(decoder.destinationID());
+
+    PluginProxy* pluginProxy = m_plugins.get(decoder.destinationID());
+    if (!pluginProxy)
+        return;
+
+    pluginProxy->didReceivePluginProxyMessage(connection, decoder);
+}
+
+bool PluginProcessConnection::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, UniqueRef<IPC::Encoder>& replyEncoder)
+{
+    if (decoder.messageReceiverName() == Messages::NPObjectMessageReceiver::messageReceiverName())
+        return m_npRemoteObjectMap->didReceiveSyncMessage(connection, decoder, replyEncoder);
+
+    uint64_t destinationID = decoder.destinationID();
+
+    if (!destinationID)
+        return didReceiveSyncPluginProcessConnectionMessage(connection, decoder, replyEncoder);
+
+    PluginProxy* pluginProxy = m_plugins.get(destinationID);
+    if (!pluginProxy)
+        return false;
+
+    return pluginProxy->didReceiveSyncPluginProxyMessage(connection, decoder, replyEncoder);
+}
+
+void PluginProcessConnection::didClose(IPC::Connection&)
+{
+    // The plug-in process must have crashed.
+    for (HashMap<uint64_t, PluginProxy*>::const_iterator::Values it = m_plugins.begin().values(), end = m_plugins.end().values(); it != end; ++it) {
+        PluginProxy* pluginProxy = (*it);
+
+        pluginProxy->pluginProcessCrashed();
+    }
+}
+
+void PluginProcessConnection::didReceiveInvalidMessage(IPC::Connection&, IPC::MessageName)
+{
+}
+
+void PluginProcessConnection::setException(const String& exceptionString, CompletionHandler<void()>&& completionHandler)
+{
+    NPRuntimeObjectMap::setGlobalException(exceptionString);
+    completionHandler();
+}
+    
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProcessConnection.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProcessConnection.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProcessConnection.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProcessConnection.h	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PluginProcessConnection_h
+#define PluginProcessConnection_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "Connection.h"
+#include "Plugin.h"
+#include "PluginProcess.h"
+#include "PluginProcessAttributes.h"
+#include <wtf/RefCounted.h>
+
+namespace WebKit {
+
+class NPRemoteObjectMap;
+class PluginProcessConnectionManager;
+class PluginProxy;
+    
+class PluginProcessConnection : public RefCounted<PluginProcessConnection>, IPC::Connection::Client {
+public:
+    static Ref<PluginProcessConnection> create(PluginProcessConnectionManager* pluginProcessConnectionManager, uint64_t pluginProcessToken, IPC::Connection::Identifier connectionIdentifier, bool supportsAsynchronousPluginInitialization)
+    {
+        return adoptRef(*new PluginProcessConnection(pluginProcessConnectionManager, pluginProcessToken, connectionIdentifier, supportsAsynchronousPluginInitialization));
+    }
+    ~PluginProcessConnection();
+
+    uint64_t pluginProcessToken() const { return m_pluginProcessToken; }
+
+    IPC::Connection* connection() const { return m_connection.get(); }
+
+    void addPluginProxy(PluginProxy*);
+    void removePluginProxy(PluginProxy*);
+
+    NPRemoteObjectMap* npRemoteObjectMap() const { return m_npRemoteObjectMap.get(); }
+
+    bool supportsAsynchronousPluginInitialization() const { return m_supportsAsynchronousPluginInitialization; }
+    
+private:
+    PluginProcessConnection(PluginProcessConnectionManager*, uint64_t pluginProcessToken, IPC::Connection::Identifier connectionIdentifier, bool supportsAsynchronousInitialization);
+
+    // IPC::Connection::Client
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+    bool didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&) override;
+    void didClose(IPC::Connection&) override;
+    void didReceiveInvalidMessage(IPC::Connection&, IPC::MessageName) override;
+
+    // Message handlers.
+    bool didReceiveSyncPluginProcessConnectionMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&);
+    void setException(const String&, CompletionHandler<void()>&&);
+
+    PluginProcessConnectionManager* m_pluginProcessConnectionManager;
+    uint64_t m_pluginProcessToken;
+
+    // The connection from the web process to the plug-in process.
+    RefPtr<IPC::Connection> m_connection;
+
+    // The plug-ins. We use a weak reference to the plug-in proxies because the plug-in view holds the strong reference.
+    HashMap<uint64_t, PluginProxy*> m_plugins;
+
+    RefPtr<NPRemoteObjectMap> m_npRemoteObjectMap;
+    
+    bool m_supportsAsynchronousPluginInitialization;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // PluginProcessConnection_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProcessConnectionManager.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProcessConnectionManager.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProcessConnectionManager.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProcessConnectionManager.cpp	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginProcessConnectionManager.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "Decoder.h"
+#include "Encoder.h"
+#include "PluginProcessConnection.h"
+#include "PluginProcessConnectionManagerMessages.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebProcess.h"
+#include "WebProcessProxyMessages.h"
+
+#if OS(DARWIN) && !USE(UNIX_DOMAIN_SOCKETS)
+#include "MachPort.h"
+#endif
+
+namespace WebKit {
+
+Ref<PluginProcessConnectionManager> PluginProcessConnectionManager::create()
+{
+    return adoptRef(*new PluginProcessConnectionManager);
+}
+
+PluginProcessConnectionManager::PluginProcessConnectionManager()
+    : m_queue(WorkQueue::create("com.apple.WebKit.PluginProcessConnectionManager"))
+{
+}
+
+PluginProcessConnectionManager::~PluginProcessConnectionManager()
+{
+    ASSERT_NOT_REACHED();
+}
+
+void PluginProcessConnectionManager::initializeConnection(IPC::Connection* connection)
+{
+    connection->addWorkQueueMessageReceiver(Messages::PluginProcessConnectionManager::messageReceiverName(), m_queue.get(), this);
+}
+
+PluginProcessConnection* PluginProcessConnectionManager::getPluginProcessConnection(uint64_t pluginProcessToken)
+{
+    for (size_t i = 0; i < m_pluginProcessConnections.size(); ++i) {
+        if (m_pluginProcessConnections[i]->pluginProcessToken() == pluginProcessToken)
+            return m_pluginProcessConnections[i].get();
+    }
+
+    IPC::Attachment encodedConnectionIdentifier;
+    bool supportsAsynchronousInitialization;
+    if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebProcessProxy::GetPluginProcessConnection(pluginProcessToken),
+                                                     Messages::WebProcessProxy::GetPluginProcessConnection::Reply(encodedConnectionIdentifier, supportsAsynchronousInitialization), 0))
+        return nullptr;
+
+#if USE(UNIX_DOMAIN_SOCKETS)
+    IPC::Connection::Identifier connectionIdentifier = encodedConnectionIdentifier.releaseFileDescriptor();
+#elif OS(DARWIN)
+    IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.port());
+#elif OS(WINDOWS)
+    IPC::Connection::Identifier connectionIdentifier = encodedConnectionIdentifier.handle();
+#endif
+    if (!IPC::Connection::identifierIsValid(connectionIdentifier))
+        return nullptr;
+
+    auto pluginProcessConnection = PluginProcessConnection::create(this, pluginProcessToken, connectionIdentifier, supportsAsynchronousInitialization);
+    m_pluginProcessConnections.append(pluginProcessConnection.copyRef());
+
+    {
+        Locker locker { m_tokensAndConnectionsLock };
+        ASSERT(!m_tokensAndConnections.contains(pluginProcessToken));
+
+        m_tokensAndConnections.set(pluginProcessToken, pluginProcessConnection->connection());
+    }
+
+    return pluginProcessConnection.ptr();
+}
+
+void PluginProcessConnectionManager::removePluginProcessConnection(PluginProcessConnection* pluginProcessConnection)
+{
+    size_t vectorIndex = m_pluginProcessConnections.find(pluginProcessConnection);
+    ASSERT(vectorIndex != notFound);
+
+    {
+        Locker locker { m_tokensAndConnectionsLock };
+        ASSERT(m_tokensAndConnections.contains(pluginProcessConnection->pluginProcessToken()));
+        
+        m_tokensAndConnections.remove(pluginProcessConnection->pluginProcessToken());
+    }
+
+    m_pluginProcessConnections.remove(vectorIndex);
+}
+
+void PluginProcessConnectionManager::pluginProcessCrashed(uint64_t pluginProcessToken)
+{
+    Locker locker { m_tokensAndConnectionsLock };
+    IPC::Connection* connection = m_tokensAndConnections.get(pluginProcessToken);
+
+    // It's OK for connection to be null here; it will happen if this web process doesn't know
+    // anything about the plug-in process.
+    if (!connection)
+        return;
+
+    connection->postConnectionDidCloseOnConnectionWorkQueue();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProcessConnectionManager.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProcessConnectionManager.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProcessConnectionManager.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProcessConnectionManager.h	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PluginProcessConnectionManager_h
+#define PluginProcessConnectionManager_h
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "PluginProcess.h"
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/Lock.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Threading.h>
+#include <wtf/Vector.h>
+#include <wtf/text/StringHash.h>
+
+// Manages plug-in process connections for the given web process.
+
+namespace WebKit {
+
+class PluginProcessConnection;
+        
+class PluginProcessConnectionManager : public IPC::Connection::WorkQueueMessageReceiver {
+public:
+    static Ref<PluginProcessConnectionManager> create();
+    ~PluginProcessConnectionManager();
+
+    void initializeConnection(IPC::Connection*);
+
+    PluginProcessConnection* getPluginProcessConnection(uint64_t pluginProcessToken);
+    void removePluginProcessConnection(PluginProcessConnection*);
+
+private:
+    PluginProcessConnectionManager();
+
+    // IPC::Connection::WorkQueueMessageReceiver.
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+
+    void pluginProcessCrashed(uint64_t pluginProcessToken);
+
+    Ref<WorkQueue> m_queue;
+
+    Vector<RefPtr<PluginProcessConnection>> m_pluginProcessConnections;
+
+    Lock m_tokensAndConnectionsLock;
+    HashMap<uint64_t, RefPtr<IPC::Connection>> m_tokensAndConnections WTF_GUARDED_BY_LOCK(m_tokensAndConnectionsLock);
+};
+
+}
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#endif // PluginProcessConnectionManager_h
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProcessConnectionManager.messages.in webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProcessConnectionManager.messages.in
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProcessConnectionManager.messages.in	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProcessConnectionManager.messages.in	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,29 @@
+# Copyright (C) 2013 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+messages -> PluginProcessConnectionManager {
+    PluginProcessCrashed(uint64_t pluginProcessToken)
+}
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProcessConnection.messages.in webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProcessConnection.messages.in
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProcessConnection.messages.in	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProcessConnection.messages.in	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,30 @@
+# Copyright (C) 2011 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+messages -> PluginProcessConnection LegacyReceiver {
+    # Set a global JavaScript exception.
+    SetException(String exceptionString) -> () Synchronous
+}
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProxy.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProxy.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProxy.cpp	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProxy.cpp	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,747 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginProxy.h"
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "DataReference.h"
+#include "NPRemoteObjectMap.h"
+#include "NPRuntimeUtilities.h"
+#include "NPVariantData.h"
+#include "PluginController.h"
+#include "PluginControllerProxyMessages.h"
+#include "PluginCreationParameters.h"
+#include "PluginProcessConnection.h"
+#include "PluginProcessConnectionManager.h"
+#include "ShareableBitmap.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebKeyboardEvent.h"
+#include "WebMouseEvent.h"
+#include "WebProcess.h"
+#include "WebProcessConnectionMessages.h"
+#include "WebWheelEvent.h"
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/SharedBuffer.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+static uint64_t generatePluginInstanceID()
+{
+    static uint64_t uniquePluginInstanceID;
+    return ++uniquePluginInstanceID;
+}
+
+Ref<PluginProxy> PluginProxy::create(uint64_t pluginProcessToken)
+{
+    return adoptRef(*new PluginProxy(pluginProcessToken));
+}
+
+PluginProxy::PluginProxy(uint64_t pluginProcessToken)
+    : Plugin(PluginProxyType)
+    , m_pluginProcessToken(pluginProcessToken)
+    , m_pluginInstanceID(generatePluginInstanceID())
+{
+}
+
+PluginProxy::~PluginProxy()
+{
+}
+
+void PluginProxy::pluginProcessCrashed()
+{
+    controller()->pluginProcessCrashed();
+}
+
+bool PluginProxy::initialize(const Parameters& parameters)
+{
+    ASSERT(!m_connection);
+    m_connection = WebProcess::singleton().pluginProcessConnectionManager().getPluginProcessConnection(m_pluginProcessToken);
+    
+    if (!m_connection)
+        return false;
+    
+    // Add the plug-in proxy before creating the plug-in; it needs to be in the map because CreatePlugin
+    // can call back out to the plug-in proxy.
+    m_connection->addPluginProxy(this);
+
+    // Ask the plug-in process to create a plug-in.
+    m_pendingPluginCreationParameters = makeUnique<PluginCreationParameters>();
+
+    m_pendingPluginCreationParameters->pluginInstanceID = m_pluginInstanceID;
+    m_pendingPluginCreationParameters->windowNPObjectID = windowNPObjectID();
+    m_pendingPluginCreationParameters->parameters = parameters;
+    m_pendingPluginCreationParameters->userAgent = controller()->userAgent();
+    m_pendingPluginCreationParameters->contentsScaleFactor = contentsScaleFactor();
+    m_pendingPluginCreationParameters->isPrivateBrowsingEnabled = controller()->isPrivateBrowsingEnabled();
+    m_pendingPluginCreationParameters->isMuted = controller()->isMuted();
+    m_pendingPluginCreationParameters->artificialPluginInitializationDelayEnabled = controller()->artificialPluginInitializationDelayEnabled();
+    m_pendingPluginCreationParameters->isAcceleratedCompositingEnabled = controller()->isAcceleratedCompositingEnabled();
+
+    if (!canInitializeAsynchronously())
+        return initializeSynchronously();
+
+    // Remember that we tried to create this plug-in asynchronously in case we need to create it synchronously later.
+    m_waitingOnAsynchronousInitialization = true;
+    PluginCreationParameters creationParameters(*m_pendingPluginCreationParameters.get());
+    m_connection->connection()->send(Messages::WebProcessConnection::CreatePluginAsynchronously(creationParameters), m_pluginInstanceID);
+    return true;
+}
+
+bool PluginProxy::canInitializeAsynchronously() const
+{
+    return controller()->asynchronousPluginInitializationEnabled() && (m_connection->supportsAsynchronousPluginInitialization() || controller()->asynchronousPluginInitializationEnabledForAllPlugins());
+}
+
+bool PluginProxy::initializeSynchronously()
+{
+    ASSERT(m_pendingPluginCreationParameters);
+
+    m_pendingPluginCreationParameters->asynchronousCreationIncomplete = m_waitingOnAsynchronousInitialization;
+    bool result = false;
+    bool wantsWheelEvents = false;
+    uint32_t remoteLayerClientID = 0;
+    
+    PluginCreationParameters parameters(*m_pendingPluginCreationParameters.get());
+
+    if (!m_connection->connection()->sendSync(Messages::WebProcessConnection::CreatePlugin(parameters), Messages::WebProcessConnection::CreatePlugin::Reply(result, wantsWheelEvents, remoteLayerClientID), 0) || !result)
+        didFailToCreatePluginInternal();
+    else
+        didCreatePluginInternal(wantsWheelEvents, remoteLayerClientID);
+    
+    return result;
+}
+
+void PluginProxy::didCreatePlugin(bool wantsWheelEvents, uint32_t remoteLayerClientID, CompletionHandler<void()>&& completionHandler)
+{
+    // We might have tried to create the plug-in sychronously while waiting on the asynchronous reply,
+    // in which case we should ignore this message.
+    if (!m_waitingOnAsynchronousInitialization)
+        return completionHandler();
+
+    didCreatePluginInternal(wantsWheelEvents, remoteLayerClientID);
+    completionHandler();
+}
+
+void PluginProxy::didFailToCreatePlugin(CompletionHandler<void()>&& completionHandler)
+{
+    // We might have tried to create the plug-in sychronously while waiting on the asynchronous reply,
+    // in which case we should ignore this message.
+    if (!m_waitingOnAsynchronousInitialization)
+        return completionHandler();
+
+    didFailToCreatePluginInternal();
+    completionHandler();
+}
+
+void PluginProxy::didCreatePluginInternal(bool wantsWheelEvents, uint32_t remoteLayerClientID)
+{
+    m_wantsWheelEvents = wantsWheelEvents;
+    m_remoteLayerClientID = remoteLayerClientID;
+    m_isStarted = true;
+    controller()->didInitializePlugin();
+
+    // Whether synchronously or asynchronously, this plug-in was created and we shouldn't need to remember
+    // anything about how.
+    m_pendingPluginCreationParameters = nullptr;
+    m_waitingOnAsynchronousInitialization = false;
+}
+
+void PluginProxy::didFailToCreatePluginInternal()
+{
+    // Calling out to the connection and the controller could potentially cause the plug-in proxy to go away, so protect it here.
+    Ref<PluginProxy> protect(*this);
+
+    m_connection->removePluginProxy(this);
+    controller()->didFailToInitializePlugin();
+
+    // Whether synchronously or asynchronously, this plug-in failed to create and we shouldn't need to remember
+    // anything about how.
+    m_pendingPluginCreationParameters = nullptr;
+    m_waitingOnAsynchronousInitialization = false;
+}
+
+void PluginProxy::destroy()
+{
+    m_isStarted = false;
+
+    if (!m_connection)
+        return;
+
+    // Although this message is sent synchronously, the Plugin process replies immediately (before performing any tasks) so this is only waiting for
+    // confirmation that the Plugin process received the DestroyPlugin message.
+    m_connection->connection()->sendSync(Messages::WebProcessConnection::DestroyPlugin(m_pluginInstanceID, m_waitingOnAsynchronousInitialization), Messages::WebProcessConnection::DestroyPlugin::Reply(), 0, 1_s);
+    m_connection->removePluginProxy(this);
+}
+
+void PluginProxy::paint(GraphicsContext& graphicsContext, const IntRect& dirtyRect)
+{
+    if (!needsBackingStore() || !m_backingStore)
+        return;
+
+    if (!m_pluginBackingStoreContainsValidData) {
+        m_connection->connection()->sendSync(Messages::PluginControllerProxy::PaintEntirePlugin(), Messages::PluginControllerProxy::PaintEntirePlugin::Reply(), m_pluginInstanceID);
+    
+        // Blit the plug-in backing store into our own backing store.
+        auto graphicsContext = m_backingStore->createGraphicsContext();
+        if (graphicsContext) {
+            graphicsContext->applyDeviceScaleFactor(contentsScaleFactor());
+            graphicsContext->setCompositeOperation(CompositeOperator::Copy);
+
+            m_pluginBackingStore->paint(*graphicsContext, contentsScaleFactor(), IntPoint(), pluginBounds());
+
+            m_pluginBackingStoreContainsValidData = true;
+        }
+    }
+
+    m_backingStore->paint(graphicsContext, contentsScaleFactor(), dirtyRect.location(), dirtyRect);
+
+    if (m_waitingForPaintInResponseToUpdate) {
+        m_waitingForPaintInResponseToUpdate = false;
+        m_connection->connection()->send(Messages::PluginControllerProxy::DidUpdate(), m_pluginInstanceID);
+    }
+}
+
+bool PluginProxy::supportsSnapshotting() const
+{
+    if (m_waitingOnAsynchronousInitialization)
+        return false;
+
+    bool isSupported = false;
+    if (m_connection && !m_connection->connection()->sendSync(Messages::PluginControllerProxy::SupportsSnapshotting(), Messages::PluginControllerProxy::SupportsSnapshotting::Reply(isSupported), m_pluginInstanceID))
+        return false;
+
+    return isSupported;
+}
+
+RefPtr<ShareableBitmap> PluginProxy::snapshot()
+{
+    ShareableBitmap::Handle snapshotStoreHandle;
+    m_connection->connection()->sendSync(Messages::PluginControllerProxy::Snapshot(), Messages::PluginControllerProxy::Snapshot::Reply(snapshotStoreHandle), m_pluginInstanceID);
+
+    if (snapshotStoreHandle.isNull())
+        return nullptr;
+
+    return ShareableBitmap::create(snapshotStoreHandle);
+}
+
+bool PluginProxy::isTransparent()
+{
+    // This should never be called from the web process.
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+bool PluginProxy::wantsWheelEvents()
+{
+    return m_wantsWheelEvents;
+}
+
+void PluginProxy::geometryDidChange()
+{
+    ASSERT(m_isStarted);
+
+    ShareableBitmap::Handle pluginBackingStoreHandle;
+
+    if (updateBackingStore()) {
+        // Create a new plug-in backing store.
+        m_pluginBackingStore = ShareableBitmap::createShareable(m_backingStore->size(), { });
+        if (!m_pluginBackingStore)
+            return;
+
+        // Create a handle to the plug-in backing store so we can send it over.
+        if (!m_pluginBackingStore->createHandle(pluginBackingStoreHandle)) {
+            m_pluginBackingStore = nullptr;
+            return;
+        }
+
+        m_pluginBackingStoreContainsValidData = false;
+    }
+
+    m_connection->connection()->send(Messages::PluginControllerProxy::GeometryDidChange(m_pluginSize, m_clipRect, m_pluginToRootViewTransform, contentsScaleFactor(), pluginBackingStoreHandle), m_pluginInstanceID, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
+}
+
+void PluginProxy::geometryDidChange(const IntSize& pluginSize, const IntRect& clipRect, const AffineTransform& pluginToRootViewTransform)
+{
+    if (pluginSize == m_pluginSize && m_clipRect == clipRect && m_pluginToRootViewTransform == pluginToRootViewTransform) {
+        // Nothing to do.
+        return;
+    }
+    
+    m_pluginSize = pluginSize;
+    m_clipRect = clipRect;
+    m_pluginToRootViewTransform = pluginToRootViewTransform;
+
+    geometryDidChange();
+}
+
+void PluginProxy::visibilityDidChange(bool isVisible)
+{
+    ASSERT(m_isStarted);
+    m_connection->connection()->send(Messages::PluginControllerProxy::VisibilityDidChange(isVisible), m_pluginInstanceID);
+}
+
+void PluginProxy::frameDidFinishLoading(uint64_t requestID)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::FrameDidFinishLoading(requestID), m_pluginInstanceID);
+}
+
+void PluginProxy::frameDidFail(uint64_t requestID, bool wasCancelled)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::FrameDidFail(requestID, wasCancelled), m_pluginInstanceID);
+}
+
+void PluginProxy::didEvaluateJavaScript(uint64_t requestID, const WTF::String& result)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::DidEvaluateJavaScript(requestID, result), m_pluginInstanceID);
+}
+
+void PluginProxy::streamWillSendRequest(uint64_t streamID, const URL& requestURL, const URL& responseURL, int responseStatus)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::StreamWillSendRequest(streamID, requestURL.string(), responseURL.string(), responseStatus), m_pluginInstanceID);
+}
+
+void PluginProxy::streamDidReceiveResponse(uint64_t streamID, const URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers, const String& /* suggestedFileName */)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidReceiveResponse(streamID, responseURL.string(), streamLength, lastModifiedTime, mimeType, headers), m_pluginInstanceID);
+}
+                                           
+void PluginProxy::streamDidReceiveData(uint64_t streamID, const WebCore::SharedBuffer& buffer)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidReceiveData(streamID, IPC::DataReference(buffer.data(), buffer.size())), m_pluginInstanceID);
+}
+
+void PluginProxy::streamDidFinishLoading(uint64_t streamID)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidFinishLoading(streamID), m_pluginInstanceID);
+}
+
+void PluginProxy::streamDidFail(uint64_t streamID, bool wasCancelled)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidFail(streamID, wasCancelled), m_pluginInstanceID);
+}
+
+void PluginProxy::manualStreamDidReceiveResponse(const URL& responseURL, uint32_t streamLength,  uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers, const String& /* suggestedFileName */)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::ManualStreamDidReceiveResponse(responseURL.string(), streamLength, lastModifiedTime, mimeType, headers), m_pluginInstanceID);
+}
+
+void PluginProxy::manualStreamDidReceiveData(const SharedBuffer& buffer)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::ManualStreamDidReceiveData(IPC::DataReference(buffer.data(), buffer.size())), m_pluginInstanceID);
+}
+
+void PluginProxy::manualStreamDidFinishLoading()
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::ManualStreamDidFinishLoading(), m_pluginInstanceID);
+}
+
+void PluginProxy::manualStreamDidFail(bool wasCancelled)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::ManualStreamDidFail(wasCancelled), m_pluginInstanceID);
+}
+
+bool PluginProxy::handleMouseEvent(const WebMouseEvent& mouseEvent)
+{
+    if (m_waitingOnAsynchronousInitialization)
+        return false;
+
+    m_connection->connection()->send(Messages::PluginControllerProxy::HandleMouseEvent(mouseEvent), m_pluginInstanceID);
+    return true;
+}
+
+bool PluginProxy::handleWheelEvent(const WebWheelEvent& wheelEvent)
+{
+    if (m_waitingOnAsynchronousInitialization)
+        return false;
+
+    bool handled = false;
+    if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleWheelEvent(wheelEvent), Messages::PluginControllerProxy::HandleWheelEvent::Reply(handled), m_pluginInstanceID))
+        return false;
+
+    return handled;
+}
+
+bool PluginProxy::handleMouseEnterEvent(const WebMouseEvent& mouseEnterEvent)
+{
+    if (m_waitingOnAsynchronousInitialization)
+        return false;
+
+    bool handled = false;
+    if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleMouseEnterEvent(mouseEnterEvent), Messages::PluginControllerProxy::HandleMouseEnterEvent::Reply(handled), m_pluginInstanceID))
+        return false;
+    
+    return handled;
+}
+
+bool PluginProxy::handleMouseLeaveEvent(const WebMouseEvent& mouseLeaveEvent)
+{
+    if (m_waitingOnAsynchronousInitialization)
+        return false;
+
+    bool handled = false;
+    if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleMouseLeaveEvent(mouseLeaveEvent), Messages::PluginControllerProxy::HandleMouseLeaveEvent::Reply(handled), m_pluginInstanceID))
+        return false;
+    
+    return handled;
+}
+
+bool PluginProxy::handleContextMenuEvent(const WebMouseEvent&)
+{
+    // We don't know if the plug-in has handled mousedown event by displaying a context menu, so we never want WebKit to show a default one.
+    return true;
+}
+
+bool PluginProxy::handleKeyboardEvent(const WebKeyboardEvent& keyboardEvent)
+{
+    if (m_waitingOnAsynchronousInitialization)
+        return false;
+
+    bool handled = false;
+    if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleKeyboardEvent(keyboardEvent), Messages::PluginControllerProxy::HandleKeyboardEvent::Reply(handled), m_pluginInstanceID))
+        return false;
+    
+    return handled;
+}
+
+void PluginProxy::setFocus(bool hasFocus)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::SetFocus(hasFocus), m_pluginInstanceID);
+}
+
+bool PluginProxy::handleEditingCommand(const String& commandName, const String& argument)
+{
+    if (m_waitingOnAsynchronousInitialization)
+        return false;
+
+    bool handled = false;
+    if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleEditingCommand(commandName, argument), Messages::PluginControllerProxy::HandleEditingCommand::Reply(handled), m_pluginInstanceID))
+        return false;
+    
+    return handled;
+}
+    
+bool PluginProxy::isEditingCommandEnabled(const String& commandName)
+{
+    if (m_waitingOnAsynchronousInitialization)
+        return false;
+
+    bool enabled = false;
+    if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::IsEditingCommandEnabled(commandName), Messages::PluginControllerProxy::IsEditingCommandEnabled::Reply(enabled), m_pluginInstanceID))
+        return false;
+    
+    return enabled;
+}
+    
+bool PluginProxy::handlesPageScaleFactor() const
+{
+    if (m_waitingOnAsynchronousInitialization)
+        return false;
+
+    bool handled = false;
+    if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandlesPageScaleFactor(), Messages::PluginControllerProxy::HandlesPageScaleFactor::Reply(handled), m_pluginInstanceID))
+        return false;
+    
+    return handled;
+}
+
+bool PluginProxy::requiresUnifiedScaleFactor() const
+{
+    if (m_waitingOnAsynchronousInitialization)
+        return false;
+
+    bool required = false;
+    if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::RequiresUnifiedScaleFactor(), Messages::PluginControllerProxy::RequiresUnifiedScaleFactor::Reply(required), m_pluginInstanceID))
+        return false;
+    
+    return required;
+}
+
+NPObject* PluginProxy::pluginScriptableNPObject()
+{
+    // Sending the synchronous Messages::PluginControllerProxy::GetPluginScriptableNPObject message can cause us to dispatch an
+    // incoming synchronous message that ends up destroying the PluginProxy object.
+    PluginController::PluginDestructionProtector protector(controller());
+
+    uint64_t pluginScriptableNPObjectID = 0;
+    
+    if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::GetPluginScriptableNPObject(), Messages::PluginControllerProxy::GetPluginScriptableNPObject::Reply(pluginScriptableNPObjectID), m_pluginInstanceID))
+        return 0;
+
+    if (!pluginScriptableNPObjectID)
+        return 0;
+
+    return m_connection->npRemoteObjectMap()->createNPObjectProxy(pluginScriptableNPObjectID, this);
+}
+
+void PluginProxy::windowFocusChanged(bool hasFocus)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::WindowFocusChanged(hasFocus), m_pluginInstanceID);
+}
+
+void PluginProxy::windowVisibilityChanged(bool isVisible)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::WindowVisibilityChanged(isVisible), m_pluginInstanceID);
+}
+
+#if PLATFORM(COCOA)
+void PluginProxy::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::WindowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates), m_pluginInstanceID);
+}
+uint64_t PluginProxy::pluginComplexTextInputIdentifier() const
+{
+    return m_pluginInstanceID;
+}
+
+void PluginProxy::sendComplexTextInput(const String& textInput)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::SendComplexTextInput(textInput), m_pluginInstanceID);
+}
+#endif
+
+void PluginProxy::contentsScaleFactorChanged(float)
+{
+    geometryDidChange();
+}
+
+void PluginProxy::storageBlockingStateChanged(bool isStorageBlockingEnabled)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::StorageBlockingStateChanged(isStorageBlockingEnabled), m_pluginInstanceID);
+}
+
+void PluginProxy::privateBrowsingStateChanged(bool isPrivateBrowsingEnabled)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::PrivateBrowsingStateChanged(isPrivateBrowsingEnabled), m_pluginInstanceID);
+}
+
+void PluginProxy::mutedStateChanged(bool isMuted)
+{
+    m_connection->connection()->send(Messages::PluginControllerProxy::MutedStateChanged(isMuted), m_pluginInstanceID);
+}
+
+bool PluginProxy::getFormValue(String& formValue)
+{
+    bool returnValue;
+    if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::GetFormValue(), Messages::PluginControllerProxy::GetFormValue::Reply(returnValue, formValue), m_pluginInstanceID))
+        return false;
+
+    return returnValue;
+}
+
+bool PluginProxy::handleScroll(ScrollDirection, ScrollGranularity)
+{
+    return false;
+}
+
+Scrollbar* PluginProxy::horizontalScrollbar()
+{
+    return 0;
+}
+
+Scrollbar* PluginProxy::verticalScrollbar()
+{
+    return 0;
+}
+
+void PluginProxy::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups)
+{
+    controller()->loadURL(requestID, method, urlString, target, headerFields, httpBody, allowPopups);
+}
+
+void PluginProxy::proxiesForURL(const String& urlString, CompletionHandler<void(String)>&& completionHandler)
+{
+    completionHandler(controller()->proxiesForURL(urlString));
+}
+
+void PluginProxy::cookiesForURL(const String& urlString, CompletionHandler<void(String)>&& completionHandler)
+{
+    completionHandler(controller()->cookiesForURL(urlString));
+}
+
+void PluginProxy::setCookiesForURL(const String& urlString, const String& cookieString)
+{
+    controller()->setCookiesForURL(urlString, cookieString);
+}
+
+void PluginProxy::getAuthenticationInfo(const ProtectionSpace& protectionSpace, CompletionHandler<void(bool returnValue, String username, String password)>&& completionHandler)
+{
+    String username;
+    String password;
+    bool returnValue = controller()->getAuthenticationInfo(protectionSpace, username, password);
+    completionHandler(returnValue, username, password);
+}
+
+float PluginProxy::contentsScaleFactor()
+{
+    return controller()->contentsScaleFactor();
+}
+
+bool PluginProxy::updateBackingStore()
+{
+    if (m_pluginSize.isEmpty() || !needsBackingStore())
+        return false;
+
+    IntSize backingStoreSize = m_pluginSize;
+    backingStoreSize.scale(contentsScaleFactor());
+
+    if (m_backingStore) {
+        if (m_backingStore->size() == backingStoreSize)
+            return false;
+        m_backingStore = nullptr; // Give malloc a chance to recycle our backing store.
+    }
+
+    m_backingStore = ShareableBitmap::create(backingStoreSize, { });
+    return !!m_backingStore;
+}
+
+uint64_t PluginProxy::windowNPObjectID()
+{
+    NPObject* windowScriptNPObject = controller()->windowScriptNPObject();
+    if (!windowScriptNPObject)
+        return 0;
+
+    uint64_t windowNPObjectID = m_connection->npRemoteObjectMap()->registerNPObject(windowScriptNPObject, this);
+    releaseNPObject(windowScriptNPObject);
+
+    return windowNPObjectID;
+}
+
+IntRect PluginProxy::pluginBounds()
+{
+    return IntRect(IntPoint(), m_pluginSize);
+}
+
+void PluginProxy::getPluginElementNPObject(CompletionHandler<void(uint64_t)>&& completionHandler)
+{
+    NPObject* pluginElementNPObject = controller()->pluginElementNPObject();
+    if (!pluginElementNPObject)
+        return completionHandler(0);
+
+    uint64_t pluginElementNPObjectID = m_connection->npRemoteObjectMap()->registerNPObject(pluginElementNPObject, this);
+    releaseNPObject(pluginElementNPObject);
+    completionHandler(pluginElementNPObjectID);
+}
+
+void PluginProxy::evaluate(const NPVariantData& npObjectAsVariantData, const String& scriptString, bool allowPopups, CompletionHandler<void(bool returnValue, NPVariantData&& resultData)>&& completionHandler)
+{
+    PluginController::PluginDestructionProtector protector(controller());
+
+    NPVariant npObjectAsVariant = m_connection->npRemoteObjectMap()->npVariantDataToNPVariant(npObjectAsVariantData, this);
+    if (!NPVARIANT_IS_OBJECT(npObjectAsVariant) || !(NPVARIANT_TO_OBJECT(npObjectAsVariant)))
+        return completionHandler(false, { });
+
+    NPVariant result;
+    bool returnValue = controller()->evaluate(NPVARIANT_TO_OBJECT(npObjectAsVariant), scriptString, &result, allowPopups);
+    if (!returnValue)
+        return completionHandler(false, { });
+
+    // Convert the NPVariant to an NPVariantData.
+    NPVariantData resultData = m_connection->npRemoteObjectMap()->npVariantToNPVariantData(result, this);
+    
+    // And release the result.
+    releaseNPVariantValue(&result);
+    releaseNPVariantValue(&npObjectAsVariant);
+    
+    completionHandler(returnValue, WTFMove(resultData));
+}
+
+void PluginProxy::setPluginIsPlayingAudio(bool pluginIsPlayingAudio)
+{
+    controller()->setPluginIsPlayingAudio(pluginIsPlayingAudio);
+}
+
+void PluginProxy::continueStreamLoad(uint64_t streamID)
+{
+    controller()->continueStreamLoad(streamID);
+}
+
+void PluginProxy::cancelStreamLoad(uint64_t streamID)
+{
+    controller()->cancelStreamLoad(streamID);
+}
+
+void PluginProxy::cancelManualStreamLoad()
+{
+    controller()->cancelManualStreamLoad();
+}
+
+void PluginProxy::setStatusbarText(const String& statusbarText)
+{
+    controller()->setStatusbarText(statusbarText);
+}
+
+#if PLATFORM(X11)
+void PluginProxy::createPluginContainer(CompletionHandler<void(uint64_t windowID)>&& completionHandler)
+{
+    completionHandler(controller()->createPluginContainer());
+}
+
+void PluginProxy::windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID)
+{
+    controller()->windowedPluginGeometryDidChange(frameRect, clipRect, windowID);
+}
+
+void PluginProxy::windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID)
+{
+    controller()->windowedPluginVisibilityDidChange(isVisible, windowID);
+}
+#endif
+
+void PluginProxy::update(const IntRect& paintedRect)
+{
+    if (paintedRect == pluginBounds())
+        m_pluginBackingStoreContainsValidData = true;
+
+    if (m_backingStore) {
+        // Blit the plug-in backing store into our own backing store.
+        auto graphicsContext = m_backingStore->createGraphicsContext();
+        if (graphicsContext) {
+            graphicsContext->applyDeviceScaleFactor(contentsScaleFactor());
+            graphicsContext->setCompositeOperation(CompositeOperator::Copy);
+            m_pluginBackingStore->paint(*graphicsContext, contentsScaleFactor(), paintedRect.location(), paintedRect);
+        }
+    }
+
+    // Ask the controller to invalidate the rect for us.
+    m_waitingForPaintInResponseToUpdate = true;
+    controller()->invalidate(paintedRect);
+}
+
+IntPoint PluginProxy::convertToRootView(const IntPoint& point) const
+{
+    return m_pluginToRootViewTransform.mapPoint(point);
+}
+
+RefPtr<WebCore::FragmentedSharedBuffer> PluginProxy::liveResourceData() const
+{
+    return nullptr;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProxy.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProxy.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProxy.h	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProxy.h	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2010, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+#include "Connection.h"
+#include "Plugin.h"
+#include "PluginProcess.h"
+#include <WebCore/AffineTransform.h>
+#include <WebCore/IntRect.h>
+#include <WebCore/SecurityOrigin.h>
+#include <memory>
+
+#if PLATFORM(COCOA)
+#include <wtf/RetainPtr.h>
+OBJC_CLASS CALayer;
+#endif
+
+namespace WebCore {
+    class HTTPHeaderMap;
+    class ProtectionSpace;
+}
+
+namespace WebKit {
+
+class ShareableBitmap;
+class NPVariantData;
+class PluginProcessConnection;
+
+struct PluginCreationParameters;
+
+class PluginProxy : public Plugin {
+public:
+    static Ref<PluginProxy> create(uint64_t pluginProcessToken);
+    ~PluginProxy();
+
+    uint64_t pluginInstanceID() const { return m_pluginInstanceID; }
+    void pluginProcessCrashed();
+
+    void didReceivePluginProxyMessage(IPC::Connection&, IPC::Decoder&);
+    bool didReceiveSyncPluginProxyMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&);
+
+private:
+    explicit PluginProxy(uint64_t pluginProcessToken);
+
+    // Plugin
+    bool initialize(const Parameters&) override;
+    bool initializeSynchronously();
+
+    void destroy() override;
+    void paint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override;
+    bool supportsSnapshotting() const override;
+    RefPtr<ShareableBitmap> snapshot() override;
+#if PLATFORM(COCOA)
+    PlatformLayer* pluginLayer() override;
+#endif
+    bool isTransparent() override;
+    bool wantsWheelEvents() override;
+    void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) override;
+    void visibilityDidChange(bool isVisible) override;
+    void frameDidFinishLoading(uint64_t requestID) override;
+    void frameDidFail(uint64_t requestID, bool wasCancelled) override;
+    void didEvaluateJavaScript(uint64_t requestID, const String& result) override;
+    void streamWillSendRequest(uint64_t streamID, const URL& requestURL, const URL& responseURL, int responseStatus) override;
+    void streamDidReceiveResponse(uint64_t streamID, const URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) override;
+    void streamDidReceiveData(uint64_t streamID, const WebCore::SharedBuffer& buffer) override;
+    void streamDidFinishLoading(uint64_t streamID) override;
+    void streamDidFail(uint64_t streamID, bool wasCancelled) override;
+    void manualStreamDidReceiveResponse(const URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers, const String& suggestedFileName) override;
+    void manualStreamDidReceiveData(const WebCore::SharedBuffer& buffer) override;
+    void manualStreamDidFinishLoading() override;
+    void manualStreamDidFail(bool wasCancelled) override;
+    
+    bool handleMouseEvent(const WebMouseEvent&) override;
+    bool handleWheelEvent(const WebWheelEvent&) override;
+    bool handleMouseEnterEvent(const WebMouseEvent&) override;
+    bool handleMouseLeaveEvent(const WebMouseEvent&) override;
+    bool handleContextMenuEvent(const WebMouseEvent&) override;
+    bool handleKeyboardEvent(const WebKeyboardEvent&) override;
+    void setFocus(bool) override;
+    bool handleEditingCommand(const String& commandName, const String& argument) override;
+    bool isEditingCommandEnabled(const String& commandName) override;
+    bool shouldAllowScripting() override { return true; }
+    bool shouldAllowNavigationFromDrags() override { return false; }
+    
+    bool handlesPageScaleFactor() const override;
+    bool requiresUnifiedScaleFactor() const override;
+    
+    NPObject* pluginScriptableNPObject() override;
+
+    void windowFocusChanged(bool) override;
+    void windowVisibilityChanged(bool) override;
+
+#if PLATFORM(COCOA)
+    void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) override;
+    uint64_t pluginComplexTextInputIdentifier() const override;
+    void sendComplexTextInput(const String& textInput) override;
+    void setLayerHostingMode(LayerHostingMode) override;
+#endif
+
+    void contentsScaleFactorChanged(float) override;
+    void storageBlockingStateChanged(bool) override;
+    void privateBrowsingStateChanged(bool) override;
+    void mutedStateChanged(bool) override;
+    bool getFormValue(String& formValue) override;
+    bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) override;
+    WebCore::Scrollbar* horizontalScrollbar() override;
+    WebCore::Scrollbar* verticalScrollbar() override;
+
+    unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned) override  { return 0; }
+    bool findString(const String&, WebCore::FindOptions, unsigned) override { return false; }
+
+    WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const override;
+
+    RefPtr<WebCore::FragmentedSharedBuffer> liveResourceData() const override;
+    bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) override { return false; }
+
+    String getSelectionString() const override { return String(); }
+    String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const override { return String(); }
+    bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const override { return false; }
+
+    float contentsScaleFactor();
+    bool needsBackingStore() const;
+    bool updateBackingStore();
+    uint64_t windowNPObjectID();
+    WebCore::IntRect pluginBounds();
+
+    void geometryDidChange();
+
+    // Message handlers.
+    void loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const WebCore::HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups);
+    void update(const WebCore::IntRect& paintedRect);
+    void proxiesForURL(const String& urlString, CompletionHandler<void(String)>&&);
+    void cookiesForURL(const String& urlString, CompletionHandler<void(String)>&&);
+    void setCookiesForURL(const String& urlString, const String& cookieString);
+    void getAuthenticationInfo(const WebCore::ProtectionSpace&, CompletionHandler<void(bool returnValue, String username, String password)>&&);
+    void getPluginElementNPObject(CompletionHandler<void(uint64_t)>&&);
+    void evaluate(const NPVariantData& npObjectAsVariantData, const String& scriptString, bool allowPopups, CompletionHandler<void(bool returnValue, NPVariantData&& resultData)>&&);
+    void setPluginIsPlayingAudio(bool);
+    void continueStreamLoad(uint64_t streamID);
+    void cancelStreamLoad(uint64_t streamID);
+    void cancelManualStreamLoad();
+    void setStatusbarText(const String& statusbarText);
+#if PLATFORM(COCOA)
+    void pluginFocusOrWindowFocusChanged(bool);
+    void setComplexTextInputState(uint64_t);
+    void setLayerHostingContextID(uint32_t);
+#endif
+#if PLATFORM(X11)
+    void createPluginContainer(CompletionHandler<void(uint64_t windowID)>&&);
+    void windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID);
+    void windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID);
+#endif
+
+    bool canInitializeAsynchronously() const;
+
+    void didCreatePlugin(bool wantsWheelEvents, uint32_t remoteLayerClientID, CompletionHandler<void()>&&);
+    void didFailToCreatePlugin(CompletionHandler<void()>&&);
+
+    void didCreatePluginInternal(bool wantsWheelEvents, uint32_t remoteLayerClientID);
+    void didFailToCreatePluginInternal();
+
+    uint64_t m_pluginProcessToken { 0 };
+
+    RefPtr<PluginProcessConnection> m_connection;
+    uint64_t m_pluginInstanceID { 0 };
+
+    WebCore::IntSize m_pluginSize;
+
+    // The clip rect in plug-in coordinates.
+    WebCore::IntRect m_clipRect;
+
+    // A transform that can be used to convert from root view coordinates to plug-in coordinates.
+    WebCore::AffineTransform m_pluginToRootViewTransform;
+
+    // This is the backing store that we paint when we're told to paint.
+    RefPtr<ShareableBitmap> m_backingStore;
+
+    // This is the shared memory backing store that the plug-in paints into. When the plug-in tells us
+    // that it's painted something in it, we'll blit from it to our own backing store.
+    RefPtr<ShareableBitmap> m_pluginBackingStore;
+    
+    // Whether all of the plug-in backing store contains valid data.
+    bool m_pluginBackingStoreContainsValidData { false };
+
+    bool m_isStarted { false };
+
+    // Whether we're called invalidate in response to an update call, and are now waiting for a paint call.
+    bool m_waitingForPaintInResponseToUpdate { false };
+
+    // Whether we should send wheel events to this plug-in or not.
+    bool m_wantsWheelEvents { false };
+
+    // The client ID for the CA layer in the plug-in process. Will be 0 if the plug-in is not a CA plug-in.
+    uint32_t m_remoteLayerClientID { 0 };
+
+    std::unique_ptr<PluginCreationParameters> m_pendingPluginCreationParameters;
+    bool m_waitingOnAsynchronousInitialization { false };
+
+#if PLATFORM(COCOA)
+    RetainPtr<CALayer> m_pluginLayer;
+#endif
+};
+
+} // namespace WebKit
+
+SPECIALIZE_TYPE_TRAITS_PLUGIN(PluginProxy, isPluginProxy())
+
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProxy.messages.in webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProxy.messages.in
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginProxy.messages.in	1969-12-31 18:00:00.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginProxy.messages.in	2022-03-22 16:38:57.397580237 -0500
@@ -0,0 +1,94 @@
+# Copyright (C) 2010 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+
+messages -> PluginProxy LegacyReceiver {
+    # Asks the web process to load a URL.
+    LoadURL(uint64_t requestID, String method, String urlString, String target, WebCore::HTTPHeaderMap headerFields, Vector<uint8_t> httpBody, bool allowPopups);
+
+    # Called when the plug-in has painted into its backing store. The painted rect is in plug-in coordinates.
+    Update(WebCore::IntRect paintedRect)
+
+    # Returns a PAC style string with proxies for the given URL.
+    ProxiesForURL(String urlString) -> (String proxiesString) Synchronous
+
+    # Returns the cookies for the given URL.
+    CookiesForURL(String urlString) -> (String cookieString) Synchronous
+
+    # Sets the cookies for the given URL.
+    SetCookiesForURL(String urlString, String cookieString)
+
+    # Gets the authentication info for the given protection space.
+    GetAuthenticationInfo(WebCore::ProtectionSpace protectionSpace) -> (bool returnValue, String username, String password) Synchronous
+
+    # Gets a reference to the plug-in element NPObject.
+    GetPluginElementNPObject() -> (uint64_t pluginElementNPObjectID) Synchronous
+
+    # Evaluates the given JavaScript string.
+    Evaluate(WebKit::NPVariantData npObjectAsVariantData, String scriptString, bool allowPopups) -> (bool returnValue, WebKit::NPVariantData resultData) Synchronous
+
+    # Cancels the given stream load.
+    CancelStreamLoad(uint64_t streamID)
+
+    # Continues the given stream load.
+    ContinueStreamLoad(uint64_t streamID)
+
+    # Cancel the manual stream load.
+    CancelManualStreamLoad()
+
+    # Set the status bar text.
+    SetStatusbarText(String statusbarText)
+
+#if PLATFORM(COCOA)
+    # Called when the plug-in's focus or its containing window focus changes.
+    PluginFocusOrWindowFocusChanged(bool pluginHasFocusAndWindowHasFocus)
+
+    # Change whether complex text input is enabled for this plug-in.
+    SetComplexTextInputState(uint64_t complexTextInputState)
+
+    # Update the layer hosting context ID. Called whenever the layer hosting state changes.
+    SetLayerHostingContextID(uint32_t layerHostingContextID)
+#endif
+
+#if PLATFORM(X11)
+    # Create the plugin container for windowed plugins
+    CreatePluginContainer() -> (uint64_t windowID) Synchronous
+
+    # Update geometry of windowed plugin widget
+    WindowedPluginGeometryDidChange(WebCore::IntRect frameRect, WebCore::IntRect clipRect, uint64_t windowID)
+
+    # Update visibility of windowed plugin widget
+    WindowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID)
+#endif
+
+    # Tells the WebProcess that the plug-in was successfully initialized asynchronously
+    DidCreatePlugin(bool wantsWheelEvents, uint32_t remoteLayerClientID) -> () Synchronous
+    
+    # Tells the WebProcess that the plug-in failed to initialize.
+    DidFailToCreatePlugin() -> () Synchronous
+
+    # Tells the WebProcess that the plug-in has started or stopped playing audio.
+    SetPluginIsPlayingAudio(bool pluginIsPlayingAudio)
+}
+
+#endif
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginView.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginView.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginView.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginView.cpp	2022-03-22 16:38:57.397580237 -0500
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "PluginView.h"
 
+#include "NPRuntimeUtilities.h"
 #include "Plugin.h"
 #include "ShareableBitmap.h"
 #include "WebCoreArgumentCoders.h"
@@ -61,6 +62,7 @@
 #include <WebCore/PageInlines.h>
 #include <WebCore/PlatformMouseEvent.h>
 #include <WebCore/ProtectionSpace.h>
+#include <WebCore/ProxyServer.h>
 #include <WebCore/RenderEmbeddedObject.h>
 #include <WebCore/ScriptController.h>
 #include <WebCore/ScrollView.h>
@@ -72,6 +74,10 @@
 #include <wtf/CompletionHandler.h>
 #include <wtf/text/StringBuilder.h>
 
+#if PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
+#include <WebCore/PlatformDisplay.h>
+#endif
+
 namespace WebKit {
 using namespace JSC;
 using namespace WebCore;
@@ -258,6 +264,10 @@ void PluginView::Stream::didFinishLoadin
     // Calling streamDidFinishLoading could cause us to be deleted, so we hold on to a reference here.
     Ref<Stream> protect(*this);
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    // Protect the plug-in while we're calling into it.
+    NPRuntimeObjectMap::PluginProtector pluginProtector(&m_pluginView->m_npRuntimeObjectMap);
+#endif
     m_pluginView->m_plugin->streamDidFinishLoading(m_streamID);
 
     m_pluginView->removeStream(this);
@@ -322,11 +332,36 @@ void PluginView::destroyPluginAndReset()
 
         m_pendingURLRequests.clear();
         m_pendingURLRequestsTimer.stop();
+
+#if PLATFORM(COCOA)
+        if (m_webPage)
+            pluginFocusOrWindowFocusChanged(false);
+#endif
     }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    // Invalidate the object map.
+    m_npRuntimeObjectMap.invalidate();
+#endif
+
     cancelAllStreams();
 }
 
+void PluginView::recreateAndInitialize(Ref<Plugin>&& plugin)
+{
+    if (m_plugin)
+        destroyPluginAndReset();
+
+    m_plugin = WTFMove(plugin);
+    m_isInitialized = false;
+    m_isWaitingForSynchronousInitialization = false;
+    m_isWaitingUntilMediaCanStart = false;
+    m_manualStreamState = ManualStreamState::Initial;
+    m_transientPaintingSnapshot = nullptr;
+
+    initializePlugin();
+}
+
 void PluginView::setLayerHostingMode(LayerHostingMode layerHostingMode)
 {
 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
@@ -492,6 +527,18 @@ void PluginView::windowAndViewFramesChan
     m_plugin->windowAndViewFramesChanged(enclosingIntRect(windowFrameInScreenCoordinates), enclosingIntRect(viewFrameInWindowCoordinates));
 }
 
+bool PluginView::sendComplexTextInput(uint64_t pluginComplexTextInputIdentifier, const String& textInput)
+{
+    if (!m_plugin)
+        return false;
+
+    if (m_plugin->pluginComplexTextInputIdentifier() != pluginComplexTextInputIdentifier)
+        return false;
+
+    m_plugin->sendComplexTextInput(textInput);
+    return true;
+}
+    
 id PluginView::accessibilityAssociatedPluginParentForElement(Element* element) const
 {
     if (!m_plugin)
@@ -537,7 +584,18 @@ void PluginView::initializePlugin()
 
     m_plugin->initialize(*this, m_parameters);
     
-    // Plug-in initialization continued in didInitializePlugin().
+    // Plug-in initialization continued in didFailToInitializePlugin() or didInitializePlugin().
+}
+
+void PluginView::didFailToInitializePlugin()
+{
+    m_plugin = nullptr;
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    String frameURLString = frame()->loader().documentLoader()->responseURL().string();
+    String pageURLString = m_webPage->corePage()->mainFrame().loader().documentLoader()->responseURL().string();
+    m_webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(m_parameters.mimeType, frameURLString, pageURLString));
+#endif
 }
 
 void PluginView::didInitializePlugin()
@@ -584,9 +642,9 @@ void PluginView::didInitializePlugin()
 PlatformLayer* PluginView::platformLayer() const
 {
     // The plug-in can be null here if it failed to initialize.
-    if (!m_isInitialized || !m_plugin)
+    if (!m_isInitialized || !m_plugin || m_pluginProcessHasCrashed)
         return 0;
-
+        
     return m_plugin->pluginLayer();
 }
 #endif
@@ -603,8 +661,19 @@ JSObject* PluginView::scriptObject(JSGlo
     if (!m_isInitialized || !m_plugin)
         return 0;
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    NPObject* scriptableNPObject = m_plugin->pluginScriptableNPObject();
+    if (!scriptableNPObject)
+        return 0;
+
+    JSObject* jsObject = m_npRuntimeObjectMap.getOrCreateJSObject(globalObject, scriptableNPObject);
+    releaseNPObject(scriptableNPObject);
+
+    return jsObject;
+#else
     UNUSED_PARAM(globalObject);
     return 0;
+#endif
 }
 
 void PluginView::storageBlockingStateChanged()
@@ -618,6 +687,24 @@ void PluginView::storageBlockingStateCha
     m_plugin->storageBlockingStateChanged(storageBlockingPolicy);
 }
 
+void PluginView::privateBrowsingStateChanged(bool privateBrowsingEnabled)
+{
+    // The plug-in can be null here if it failed to initialize.
+    if (!m_isInitialized || !m_plugin)
+        return;
+
+    m_plugin->privateBrowsingStateChanged(privateBrowsingEnabled);
+}
+
+bool PluginView::getFormValue(String& formValue)
+{
+    // The plug-in can be null here if it failed to initialize.
+    if (!m_isInitialized || !m_plugin)
+        return false;
+
+    return m_plugin->getFormValue(formValue);
+}
+
 bool PluginView::scroll(ScrollDirection direction, ScrollGranularity granularity)
 {
     // The plug-in can be null here if it failed to initialize.
@@ -854,6 +941,11 @@ bool PluginView::shouldAllowNavigationFr
     return m_plugin->shouldAllowNavigationFromDrags();
 }
 
+bool PluginView::shouldNotAddLayer() const
+{
+    return false;
+}
+
 void PluginView::willDetachRenderer()
 {
     if (!m_isInitialized || !m_plugin)
@@ -882,6 +974,14 @@ bool PluginView::performDictionaryLookup
     return m_plugin->performDictionaryLookupAtLocation(point);
 }
 
+String PluginView::getSelectionForWordAtPoint(const WebCore::FloatPoint& point) const
+{
+    if (!m_isInitialized || !m_plugin)
+        return String();
+    
+    return m_plugin->getSelectionForWordAtPoint(point);
+}
+
 bool PluginView::existingSelectionContainsPoint(const WebCore::FloatPoint& point) const
 {
     if (!m_isInitialized || !m_plugin)
@@ -1220,6 +1320,27 @@ void PluginView::mediaCanStart(WebCore::
 
 void PluginView::pageMutedStateDidChange()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    // The plug-in can be null here if it failed to initialize.
+    if (!m_isInitialized || !m_plugin)
+        return;
+
+    m_plugin->mutedStateChanged(isMuted());
+#endif
+}
+
+void PluginView::invalidate(const IntRect& dirtyRect)
+{
+    invalidateRect(dirtyRect);
+}
+
+String PluginView::userAgent()
+{
+    Frame* frame = m_pluginElement->document().frame();
+    if (!frame)
+        return String();
+    
+    return frame->loader().client().userAgent(URL());
 }
 
 void PluginView::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups)
@@ -1242,6 +1363,176 @@ void PluginView::loadURL(uint64_t reques
     m_pendingURLRequestsTimer.startOneShot(0_s);
 }
 
+void PluginView::cancelStreamLoad(uint64_t streamID)
+{
+    // Keep a reference to the stream. Stream::cancel might remove the stream from the map, and thus
+    // releasing its last reference.
+    RefPtr<Stream> stream = m_streams.get(streamID);
+    if (!stream)
+        return;
+
+    // Cancelling the stream here will remove it from the map.
+    stream->cancel();
+    ASSERT(!m_streams.contains(streamID));
+}
+
+void PluginView::continueStreamLoad(uint64_t streamID)
+{
+    RefPtr<Stream> stream = m_streams.get(streamID);
+    if (!stream)
+        return;
+
+    stream->continueLoad();
+}
+
+void PluginView::cancelManualStreamLoad()
+{
+    if (!frame())
+        return;
+
+    DocumentLoader* documentLoader = frame()->loader().activeDocumentLoader();
+    ASSERT(documentLoader);
+    if (documentLoader && documentLoader->isLoadingMainResource())
+        documentLoader->cancelMainResourceLoad(frame()->loader().cancelledError(m_parameters.url));
+}
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+NPObject* PluginView::windowScriptNPObject()
+{
+    if (!frame())
+        return nullptr;
+
+    if (!frame()->script().canExecuteScripts(NotAboutToExecuteScript)) {
+        // FIXME: Investigate if other browsers allow plug-ins to access JavaScript objects even if JavaScript is disabled.
+        return nullptr;
+    }
+
+    return m_npRuntimeObjectMap.getOrCreateNPObject(pluginWorld().vm(), frame()->windowProxy().jsWindowProxy(pluginWorld())->window());
+}
+
+NPObject* PluginView::pluginElementNPObject()
+{
+    if (!frame())
+        return 0;
+
+    if (!frame()->script().canExecuteScripts(NotAboutToExecuteScript)) {
+        // FIXME: Investigate if other browsers allow plug-ins to access JavaScript objects even if JavaScript is disabled.
+        return 0;
+    }
+
+    JSObject* object = frame()->script().jsObjectForPluginElement(m_pluginElement.get());
+    ASSERT(object);
+
+    return m_npRuntimeObjectMap.getOrCreateNPObject(pluginWorld().vm(), object);
+}
+
+bool PluginView::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result, bool allowPopups)
+{
+    // FIXME: Is this check necessary?
+    if (!m_pluginElement->document().frame())
+        return false;
+
+    // Calling evaluate will run JavaScript that can potentially remove the plug-in element, so we need to
+    // protect the plug-in view from destruction.
+    NPRuntimeObjectMap::PluginProtector pluginProtector(&m_npRuntimeObjectMap);
+
+    UserGestureIndicator gestureIndicator(allowPopups ? std::optional<ProcessingUserGestureState>(ProcessingUserGesture) : std::nullopt);
+    return m_npRuntimeObjectMap.evaluate(npObject, scriptString, result);
+}
+
+void PluginView::setPluginIsPlayingAudio(bool pluginIsPlayingAudio)
+{
+    if (m_pluginIsPlayingAudio == pluginIsPlayingAudio)
+        return;
+
+    m_pluginIsPlayingAudio = pluginIsPlayingAudio;
+    m_pluginElement->document().updateIsPlayingMedia();
+}
+
+bool PluginView::isMuted() const
+{
+    if (!frame() || !frame()->page())
+        return false;
+
+    return frame()->page()->isAudioMuted();
+}
+#endif
+
+void PluginView::setStatusbarText(const String& statusbarText)
+{
+    if (!frame())
+        return;
+    
+    Page* page = frame()->page();
+    if (!page)
+        return;
+
+    page->chrome().setStatusbarText(*frame(), statusbarText);
+}
+
+bool PluginView::isAcceleratedCompositingEnabled()
+{
+    if (!frame())
+        return false;
+    
+    return frame()->settings().acceleratedCompositingEnabled();
+}
+
+#if PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
+uint64_t PluginView::createPluginContainer()
+{
+    uint64_t windowID = 0;
+    if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11)
+        m_webPage->sendSync(Messages::WebPageProxy::CreatePluginContainer(), Messages::WebPageProxy::CreatePluginContainer::Reply(windowID));
+    return windowID;
+}
+
+void PluginView::windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID)
+{
+    m_webPage->send(Messages::WebPageProxy::WindowedPluginGeometryDidChange(frameRect, clipRect, windowID));
+}
+
+void PluginView::windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID)
+{
+    m_webPage->send(Messages::WebPageProxy::WindowedPluginVisibilityDidChange(isVisible, windowID));
+}
+#endif
+
+void PluginView::pluginProcessCrashed()
+{
+    m_pluginProcessHasCrashed = true;
+
+    auto* renderer = m_pluginElement->renderer();
+    if (!is<RenderEmbeddedObject>(renderer))
+        return;
+
+    m_pluginElement->invalidateStyleAndLayerComposition();
+
+    downcast<RenderEmbeddedObject>(*renderer).setPluginUnavailabilityReason(RenderEmbeddedObject::PluginCrashed);
+
+    Widget::invalidate();
+}
+
+#if PLATFORM(COCOA)
+void PluginView::pluginFocusOrWindowFocusChanged(bool pluginHasFocusAndWindowHasFocus)
+{
+    if (m_webPage)
+        m_webPage->send(Messages::WebPageProxy::PluginFocusOrWindowFocusChanged(m_plugin->pluginComplexTextInputIdentifier(), pluginHasFocusAndWindowHasFocus));
+}
+
+void PluginView::setComplexTextInputState(PluginComplexTextInputState pluginComplexTextInputState)
+{
+    if (m_webPage)
+        m_webPage->send(Messages::WebPageProxy::SetPluginComplexTextInputState(m_plugin->pluginComplexTextInputIdentifier(), pluginComplexTextInputState));
+}
+
+const MachSendRight& PluginView::compositingRenderServerPort()
+{
+    return WebProcess::singleton().compositingRenderServerPort();
+}
+
+#endif
+
 float PluginView::contentsScaleFactor()
 {
     if (Page* page = frame() ? frame()->page() : 0)
@@ -1249,6 +1540,96 @@ float PluginView::contentsScaleFactor()
         
     return 1;
 }
+    
+String PluginView::proxiesForURL(const String& urlString)
+{
+    Vector<ProxyServer> proxyServers = proxyServersForURL(URL(URL(), urlString));
+    return toString(proxyServers);
+}
+
+String PluginView::cookiesForURL(const String& urlString)
+{
+    if (auto* page = m_pluginElement->document().page())
+        return page->cookieJar().cookies(m_pluginElement->document(), URL(URL(), urlString));
+    ASSERT_NOT_REACHED();
+    return { };
+}
+
+void PluginView::setCookiesForURL(const String& urlString, const String& cookieString)
+{
+    if (auto* page = m_pluginElement->document().page())
+        page->cookieJar().setCookies(m_pluginElement->document(), URL(URL(), urlString), cookieString);
+    else
+        ASSERT_NOT_REACHED();
+}
+
+bool PluginView::getAuthenticationInfo(const ProtectionSpace& protectionSpace, String& username, String& password)
+{
+    auto* contentDocument = m_pluginElement->contentDocument();
+    if (!contentDocument)
+        return false;
+
+    auto credential = CredentialStorage::getFromPersistentStorage(protectionSpace);
+    if (!credential.hasPassword())
+        return false;
+
+    username = credential.user();
+    password = credential.password();
+
+    return true;
+}
+
+bool PluginView::isPrivateBrowsingEnabled()
+{
+    // If we can't get the real setting, we'll assume that private browsing is enabled.
+    if (!frame())
+        return true;
+
+    if (!frame()->document()->securityOrigin().canAccessPluginStorage(frame()->document()->topOrigin()))
+        return true;
+
+    return frame()->page()->usesEphemeralSession();
+}
+
+bool PluginView::asynchronousPluginInitializationEnabled() const
+{
+    return m_webPage->asynchronousPluginInitializationEnabled();
+}
+
+bool PluginView::asynchronousPluginInitializationEnabledForAllPlugins() const
+{
+    return m_webPage->asynchronousPluginInitializationEnabledForAllPlugins();
+}
+
+bool PluginView::artificialPluginInitializationDelayEnabled() const
+{
+    return m_webPage->artificialPluginInitializationDelayEnabled();
+}
+
+void PluginView::protectPluginFromDestruction()
+{
+    if (m_plugin && !m_plugin->isBeingDestroyed())
+        ref();
+}
+
+void PluginView::unprotectPluginFromDestruction()
+{
+    if (!m_plugin || m_plugin->isBeingDestroyed())
+        return;
+
+    // A plug-in may ask us to evaluate JavaScript that removes the plug-in from the
+    // page, but expect the object to still be alive when the call completes. Flash,
+    // for example, may crash if the plug-in is destroyed and we return to code for
+    // the destroyed object higher on the stack. To prevent this, if the plug-in has
+    // only one remaining reference, call deref() asynchronously.
+    if (hasOneRef()) {
+        RunLoop::main().dispatch([lastRef = adoptRef(*this)] {
+        });
+        return;
+    }
+
+    deref();
+}
 
 void PluginView::didFinishLoad(WebFrame* webFrame)
 {
@@ -1284,6 +1665,9 @@ bool PluginView::shouldCreateTransientPa
         }
     }
 
+    if (!m_plugin->canCreateTransientPaintingSnapshot())
+        return false;
+
     return true;
 }
 
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginView.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginView.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/PluginView.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/PluginView.h	2022-03-22 16:38:57.397580237 -0500
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "LayerTreeContext.h"
+#include "NPRuntimeObjectMap.h"
 #include "Plugin.h"
 #include "PluginController.h"
 #include "WebFrame.h"
@@ -68,6 +69,8 @@ class PluginView : public WebCore::Plugi
 public:
     static Ref<PluginView> create(WebCore::HTMLPlugInElement&, Ref<Plugin>&&, const Plugin::Parameters&);
 
+    void recreateAndInitialize(Ref<Plugin>&&);
+
     WebCore::Frame* frame() const;
 
     bool isBeingDestroyed() const { return !m_plugin || m_plugin->isBeingDestroyed(); }
@@ -83,6 +86,7 @@ public:
 #if PLATFORM(COCOA)
     void setDeviceScaleFactor(float);
     void windowAndViewFramesChanged(const WebCore::FloatRect& windowFrameInScreenCoordinates, const WebCore::FloatRect& viewFrameInWindowCoordinates);
+    bool sendComplexTextInput(uint64_t pluginComplexTextInputIdentifier, const String& textInput);
     RetainPtr<PDFDocument> pdfDocumentForPrinting() const { return m_plugin->pdfDocumentForPrinting(); }
     id accessibilityHitTest(const WebCore::IntPoint& point) const override { return m_plugin->accessibilityHitTest(point); }
     id accessibilityObject() const override;
@@ -115,6 +119,7 @@ public:
 
     RefPtr<WebCore::FragmentedSharedBuffer> liveResourceData() const;
     bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&);
+    String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const;
     bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const;
 
 private:
@@ -153,11 +158,14 @@ private:
 #endif
     JSC::JSObject* scriptObject(JSC::JSGlobalObject*) override;
     void storageBlockingStateChanged() override;
+    void privateBrowsingStateChanged(bool) override;
+    bool getFormValue(String&) override;
     bool scroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) override;
     WebCore::Scrollbar* horizontalScrollbar() override;
     WebCore::Scrollbar* verticalScrollbar() override;
     bool wantsWheelEvents() override;
     bool shouldAllowNavigationFromDrags() const override;
+    bool shouldNotAddLayer() const override;
     void willDetachRenderer() override;
 
     // WebCore::Widget
@@ -183,10 +191,45 @@ private:
     void pageMutedStateDidChange() override;
 
     // PluginController
+    void invalidate(const WebCore::IntRect&) override;
+    String userAgent() override;
     void loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const WebCore::HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups) override;
+    void cancelStreamLoad(uint64_t streamID) override;
+    void continueStreamLoad(uint64_t streamID) override;
+    void cancelManualStreamLoad() override;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    NPObject* windowScriptNPObject() override;
+    NPObject* pluginElementNPObject() override;
+    bool evaluate(NPObject*, const String& scriptString, NPVariant* result, bool allowPopups) override;
+    void setPluginIsPlayingAudio(bool) override;
+    bool isMuted() const override;
+#endif
+    void setStatusbarText(const String&) override;
+    bool isAcceleratedCompositingEnabled() override;
+    void pluginProcessCrashed() override;
+#if PLATFORM(COCOA)
+    void pluginFocusOrWindowFocusChanged(bool pluginHasFocusAndWindowHasFocus) override;
+    const WTF::MachSendRight& compositingRenderServerPort() override;
+#endif
     float contentsScaleFactor() override;
+    String proxiesForURL(const String&) override;
+    String cookiesForURL(const String&) override;
+    void setCookiesForURL(const String& urlString, const String& cookieString) override;
+    bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password) override;
+    bool isPrivateBrowsingEnabled() override;
+    bool asynchronousPluginInitializationEnabled() const override;
+    bool asynchronousPluginInitializationEnabledForAllPlugins() const override;
+    bool artificialPluginInitializationDelayEnabled() const override;
+    void protectPluginFromDestruction() override;
+    void unprotectPluginFromDestruction() override;
+#if PLATFORM(X11) && ENABLE(NETSCAPE_PLUGIN_API)
+    uint64_t createPluginContainer() override;
+    void windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID) override;
+    void windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID) override;
+#endif
 
     void didInitializePlugin() override;
+    void didFailToInitializePlugin() override;
     void destroyPluginAndReset();
 
     // WebFrame::LoadListener
@@ -197,12 +240,13 @@ private:
 
     RefPtr<WebCore::HTMLPlugInElement> m_pluginElement;
     RefPtr<Plugin> m_plugin;
-    WeakPtr<WebPage> m_webPage;
+    WebPage* m_webPage;
     Plugin::Parameters m_parameters;
 
     bool m_isInitialized { false };
     bool m_isWaitingForSynchronousInitialization { false };
     bool m_isWaitingUntilMediaCanStart { false };
+    bool m_pluginProcessHasCrashed { false };
 
     // Pending URLRequests that the plug-in has made.
     Deque<RefPtr<URLRequest>> m_pendingURLRequests;
@@ -215,6 +259,11 @@ private:
     // Streams that the plug-in has requested to load. 
     HashMap<uint64_t, RefPtr<Stream>> m_streams;
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    // A map of all related NPObjects for this plug-in view.
+    NPRuntimeObjectMap m_npRuntimeObjectMap { this };
+#endif
+
     // The manual stream state. This is used so we can deliver a manual stream to a plug-in
     // when it is initialized.
     enum class ManualStreamState { Initial, HasReceivedResponse, Finished, Failed };
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/WebPluginInfoProvider.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/WebPluginInfoProvider.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/WebPluginInfoProvider.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/WebPluginInfoProvider.cpp	2022-03-22 16:38:57.397580237 -0500
@@ -67,11 +67,23 @@ WebPluginInfoProvider::~WebPluginInfoPro
 
 void WebPluginInfoProvider::refreshPlugins()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    m_cachedPlugins.clear();
+    m_pluginCacheIsPopulated = false;
+    m_shouldRefreshPlugins = true;
+#endif
 }
 
 Vector<PluginInfo> WebPluginInfoProvider::pluginInfo(Page& page, std::optional<Vector<SupportedPluginIdentifier>>& supportedPluginIdentifiers)
 {
-#if ENABLE(PDFKIT_PLUGIN)
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    populatePluginCache(page);
+
+    if (m_cachedSupportedPluginIdentifiers)
+        supportedPluginIdentifiers = *m_cachedSupportedPluginIdentifiers;
+
+    return page.mainFrame().arePluginsEnabled() ? m_cachedPlugins : m_cachedApplicationPlugins;
+#elif ENABLE(PDFKIT_PLUGIN)
     UNUSED_PARAM(page);
     UNUSED_PARAM(supportedPluginIdentifiers);
     return { PDFPlugin::pluginInfo() };
@@ -79,7 +91,7 @@ Vector<PluginInfo> WebPluginInfoProvider
     UNUSED_PARAM(page);
     UNUSED_PARAM(supportedPluginIdentifiers);
     return { };
-#endif // ENABLE(PDFKIT_PLUGIN)
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
 }
 
 Vector<WebCore::PluginInfo> WebPluginInfoProvider::webVisiblePluginInfo(Page& page, const URL& url)
@@ -109,4 +121,27 @@ Vector<WebCore::PluginInfo> WebPluginInf
     return plugins;
 }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+void WebPluginInfoProvider::populatePluginCache(const WebCore::Page& page)
+{
+    if (!m_pluginCacheIsPopulated) {
+#if PLATFORM(COCOA)
+        // Application plugins are not affected by enablePlugins setting, so we always need to scan plugins to get them.
+        bool shouldScanPlugins = true;
+#else
+        bool shouldScanPlugins = page.mainFrame().arePluginsEnabled();
+#endif
+        if (shouldScanPlugins) {
+            HangDetectionDisabler hangDetectionDisabler;
+            if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebProcessProxy::GetPlugins(m_shouldRefreshPlugins),
+                Messages::WebProcessProxy::GetPlugins::Reply(m_cachedPlugins, m_cachedApplicationPlugins, m_cachedSupportedPluginIdentifiers), 0))
+                return;
+        }
+
+        m_shouldRefreshPlugins = false;
+        m_pluginCacheIsPopulated = true;
+    }
+}
+#endif
+
 }
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/WebPluginInfoProvider.h webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/WebPluginInfoProvider.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/Plugins/WebPluginInfoProvider.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/Plugins/WebPluginInfoProvider.h	2022-03-22 16:38:57.397580237 -0500
@@ -43,6 +43,18 @@ private:
     Vector<WebCore::PluginInfo> pluginInfo(WebCore::Page&, std::optional<Vector<WebCore::SupportedPluginIdentifier>>&) final;
     Vector<WebCore::PluginInfo> webVisiblePluginInfo(WebCore::Page&, const URL&) final;
     void refreshPlugins() override;
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    void populatePluginCache(const WebCore::Page&);
+#endif
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    bool m_pluginCacheIsPopulated { false };
+    bool m_shouldRefreshPlugins { false };
+    Vector<WebCore::PluginInfo> m_cachedPlugins;
+    Vector<WebCore::PluginInfo> m_cachedApplicationPlugins;
+    std::optional<Vector<WebCore::SupportedPluginIdentifier>> m_cachedSupportedPluginIdentifiers;
+#endif
 };
 
 }
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2022-03-22 16:38:57.401580258 -0500
@@ -707,8 +707,23 @@ bool WebChromeClient::shouldUnavailableP
     
 void WebChromeClient::unavailablePluginButtonClicked(Element& element, RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason) const
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    ASSERT(element.hasTagName(objectTag) || element.hasTagName(embedTag) || element.hasTagName(appletTag));
+    ASSERT(pluginUnavailabilityReason == RenderEmbeddedObject::PluginMissing || pluginUnavailabilityReason == RenderEmbeddedObject::InsecurePluginVersion || pluginUnavailabilityReason);
+
+    auto& pluginElement = downcast<HTMLPlugInImageElement>(element);
+
+    String frameURLString = pluginElement.document().frame()->loader().documentLoader()->responseURL().string();
+    String pageURLString = m_page.mainFrame()->loader().documentLoader()->responseURL().string();
+    String pluginURLString = pluginElement.document().completeURL(pluginElement.url()).string();
+    URL pluginspageAttributeURL = pluginElement.document().completeURL(stripLeadingAndTrailingHTMLSpaces(pluginElement.attributeWithoutSynchronization(pluginspageAttr)));
+    if (!pluginspageAttributeURL.protocolIsInHTTPFamily())
+        pluginspageAttributeURL = URL();
+    m_page.send(Messages::WebPageProxy::UnavailablePluginButtonClicked(pluginUnavailabilityReason, pluginElement.serviceType(), pluginURLString, pluginspageAttributeURL.string(), frameURLString, pageURLString));
+#else
     UNUSED_PARAM(element);
     UNUSED_PARAM(pluginUnavailabilityReason);
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
 }
 
 void WebChromeClient::mouseDidMoveOverElement(const HitTestResult& hitTestResult, unsigned modifierFlags, const String& toolTip, TextDirection)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp	2022-03-22 16:38:57.401580258 -0500
@@ -33,6 +33,7 @@
 #include "NetworkConnectionToWebProcessMessages.h"
 #include "NetworkProcessConnection.h"
 #include "NetworkResourceLoadParameters.h"
+#include "PluginInfoStore.h"
 #include "SharedBufferCopy.h"
 #include "WebCoreArgumentCoders.h"
 #include "WebErrors.h"
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebPage/WebPage.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/WebPage/WebPage.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2022-03-22 16:38:57.401580258 -0500
@@ -49,10 +49,13 @@
 #include "MediaKeySystemPermissionRequestManager.h"
 #include "MediaPlaybackState.h"
 #include "MediaRecorderProvider.h"
+#include "NetscapePlugin.h"
 #include "NetworkConnectionToWebProcessMessages.h"
 #include "NetworkProcessConnection.h"
 #include "NotificationPermissionRequestManager.h"
 #include "PageBanner.h"
+#include "PluginProcessAttributes.h"
+#include "PluginProxy.h"
 #include "PluginView.h"
 #include "PrintInfo.h"
 #include "RemoteRenderingBackendProxy.h"
@@ -1163,11 +1166,53 @@ void WebPage::initializeInjectedBundleFu
 #if ENABLE(PDFKIT_PLUGIN)
 RefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, HTMLPlugInElement* pluginElement, const Plugin::Parameters& parameters, String& newMIMEType)
 {
-    if (shouldUsePDFPlugin(parameters.mimeType, parameters.url.path()))
-        return PDFPlugin::create(*frame, pluginElement);
+    String frameURLString = frame->coreFrame()->loader().documentLoader()->responseURL().string();
+    String pageURLString = m_page->mainFrame().loader().documentLoader()->responseURL().string();
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    bool allowOnlyApplicationPlugins = !frame->coreFrame()->arePluginsEnabled();
+#endif
+
+    uint64_t pluginProcessToken { 0 };
+    uint32_t pluginLoadPolicy { 0 };
+    String unavailabilityDescription;
+    bool isUnsupported { false };
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    if (!sendSync(Messages::WebPageProxy::FindPlugin(parameters.mimeType, parameters.url.string(), frameURLString, pageURLString, allowOnlyApplicationPlugins), Messages::WebPageProxy::FindPlugin::Reply(pluginProcessToken, newMIMEType, pluginLoadPolicy, unavailabilityDescription, isUnsupported)))
+        return nullptr;
+#endif
+
+    PluginModuleLoadPolicy loadPolicy = static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy);
+    bool isBlockedPlugin = (loadPolicy == PluginModuleBlockedForSecurity) || (loadPolicy == PluginModuleBlockedForCompatibility);
+
+    if (isUnsupported || isBlockedPlugin || !pluginProcessToken) {
+#if ENABLE(PDFKIT_PLUGIN)
+        if (shouldUsePDFPlugin(parameters.mimeType, parameters.url.path()))
+            return PDFPlugin::create(*frame, pluginElement);
+#endif
+    }
+
+    if (isUnsupported) {
+        pluginElement->setReplacement(RenderEmbeddedObject::UnsupportedPlugin, unavailabilityDescription);
+        return nullptr;
+    }
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    if (isBlockedPlugin) {
+        bool isReplacementObscured = pluginElement->setReplacement(RenderEmbeddedObject::InsecurePluginVersion, unavailabilityDescription);
+        send(Messages::WebPageProxy::DidBlockInsecurePluginVersion(parameters.mimeType, parameters.url.string(), frameURLString, pageURLString, isReplacementObscured));
+        return nullptr;
+    }
+
+    if (!pluginProcessToken)
+        return nullptr;
+
+    return PluginProxy::create(pluginProcessToken);
+#else
     return nullptr;
+#endif
 }
-#endif // ENABLE(PDFKIT_PLUGIN)
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
 
 #if ENABLE(WEBGL) && !PLATFORM(MAC)
 WebCore::WebGLLoadPolicy WebPage::webGLPolicyForURL(WebFrame*, const URL&)
@@ -3982,6 +4027,9 @@ void WebPage::updatePreferences(const We
     DatabaseManager::singleton().setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
 
     m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey());
+    m_asynchronousPluginInitializationEnabled = store.getBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledKey());
+    m_asynchronousPluginInitializationEnabledForAllPlugins = store.getBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledForAllPluginsKey());
+    m_artificialPluginInitializationDelayEnabled = store.getBoolValueForKey(WebPreferencesKey::artificialPluginInitializationDelayEnabledKey());
 
     bool isAppNapEnabled = store.getBoolValueForKey(WebPreferencesKey::pageVisibilityBasedProcessSuppressionEnabledKey());
     if (m_isAppNapEnabled != isAppNapEnabled) {
@@ -5863,8 +5911,24 @@ FrameView* WebPage::mainFrameView() cons
 
 bool WebPage::canPluginHandleResponse(const ResourceResponse& response)
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    uint32_t pluginLoadPolicy;
+    bool allowOnlyApplicationPlugins = !m_mainFrame->coreFrame()->arePluginsEnabled();
+
+    uint64_t pluginProcessToken;
+    String newMIMEType;
+    String unavailabilityDescription;
+    bool isUnsupported = false;
+    if (!sendSync(Messages::WebPageProxy::FindPlugin(response.mimeType(), response.url().string(), response.url().string(), response.url().string(), allowOnlyApplicationPlugins), Messages::WebPageProxy::FindPlugin::Reply(pluginProcessToken, newMIMEType, pluginLoadPolicy, unavailabilityDescription, isUnsupported)))
+        return false;
+
+    ASSERT(!isUnsupported);
+    bool isBlockedPlugin = (pluginLoadPolicy == PluginModuleBlockedForSecurity) || (pluginLoadPolicy == PluginModuleBlockedForCompatibility);
+    return !isUnsupported && !isBlockedPlugin && pluginProcessToken;
+#else
     UNUSED_PARAM(response);
     return false;
+#endif
 }
 
 bool WebPage::shouldUseCustomContentProviderForResponse(const ResourceResponse& response)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebPage/WebPage.h webkitgtk-2.36.0/Source/WebKit/WebProcess/WebPage/WebPage.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebPage/WebPage.h	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/WebPage/WebPage.h	2022-03-22 16:38:57.401580258 -0500
@@ -949,6 +949,8 @@ public:
     WKAccessibilityWebPageObject* accessibilityRemoteObject();
     NSObject *accessibilityObjectForMainFramePlugin();
     const WebCore::FloatPoint& accessibilityPosition() const { return m_accessibilityPosition; }
+    
+    void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput);
 
     void setTextAsync(const String&);
     void insertTextAsync(const String& text, const EditingRange& replacementRange, InsertTextOptions&&);
@@ -1146,6 +1148,13 @@ public:
 
     bool shouldUseCustomContentProviderForResponse(const WebCore::ResourceResponse&);
 
+    bool asynchronousPluginInitializationEnabled() const { return m_asynchronousPluginInitializationEnabled; }
+    void setAsynchronousPluginInitializationEnabled(bool enabled) { m_asynchronousPluginInitializationEnabled = enabled; }
+    bool asynchronousPluginInitializationEnabledForAllPlugins() const { return m_asynchronousPluginInitializationEnabledForAllPlugins; }
+    void setAsynchronousPluginInitializationEnabledForAllPlugins(bool enabled) { m_asynchronousPluginInitializationEnabledForAllPlugins = enabled; }
+    bool artificialPluginInitializationDelayEnabled() const { return m_artificialPluginInitializationDelayEnabled; }
+    void setArtificialPluginInitializationDelayEnabled(bool enabled) { m_artificialPluginInitializationDelayEnabled = enabled; }
+
 #if PLATFORM(COCOA)
     bool pdfPluginEnabled() const { return m_pdfPluginEnabled; }
     void setPDFPluginEnabled(bool enabled) { m_pdfPluginEnabled = enabled; }
@@ -2010,6 +2019,9 @@ private:
     bool m_isClosed { false };
     bool m_tabToLinks { false };
     
+    bool m_asynchronousPluginInitializationEnabled { false };
+    bool m_asynchronousPluginInitializationEnabledForAllPlugins { false };
+    bool m_artificialPluginInitializationDelayEnabled { false };
     bool m_mainFrameIsScrollable { true };
 
     bool m_alwaysShowsHorizontalScroller { false };
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebPage/WebPage.messages.in webkitgtk-2.36.0/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2022-02-23 02:59:05.000000000 -0600
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2022-03-22 16:38:57.401580258 -0500
@@ -461,6 +461,9 @@ GenerateSyntheticEditingCommand(enum:uin
 #endif
 
 #if PLATFORM(COCOA)
+    # Complex text input support for plug-ins.
+    SendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, String textInput)
+
     WindowAndViewFramesChanged(WebCore::FloatRect windowFrameInScreenCoordinates, WebCore::FloatRect windowFrameInUnflippedScreenCoordinates, WebCore::FloatRect viewFrameInWindowCoordinates, WebCore::FloatPoint accessibilityViewCoordinates)
     SetMainFrameIsScrollable(bool isScrollable)
     RegisterUIProcessAccessibilityTokens(IPC::DataReference elemenToken, IPC::DataReference windowToken)
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebProcess.cpp webkitgtk-2.36.0/Source/WebKit/WebProcess/WebProcess.cpp
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebProcess.cpp	2022-03-18 07:53:19.000000000 -0500
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/WebProcess.cpp	2022-03-22 16:43:52.295137293 -0500
@@ -42,6 +42,7 @@
 #include "NetworkProcessConnectionInfo.h"
 #include "NetworkSession.h"
 #include "NetworkSessionCreationParameters.h"
+#include "PluginProcessConnectionManager.h"
 #include "ProcessAssertion.h"
 #include "RemoteAudioHardwareListener.h"
 #include "RemoteAudioSession.h"
@@ -287,6 +288,9 @@ WebProcess::WebProcess()
     , m_webLockRegistry(RemoteWebLockRegistry::create(*this))
     , m_cookieJar(WebCookieJar::create())
     , m_dnsPrefetchHystereris([this](PAL::HysteresisState state) { if (state == PAL::HysteresisState::Stopped) m_dnsPrefetchedHosts.clear(); })
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    , m_pluginProcessConnectionManager(PluginProcessConnectionManager::create())
+#endif
     , m_nonVisibleProcessGraphicsCleanupTimer(*this, &WebProcess::nonVisibleProcessGraphicsCleanupTimerFired)
 #if ENABLE(NON_VISIBLE_WEBPROCESS_MEMORY_CLEANUP_TIMER)
     , m_nonVisibleProcessMemoryCleanupTimer(*this, &WebProcess::nonVisibleProcessMemoryCleanupTimerFired)
@@ -380,6 +384,10 @@ void WebProcess::initializeConnection(IP
 
     m_webInspectorInterruptDispatcher->initializeConnection(connection);
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    m_pluginProcessConnectionManager->initializeConnection(connection);
+#endif
+
     for (auto& supplement : m_supplements.values())
         supplement->initializeConnection(connection);
 
@@ -550,6 +558,8 @@ void WebProcess::initializeWebProcess(We
 
     setShouldUseFontSmoothing(parameters.shouldUseFontSmoothing);
 
+    setTerminationTimeout(parameters.terminationTimeout);
+
     setMemoryCacheDisabled(parameters.memoryCacheDisabled);
 
     WebCore::RuntimeEnabledFeatures::sharedFeatures().setAttrStyleEnabled(parameters.attrStyleEnabled);
@@ -778,6 +788,13 @@ void WebProcess::fullKeyboardAccessModeC
     m_fullKeyboardAccessEnabled = fullKeyboardAccessEnabled;
 }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+PluginProcessConnectionManager& WebProcess::pluginProcessConnectionManager()
+{
+    return *m_pluginProcessConnectionManager;
+}
+#endif
+
 void WebProcess::setCacheModel(CacheModel cacheModel)
 {
     if (m_hasSetCacheModel && (cacheModel == m_cacheModel))
@@ -1017,6 +1034,9 @@ void WebProcess::isJITEnabled(Completion
 
 void WebProcess::refreshPlugins()
 {
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    WebPluginInfoProvider::singleton().refresh(false);
+#endif
 }
 
 void WebProcess::garbageCollectJavaScriptObjects()
diff -urpN webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebProcess.h webkitgtk-2.36.0/Source/WebKit/WebProcess/WebProcess.h
--- webkitgtk-2.36.0.orig/Source/WebKit/WebProcess/WebProcess.h	2022-03-16 08:48:02.000000000 -0500
+++ webkitgtk-2.36.0/Source/WebKit/WebProcess/WebProcess.h	2022-03-22 16:38:57.401580258 -0500
@@ -29,6 +29,7 @@
 #include "AuxiliaryProcess.h"
 #include "CacheModel.h"
 #include "IdentifierTypes.h"
+#include "PluginProcessConnectionManager.h"
 #include "SandboxExtension.h"
 #include "StorageAreaMapIdentifier.h"
 #include "TextCheckerState.h"
@@ -236,6 +237,10 @@ public:
     
     const TextCheckerState& textCheckerState() const { return m_textCheckerState; }
     void setTextCheckerState(const TextCheckerState&);
+    
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    PluginProcessConnectionManager& pluginProcessConnectionManager();
+#endif
 
     EventDispatcher& eventDispatcher() { return m_eventDispatcher.get(); }
 
@@ -683,6 +688,10 @@ private:
 
     std::unique_ptr<WebAutomationSessionProxy> m_automationSessionProxy;
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    RefPtr<PluginProcessConnectionManager> m_pluginProcessConnectionManager;
+#endif
+
 #if ENABLE(SERVICE_CONTROLS)
     bool m_hasImageServices { false };
     bool m_hasSelectionServices { false };
diff -urpN webkitgtk-2.36.0.orig/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml webkitgtk-2.36.0/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml
--- webkitgtk-2.36.0.orig/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml	2022-02-23 02:58:57.000000000 -0600
+++ webkitgtk-2.36.0/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml	2022-03-22 16:38:57.401580258 -0500
@@ -281,6 +281,18 @@ EventHandlerDrivenSmoothKeyboardScrollin
   WebCore:
    default: false
 
+# FIXME: This is not relevent for WebKitLegacy, so should be excluded from WebKitLegacy entirely.
+ExperimentalPlugInSandboxProfilesEnabled:
+  type: bool
+  humanReadableName: "Sandbox Plug-Ins"
+  humanReadableDescription: "Enable Plug-In sandboxing"
+  webcoreBinding: RuntimeEnabledFeatures
+  defaultValue:
+    WebKitLegacy:
+      default: false
+    WebKit:
+      default: false
+
 FasterClicksEnabled:
   type: bool
   humanReadableName: "Fast clicks"
diff -urpN webkitgtk-2.36.0.orig/Source/WTF/Scripts/Preferences/WebPreferences.yaml webkitgtk-2.36.0/Source/WTF/Scripts/Preferences/WebPreferences.yaml
--- webkitgtk-2.36.0.orig/Source/WTF/Scripts/Preferences/WebPreferences.yaml	2022-02-23 02:58:57.000000000 -0600
+++ webkitgtk-2.36.0/Source/WTF/Scripts/Preferences/WebPreferences.yaml	2022-03-22 16:38:57.401580258 -0500
@@ -312,6 +312,30 @@ ApplePayEnabled:
       "ENABLE(APPLE_PAY_REMOTE_UI)": true
       default: false
 
+ArtificialPluginInitializationDelayEnabled:
+  type: bool
+  webcoreBinding: none
+  exposed: [ WebKit ]
+  defaultValue:
+    WebKit:
+      default: false
+
+AsynchronousPluginInitializationEnabled:
+  type: bool
+  webcoreBinding: none
+  exposed: [ WebKit ]
+  defaultValue:
+    WebKit:
+      default: false
+
+AsynchronousPluginInitializationEnabledForAllPlugins:
+  type: bool
+  webcoreBinding: none
+  exposed: [ WebKit ]
+  defaultValue:
+    WebKit:
+      default: false
+
 AsynchronousSpellCheckingEnabled:
   type: bool
   defaultValue:
@@ -345,6 +369,17 @@ AuthorAndUserStylesEnabled:
     WebCore:
       default: true
 
+BackForwardCacheSupportsPlugins:
+  type: bool
+  webKitLegacyPreferenceKey: WebKitPageCacheSupportsPluginsPreferenceKey
+  defaultValue:
+    WebKitLegacy:
+      default: true
+    WebKit:
+      default: true
+    WebCore:
+      default: false
+
 BackspaceKeyNavigationEnabled:
   type: bool
   defaultValue:
diff -urpN webkitgtk-2.36.0.orig/Source/WTF/wtf/PlatformEnable.h webkitgtk-2.36.0/Source/WTF/wtf/PlatformEnable.h
--- webkitgtk-2.36.0.orig/Source/WTF/wtf/PlatformEnable.h	2022-02-23 02:58:57.000000000 -0600
+++ webkitgtk-2.36.0/Source/WTF/wtf/PlatformEnable.h	2022-03-22 16:38:57.401580258 -0500
@@ -395,6 +395,10 @@
 #define ENABLE_MOUSE_FORCE_EVENTS 1
 #endif
 
+#if !defined(ENABLE_NETSCAPE_PLUGIN_API)
+#define ENABLE_NETSCAPE_PLUGIN_API 0
+#endif
+
 #if !defined(ENABLE_NETSCAPE_PLUGIN_METADATA_CACHE)
 #define ENABLE_NETSCAPE_PLUGIN_METADATA_CACHE 0
 #endif
diff -urpN webkitgtk-2.36.0.orig/Tools/PlatformGTK.cmake webkitgtk-2.36.0/Tools/PlatformGTK.cmake
--- webkitgtk-2.36.0.orig/Tools/PlatformGTK.cmake	2022-02-23 02:59:06.000000000 -0600
+++ webkitgtk-2.36.0/Tools/PlatformGTK.cmake	2022-03-22 16:38:57.401580258 -0500
@@ -7,6 +7,10 @@ if (DEVELOPER_MODE)
     if (ENABLE_API_TESTS)
         add_subdirectory(TestWebKitAPI/glib)
     endif ()
+
+    if (ENABLE_NETSCAPE_PLUGIN_API)
+        add_subdirectory(DumpRenderTree/TestNetscapePlugIn)
+    endif ()
 endif ()
 
 if (ENABLE_MINIBROWSER)
diff -urpN webkitgtk-2.36.0.orig/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitSettings.cpp webkitgtk-2.36.0/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitSettings.cpp
--- webkitgtk-2.36.0.orig/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitSettings.cpp	2022-02-23 02:59:07.000000000 -0600
+++ webkitgtk-2.36.0/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitSettings.cpp	2022-03-22 16:38:57.401580258 -0500
@@ -82,6 +82,11 @@ static void testWebKitSettings(Test*, gc
     webkit_settings_set_enable_frame_flattening(settings, TRUE);
     g_assert_true(webkit_settings_get_enable_frame_flattening(settings));
 
+    // Plugins are enabled by default.
+    g_assert_true(webkit_settings_get_enable_plugins(settings));
+    webkit_settings_set_enable_plugins(settings, FALSE);
+    g_assert_false(webkit_settings_get_enable_plugins(settings));
+
     // Java is enabled by default.
     g_assert_true(webkit_settings_get_enable_java(settings));
     webkit_settings_set_enable_java(settings, FALSE);
diff -urpN webkitgtk-2.36.0.orig/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp webkitgtk-2.36.0/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp
--- webkitgtk-2.36.0.orig/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp	2022-02-23 02:59:07.000000000 -0600
+++ webkitgtk-2.36.0/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp	2022-03-22 16:38:57.401580258 -0500
@@ -78,6 +78,84 @@ static void testWebContextEphemeral(Test
     g_assert_true(webkit_web_context_is_ephemeral(context.get()));
 }
 
+#if ENABLE(NETSCAPE_PLUGIN_API)
+class PluginsTest: public Test {
+public:
+    MAKE_GLIB_TEST_FIXTURE(PluginsTest);
+
+    PluginsTest()
+        : m_mainLoop(g_main_loop_new(nullptr, TRUE))
+        , m_plugins(nullptr)
+    {
+        webkit_web_context_set_additional_plugins_directory(m_webContext.get(), WEBKIT_TEST_PLUGIN_DIR);
+    }
+
+    ~PluginsTest()
+    {
+        g_main_loop_unref(m_mainLoop);
+        g_list_free_full(m_plugins, g_object_unref);
+    }
+
+    static void getPluginsAsyncReadyCallback(GObject*, GAsyncResult* result, PluginsTest* test)
+    {
+        test->m_plugins = webkit_web_context_get_plugins_finish(test->m_webContext.get(), result, nullptr);
+        g_main_loop_quit(test->m_mainLoop);
+    }
+
+    GList* getPlugins()
+    {
+        g_list_free_full(m_plugins, g_object_unref);
+        webkit_web_context_get_plugins(m_webContext.get(), nullptr, reinterpret_cast<GAsyncReadyCallback>(getPluginsAsyncReadyCallback), this);
+        g_main_loop_run(m_mainLoop);
+        return m_plugins;
+    }
+
+    GMainLoop* m_mainLoop;
+    GList* m_plugins;
+};
+
+static void testWebContextGetPlugins(PluginsTest* test, gconstpointer)
+{
+    GList* plugins = test->getPlugins();
+    g_assert_nonnull(plugins);
+
+    GRefPtr<WebKitPlugin> testPlugin;
+    for (GList* item = plugins; item; item = g_list_next(item)) {
+        WebKitPlugin* plugin = WEBKIT_PLUGIN(item->data);
+        test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(plugin));
+        if (!g_strcmp0(webkit_plugin_get_name(plugin), "WebKit Test PlugIn")) {
+            testPlugin = plugin;
+            break;
+        }
+    }
+    g_assert_true(WEBKIT_IS_PLUGIN(testPlugin.get()));
+
+    char normalizedPath[PATH_MAX];
+    g_assert_nonnull(realpath(WEBKIT_TEST_PLUGIN_DIR, normalizedPath));
+    GUniquePtr<char> pluginPath(g_build_filename(normalizedPath, "libTestNetscapePlugIn.so", nullptr));
+    g_assert_cmpstr(webkit_plugin_get_path(testPlugin.get()), ==, pluginPath.get());
+    g_assert_cmpstr(webkit_plugin_get_description(testPlugin.get()), ==, "Simple Netscape® plug-in that handles test content for WebKit");
+    GList* mimeInfoList = webkit_plugin_get_mime_info_list(testPlugin.get());
+    g_assert_nonnull(mimeInfoList);
+    g_assert_cmpuint(g_list_length(mimeInfoList), ==, 2);
+
+    WebKitMimeInfo* mimeInfo = static_cast<WebKitMimeInfo*>(mimeInfoList->data);
+    g_assert_cmpstr(webkit_mime_info_get_mime_type(mimeInfo), ==, "image/png");
+    g_assert_cmpstr(webkit_mime_info_get_description(mimeInfo), ==, "png image");
+    const gchar* const* extensions = webkit_mime_info_get_extensions(mimeInfo);
+    g_assert_nonnull(extensions);
+    g_assert_cmpstr(extensions[0], ==, "png");
+
+    mimeInfoList = g_list_next(mimeInfoList);
+    mimeInfo = static_cast<WebKitMimeInfo*>(mimeInfoList->data);
+    g_assert_cmpstr(webkit_mime_info_get_mime_type(mimeInfo), ==, "application/x-webkit-test-netscape");
+    g_assert_cmpstr(webkit_mime_info_get_description(mimeInfo), ==, "test netscape content");
+    extensions = webkit_mime_info_get_extensions(mimeInfo);
+    g_assert_nonnull(extensions);
+    g_assert_cmpstr(extensions[0], ==, "testnetscape");
+}
+#endif // ENABLE(NETSCAPE_PLUGIN_API)
+
 static const char* kBarHTML = "<html><body>Bar</body></html>";
 static const char* kEchoHTMLFormat = "<html><body>%s</body></html>";
 static const char* errorDomain = "test";
@@ -998,6 +1076,9 @@ void beforeAll()
 
     Test::add("WebKitWebContext", "default-context", testWebContextDefault);
     Test::add("WebKitWebContext", "ephemeral", testWebContextEphemeral);
+#if ENABLE(NETSCAPE_PLUGIN_API)
+    PluginsTest::add("WebKitWebContext", "get-plugins", testWebContextGetPlugins);
+#endif
     URISchemeTest::add("WebKitWebContext", "uri-scheme", testWebContextURIScheme);
     // FIXME: implement spellchecker in WPE.
 #if PLATFORM(GTK)
