WebProcess should be terminated if invalid frameIDs are
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Dec 2010 01:57:42 +0000 (01:57 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Dec 2010 01:57:42 +0000 (01:57 +0000)
passed to the UIProcess.
https://bugs.webkit.org/show_bug.cgi?id=51508

Reviewed by Darin Adler.

- Introduce a mechanism to mark a messages as invalid due to
  reasons other than in ability to decode the message, eg. an
  invalid frameID is passed in a message.

* Platform/CoreIPC/Connection.cpp:
(CoreIPC::Connection::Connection):
(CoreIPC::Connection::markCurrentlyDispatchedMessageAsInvalid): Sets
the m_didReceiveInvalidMessage bit so that it can be picked up in
(CoreIPC::Connection::dispatchMessages): Check for m_didReceiveInvalidMessage in
addition to tainted arguments.
* Platform/CoreIPC/Connection.h:
Add base macro for others to extend, that calls markCurrentlyDispatchedMessageAsInvalid()
ASSERTs, and returns.

* UIProcess/WebPageProxy.cpp:
Add Message checks for all WebFrameProxy's gotten from frameIDs passed
over the wire.
* UIProcess/WebProcessProxy.cpp:
(WebKit::isGoodMapKey):
Checks that the key can be inserted safely into a map (eg. not the empty or deleted value).

(WebKit::WebProcessProxy::webFrame):
Return null for bad keys (eg. 0 or -1).

(WebKit::WebProcessProxy::canCreateFrame):
Added. Checks that the ID is good and not in the map yet. Used
as a consistency check before creating frames.

(WebKit::WebProcessProxy::frameCreated):
ASSERT that the key is good, in addition to not in the map yet.

(WebKit::WebProcessProxy::didDestroyFrame):
ASSERT that the key is good.

* UIProcess/WebProcessProxy.h:
Move WebFrameProxy HashMap type into a typedef.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@74528 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit2/ChangeLog
WebKit2/Platform/CoreIPC/Connection.cpp
WebKit2/Platform/CoreIPC/Connection.h
WebKit2/UIProcess/WebPageProxy.cpp
WebKit2/UIProcess/WebProcessProxy.cpp
WebKit2/UIProcess/WebProcessProxy.h

index 2355257475db863c801fe4f64b91361175d43d6e..348b3998aef996ba1fe71adb14216a04ff2d7cc6 100644 (file)
@@ -1,3 +1,48 @@
+2010-12-22  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Darin Adler.
+
+        WebProcess should be terminated if invalid frameIDs are
+        passed to the UIProcess.
+        https://bugs.webkit.org/show_bug.cgi?id=51508
+
+        - Introduce a mechanism to mark a messages as invalid due to
+          reasons other than in ability to decode the message, eg. an
+          invalid frameID is passed in a message.
+
+        * Platform/CoreIPC/Connection.cpp:
+        (CoreIPC::Connection::Connection):
+        (CoreIPC::Connection::markCurrentlyDispatchedMessageAsInvalid): Sets
+        the m_didReceiveInvalidMessage bit so that it can be picked up in 
+        (CoreIPC::Connection::dispatchMessages): Check for m_didReceiveInvalidMessage in
+        addition to tainted arguments.
+        * Platform/CoreIPC/Connection.h:
+        Add base macro for others to extend, that calls markCurrentlyDispatchedMessageAsInvalid()
+        ASSERTs, and returns.
+
+        * UIProcess/WebPageProxy.cpp:
+        Add Message checks for all WebFrameProxy's gotten from frameIDs passed
+        over the wire.
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::isGoodMapKey):
+        Checks that the key can be inserted safely into a map (eg. not the empty or deleted value).
+
+        (WebKit::WebProcessProxy::webFrame):
+        Return null for bad keys (eg. 0 or -1).
+
+        (WebKit::WebProcessProxy::canCreateFrame):
+        Added. Checks that the ID is good and not in the map yet. Used
+        as a consistency check before creating frames.
+
+        (WebKit::WebProcessProxy::frameCreated): 
+        ASSERT that the key is good, in addition to not in the map yet.
+
+        (WebKit::WebProcessProxy::didDestroyFrame):
+        ASSERT that the key is good.
+
+        * UIProcess/WebProcessProxy.h:
+        Move WebFrameProxy HashMap type into a typedef.
+
 2010-12-22  Darin Adler  <darin@apple.com>
 
         Reviewed by Anders Carlsson.
index f1f1b696d4e18a042f6286ef3c4f809f10d676a5..da92ce45c55fef0bcf49e9ccdff62bacebf7809c 100644 (file)
@@ -51,6 +51,8 @@ Connection::Connection(Identifier identifier, bool isServer, Client* client, Run
     , m_isConnected(false)
     , m_connectionQueue("com.apple.CoreIPC.ReceiveQueue")
     , m_clientRunLoop(clientRunLoop)
+    , m_inDispatchMessageCount(0)
+    , m_didReceiveInvalidMessage(false)
     , m_shouldWaitForSyncReplies(true)
 {
     ASSERT(m_client);
@@ -78,6 +80,14 @@ void Connection::invalidate()
     m_connectionQueue.scheduleWork(WorkItem::create(this, &Connection::platformInvalidate));
 }
 
+void Connection::markCurrentlyDispatchedMessageAsInvalid()
+{
+    // This should only be called while processing a message.
+    ASSERT(m_inDispatchMessageCount > 0);
+
+    m_didReceiveInvalidMessage = true;
+}
+
 PassOwnPtr<ArgumentEncoder> Connection::createSyncMessageArgumentEncoder(uint64_t destinationID, uint64_t& syncRequestID)
 {
     OwnPtr<ArgumentEncoder> argumentEncoder = ArgumentEncoder::create(destinationID);
@@ -420,13 +430,23 @@ void Connection::dispatchMessages()
         IncomingMessage& message = incomingMessages[i];
         OwnPtr<ArgumentDecoder> arguments = message.releaseArguments();
 
+        m_inDispatchMessageCount++;
+
+        bool oldDidReceiveInvalidMessage = m_didReceiveInvalidMessage;
+        m_didReceiveInvalidMessage = false;
+
         if (message.messageID().isSync())
             dispatchSyncMessage(message.messageID(), arguments.get());
         else
             m_client->didReceiveMessage(this, message.messageID(), arguments.get());
 
-        if (arguments->isInvalid())
+        m_didReceiveInvalidMessage |= arguments->isInvalid();
+        m_inDispatchMessageCount--;
+
+        if (m_didReceiveInvalidMessage)
             m_client->didReceiveInvalidMessage(this, message.messageID());
+
+        m_didReceiveInvalidMessage = oldDidReceiveInvalidMessage;
     }
 }
 
index dfe7f82377d924d96b9b83bfc5eefe916afd42df..b7e5b0f12c0af243d072204f8e687665e0226ace 100644 (file)
@@ -60,6 +60,14 @@ enum SyncReplyMode {
     ManualReply
 };
 
+#define MESSAGE_CHECK_BASE(assertion, connection) do \
+    if (!(assertion)) { \
+        ASSERT(assertion); \
+        (connection)->markCurrentlyDispatchedMessageAsInvalid(); \
+        return; \
+    } \
+while (0)
+
 class Connection : public ThreadSafeShared<Connection> {
 public:
     class MessageReceiver {
@@ -105,6 +113,7 @@ public:
 
     bool open();
     void invalidate();
+    void markCurrentlyDispatchedMessageAsInvalid();
 
     // FIXME: This variant of send is deprecated, all clients should move to the overload that takes a message.
     template<typename E, typename T> bool send(E messageID, uint64_t destinationID, const T& arguments);
@@ -189,6 +198,9 @@ private:
     WorkQueue m_connectionQueue;
     RunLoop* m_clientRunLoop;
 
+    uint32_t m_inDispatchMessageCount;
+    bool m_didReceiveInvalidMessage;
+
     // Incoming messages.
     typedef Message<ArgumentDecoder> IncomingMessage;
 
index d8c412e0f620ba95f0406370c42328546bc88b38..81f2f36a362b0405469ad896afcf3a509df75cd4 100644 (file)
@@ -73,6 +73,8 @@
 // This controls what strategy we use for mouse wheel coalesing.
 #define MERGE_WHEEL_EVENTS 0
 
+#define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, process()->connection())
+
 using namespace WebCore;
 
 namespace WebKit {
@@ -901,16 +903,24 @@ void WebPageProxy::interpretKeyEvent(uint32_t type, Vector<KeypressCommand>& com
 
 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
 {
-    ASSERT(!m_mainFrame);
+    MESSAGE_CHECK(!m_mainFrame);
+    MESSAGE_CHECK(process()->canCreateFrame(frameID));
 
     m_mainFrame = WebFrameProxy::create(this, frameID);
+
+    // Add the frame to the process wide map.
     process()->frameCreated(frameID, m_mainFrame.get());
 }
 
 void WebPageProxy::didCreateSubFrame(uint64_t frameID)
 {
-    ASSERT(m_mainFrame);
-    process()->frameCreated(frameID, WebFrameProxy::create(this, frameID).get());
+    MESSAGE_CHECK(m_mainFrame);
+    MESSAGE_CHECK(process()->canCreateFrame(frameID));
+    
+    RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID);
+
+    // Add the frame to the process wide map.
+    process()->frameCreated(frameID, subFrame.get());
 }
 
 void WebPageProxy::didStartProgress()
@@ -942,6 +952,7 @@ void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, const Strin
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     if (!loadingSubstituteDataForUnreachableURL)
         frame->setUnreachableURL(String());
@@ -958,8 +969,10 @@ void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t f
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     frame->didReceiveServerRedirectForProvisionalLoad(url);
+
     m_loaderClient.didReceiveServerRedirectForProvisionalLoadForFrame(this, frame, userData.get());
 }
 
@@ -971,8 +984,10 @@ void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const Resour
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     frame->didFailProvisionalLoad();
+
     m_loaderClient.didFailProvisionalLoadWithErrorForFrame(this, frame, error, userData.get());
 }
 
@@ -984,6 +999,7 @@ void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, const String& mimeTyp
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     frame->didCommitLoad(mimeType, certificateInfo);
 
@@ -1003,6 +1019,7 @@ void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, CoreIPC::Argu
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     m_loaderClient.didFinishDocumentLoadForFrame(this, frame, userData.get());
 }
@@ -1015,8 +1032,10 @@ void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, CoreIPC::ArgumentDeco
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     frame->didFinishLoad();
+
     m_loaderClient.didFinishLoadForFrame(this, frame, userData.get());
 }
 
@@ -1028,6 +1047,8 @@ void WebPageProxy::didFailLoadForFrame(uint64_t frameID, const ResourceError& er
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
     frame->didFailLoad();
 
     m_loaderClient.didFailLoadWithErrorForFrame(this, frame, error, userData.get());
@@ -1041,6 +1062,8 @@ void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint32_t
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
     frame->didSameDocumentNavigation(url);
 
     m_loaderClient.didSameDocumentNavigationForFrame(this, frame, static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType), userData.get());
@@ -1054,6 +1077,8 @@ void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
     frame->didChangeTitle(title);
     
     m_loaderClient.didReceiveTitleForFrame(this, title, frame, userData.get());
@@ -1067,6 +1092,7 @@ void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, CoreIPC::ArgumentDec
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     m_loaderClient.didFirstLayoutForFrame(this, frame, userData.get());
 }
@@ -1079,6 +1105,7 @@ void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, Core
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     m_loaderClient.didFirstVisuallyNonEmptyLayoutForFrame(this, frame, userData.get());
 }
@@ -1091,6 +1118,7 @@ void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, CoreIPC::Argume
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     m_loaderClient.didRemoveFrameFromHierarchy(this, frame, userData.get());
 }
@@ -1103,6 +1131,7 @@ void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, CoreIPC::
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     m_loaderClient.didDisplayInsecureContentForFrame(this, frame, userData.get());
 }
@@ -1115,6 +1144,7 @@ void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, CoreIPC::Argu
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     m_loaderClient.didRunInsecureContentForFrame(this, frame, userData.get());
 }
@@ -1122,6 +1152,7 @@ void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, CoreIPC::Argu
 void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     frame->setIsFrameSet(value);
 }
@@ -1131,6 +1162,8 @@ void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
 void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, uint32_t opaqueNavigationType, uint32_t opaqueModifiers, int32_t opaqueMouseButton, const String& url, uint64_t listenerID)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
     NavigationType navigationType = static_cast<NavigationType>(opaqueNavigationType);
     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
     WebMouseEvent::Button mouseButton = static_cast<WebMouseEvent::Button>(opaqueMouseButton);
@@ -1143,6 +1176,8 @@ void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, uint32_t op
 void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, uint32_t opaqueNavigationType, uint32_t opaqueModifiers, int32_t opaqueMouseButton, const String& url, uint64_t listenerID)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
     NavigationType navigationType = static_cast<NavigationType>(opaqueNavigationType);
     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
     WebMouseEvent::Button mouseButton = static_cast<WebMouseEvent::Button>(opaqueMouseButton);
@@ -1155,6 +1190,8 @@ void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, uint32_t opa
 void WebPageProxy::decidePolicyForMIMEType(uint64_t frameID, const String& MIMEType, const String& url, uint64_t listenerID, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
 
     ASSERT(!m_inDecidePolicyForMIMEType);
@@ -1185,7 +1222,10 @@ void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, cons
         return;
 
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
     WebFrameProxy* sourceFrame = process()->webFrame(sourceFrameID);
+    MESSAGE_CHECK(sourceFrame);
 
     RefPtr<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
     if (!m_formClient.willSubmitForm(this, frame, sourceFrame, textFieldValues.stringPairVector(), userData.get(), listener.get()))
@@ -1197,6 +1237,7 @@ void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, cons
 void WebPageProxy::didInitiateLoadForResource(uint64_t frameID, uint64_t resourceIdentifier, const ResourceRequest& request)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     m_resourceLoadClient.didInitiateLoadForResource(this, frame, resourceIdentifier, request);
 }
@@ -1204,6 +1245,7 @@ void WebPageProxy::didInitiateLoadForResource(uint64_t frameID, uint64_t resourc
 void WebPageProxy::didSendRequestForResource(uint64_t frameID, uint64_t resourceIdentifier, const ResourceRequest& request, const ResourceResponse& redirectResponse)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     m_resourceLoadClient.didSendRequestForResource(this, frame, resourceIdentifier, request, redirectResponse);
 }
@@ -1211,6 +1253,7 @@ void WebPageProxy::didSendRequestForResource(uint64_t frameID, uint64_t resource
 void WebPageProxy::didReceiveResponseForResource(uint64_t frameID, uint64_t resourceIdentifier, const ResourceResponse& response)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     m_resourceLoadClient.didReceiveResponseForResource(this, frame, resourceIdentifier, response);
 }
@@ -1218,6 +1261,7 @@ void WebPageProxy::didReceiveResponseForResource(uint64_t frameID, uint64_t reso
 void WebPageProxy::didReceiveContentLengthForResource(uint64_t frameID, uint64_t resourceIdentifier, uint64_t contentLength)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     m_resourceLoadClient.didReceiveContentLengthForResource(this, frame, resourceIdentifier, contentLength);
 }
@@ -1225,6 +1269,7 @@ void WebPageProxy::didReceiveContentLengthForResource(uint64_t frameID, uint64_t
 void WebPageProxy::didFinishLoadForResource(uint64_t frameID, uint64_t resourceIdentifier)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     m_resourceLoadClient.didFinishLoadForResource(this, frame, resourceIdentifier);
 }
@@ -1232,11 +1277,11 @@ void WebPageProxy::didFinishLoadForResource(uint64_t frameID, uint64_t resourceI
 void WebPageProxy::didFailLoadForResource(uint64_t frameID, uint64_t resourceIdentifier, const ResourceError& error)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
 
     m_resourceLoadClient.didFailLoadForResource(this, frame, resourceIdentifier, error);
 }
 
-
 // UIClient
 
 void WebPageProxy::createNewPage(const WindowFeatures& windowFeatures, uint32_t opaqueModifiers, int32_t opaqueMouseButton, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
@@ -1262,17 +1307,26 @@ void WebPageProxy::closePage()
 
 void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message)
 {
-    m_uiClient.runJavaScriptAlert(this, message, process()->webFrame(frameID));
+    WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
+    m_uiClient.runJavaScriptAlert(this, message, frame);
 }
 
 void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, bool& result)
 {
-    result = m_uiClient.runJavaScriptConfirm(this, message, process()->webFrame(frameID));
+    WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
+    result = m_uiClient.runJavaScriptConfirm(this, message, frame);
 }
 
 void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, String& result)
 {
-    result = m_uiClient.runJavaScriptPrompt(this, message, defaultValue, process()->webFrame(frameID));
+    WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
+    result = m_uiClient.runJavaScriptPrompt(this, message, defaultValue, frame);
 }
 
 void WebPageProxy::setStatusText(const String& text)
@@ -1354,7 +1408,10 @@ void WebPageProxy::canRunBeforeUnloadConfirmPanel(bool& canRun)
 
 void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose)
 {
-    shouldClose = m_uiClient.runBeforeUnloadConfirmPanel(this, message, process()->webFrame(frameID));
+    WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
+    shouldClose = m_uiClient.runBeforeUnloadConfirmPanel(this, message, frame);
 }
 
 #if ENABLE(TILED_BACKING_STORE)
@@ -1381,9 +1438,12 @@ void WebPageProxy::runOpenPanel(uint64_t frameID, const WebOpenPanelParameters::
         m_openPanelResultListener = 0;
     }
 
+    WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
     m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this);
 
-    if (!m_uiClient.runOpenPanel(this, process()->webFrame(frameID), data, m_openPanelResultListener.get()))
+    if (!m_uiClient.runOpenPanel(this, frame, data, m_openPanelResultListener.get()))
         didCancelForOpenPanel();
 }
 
@@ -1708,7 +1768,8 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
     case WebEvent::RawKeyDown:
     case WebEvent::Char: {
         NativeWebKeyboardEvent event = m_keyEventQueue.first();
-        ASSERT(type == event.type());
+        MESSAGE_CHECK(type == event.type());
+
         m_keyEventQueue.removeFirst();
 
         if (handled)
@@ -1749,7 +1810,15 @@ void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackI
 
 void WebPageProxy::focusedFrameChanged(uint64_t frameID)
 {
-    m_focusedFrame = frameID ? process()->webFrame(frameID) : 0;
+    if (!frameID) {
+        m_focusedFrame = 0;
+        return;
+    }
+
+    WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
+    m_focusedFrame = frame;
 }
 
 #if USE(ACCELERATED_COMPOSITING)
@@ -1855,6 +1924,8 @@ void WebPageProxy::backForwardClear()
 void WebPageProxy::canAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, const WebCore::ProtectionSpace& coreProtectionSpace, bool& canAuthenticate)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
     RefPtr<WebProtectionSpace> protectionSpace = WebProtectionSpace::create(coreProtectionSpace);
     
     canAuthenticate = m_loaderClient.canAuthenticateAgainstProtectionSpaceInFrame(this, frame, protectionSpace.get());
@@ -1863,6 +1934,8 @@ void WebPageProxy::canAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID
 void WebPageProxy::didReceiveAuthenticationChallenge(uint64_t frameID, const WebCore::AuthenticationChallenge& coreChallenge, uint64_t challengeID)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
     RefPtr<AuthenticationChallengeProxy> authenticationChallenge = AuthenticationChallengeProxy::create(coreChallenge, challengeID, this);
     
     m_loaderClient.didReceiveAuthenticationChallengeInFrame(this, frame, authenticationChallenge.get());
@@ -1871,6 +1944,8 @@ void WebPageProxy::didReceiveAuthenticationChallenge(uint64_t frameID, const Web
 void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentUsage, uint64_t expectedUsage, uint64_t& newQuota)
 {
     WebFrameProxy* frame = process()->webFrame(frameID);
+    MESSAGE_CHECK(frame);
+
     RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
 
     newQuota = m_uiClient.exceededDatabaseQuota(this, frame, origin.get(), databaseName, displayName, currentQuota, currentUsage, expectedUsage);
index eed7213a0267316302126de45fb94b8d7a2ef654..cb72b7c2728179807dcd70ef83d49e2c293f06ba 100644 (file)
@@ -43,6 +43,12 @@ using namespace WebCore;
 
 namespace WebKit {
 
+template<typename HashMap>
+static inline bool isGoodKey(const typename HashMap::KeyType& key)
+{
+    return key != HashTraits<typename HashMap::KeyType>::emptyValue() && !HashTraits<typename HashMap::KeyType>::isDeletedValue(key);
+}
+
 static uint64_t generatePageID()
 {
     static uint64_t uniquePageID = 1;
@@ -281,7 +287,6 @@ void WebProcessProxy::didClose(CoreIPC::Connection*)
 
     for (size_t i = 0, size = pages.size(); i < size; ++i)
         pages[i]->processDidCrash();
-
 }
 
 void WebProcessProxy::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID)
@@ -342,12 +347,17 @@ void WebProcessProxy::didFinishLaunching(CoreIPC::Connection::Identifier connect
 
 WebFrameProxy* WebProcessProxy::webFrame(uint64_t frameID) const
 {
-    return m_frameMap.get(frameID).get();
+    return isGoodKey<WebFrameProxyMap>(frameID) ? m_frameMap.get(frameID).get() : 0;
+}
+
+bool WebProcessProxy::canCreateFrame(uint64_t frameID) const
+{
+    return isGoodKey<WebFrameProxyMap>(frameID) && !m_frameMap.contains(frameID);
 }
 
 void WebProcessProxy::frameCreated(uint64_t frameID, WebFrameProxy* frameProxy)
 {
-    ASSERT(!m_frameMap.contains(frameID));
+    ASSERT(canCreateFrame(frameID));
     m_frameMap.set(frameID, frameProxy);
 }
 
@@ -356,6 +366,7 @@ void WebProcessProxy::didDestroyFrame(uint64_t frameID)
     // If the page is closed before it has had the chance to send the DidCreateMainFrame message
     // back to the UIProcess, then the frameDestroyed message will still be received because it
     // gets sent directly to the WebProcessProxy.
+    ASSERT(isGoodKey<WebFrameProxyMap>(frameID));
     m_frameMap.remove(frameID);
 }
 
index df4acce16f9ec37152499622a20763de103deb7d..a0203f8d90a800b33d9deac62e67d9e44a1d9c54 100644 (file)
@@ -55,6 +55,7 @@ class WebProcessProxy : public RefCounted<WebProcessProxy>, CoreIPC::Connection:
 public:
     typedef HashMap<uint64_t, RefPtr<WebPageProxy> > WebPageProxyMap;
     typedef WebPageProxyMap::const_iterator::Values pages_const_iterator;
+    typedef HashMap<uint64_t, RefPtr<WebFrameProxy> > WebFrameProxyMap;
     typedef HashMap<uint64_t, RefPtr<WebBackForwardListItem> > WebBackForwardListItemMap;
 
     static PassRefPtr<WebProcessProxy> create(WebContext*);
@@ -95,6 +96,7 @@ public:
     bool canSendMessage() const { return isValid() || isLaunching(); }
 
     WebFrameProxy* webFrame(uint64_t) const;
+    bool canCreateFrame(uint64_t frameID) const;
     void frameCreated(uint64_t, WebFrameProxy*);
     void didDestroyFrame(uint64_t);
     void disconnectFramesFromPage(WebPageProxy*); // Including main frame.
@@ -144,9 +146,8 @@ private:
     WebContext* m_context;
 
     WebPageProxyMap m_pageMap;
+    WebFrameProxyMap m_frameMap;
     WebBackForwardListItemMap m_backForwardListItemMap;
-
-    HashMap<uint64_t, RefPtr<WebFrameProxy> > m_frameMap;
 };
 
 template<typename E, typename T>