diff options
Diffstat (limited to 'Source/WebCore/Modules/indexeddb/IDBFactory.cpp')
-rw-r--r-- | Source/WebCore/Modules/indexeddb/IDBFactory.cpp | 213 |
1 files changed, 85 insertions, 128 deletions
diff --git a/Source/WebCore/Modules/indexeddb/IDBFactory.cpp b/Source/WebCore/Modules/indexeddb/IDBFactory.cpp index 7c73d8449..db9aa0e66 100644 --- a/Source/WebCore/Modules/indexeddb/IDBFactory.cpp +++ b/Source/WebCore/Modules/indexeddb/IDBFactory.cpp @@ -1,29 +1,26 @@ /* - * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2015, 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. * - * 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 name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE 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 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. + * 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" @@ -33,153 +30,113 @@ #include "Document.h" #include "ExceptionCode.h" -#include "Frame.h" -#include "GroupSettings.h" -#include "HistogramSupport.h" #include "IDBBindingUtilities.h" -#include "IDBDatabase.h" -#include "IDBDatabaseCallbacksImpl.h" -#include "IDBDatabaseException.h" -#include "IDBFactoryBackendInterface.h" -#include "IDBHistograms.h" +#include "IDBConnectionProxy.h" +#include "IDBDatabaseIdentifier.h" #include "IDBKey.h" -#include "IDBKeyRange.h" #include "IDBOpenDBRequest.h" #include "Logging.h" #include "Page.h" -#include "PageGroup.h" +#include "ScriptExecutionContext.h" #include "SecurityOrigin.h" -#include "WorkerGlobalScope.h" -#include "WorkerLoaderProxy.h" -#include "WorkerThread.h" + +using namespace JSC; namespace WebCore { -IDBFactory::IDBFactory(IDBFactoryBackendInterface* factory) - : m_backend(factory) +static bool shouldThrowSecurityException(ScriptExecutionContext& context) { - // We pass a reference to this object before it can be adopted. - relaxAdoptionRequirement(); + ASSERT(is<Document>(context) || context.isWorkerGlobalScope()); + if (is<Document>(context)) { + Document& document = downcast<Document>(context); + if (!document.frame()) + return true; + if (!document.page()) + return true; + } + + if (!context.securityOrigin()->canAccessDatabase(context.topOrigin())) + return true; + + return false; } -IDBFactory::~IDBFactory() +Ref<IDBFactory> IDBFactory::create(IDBClient::IDBConnectionProxy& connectionProxy) { + return adoptRef(*new IDBFactory(connectionProxy)); } -namespace { -static bool isContextValid(ScriptExecutionContext* context) +IDBFactory::IDBFactory(IDBClient::IDBConnectionProxy& connectionProxy) + : m_connectionProxy(connectionProxy) { - ASSERT(context->isDocument() || context->isWorkerGlobalScope()); - if (context->isDocument()) { - Document* document = toDocument(context); - return document->frame() && document->page(); - } - return true; } -static String getIndexedDBDatabasePath(ScriptExecutionContext* context) +IDBFactory::~IDBFactory() { - ASSERT(isContextValid(context)); - if (context->isDocument()) { - Document* document = toDocument(context); - return document->page()->group().groupSettings().indexedDBDatabasePath(); - } - WorkerGlobalScope* workerGlobalScope = static_cast<WorkerGlobalScope*>(context); - const GroupSettings* groupSettings = workerGlobalScope->groupSettings(); - if (groupSettings) - return groupSettings->indexedDBDatabasePath(); - return String(); -} } -PassRefPtr<IDBRequest> IDBFactory::getDatabaseNames(ScriptExecutionContext* context, ExceptionCode& ec) +ExceptionOr<Ref<IDBOpenDBRequest>> IDBFactory::open(ScriptExecutionContext& context, const String& name, std::optional<uint64_t> version) { - LOG(StorageAPI, "IDBFactory::getDatabaseNames"); - if (!isContextValid(context)) - return 0; - if (!context->securityOrigin()->canAccessDatabase(context->topOrigin())) { - ec = SECURITY_ERR; - return 0; - } + LOG(IndexedDB, "IDBFactory::open"); + + if (version && !version.value()) + return Exception { TypeError, ASCIILiteral("IDBFactory.open() called with a version of 0") }; - RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), 0); - m_backend->getDatabaseNames(request, context->securityOrigin(), context, getIndexedDBDatabasePath(context)); - return request; + return openInternal(context, name, version.value_or(0)); } -PassRefPtr<IDBOpenDBRequest> IDBFactory::open(ScriptExecutionContext* context, const String& name, ExceptionCode& ec) +ExceptionOr<Ref<IDBOpenDBRequest>> IDBFactory::openInternal(ScriptExecutionContext& context, const String& name, uint64_t version) { - LOG(StorageAPI, "IDBFactory::open"); - return openInternal(context, name, 0, IndexedDB::VersionNullness::Null, ec); -} + if (name.isNull()) + return Exception { TypeError, ASCIILiteral("IDBFactory.open() called without a database name") }; -PassRefPtr<IDBOpenDBRequest> IDBFactory::open(ScriptExecutionContext* context, const String& name, unsigned long long version, ExceptionCode& ec) -{ - LOG(StorageAPI, "IDBFactory::open"); - if (!version) { - ec = TypeError; - return 0; - } - return openInternal(context, name, version, IndexedDB::VersionNullness::NonNull, ec); -} + if (shouldThrowSecurityException(context)) + return Exception { SECURITY_ERR, ASCIILiteral("IDBFactory.open() called in an invalid security context") }; -PassRefPtr<IDBOpenDBRequest> IDBFactory::openInternal(ScriptExecutionContext* context, const String& name, uint64_t version, IndexedDB::VersionNullness versionNullness, ExceptionCode& ec) -{ - HistogramSupport::histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls", IDBOpenCall, IDBMethodsMax); - ASSERT(version >= 1 || versionNullness == IndexedDB::VersionNullness::Null); - if (name.isNull()) { - ec = TypeError; - return 0; - } - if (!isContextValid(context)) - return 0; - if (!context->securityOrigin()->canAccessDatabase(context->topOrigin())) { - ec = SECURITY_ERR; - return 0; - } + ASSERT(context.securityOrigin()); + IDBDatabaseIdentifier databaseIdentifier(name, *context.securityOrigin(), context.topOrigin()); + if (!databaseIdentifier.isValid()) + return Exception { TypeError, ASCIILiteral("IDBFactory.open() called with an invalid security origin") }; - RefPtr<IDBDatabaseCallbacks> databaseCallbacks = IDBDatabaseCallbacksImpl::create(); - int64_t transactionId = IDBDatabase::nextTransactionId(); - RefPtr<IDBOpenDBRequest> request = IDBOpenDBRequest::create(context, databaseCallbacks, transactionId, version, versionNullness); - m_backend->open(name, version, transactionId, request, databaseCallbacks, *(context->securityOrigin()), *(context->topOrigin())); - return request; + LOG(IndexedDBOperations, "IDB opening database: %s %" PRIu64, name.utf8().data(), version); + + return m_connectionProxy->openDatabase(context, databaseIdentifier, version); } -PassRefPtr<IDBOpenDBRequest> IDBFactory::deleteDatabase(ScriptExecutionContext* context, const String& name, ExceptionCode& ec) +ExceptionOr<Ref<IDBOpenDBRequest>> IDBFactory::deleteDatabase(ScriptExecutionContext& context, const String& name) { - LOG(StorageAPI, "IDBFactory::deleteDatabase"); - HistogramSupport::histogramEnumeration("WebCore.IndexedDB.FrontEndAPICalls", IDBDeleteDatabaseCall, IDBMethodsMax); - if (name.isNull()) { - ec = TypeError; - return 0; - } - if (!isContextValid(context)) - return 0; - if (!context->securityOrigin()->canAccessDatabase(context->topOrigin())) { - ec = SECURITY_ERR; - return 0; - } + LOG(IndexedDB, "IDBFactory::deleteDatabase - %s", name.utf8().data()); - RefPtr<IDBOpenDBRequest> request = IDBOpenDBRequest::create(context, 0, 0, 0, IndexedDB::VersionNullness::Null); - m_backend->deleteDatabase(name, request, context->securityOrigin(), context, getIndexedDBDatabasePath(context)); - return request; + if (name.isNull()) + return Exception { TypeError, ASCIILiteral("IDBFactory.deleteDatabase() called without a database name") }; + + if (shouldThrowSecurityException(context)) + return Exception { SECURITY_ERR, ASCIILiteral("IDBFactory.deleteDatabase() called in an invalid security context") }; + + ASSERT(context.securityOrigin()); + IDBDatabaseIdentifier databaseIdentifier(name, *context.securityOrigin(), context.topOrigin()); + if (!databaseIdentifier.isValid()) + return Exception { TypeError, ASCIILiteral("IDBFactory.deleteDatabase() called with an invalid security origin") }; + + LOG(IndexedDBOperations, "IDB deleting database: %s", name.utf8().data()); + + return m_connectionProxy->deleteDatabase(context, databaseIdentifier); } -short IDBFactory::cmp(ScriptExecutionContext* context, const Deprecated::ScriptValue& firstValue, const Deprecated::ScriptValue& secondValue, ExceptionCode& ec) +ExceptionOr<short> IDBFactory::cmp(ExecState& execState, JSValue firstValue, JSValue secondValue) { - DOMRequestState requestState(context); - RefPtr<IDBKey> first = scriptValueToIDBKey(&requestState, firstValue); - RefPtr<IDBKey> second = scriptValueToIDBKey(&requestState, secondValue); + auto first = scriptValueToIDBKey(execState, firstValue); + auto second = scriptValueToIDBKey(execState, secondValue); - ASSERT(first); - ASSERT(second); + if (!first->isValid() || !second->isValid()) + return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'cmp' on 'IDBFactory': The parameter is not a valid key.") }; - if (!first->isValid() || !second->isValid()) { - ec = IDBDatabaseException::DataError; - return 0; - } + return first->compare(second.get()); +} - return static_cast<short>(first->compare(second.get())); +void IDBFactory::getAllDatabaseNames(const SecurityOrigin& mainFrameOrigin, const SecurityOrigin& openingOrigin, std::function<void (const Vector<String>&)> callback) +{ + m_connectionProxy->getAllDatabaseNames(mainFrameOrigin, openingOrigin, callback); } } // namespace WebCore |