<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre, #msg p { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[28700] trunk</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/28700">28700</a></dd>
<dt>Author</dt> <dd>aroben@apple.com</dd>
<dt>Date</dt> <dd>2007-12-13 17:07:19 -0800 (Thu, 13 Dec 2007)</dd>
</dl>

<h3>Log Message</h3>
<pre>Fix &lt;rdar://5517707&gt; Crash on wptv.wp.pl when &quot;make bigger&quot; button is clicked

WebCore:

        Fix &lt;rdar://5517707&gt; Crash on wptv.wp.pl when &quot;make bigger&quot; button is clicked

        Windows Media Player has a modal message loop that will deliver
        messages to us at inappropriate times and we will crash if we handle
        them when they are delivered. In PluginViewWin, we add a quirk for
        Media Player to set a flag whenever we give the plugin a chance to
        execute code, and in SharedTimerWin we check if the plugin is
        executing code and repost messages if so.

        Reviewed by Anders.

        * platform/win/SharedTimerWin.cpp:
        (WebCore::TimerWindowWndProc): Repost messages if we're calling a
        plugin.
        * plugins/win/PluginViewWin.cpp: Surround all calls to the plugin with
        setCallingPlugin(true/false).
        (WebCore::PluginViewWin::updateWindow):
        (WebCore::PluginViewWin::dispatchNPEvent):
        (WebCore::PluginViewWin::setNPWindowRect):
        (WebCore::PluginViewWin::start):
        (WebCore::PluginViewWin::stop):
        (WebCore::PluginViewWin::performRequest):
        (WebCore::PluginViewWin::bindingInstance):
        (WebCore::PluginViewWin::determineQuirks):
        (WebCore::PluginViewWin::setCallingPlugin): Added.
        (WebCore::PluginViewWin::isCallingPlugin): Added.
        * plugins/win/PluginViewWin.h: Added a new quirk.

WebKit/win:

        Fix &lt;rdar://5517707&gt; Crash on wptv.wp.pl when &quot;make bigger&quot; button is clicked

        Reviewed by Anders.

        * WebView.cpp:
        (WebViewWndProc): Repost paint messages and ignore all other messages
        when we're calling a plugin.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebCoreChangeLog">trunk/WebCore/ChangeLog</a></li>
<li><a href="#trunkWebCoreplatformwinSharedTimerWincpp">trunk/WebCore/platform/win/SharedTimerWin.cpp</a></li>
<li><a href="#trunkWebCorepluginswinPluginViewWincpp">trunk/WebCore/plugins/win/PluginViewWin.cpp</a></li>
<li><a href="#trunkWebCorepluginswinPluginViewWinh">trunk/WebCore/plugins/win/PluginViewWin.h</a></li>
<li><a href="#trunkWebKitwinChangeLog">trunk/WebKit/win/ChangeLog</a></li>
<li><a href="#trunkWebKitwinWebViewcpp">trunk/WebKit/win/WebView.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/ChangeLog (28699 => 28700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/ChangeLog        2007-12-14 00:56:10 UTC (rev 28699)
+++ trunk/WebCore/ChangeLog        2007-12-14 01:07:19 UTC (rev 28700)
</span><span class="lines">@@ -1,3 +1,33 @@
</span><ins>+2007-12-13  Adam Roben  &lt;aroben@apple.com&gt;
+
+        Fix &lt;rdar://5517707&gt; Crash on wptv.wp.pl when &quot;make bigger&quot; button is clicked
+
+        Windows Media Player has a modal message loop that will deliver
+        messages to us at inappropriate times and we will crash if we handle
+        them when they are delivered. In PluginViewWin, we add a quirk for
+        Media Player to set a flag whenever we give the plugin a chance to
+        execute code, and in SharedTimerWin we check if the plugin is
+        executing code and repost messages if so.
+
+        Reviewed by Anders.
+
+        * platform/win/SharedTimerWin.cpp:
+        (WebCore::TimerWindowWndProc): Repost messages if we're calling a
+        plugin.
+        * plugins/win/PluginViewWin.cpp: Surround all calls to the plugin with
+        setCallingPlugin(true/false).
+        (WebCore::PluginViewWin::updateWindow):
+        (WebCore::PluginViewWin::dispatchNPEvent):
+        (WebCore::PluginViewWin::setNPWindowRect):
+        (WebCore::PluginViewWin::start):
+        (WebCore::PluginViewWin::stop):
+        (WebCore::PluginViewWin::performRequest):
+        (WebCore::PluginViewWin::bindingInstance):
+        (WebCore::PluginViewWin::determineQuirks):
+        (WebCore::PluginViewWin::setCallingPlugin): Added.
+        (WebCore::PluginViewWin::isCallingPlugin): Added.
+        * plugins/win/PluginViewWin.h: Added a new quirk.
+
</ins><span class="cx"> 2007-12-13  Alp Toker  &lt;alp@atoker.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add a missing DEPENDPATH. Fixes non-clean builds following networking
</span></span></pre></div>
<a id="trunkWebCoreplatformwinSharedTimerWincpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/platform/win/SharedTimerWin.cpp (28699 => 28700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/platform/win/SharedTimerWin.cpp        2007-12-14 00:56:10 UTC (rev 28699)
+++ trunk/WebCore/platform/win/SharedTimerWin.cpp        2007-12-14 01:07:19 UTC (rev 28700)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #include &quot;SharedTimer.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Page.h&quot;
</span><ins>+#include &quot;PluginViewWin.h&quot;
</ins><span class="cx"> #include &quot;SystemTime.h&quot;
</span><span class="cx"> #include &quot;Widget.h&quot;
</span><span class="cx"> #include &lt;wtf/Assertions.h&gt;
</span><span class="lines">@@ -45,6 +46,15 @@
</span><span class="cx"> 
</span><span class="cx"> LRESULT CALLBACK TimerWindowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
</span><span class="cx"> {
</span><ins>+    // Windows Media Player has a modal message loop that will deliver messages
+    // to us at inappropriate times and we will crash if we handle them when
+    // they are delivered. We repost all messages so that we will get to handle
+    // them once the modal loop exits.
+    if (PluginViewWin::isCallingPlugin()) {
+        PostMessage(hWnd, message, wParam, lParam);
+        return 0;
+    }
+
</ins><span class="cx">     if (message == timerFiredMessage) {
</span><span class="cx">         processingCustomTimerMessage = true;
</span><span class="cx">         sharedTimerFiredFunction();
</span></span></pre></div>
<a id="trunkWebCorepluginswinPluginViewWincpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/plugins/win/PluginViewWin.cpp (28699 => 28700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/plugins/win/PluginViewWin.cpp        2007-12-14 00:56:10 UTC (rev 28699)
+++ trunk/WebCore/plugins/win/PluginViewWin.cpp        2007-12-14 01:07:19 UTC (rev 28700)
</span><span class="lines">@@ -96,6 +96,7 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static const double MessageThrottleTimeInterval = 0.001;
</span><ins>+static int s_callingPlugin;
</ins><span class="cx"> 
</span><span class="cx"> class PluginMessageThrottlerWin {
</span><span class="cx"> public:
</span><span class="lines">@@ -345,6 +346,7 @@
</span><span class="cx">         //rgn = ::CreateRectRgn(0, 0, 0, 0);
</span><span class="cx">         //::SetWindowRgn(m_window, rgn, false);
</span><span class="cx"> 
</span><ins>+        setCallingPlugin(true);
</ins><span class="cx">         if (m_windowRect != oldWindowRect)
</span><span class="cx">             ::MoveWindow(m_window, m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(), true);
</span><span class="cx"> 
</span><span class="lines">@@ -352,6 +354,7 @@
</span><span class="cx">         rgn = ::CreateRectRgn(m_clipRect.x(), m_clipRect.y(), m_clipRect.right(), m_clipRect.bottom());
</span><span class="cx">         ::SetWindowRgn(m_window, rgn, true);
</span><span class="cx">         ::UpdateWindow(m_window);
</span><ins>+        setCallingPlugin(false);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -448,7 +451,9 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     KJS::JSLock::DropAllLocks dropAllLocks;
</span><ins>+    setCallingPlugin(true);
</ins><span class="cx">     bool result = m_plugin-&gt;pluginFuncs()-&gt;event(m_instance, &amp;npEvent);
</span><ins>+    setCallingPlugin(false);
</ins><span class="cx"> 
</span><span class="cx">     if (shouldPop) 
</span><span class="cx">         popPopupsEnabledState();
</span><span class="lines">@@ -679,7 +684,9 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_plugin-&gt;pluginFuncs()-&gt;setwindow) {
</span><span class="cx">         KJS::JSLock::DropAllLocks dropAllLocks;
</span><ins>+        setCallingPlugin(true);
</ins><span class="cx">         m_plugin-&gt;pluginFuncs()-&gt;setwindow(m_instance, &amp;m_npWindow);
</span><ins>+        setCallingPlugin(false);
</ins><span class="cx"> 
</span><span class="cx">         if (!m_isWindowed)
</span><span class="cx">             return;
</span><span class="lines">@@ -704,7 +711,9 @@
</span><span class="cx">     PluginViewWin::setCurrentPluginView(this);
</span><span class="cx">     {
</span><span class="cx">         KJS::JSLock::DropAllLocks dropAllLocks;
</span><ins>+        setCallingPlugin(true);
</ins><span class="cx">         npErr = m_plugin-&gt;pluginFuncs()-&gt;newp((NPMIMEType)m_mimeType.data(), m_instance, m_mode, m_paramCount, m_paramNames, m_paramValues, NULL);
</span><ins>+        setCallingPlugin(false);
</ins><span class="cx">         LOG_NPERROR(npErr);
</span><span class="cx">     }
</span><span class="cx">     PluginViewWin::setCurrentPluginView(0);
</span><span class="lines">@@ -752,12 +761,17 @@
</span><span class="cx"> 
</span><span class="cx">     // Clear the window
</span><span class="cx">     m_npWindow.window = 0;
</span><del>-    if (m_plugin-&gt;pluginFuncs()-&gt;setwindow)
</del><ins>+    if (m_plugin-&gt;pluginFuncs()-&gt;setwindow) {
+        setCallingPlugin(true);
</ins><span class="cx">         m_plugin-&gt;pluginFuncs()-&gt;setwindow(m_instance, &amp;m_npWindow);
</span><ins>+        setCallingPlugin(false);
+    }
</ins><span class="cx"> 
</span><span class="cx">     // Destroy the plugin
</span><span class="cx">     NPSavedData* savedData = 0;
</span><ins>+    setCallingPlugin(true);
</ins><span class="cx">     NPError npErr = m_plugin-&gt;pluginFuncs()-&gt;destroy(m_instance, &amp;savedData);
</span><ins>+    setCallingPlugin(false);
</ins><span class="cx">     LOG_NPERROR(npErr);
</span><span class="cx"> 
</span><span class="cx">     if (savedData) {
</span><span class="lines">@@ -832,7 +846,9 @@
</span><span class="cx">             // FIXME: &lt;rdar://problem/4807469&gt; This should be sent when the document has finished loading
</span><span class="cx">             if (request-&gt;sendNotification()) {
</span><span class="cx">                 KJS::JSLock::DropAllLocks dropAllLocks;
</span><ins>+                setCallingPlugin(true);
</ins><span class="cx">                 m_plugin-&gt;pluginFuncs()-&gt;urlnotify(m_instance, requestURL.deprecatedString().utf8(), NPRES_DONE, request-&gt;notifyData());
</span><ins>+                setCallingPlugin(false);
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         return;
</span><span class="lines">@@ -1389,7 +1405,9 @@
</span><span class="cx">     NPError npErr;
</span><span class="cx">     {
</span><span class="cx">         KJS::JSLock::DropAllLocks dropAllLocks;
</span><ins>+        setCallingPlugin(true);
</ins><span class="cx">         npErr = m_plugin-&gt;pluginFuncs()-&gt;getvalue(m_instance, NPPVpluginScriptableNPObject, &amp;object);
</span><ins>+        setCallingPlugin(false);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (npErr != NPERR_NO_ERROR || !object)
</span><span class="lines">@@ -1445,6 +1463,13 @@
</span><span class="cx">         // Windowless mode does not work at all with the WMP plugin so just remove that parameter 
</span><span class="cx">         // and don't pass it to the plug-in.
</span><span class="cx">         m_quirks |= PluginQuirkRemoveWindowlessVideoParam;
</span><ins>+
+        // WMP has a modal message loop that it enters whenever we call it or
+        // ask it to paint. This modal loop can deliver messages to other
+        // windows in WebKit at times when they are not expecting them (for
+        // example, delivering a WM_PAINT message during a layout), and these
+        // can cause crashes.
+        m_quirks |= PluginQuirkHasModalMessageLoop;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // The DivX plugin sets its size on the first NPP_SetWindow call and never updates its size, so
</span><span class="lines">@@ -1622,4 +1647,22 @@
</span><span class="cx">     m_manualStream-&gt;didFail(0, error);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PluginViewWin::setCallingPlugin(bool b) const
+{
+    if (!(m_quirks &amp; PluginQuirkHasModalMessageLoop))
+        return;
+
+    if (b)
+        ++s_callingPlugin;
+    else
+        --s_callingPlugin;
+
+    ASSERT(s_callingPlugin &gt;= 0);
+}
+
+bool PluginViewWin::isCallingPlugin()
+{
+    return s_callingPlugin &gt; 0;
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkWebCorepluginswinPluginViewWinh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/plugins/win/PluginViewWin.h (28699 => 28700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/plugins/win/PluginViewWin.h        2007-12-14 00:56:10 UTC (rev 28699)
+++ trunk/WebCore/plugins/win/PluginViewWin.h        2007-12-14 01:07:19 UTC (rev 28700)
</span><span class="lines">@@ -70,7 +70,8 @@
</span><span class="cx">         PluginQuirkRemoveWindowlessVideoParam = 1 &lt;&lt; 3,
</span><span class="cx">         PluginQuirkThrottleWMUserPlusOneMessages = 1 &lt;&lt; 4,
</span><span class="cx">         PluginQuirkDontUnloadPlugin = 1 &lt;&lt; 5,
</span><del>-        PluginQuirkDontCallWndProcForSameMessageRecursively = 1 &lt;&lt; 6
</del><ins>+        PluginQuirkDontCallWndProcForSameMessageRecursively = 1 &lt;&lt; 6,
+        PluginQuirkHasModalMessageLoop = 1 &lt;&lt; 7
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     enum PluginStatus {
</span><span class="lines">@@ -140,6 +141,9 @@
</span><span class="cx">         void didReceiveData(const char*, int);
</span><span class="cx">         void didFinishLoading();
</span><span class="cx">         void didFail(const ResourceError&amp;);
</span><ins>+
+        static bool isCallingPlugin();
+
</ins><span class="cx">     private:
</span><span class="cx">         void setParameters(const Vector&lt;String&gt;&amp; paramNames, const Vector&lt;String&gt;&amp; paramValues);
</span><span class="cx">         void init();
</span><span class="lines">@@ -148,6 +152,7 @@
</span><span class="cx">         static void setCurrentPluginView(PluginViewWin*);
</span><span class="cx">         NPError load(const FrameLoadRequest&amp;, bool sendNotification, void* notifyData);
</span><span class="cx">         NPError handlePost(const char* url, const char* target, uint32 len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders);
</span><ins>+        void setCallingPlugin(bool) const;
</ins><span class="cx">         RefPtr&lt;PluginPackageWin&gt; m_plugin;
</span><span class="cx">         Element* m_element;
</span><span class="cx">         Frame* m_parentFrame;
</span></span></pre></div>
<a id="trunkWebKitwinChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/WebKit/win/ChangeLog (28699 => 28700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKit/win/ChangeLog        2007-12-14 00:56:10 UTC (rev 28699)
+++ trunk/WebKit/win/ChangeLog        2007-12-14 01:07:19 UTC (rev 28700)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2007-12-13  Adam Roben  &lt;aroben@apple.com&gt;
+
+        Fix &lt;rdar://5517707&gt; Crash on wptv.wp.pl when &quot;make bigger&quot; button is clicked
+
+        Reviewed by Anders.
+
+        * WebView.cpp:
+        (WebViewWndProc): Repost paint messages and ignore all other messages
+        when we're calling a plugin.
+
</ins><span class="cx"> 2007-12-13  Steve Falkenburg  &lt;sfalken@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix project dependencies based on JavaScriptCore change.
</span></span></pre></div>
<a id="trunkWebKitwinWebViewcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebKit/win/WebView.cpp (28699 => 28700)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKit/win/WebView.cpp        2007-12-14 00:56:10 UTC (rev 28699)
+++ trunk/WebKit/win/WebView.cpp        2007-12-14 01:07:19 UTC (rev 28700)
</span><span class="lines">@@ -86,6 +86,7 @@
</span><span class="cx"> #include &lt;WebCore/PlatformWheelEvent.h&gt;
</span><span class="cx"> #include &lt;WebCore/PluginDatabaseWin.h&gt;
</span><span class="cx"> #include &lt;WebCore/PlugInInfoStore.h&gt;
</span><ins>+#include &lt;WebCore/PluginViewWin.h&gt;
</ins><span class="cx"> #include &lt;WebCore/ProgressTracker.h&gt;
</span><span class="cx"> #include &lt;WebCore/ResourceHandle.h&gt;
</span><span class="cx"> #include &lt;WebCore/ResourceHandleClient.h&gt;
</span><span class="lines">@@ -1561,6 +1562,17 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(webView);
</span><span class="cx"> 
</span><ins>+    // Windows Media Player has a modal message loop that will deliver messages
+    // to us at inappropriate times and we will crash if we handle them when
+    // they are delivered. We repost paint messages so that we eventually get
+    // a chance to paint once the modal loop has exited, but other messages
+    // aren't safe to repost, so we just drop them.
+    if (PluginViewWin::isCallingPlugin()) {
+        if (message == WM_PAINT)
+            PostMessage(hWnd, message, wParam, lParam);
+        return 0;
+    }
+
</ins><span class="cx">     bool handled = true;
</span><span class="cx"> 
</span><span class="cx">     switch (message) {
</span></span></pre>
</div>
</div>

</body>
</html>