From: dgrogan@chromium.org Date: Wed, 18 Jan 2012 22:39:19 +0000 (+0000) Subject: IndexedDB: Check for permission before using IndexedDB from a worker. X-Git-Tag: 070512121124~15058 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=304701b25daf28d9cfb79762c3ba706c456e2a0d;p=profile%2Fivi%2Fwebkit-efl.git IndexedDB: Check for permission before using IndexedDB from a worker. https://bugs.webkit.org/show_bug.cgi?id=76500 Reviewed by David Levin. * src/IDBFactoryBackendProxy.cpp: (WebKit::AllowIndexedDBMainThreadBridge::create): (WebKit::AllowIndexedDBMainThreadBridge::cancel): (WebKit::AllowIndexedDBMainThreadBridge::result): (WebKit::AllowIndexedDBMainThreadBridge::signalCompleted): (WebKit::AllowIndexedDBMainThreadBridge::AllowIndexedDBMainThreadBridge): (WebKit::AllowIndexedDBMainThreadBridge::allowIndexedDBTask): Call webView->permissionClient()->allowIndexedDB on the main thread because ContentSettingsObserver::AllowIndexedDB(), which is called down the chain, expects to be run on the main thread. (WebKit::AllowIndexedDBMainThreadBridge::didComplete): (WebKit::IDBFactoryBackendProxy::allowIDBFromWorkerThread): Wait for main permission check to complete on main thread before proceeding on worker thread. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@105324 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog index 3bed94e..4ae03b3 100644 --- a/Source/WebKit/chromium/ChangeLog +++ b/Source/WebKit/chromium/ChangeLog @@ -1,3 +1,25 @@ +2012-01-18 David Grogan + + IndexedDB: Check for permission before using IndexedDB from a worker. + https://bugs.webkit.org/show_bug.cgi?id=76500 + + Reviewed by David Levin. + + * src/IDBFactoryBackendProxy.cpp: + (WebKit::AllowIndexedDBMainThreadBridge::create): + (WebKit::AllowIndexedDBMainThreadBridge::cancel): + (WebKit::AllowIndexedDBMainThreadBridge::result): + (WebKit::AllowIndexedDBMainThreadBridge::signalCompleted): + (WebKit::AllowIndexedDBMainThreadBridge::AllowIndexedDBMainThreadBridge): + (WebKit::AllowIndexedDBMainThreadBridge::allowIndexedDBTask): Call + webView->permissionClient()->allowIndexedDB on the main thread because + ContentSettingsObserver::AllowIndexedDB(), which is called down the + chain, expects to be run on the main thread. + (WebKit::AllowIndexedDBMainThreadBridge::didComplete): + (WebKit::IDBFactoryBackendProxy::allowIDBFromWorkerThread): Wait for + main permission check to complete on main thread before proceeding on + worker thread. + 2012-01-18 Tommy Widenflycht [chromium] MediaStream API: Make WebMediaStreamDescriptor copyable diff --git a/Source/WebKit/chromium/src/IDBFactoryBackendProxy.cpp b/Source/WebKit/chromium/src/IDBFactoryBackendProxy.cpp index c22309b..80b711a 100755 --- a/Source/WebKit/chromium/src/IDBFactoryBackendProxy.cpp +++ b/Source/WebKit/chromium/src/IDBFactoryBackendProxy.cpp @@ -47,6 +47,7 @@ #include "platform/WebVector.h" #include "WebViewImpl.h" #include "WebWorkerBase.h" +#include "WebWorkerClientImpl.h" #include "WorkerContext.h" #include "WorkerLoaderProxy.h" #include "WorkerScriptController.h" @@ -85,9 +86,91 @@ void IDBFactoryBackendProxy::getDatabaseNames(PassRefPtr callbacks m_webIDBFactory->getDatabaseNames(new WebIDBCallbacksImpl(callbacks), origin, webFrame, dataDir); } -bool IDBFactoryBackendProxy::allowIDBFromWorkerThread(WorkerContext*, const String&, const WebSecurityOrigin&) +static const char allowIndexedDBMode[] = "allowIndexedDBMode"; + +class AllowIndexedDBMainThreadBridge : public ThreadSafeRefCounted { +public: + static PassRefPtr create(WebWorkerClientImpl* webWorkerClientImpl, const String& mode, const String& name) + { + return adoptRef(new AllowIndexedDBMainThreadBridge(webWorkerClientImpl, mode, name)); + } + + // These methods are invoked on the worker context. + void cancel() + { + MutexLocker locker(m_mutex); + m_webWorkerClientImpl = 0; + } + + bool result() + { + return m_result; + } + + // This method is invoked on the main thread. + void signalCompleted(bool result, const String& mode) + { + MutexLocker locker(m_mutex); + if (m_webWorkerClientImpl) + m_webWorkerClientImpl->postTaskForModeToWorkerContext(createCallbackTask(&didComplete, this, result), mode); + } + +private: + AllowIndexedDBMainThreadBridge(WebWorkerClientImpl* webWorkerClientImpl, const String& mode, const String& name) + : m_result(false) + , m_webWorkerClientImpl(webWorkerClientImpl) + { + WebFrameImpl* webFrame = static_cast(webWorkerClientImpl->view()->mainFrame()); + // webFrame is not deleted as long as the process is alive, relying on + // it to exist on the main thread should be ok. + WebWorkerBase::dispatchTaskToMainThread( + createCallbackTask(&allowIndexedDBTask, this, WebCore::AllowCrossThreadAccess(webFrame), name, mode)); + } + + static void allowIndexedDBTask(ScriptExecutionContext*, PassRefPtr bridge, PassRefPtr prpWebFrame, const String& name, const String& mode) + { + RefPtr webFrame = prpWebFrame; + WebViewImpl* webView = webFrame->viewImpl(); + if (!webView) { + bridge->signalCompleted(false, mode); + return; + } + bool allowed = !webView->permissionClient() || webView->permissionClient()->allowIndexedDB(webFrame.get(), name, WebSecurityOrigin()); + bridge->signalCompleted(allowed, mode); + } + + static void didComplete(ScriptExecutionContext* context, PassRefPtr bridge, bool result) + { + bridge->m_result = result; + } + + bool m_result; + Mutex m_mutex; + // WebWorkerClientImpl is never deleted as long as the renderer process + // is alive. We use it on the main thread to notify the worker thread that + // the permission result has been set. The underlying message proxy object + // is valid as long as the worker run loop hasn't returned + // MessageQueueTerminated, in which case we don't use the + // WebWorkerClientImpl. + WebWorkerClientImpl* m_webWorkerClientImpl; +}; + +bool IDBFactoryBackendProxy::allowIDBFromWorkerThread(WorkerContext* workerContext, const String& name, const WebSecurityOrigin&) { - return true; + WebWorkerClientImpl* webWorkerClientImpl = static_cast(&workerContext->thread()->workerLoaderProxy()); + WorkerRunLoop& runLoop = workerContext->thread()->runLoop(); + + String mode = allowIndexedDBMode; + mode.append(String::number(runLoop.createUniqueId())); + RefPtr bridge = AllowIndexedDBMainThreadBridge::create(webWorkerClientImpl, mode, name); + + // Either the bridge returns, or the queue gets terminated. + if (runLoop.runInMode(workerContext, mode) == MessageQueueTerminated) { + bridge->cancel(); + return false; + } + + return bridge->result(); } void IDBFactoryBackendProxy::openFromWorker(const String& name, IDBCallbacks* callbacks, PassRefPtr prpOrigin, WorkerContext* context, const String& dataDir)