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

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

Issue 2779433002: [IndexedDB] Abort transaction on unknown blob (Closed)
Patch Set: 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
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 UMA_HISTOGRAM_BOOLEAN("Storage.IndexedDB.PutValidBlob", !!handle);
pwnall 2017/03/27 20:56:33 Can you please add a comment explaining why this i
dmurph 2017/03/27 23:03:32 Done.
270 if (!handle) { 279 if (!handle) {
271 mojo::ReportBadMessage(kInvalidBlobUuid); 280 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
281 kInvalidBlobUuid);
282 idb_runner_->PostTask(FROM_HERE, base::Bind(&IndexedDBCallbacks::OnError,
283 callbacks, error));
284 idb_runner_->PostTask(
285 FROM_HERE,
286 base::Bind(&IDBThreadHelper::AbortWithError,
287 base::Unretained(helper_), transaction_id, error));
272 return; 288 return;
273 } 289 }
290 UMA_HISTOGRAM_COUNTS("Storage.IndexedDB.PutBlobSize", handle->size());
291
274 handles[i] = std::move(handle); 292 handles[i] = std::move(handle);
275 293
276 if (info->file) { 294 if (info->file) {
277 if (!info->file->path.empty() && 295 if (!info->file->path.empty() &&
278 !policy->CanReadFile(dispatcher_host_->ipc_process_id(), 296 !policy->CanReadFile(dispatcher_host_->ipc_process_id(),
279 info->file->path)) { 297 info->file->path)) {
280 mojo::ReportBadMessage(kInvalidBlobFilePath); 298 mojo::ReportBadMessage(kInvalidBlobFilePath);
281 return; 299 return;
282 } 300 }
283 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->file->path, 301 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->file->path,
284 info->file->name, info->mime_type); 302 info->file->name, info->mime_type);
285 if (info->size != -1) { 303 if (info->size != -1) {
286 blob_info[i].set_last_modified(info->file->last_modified); 304 blob_info[i].set_last_modified(info->file->last_modified);
287 blob_info[i].set_size(info->size); 305 blob_info[i].set_size(info->size);
288 } 306 }
289 } else { 307 } else {
290 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->mime_type, info->size); 308 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->mime_type, info->size);
291 } 309 }
292 } 310 }
293 311
294 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
295 dispatcher_host_.get(), origin_, std::move(callbacks_info)));
296
297 idb_runner_->PostTask( 312 idb_runner_->PostTask(
298 FROM_HERE, 313 FROM_HERE,
299 base::Bind(&IDBThreadHelper::Put, base::Unretained(helper_), 314 base::Bind(&IDBThreadHelper::Put, base::Unretained(helper_),
300 transaction_id, object_store_id, base::Passed(&value), 315 transaction_id, object_store_id, base::Passed(&value),
301 base::Passed(&handles), base::Passed(&blob_info), key, mode, 316 base::Passed(&handles), base::Passed(&blob_info), key, mode,
302 index_keys, base::Passed(&callbacks))); 317 index_keys, base::Passed(&callbacks)));
303 } 318 }
304 319
305 void DatabaseImpl::SetIndexKeys( 320 void DatabaseImpl::SetIndexKeys(
306 int64_t transaction_id, 321 int64_t transaction_id,
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 return; 800 return;
786 801
787 IndexedDBTransaction* transaction = 802 IndexedDBTransaction* transaction =
788 connection_->GetTransaction(transaction_id); 803 connection_->GetTransaction(transaction_id);
789 if (!transaction) 804 if (!transaction)
790 return; 805 return;
791 806
792 connection_->AbortTransaction(transaction); 807 connection_->AbortTransaction(transaction);
793 } 808 }
794 809
810 void DatabaseImpl::IDBThreadHelper::AbortWithError(
811 int64_t transaction_id,
812 const IndexedDBDatabaseError& error) {
813 if (!connection_->IsConnected())
814 return;
815
816 IndexedDBTransaction* transaction =
817 connection_->GetTransaction(transaction_id);
818 if (!transaction)
819 return;
820
821 connection_->AbortTransaction(transaction, error);
822 }
823
795 void DatabaseImpl::IDBThreadHelper::Commit(int64_t transaction_id) { 824 void DatabaseImpl::IDBThreadHelper::Commit(int64_t transaction_id) {
796 if (!connection_->IsConnected()) 825 if (!connection_->IsConnected())
797 return; 826 return;
798 827
799 IndexedDBTransaction* transaction = 828 IndexedDBTransaction* transaction =
800 connection_->GetTransaction(transaction_id); 829 connection_->GetTransaction(transaction_id);
801 if (!transaction) 830 if (!transaction)
802 return; 831 return;
803 832
804 // Always allow empty or delete-only transactions. 833 // Always allow empty or delete-only transactions.
(...skipping 27 matching lines...) Expand all
832 usage + transaction->size() <= quota) { 861 usage + transaction->size() <= quota) {
833 connection_->database()->Commit(transaction); 862 connection_->database()->Commit(transaction);
834 } else { 863 } else {
835 connection_->AbortTransaction( 864 connection_->AbortTransaction(
836 transaction, 865 transaction,
837 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError)); 866 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError));
838 } 867 }
839 } 868 }
840 869
841 } // namespace content 870 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698