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

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

Issue 2779433002: [IndexedDB] Abort transaction on unknown blob (Closed)
Patch Set: comments & added histogram Created 3 years, 9 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 UMA_HISTOGRAM_BOOLEAN("Storage.IndexedDB.PutValidBlob", !!handle);
Mark P 2017/03/28 18:17:07 nit: !!handle looks ugly to me. Can you rewrite i
dmurph 2017/03/29 18:21:34 Done.
270 if (!handle) { 281 if (!handle) {
271 mojo::ReportBadMessage(kInvalidBlobUuid); 282 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
cmumford 2017/03/28 18:49:31 We do want to go back to using mojo::ReportBadMess
dmurph 2017/03/29 18:21:34 Done.
283 kInvalidBlobUuid);
284 idb_runner_->PostTask(FROM_HERE, base::Bind(&IndexedDBCallbacks::OnError,
285 callbacks, error));
286 idb_runner_->PostTask(
287 FROM_HERE,
288 base::Bind(&IDBThreadHelper::AbortWithError,
289 base::Unretained(helper_), transaction_id, error));
272 return; 290 return;
273 } 291 }
292 UMA_HISTOGRAM_COUNTS("Storage.IndexedDB.PutBlobSizeKB",
Mark P 2017/03/28 18:17:07 Why not UMA_HISTOGRAM_MEMORY_KB?
dmurph 2017/03/29 18:21:34 sgtm
293 handle->size() / 1024ull);
294
274 handles[i] = std::move(handle); 295 handles[i] = std::move(handle);
275 296
276 if (info->file) { 297 if (info->file) {
277 if (!info->file->path.empty() && 298 if (!info->file->path.empty() &&
278 !policy->CanReadFile(dispatcher_host_->ipc_process_id(), 299 !policy->CanReadFile(dispatcher_host_->ipc_process_id(),
279 info->file->path)) { 300 info->file->path)) {
280 mojo::ReportBadMessage(kInvalidBlobFilePath); 301 mojo::ReportBadMessage(kInvalidBlobFilePath);
281 return; 302 return;
282 } 303 }
283 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->file->path, 304 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->file->path,
284 info->file->name, info->mime_type); 305 info->file->name, info->mime_type);
285 if (info->size != -1) { 306 if (info->size != -1) {
286 blob_info[i].set_last_modified(info->file->last_modified); 307 blob_info[i].set_last_modified(info->file->last_modified);
287 blob_info[i].set_size(info->size); 308 blob_info[i].set_size(info->size);
288 } 309 }
289 } else { 310 } else {
290 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->mime_type, info->size); 311 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->mime_type, info->size);
291 } 312 }
292 } 313 }
293 314
294 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
295 dispatcher_host_.get(), origin_, std::move(callbacks_info)));
296
297 idb_runner_->PostTask( 315 idb_runner_->PostTask(
298 FROM_HERE, 316 FROM_HERE,
299 base::Bind(&IDBThreadHelper::Put, base::Unretained(helper_), 317 base::Bind(&IDBThreadHelper::Put, base::Unretained(helper_),
300 transaction_id, object_store_id, base::Passed(&value), 318 transaction_id, object_store_id, base::Passed(&value),
301 base::Passed(&handles), base::Passed(&blob_info), key, mode, 319 base::Passed(&handles), base::Passed(&blob_info), key, mode,
302 index_keys, base::Passed(&callbacks))); 320 index_keys, base::Passed(&callbacks)));
303 } 321 }
304 322
305 void DatabaseImpl::SetIndexKeys( 323 void DatabaseImpl::SetIndexKeys(
306 int64_t transaction_id, 324 int64_t transaction_id,
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 return; 803 return;
786 804
787 IndexedDBTransaction* transaction = 805 IndexedDBTransaction* transaction =
788 connection_->GetTransaction(transaction_id); 806 connection_->GetTransaction(transaction_id);
789 if (!transaction) 807 if (!transaction)
790 return; 808 return;
791 809
792 connection_->AbortTransaction(transaction); 810 connection_->AbortTransaction(transaction);
793 } 811 }
794 812
813 void DatabaseImpl::IDBThreadHelper::AbortWithError(
814 int64_t transaction_id,
815 const IndexedDBDatabaseError& error) {
816 if (!connection_->IsConnected())
817 return;
818
819 IndexedDBTransaction* transaction =
820 connection_->GetTransaction(transaction_id);
821 if (!transaction)
822 return;
823
824 connection_->AbortTransaction(transaction, error);
825 }
826
795 void DatabaseImpl::IDBThreadHelper::Commit(int64_t transaction_id) { 827 void DatabaseImpl::IDBThreadHelper::Commit(int64_t transaction_id) {
796 if (!connection_->IsConnected()) 828 if (!connection_->IsConnected())
797 return; 829 return;
798 830
799 IndexedDBTransaction* transaction = 831 IndexedDBTransaction* transaction =
800 connection_->GetTransaction(transaction_id); 832 connection_->GetTransaction(transaction_id);
801 if (!transaction) 833 if (!transaction)
802 return; 834 return;
803 835
804 // Always allow empty or delete-only transactions. 836 // Always allow empty or delete-only transactions.
(...skipping 27 matching lines...) Expand all
832 usage + transaction->size() <= quota) { 864 usage + transaction->size() <= quota) {
833 connection_->database()->Commit(transaction); 865 connection_->database()->Commit(transaction);
834 } else { 866 } else {
835 connection_->AbortTransaction( 867 connection_->AbortTransaction(
836 transaction, 868 transaction,
837 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError)); 869 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError));
838 } 870 }
839 } 871 }
840 872
841 } // namespace content 873 } // 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