Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: content/browser/indexed_db/database_impl.cc

Issue 2779433002: [IndexedDB] Abort transaction on unknown blob (Closed)
Patch Set: comments and removed tests Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | content/browser/indexed_db/indexed_db_connection.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/indexed_db/database_impl.h" 5 #include "content/browser/indexed_db/database_impl.h"
6 6
7 #include "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
8 #include "base/metrics/histogram_macros.h"
8 #include "base/threading/thread_task_runner_handle.h" 9 #include "base/threading/thread_task_runner_handle.h"
9 #include "content/browser/bad_message.h" 10 #include "content/browser/bad_message.h"
10 #include "content/browser/child_process_security_policy_impl.h" 11 #include "content/browser/child_process_security_policy_impl.h"
11 #include "content/browser/indexed_db/indexed_db_connection.h" 12 #include "content/browser/indexed_db/indexed_db_connection.h"
12 #include "content/browser/indexed_db/indexed_db_context_impl.h" 13 #include "content/browser/indexed_db/indexed_db_context_impl.h"
13 #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" 14 #include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
14 #include "content/browser/indexed_db/indexed_db_transaction.h" 15 #include "content/browser/indexed_db/indexed_db_transaction.h"
15 #include "content/browser/indexed_db/indexed_db_value.h" 16 #include "content/browser/indexed_db/indexed_db_value.h"
16 #include "storage/browser/blob/blob_storage_context.h" 17 #include "storage/browser/blob/blob_storage_context.h"
17 #include "storage/browser/quota/quota_manager_proxy.h" 18 #include "storage/browser/quota/quota_manager_proxy.h"
18 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h" 19 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h"
19 20
20 using std::swap; 21 using std::swap;
21 22
22 namespace content { 23 namespace content {
24 class IndexedDBDatabaseError;
23 25
24 namespace { 26 namespace {
25 const char kInvalidBlobUuid[] = "Blob UUID is invalid"; 27 const char kInvalidBlobUuid[] = "Blob does not exist";
26 const char kInvalidBlobFilePath[] = "Blob file path is invalid"; 28 const char kInvalidBlobFilePath[] = "Blob file path is invalid";
27 } // namespace 29 } // namespace
28 30
29 class DatabaseImpl::IDBThreadHelper { 31 class DatabaseImpl::IDBThreadHelper {
30 public: 32 public:
31 IDBThreadHelper(std::unique_ptr<IndexedDBConnection> connection, 33 IDBThreadHelper(std::unique_ptr<IndexedDBConnection> connection,
32 const url::Origin& origin, 34 const url::Origin& origin,
33 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host); 35 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host);
34 ~IDBThreadHelper(); 36 ~IDBThreadHelper();
35 37
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 bool unique, 113 bool unique,
112 bool multi_entry); 114 bool multi_entry);
113 void DeleteIndex(int64_t transaction_id, 115 void DeleteIndex(int64_t transaction_id,
114 int64_t object_store_id, 116 int64_t object_store_id,
115 int64_t index_id); 117 int64_t index_id);
116 void RenameIndex(int64_t transaction_id, 118 void RenameIndex(int64_t transaction_id,
117 int64_t object_store_id, 119 int64_t object_store_id,
118 int64_t index_id, 120 int64_t index_id,
119 const base::string16& new_name); 121 const base::string16& new_name);
120 void Abort(int64_t transaction_id); 122 void Abort(int64_t transaction_id);
123 void AbortWithError(int64_t transaction_id,
124 const IndexedDBDatabaseError& error);
121 void Commit(int64_t transaction_id); 125 void Commit(int64_t transaction_id);
122 void OnGotUsageAndQuotaForCommit(int64_t transaction_id, 126 void OnGotUsageAndQuotaForCommit(int64_t transaction_id,
123 storage::QuotaStatusCode status, 127 storage::QuotaStatusCode status,
124 int64_t usage, 128 int64_t usage,
125 int64_t quota); 129 int64_t quota);
126 void AckReceivedBlobs(const std::vector<std::string>& uuids); 130 void AckReceivedBlobs(const std::vector<std::string>& uuids);
127 131
128 private: 132 private:
129 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host_; 133 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host_;
130 std::unique_ptr<IndexedDBConnection> connection_; 134 std::unique_ptr<IndexedDBConnection> connection_;
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 int64_t transaction_id, 255 int64_t transaction_id,
252 int64_t object_store_id, 256 int64_t object_store_id,
253 ::indexed_db::mojom::ValuePtr value, 257 ::indexed_db::mojom::ValuePtr value,
254 const IndexedDBKey& key, 258 const IndexedDBKey& key,
255 blink::WebIDBPutMode mode, 259 blink::WebIDBPutMode mode,
256 const std::vector<IndexedDBIndexKeys>& index_keys, 260 const std::vector<IndexedDBIndexKeys>& index_keys,
257 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { 261 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) {
258 ChildProcessSecurityPolicyImpl* policy = 262 ChildProcessSecurityPolicyImpl* policy =
259 ChildProcessSecurityPolicyImpl::GetInstance(); 263 ChildProcessSecurityPolicyImpl::GetInstance();
260 264
265 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
266 dispatcher_host_.get(), origin_, std::move(callbacks_info)));
267
261 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles( 268 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles(
262 value->blob_or_file_info.size()); 269 value->blob_or_file_info.size());
263 std::vector<IndexedDBBlobInfo> blob_info(value->blob_or_file_info.size()); 270 std::vector<IndexedDBBlobInfo> blob_info(value->blob_or_file_info.size());
264 for (size_t i = 0; i < value->blob_or_file_info.size(); ++i) { 271 for (size_t i = 0; i < value->blob_or_file_info.size(); ++i) {
265 ::indexed_db::mojom::BlobInfoPtr& info = value->blob_or_file_info[i]; 272 ::indexed_db::mojom::BlobInfoPtr& info = value->blob_or_file_info[i];
266 273
267 std::unique_ptr<storage::BlobDataHandle> handle = 274 std::unique_ptr<storage::BlobDataHandle> handle =
268 dispatcher_host_->blob_storage_context()->GetBlobDataFromUUID( 275 dispatcher_host_->blob_storage_context()->GetBlobDataFromUUID(
269 info->uuid); 276 info->uuid);
277
278 // Due to known issue crbug.com/351753, blobs can die while being passed to
279 // a different process. So this case must be handled gracefully.
280 // TODO(dmurph): Revert back to using mojo::ReportBadMessage once fixed.
281 UMA_HISTOGRAM_BOOLEAN("Storage.IndexedDB.PutValidBlob",
282 handle.get() != nullptr);
270 if (!handle) { 283 if (!handle) {
271 mojo::ReportBadMessage(kInvalidBlobUuid); 284 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
285 kInvalidBlobUuid);
286 idb_runner_->PostTask(FROM_HERE, base::Bind(&IndexedDBCallbacks::OnError,
287 callbacks, error));
288 idb_runner_->PostTask(
289 FROM_HERE,
290 base::Bind(&IDBThreadHelper::AbortWithError,
291 base::Unretained(helper_), transaction_id, error));
272 return; 292 return;
273 } 293 }
294 UMA_HISTOGRAM_MEMORY_KB("Storage.IndexedDB.PutBlobSizeKB",
295 handle->size() / 1024ull);
296
274 handles[i] = std::move(handle); 297 handles[i] = std::move(handle);
275 298
276 if (info->file) { 299 if (info->file) {
277 if (!info->file->path.empty() && 300 if (!info->file->path.empty() &&
278 !policy->CanReadFile(dispatcher_host_->ipc_process_id(), 301 !policy->CanReadFile(dispatcher_host_->ipc_process_id(),
279 info->file->path)) { 302 info->file->path)) {
280 mojo::ReportBadMessage(kInvalidBlobFilePath); 303 mojo::ReportBadMessage(kInvalidBlobFilePath);
281 return; 304 return;
282 } 305 }
283 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->file->path, 306 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->file->path,
284 info->file->name, info->mime_type); 307 info->file->name, info->mime_type);
285 if (info->size != -1) { 308 if (info->size != -1) {
286 blob_info[i].set_last_modified(info->file->last_modified); 309 blob_info[i].set_last_modified(info->file->last_modified);
287 blob_info[i].set_size(info->size); 310 blob_info[i].set_size(info->size);
288 } 311 }
289 } else { 312 } else {
290 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->mime_type, info->size); 313 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->mime_type, info->size);
291 } 314 }
292 } 315 }
293 316
294 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
295 dispatcher_host_.get(), origin_, std::move(callbacks_info)));
296
297 idb_runner_->PostTask( 317 idb_runner_->PostTask(
298 FROM_HERE, 318 FROM_HERE,
299 base::Bind(&IDBThreadHelper::Put, base::Unretained(helper_), 319 base::Bind(&IDBThreadHelper::Put, base::Unretained(helper_),
300 transaction_id, object_store_id, base::Passed(&value), 320 transaction_id, object_store_id, base::Passed(&value),
301 base::Passed(&handles), base::Passed(&blob_info), key, mode, 321 base::Passed(&handles), base::Passed(&blob_info), key, mode,
302 index_keys, base::Passed(&callbacks))); 322 index_keys, base::Passed(&callbacks)));
303 } 323 }
304 324
305 void DatabaseImpl::SetIndexKeys( 325 void DatabaseImpl::SetIndexKeys(
306 int64_t transaction_id, 326 int64_t transaction_id,
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 return; 805 return;
786 806
787 IndexedDBTransaction* transaction = 807 IndexedDBTransaction* transaction =
788 connection_->GetTransaction(transaction_id); 808 connection_->GetTransaction(transaction_id);
789 if (!transaction) 809 if (!transaction)
790 return; 810 return;
791 811
792 connection_->AbortTransaction(transaction); 812 connection_->AbortTransaction(transaction);
793 } 813 }
794 814
815 void DatabaseImpl::IDBThreadHelper::AbortWithError(
816 int64_t transaction_id,
817 const IndexedDBDatabaseError& error) {
818 if (!connection_->IsConnected())
819 return;
820
821 IndexedDBTransaction* transaction =
822 connection_->GetTransaction(transaction_id);
823 if (!transaction)
824 return;
825
826 connection_->AbortTransaction(transaction, error);
827 }
828
795 void DatabaseImpl::IDBThreadHelper::Commit(int64_t transaction_id) { 829 void DatabaseImpl::IDBThreadHelper::Commit(int64_t transaction_id) {
796 if (!connection_->IsConnected()) 830 if (!connection_->IsConnected())
797 return; 831 return;
798 832
799 IndexedDBTransaction* transaction = 833 IndexedDBTransaction* transaction =
800 connection_->GetTransaction(transaction_id); 834 connection_->GetTransaction(transaction_id);
801 if (!transaction) 835 if (!transaction)
802 return; 836 return;
803 837
804 // Always allow empty or delete-only transactions. 838 // Always allow empty or delete-only transactions.
(...skipping 27 matching lines...) Expand all
832 usage + transaction->size() <= quota) { 866 usage + transaction->size() <= quota) {
833 connection_->database()->Commit(transaction); 867 connection_->database()->Commit(transaction);
834 } else { 868 } else {
835 connection_->AbortTransaction( 869 connection_->AbortTransaction(
836 transaction, 870 transaction,
837 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError)); 871 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError));
838 } 872 }
839 } 873 }
840 874
841 } // namespace content 875 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/indexed_db/indexed_db_connection.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698