diff options
author | jsbell@chromium.org <jsbell@chromium.org@bbb929c8-8fbe-4397-9dbb-9b2b20218538> | 2013-11-26 23:39:14 +0000 |
---|---|---|
committer | jsbell@chromium.org <jsbell@chromium.org@bbb929c8-8fbe-4397-9dbb-9b2b20218538> | 2013-11-26 23:39:14 +0000 |
commit | 304010af88241e2f274091e1ca6b2a51035bd99f (patch) | |
tree | 6d69f3e650805085507a9d3886d800bcb8adc025 /third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.cpp | |
parent | 611234e7965d3bb98eef53f9ada0283d5f795192 (diff) | |
download | chromium_src-304010af88241e2f274091e1ca6b2a51035bd99f.zip chromium_src-304010af88241e2f274091e1ca6b2a51035bd99f.tar.gz chromium_src-304010af88241e2f274091e1ca6b2a51035bd99f.tar.bz2 |
IndexedDB: Prevent leaks due to IDBRequest holding ScriptValue
An IDBRequest's result may sometimes be a serialized value into which
it must inject a key. This is done eagerly when the message arrives from
the back-end by deserializing into a ScriptValue, which is then retained.
This can result in leaks if the resulting value is given a pointer
back to the request object.
Fix this by making the injection lazy; make the result an IDBAny which
holds the serialized value, key and key path, and only deserialize
and inject the key when called from script.
BUG=322124
R=haraken,alecflett
Review URL: https://codereview.chromium.org/84063002
git-svn-id: svn://svn.chromium.org/blink/trunk@162708 bbb929c8-8fbe-4397-9dbb-9b2b20218538
Diffstat (limited to 'third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.cpp')
-rw-r--r-- | third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.cpp | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.cpp index 91dd16a..84874ea 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBOpenDBRequest.cpp @@ -51,7 +51,7 @@ IDBOpenDBRequest::IDBOpenDBRequest(ExecutionContext* context, PassRefPtr<IDBData , m_transactionId(transactionId) , m_version(version) { - ASSERT(!m_result); + ASSERT(!resultAsAny()); ScriptWrappable::init(this); } @@ -100,7 +100,7 @@ void IDBOpenDBRequest::onUpgradeNeeded(int64_t oldVersion, PassOwnPtr<WebIDBData oldMetadata.intVersion = oldVersion; m_transaction = IDBTransaction::create(executionContext(), m_transactionId, idbDatabase.get(), this, oldMetadata); - m_result = IDBAny::create(idbDatabase.release()); + setResult(IDBAny::create(idbDatabase.release())); if (m_version == IDBDatabaseMetadata::NoIntVersion) m_version = 1; @@ -120,9 +120,10 @@ void IDBOpenDBRequest::onSuccess(PassOwnPtr<WebIDBDatabase> backend, const IDBDa return; RefPtr<IDBDatabase> idbDatabase; - if (m_result) { + if (resultAsAny()) { + // Previous onUpgradeNeeded call delivered the backend. ASSERT(!backend.get()); - idbDatabase = m_result->idbDatabase(); + idbDatabase = resultAsAny()->idbDatabase(); ASSERT(idbDatabase); ASSERT(!m_databaseCallbacks); } else { @@ -131,7 +132,7 @@ void IDBOpenDBRequest::onSuccess(PassOwnPtr<WebIDBDatabase> backend, const IDBDa idbDatabase = IDBDatabase::create(executionContext(), backend, m_databaseCallbacks); m_databaseCallbacks->connect(idbDatabase.get()); m_databaseCallbacks = 0; - m_result = IDBAny::create(idbDatabase.get()); + setResult(IDBAny::create(idbDatabase.get())); } idbDatabase->setMetadata(metadata); enqueueEvent(Event::create(EventTypeNames::success)); @@ -151,8 +152,8 @@ bool IDBOpenDBRequest::dispatchEvent(PassRefPtr<Event> event) { // If the connection closed between onUpgradeNeeded and the delivery of the "success" event, // an "error" event should be fired instead. - if (event->type() == EventTypeNames::success && m_result->type() == IDBAny::IDBDatabaseType && m_result->idbDatabase()->isClosePending()) { - m_result.clear(); + if (event->type() == EventTypeNames::success && resultAsAny()->type() == IDBAny::IDBDatabaseType && resultAsAny()->idbDatabase()->isClosePending()) { + setResult(0); onError(DOMError::create(AbortError, "The connection was closed.")); return false; } |