Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "content/browser/bad_message.h" | 7 #include "content/browser/bad_message.h" |
| 8 #include "content/browser/child_process_security_policy_impl.h" | 8 #include "content/browser/child_process_security_policy_impl.h" |
| 9 #include "content/browser/indexed_db/indexed_db_connection.h" | 9 #include "content/browser/indexed_db/indexed_db_connection.h" |
| 10 #include "content/browser/indexed_db/indexed_db_context_impl.h" | 10 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
| 11 #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" | 11 #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" |
| 12 #include "content/browser/indexed_db/indexed_db_value.h" | 12 #include "content/browser/indexed_db/indexed_db_value.h" |
| 13 #include "content/common/indexed_db/indexed_db_messages.h" | 13 #include "content/common/indexed_db/indexed_db_messages.h" |
| 14 #include "storage/browser/blob/blob_storage_context.h" | 14 #include "storage/browser/blob/blob_storage_context.h" |
| 15 #include "storage/browser/quota/quota_manager_proxy.h" | 15 #include "storage/browser/quota/quota_manager_proxy.h" |
| 16 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h" | 16 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h" |
| 17 | 17 |
| 18 using std::swap; | 18 using std::swap; |
| 19 | 19 |
| 20 namespace content { | 20 namespace content { |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 const char kInvalidBlobUuid[] = "Blob UUID is invalid"; | 23 const char kInvalidBlobUuid[] = "Blob UUID is invalid"; |
| 24 const char kInvalidBlobFilePath[] = "Blob file path is invalid"; | |
| 24 } // namespace | 25 } // namespace |
| 25 | 26 |
| 26 class DatabaseImpl::IDBThreadHelper { | 27 class DatabaseImpl::IDBThreadHelper { |
| 27 public: | 28 public: |
| 28 IDBThreadHelper(std::unique_ptr<IndexedDBConnection> connection, | 29 IDBThreadHelper(std::unique_ptr<IndexedDBConnection> connection, |
| 29 const url::Origin& origin, | 30 const url::Origin& origin, |
| 30 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host); | 31 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host); |
| 31 ~IDBThreadHelper(); | 32 ~IDBThreadHelper(); |
| 32 | 33 |
| 33 void CreateObjectStore(int64_t transaction_id, | 34 void CreateObjectStore(int64_t transaction_id, |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 61 int64_t object_store_id, | 62 int64_t object_store_id, |
| 62 int64_t index_id, | 63 int64_t index_id, |
| 63 const IndexedDBKeyRange& key_range, | 64 const IndexedDBKeyRange& key_range, |
| 64 bool key_only, | 65 bool key_only, |
| 65 int64_t max_count, | 66 int64_t max_count, |
| 66 scoped_refptr<IndexedDBCallbacks> callbacks); | 67 scoped_refptr<IndexedDBCallbacks> callbacks); |
| 67 void Put(int64_t transaction_id, | 68 void Put(int64_t transaction_id, |
| 68 int64_t object_store_id, | 69 int64_t object_store_id, |
| 69 ::indexed_db::mojom::ValuePtr value, | 70 ::indexed_db::mojom::ValuePtr value, |
| 70 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles, | 71 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles, |
| 72 std::vector<IndexedDBBlobInfo> blob_info, | |
| 71 const IndexedDBKey& key, | 73 const IndexedDBKey& key, |
| 72 blink::WebIDBPutMode mode, | 74 blink::WebIDBPutMode mode, |
| 73 const std::vector<IndexedDBIndexKeys>& index_keys, | 75 const std::vector<IndexedDBIndexKeys>& index_keys, |
| 74 scoped_refptr<IndexedDBCallbacks> callbacks); | 76 scoped_refptr<IndexedDBCallbacks> callbacks); |
| 75 void SetIndexKeys(int64_t transaction_id, | 77 void SetIndexKeys(int64_t transaction_id, |
| 76 int64_t object_store_id, | 78 int64_t object_store_id, |
| 77 const IndexedDBKey& primary_key, | 79 const IndexedDBKey& primary_key, |
| 78 const std::vector<IndexedDBIndexKeys>& index_keys); | 80 const std::vector<IndexedDBIndexKeys>& index_keys); |
| 79 void SetIndexesReady(int64_t transaction_id, | 81 void SetIndexesReady(int64_t transaction_id, |
| 80 int64_t object_store_id, | 82 int64_t object_store_id, |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 244 } | 246 } |
| 245 | 247 |
| 246 void DatabaseImpl::Put( | 248 void DatabaseImpl::Put( |
| 247 int64_t transaction_id, | 249 int64_t transaction_id, |
| 248 int64_t object_store_id, | 250 int64_t object_store_id, |
| 249 ::indexed_db::mojom::ValuePtr value, | 251 ::indexed_db::mojom::ValuePtr value, |
| 250 const IndexedDBKey& key, | 252 const IndexedDBKey& key, |
| 251 blink::WebIDBPutMode mode, | 253 blink::WebIDBPutMode mode, |
| 252 const std::vector<IndexedDBIndexKeys>& index_keys, | 254 const std::vector<IndexedDBIndexKeys>& index_keys, |
| 253 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { | 255 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { |
| 254 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; | 256 ChildProcessSecurityPolicyImpl* policy = |
| 255 for (const auto& info : value->blob_or_file_info) { | 257 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 258 | |
| 259 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles( | |
| 260 value->blob_or_file_info.size()); | |
| 261 std::vector<IndexedDBBlobInfo> blob_info(value->blob_or_file_info.size()); | |
| 262 for (size_t i = 0; i < value->blob_or_file_info.size(); ++i) { | |
| 263 ::indexed_db::mojom::BlobInfoPtr& info = value->blob_or_file_info[i]; | |
| 264 | |
| 256 std::unique_ptr<storage::BlobDataHandle> handle = | 265 std::unique_ptr<storage::BlobDataHandle> handle = |
| 257 dispatcher_host_->blob_storage_context()->GetBlobDataFromUUID( | 266 dispatcher_host_->blob_storage_context()->GetBlobDataFromUUID( |
| 258 info->uuid); | 267 info->uuid); |
| 259 if (!handle) { | 268 if (!handle) { |
| 260 mojo::ReportBadMessage(kInvalidBlobUuid); | 269 mojo::ReportBadMessage(kInvalidBlobUuid); |
| 261 return; | 270 return; |
| 262 } | 271 } |
| 263 handles.push_back(std::move(handle)); | 272 handles[i] = std::move(handle); |
| 273 | |
| 274 if (info->file) { | |
| 275 if (!info->file->path.empty() && | |
| 276 !policy->CanReadFile(dispatcher_host_->ipc_process_id(), | |
| 277 info->file->path)) { | |
| 278 mojo::ReportBadMessage(kInvalidBlobFilePath); | |
| 279 return; | |
| 280 } | |
| 281 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->file->path, | |
| 282 info->file->name, info->mime_type); | |
| 283 if (info->size != static_cast<uint64_t>(-1)) { | |
|
cmumford
2016/11/21 21:11:56
Why is BlobInfo.size currently an unsigned 64-bit
| |
| 284 blob_info[i].set_last_modified(info->file->last_modified); | |
| 285 blob_info[i].set_size(info->size); | |
| 286 } | |
| 287 } else { | |
| 288 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->mime_type, info->size); | |
| 289 } | |
| 264 } | 290 } |
| 265 | 291 |
| 266 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( | 292 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( |
| 267 dispatcher_host_.get(), origin_, std::move(callbacks_info))); | 293 dispatcher_host_.get(), origin_, std::move(callbacks_info))); |
| 268 | 294 |
| 269 idb_runner_->PostTask( | 295 idb_runner_->PostTask( |
| 270 FROM_HERE, base::Bind(&IDBThreadHelper::Put, base::Unretained(helper_), | 296 FROM_HERE, |
| 271 transaction_id, object_store_id, | 297 base::Bind(&IDBThreadHelper::Put, base::Unretained(helper_), |
| 272 base::Passed(&value), base::Passed(&handles), key, | 298 transaction_id, object_store_id, base::Passed(&value), |
| 273 mode, index_keys, base::Passed(&callbacks))); | 299 base::Passed(&handles), base::Passed(&blob_info), key, mode, |
| 300 index_keys, base::Passed(&callbacks))); | |
| 274 } | 301 } |
| 275 | 302 |
| 276 void DatabaseImpl::SetIndexKeys( | 303 void DatabaseImpl::SetIndexKeys( |
| 277 int64_t transaction_id, | 304 int64_t transaction_id, |
| 278 int64_t object_store_id, | 305 int64_t object_store_id, |
| 279 const IndexedDBKey& primary_key, | 306 const IndexedDBKey& primary_key, |
| 280 const std::vector<IndexedDBIndexKeys>& index_keys) { | 307 const std::vector<IndexedDBIndexKeys>& index_keys) { |
| 281 idb_runner_->PostTask( | 308 idb_runner_->PostTask( |
| 282 FROM_HERE, | 309 FROM_HERE, |
| 283 base::Bind(&IDBThreadHelper::SetIndexKeys, base::Unretained(helper_), | 310 base::Bind(&IDBThreadHelper::SetIndexKeys, base::Unretained(helper_), |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 540 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | 567 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, |
| 541 index_id, base::MakeUnique<IndexedDBKeyRange>(key_range), key_only, | 568 index_id, base::MakeUnique<IndexedDBKeyRange>(key_range), key_only, |
| 542 max_count, std::move(callbacks)); | 569 max_count, std::move(callbacks)); |
| 543 } | 570 } |
| 544 | 571 |
| 545 void DatabaseImpl::IDBThreadHelper::Put( | 572 void DatabaseImpl::IDBThreadHelper::Put( |
| 546 int64_t transaction_id, | 573 int64_t transaction_id, |
| 547 int64_t object_store_id, | 574 int64_t object_store_id, |
| 548 ::indexed_db::mojom::ValuePtr mojo_value, | 575 ::indexed_db::mojom::ValuePtr mojo_value, |
| 549 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles, | 576 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles, |
| 577 std::vector<IndexedDBBlobInfo> blob_info, | |
| 550 const IndexedDBKey& key, | 578 const IndexedDBKey& key, |
| 551 blink::WebIDBPutMode mode, | 579 blink::WebIDBPutMode mode, |
| 552 const std::vector<IndexedDBIndexKeys>& index_keys, | 580 const std::vector<IndexedDBIndexKeys>& index_keys, |
| 553 scoped_refptr<IndexedDBCallbacks> callbacks) { | 581 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 554 if (!connection_->IsConnected()) | 582 if (!connection_->IsConnected()) |
| 555 return; | 583 return; |
| 556 | 584 |
| 557 int64_t host_transaction_id = | 585 int64_t host_transaction_id = |
| 558 dispatcher_host_->HostTransactionId(transaction_id); | 586 dispatcher_host_->HostTransactionId(transaction_id); |
| 559 | |
| 560 ChildProcessSecurityPolicyImpl* policy = | |
| 561 ChildProcessSecurityPolicyImpl::GetInstance(); | |
| 562 std::vector<IndexedDBBlobInfo> blob_info( | |
| 563 mojo_value->blob_or_file_info.size()); | |
| 564 for (size_t i = 0; i < mojo_value->blob_or_file_info.size(); ++i) { | |
| 565 const auto& info = mojo_value->blob_or_file_info[i]; | |
| 566 if (info->file) { | |
| 567 if (!info->file->path.empty()) { | |
| 568 if (!policy->CanReadFile(dispatcher_host_->ipc_process_id(), | |
| 569 info->file->path)) { | |
| 570 bad_message::ReceivedBadMessage(dispatcher_host_.get(), | |
| 571 bad_message::IDBDH_CAN_READ_FILE); | |
| 572 return; | |
| 573 } | |
| 574 } | |
| 575 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->file->path, | |
| 576 info->file->name, info->mime_type); | |
| 577 if (info->size != static_cast<uint64_t>(-1)) { | |
| 578 blob_info[i].set_last_modified(info->file->last_modified); | |
| 579 blob_info[i].set_size(info->size); | |
| 580 } | |
| 581 } else { | |
| 582 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->mime_type, info->size); | |
| 583 } | |
| 584 } | |
| 585 | |
| 586 uint64_t commit_size = mojo_value->bits.size(); | 587 uint64_t commit_size = mojo_value->bits.size(); |
| 587 IndexedDBValue value; | 588 IndexedDBValue value; |
| 588 swap(value.bits, mojo_value->bits); | 589 swap(value.bits, mojo_value->bits); |
| 589 swap(value.blob_info, blob_info); | 590 swap(value.blob_info, blob_info); |
| 590 connection_->database()->Put(host_transaction_id, object_store_id, &value, | 591 connection_->database()->Put(host_transaction_id, object_store_id, &value, |
| 591 &handles, base::MakeUnique<IndexedDBKey>(key), | 592 &handles, base::MakeUnique<IndexedDBKey>(key), |
| 592 mode, std::move(callbacks), index_keys); | 593 mode, std::move(callbacks), index_keys); |
| 593 | 594 |
| 594 // Size can't be big enough to overflow because it represents the | 595 // Size can't be big enough to overflow because it represents the |
| 595 // actual bytes passed through IPC. | 596 // actual bytes passed through IPC. |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 772 if (status == storage::kQuotaStatusOk && usage + transaction_size <= quota) { | 773 if (status == storage::kQuotaStatusOk && usage + transaction_size <= quota) { |
| 773 connection_->database()->Commit(host_transaction_id); | 774 connection_->database()->Commit(host_transaction_id); |
| 774 } else { | 775 } else { |
| 775 connection_->database()->Abort( | 776 connection_->database()->Abort( |
| 776 host_transaction_id, | 777 host_transaction_id, |
| 777 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError)); | 778 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError)); |
| 778 } | 779 } |
| 779 } | 780 } |
| 780 | 781 |
| 781 } // namespace content | 782 } // namespace content |
| OLD | NEW |