| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "webkit/fileapi/file_system_directory_database.h" | 5 #include "webkit/fileapi/file_system_directory_database.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <stack> | 10 #include <stack> |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 ++visited_links; | 362 ++visited_links; |
| 363 } | 363 } |
| 364 } | 364 } |
| 365 | 365 |
| 366 // Check if we've visited all database entries. | 366 // Check if we've visited all database entries. |
| 367 return num_directories_in_db_ == visited_directories && | 367 return num_directories_in_db_ == visited_directories && |
| 368 num_files_in_db_ == visited_files && | 368 num_files_in_db_ == visited_files && |
| 369 num_hierarchy_links_in_db_ == visited_links; | 369 num_hierarchy_links_in_db_ == visited_links; |
| 370 } | 370 } |
| 371 | 371 |
| 372 // Returns true if the given |data_path| contains no parent references ("..") |
| 373 // and does not refer to special system files. |
| 374 // This is called in GetFileInfo, AddFileInfo and UpdateFileInfo to |
| 375 // ensure we're only dealing with valid data paths. |
| 376 bool VerifyDataPath(const FilePath& data_path) { |
| 377 // |data_path| should not contain any ".." and should be a relative path |
| 378 // (to the filesystem_data_directory_). |
| 379 if (data_path.ReferencesParent() || data_path.IsAbsolute()) |
| 380 return false; |
| 381 // See if it's not pointing to the special system paths. |
| 382 const FilePath kExcludes[] = { |
| 383 FilePath(kDirectoryDatabaseName), |
| 384 FilePath(fileapi::FileSystemUsageCache::kUsageFileName), |
| 385 }; |
| 386 for (size_t i = 0; i < arraysize(kExcludes); ++i) { |
| 387 if (data_path == kExcludes[i] || kExcludes[i].IsParent(data_path)) |
| 388 return false; |
| 389 } |
| 390 return true; |
| 391 } |
| 392 |
| 372 } // namespace | 393 } // namespace |
| 373 | 394 |
| 374 namespace fileapi { | 395 namespace fileapi { |
| 375 | 396 |
| 376 FileSystemDirectoryDatabase::FileInfo::FileInfo() : parent_id(0) { | 397 FileSystemDirectoryDatabase::FileInfo::FileInfo() : parent_id(0) { |
| 377 } | 398 } |
| 378 | 399 |
| 379 FileSystemDirectoryDatabase::FileInfo::~FileInfo() { | 400 FileSystemDirectoryDatabase::FileInfo::~FileInfo() { |
| 380 } | 401 } |
| 381 | 402 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 | 475 |
| 455 bool FileSystemDirectoryDatabase::GetFileInfo(FileId file_id, FileInfo* info) { | 476 bool FileSystemDirectoryDatabase::GetFileInfo(FileId file_id, FileInfo* info) { |
| 456 if (!Init(REPAIR_ON_CORRUPTION)) | 477 if (!Init(REPAIR_ON_CORRUPTION)) |
| 457 return false; | 478 return false; |
| 458 DCHECK(info); | 479 DCHECK(info); |
| 459 std::string file_key = GetFileLookupKey(file_id); | 480 std::string file_key = GetFileLookupKey(file_id); |
| 460 std::string file_data_string; | 481 std::string file_data_string; |
| 461 leveldb::Status status = | 482 leveldb::Status status = |
| 462 db_->Get(leveldb::ReadOptions(), file_key, &file_data_string); | 483 db_->Get(leveldb::ReadOptions(), file_key, &file_data_string); |
| 463 if (status.ok()) { | 484 if (status.ok()) { |
| 464 return FileInfoFromPickle( | 485 bool success = FileInfoFromPickle( |
| 465 Pickle(file_data_string.data(), file_data_string.length()), info); | 486 Pickle(file_data_string.data(), file_data_string.length()), info); |
| 487 if (!success) |
| 488 return false; |
| 489 if (!VerifyDataPath(info->data_path)) { |
| 490 LOG(ERROR) << "Resolved data path is invalid: " |
| 491 << info->data_path.value(); |
| 492 return false; |
| 493 } |
| 494 return true; |
| 466 } | 495 } |
| 467 // Special-case the root, for databases that haven't been initialized yet. | 496 // Special-case the root, for databases that haven't been initialized yet. |
| 468 // Without this, a query for the root's file info, made before creating the | 497 // Without this, a query for the root's file info, made before creating the |
| 469 // first file in the database, will fail and confuse callers. | 498 // first file in the database, will fail and confuse callers. |
| 470 if (status.IsNotFound() && !file_id) { | 499 if (status.IsNotFound() && !file_id) { |
| 471 info->name = FilePath::StringType(); | 500 info->name = FilePath::StringType(); |
| 472 info->data_path = FilePath(); | 501 info->data_path = FilePath(); |
| 473 info->modification_time = base::Time::Now(); | 502 info->modification_time = base::Time::Now(); |
| 474 info->parent_id = 0; | 503 info->parent_id = 0; |
| 475 return true; | 504 return true; |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 if (!info.is_directory()) { | 843 if (!info.is_directory()) { |
| 815 LOG(ERROR) << "New parent directory is a file!"; | 844 LOG(ERROR) << "New parent directory is a file!"; |
| 816 return false; | 845 return false; |
| 817 } | 846 } |
| 818 return true; | 847 return true; |
| 819 } | 848 } |
| 820 | 849 |
| 821 // This does very few safety checks! | 850 // This does very few safety checks! |
| 822 bool FileSystemDirectoryDatabase::AddFileInfoHelper( | 851 bool FileSystemDirectoryDatabase::AddFileInfoHelper( |
| 823 const FileInfo& info, FileId file_id, leveldb::WriteBatch* batch) { | 852 const FileInfo& info, FileId file_id, leveldb::WriteBatch* batch) { |
| 853 if (!VerifyDataPath(info.data_path)) { |
| 854 LOG(ERROR) << "Invalid data path is given: " << info.data_path.value(); |
| 855 return false; |
| 856 } |
| 824 std::string id_string = GetFileLookupKey(file_id); | 857 std::string id_string = GetFileLookupKey(file_id); |
| 825 if (!file_id) { | 858 if (!file_id) { |
| 826 // The root directory doesn't need to be looked up by path from its parent. | 859 // The root directory doesn't need to be looked up by path from its parent. |
| 827 DCHECK(!info.parent_id); | 860 DCHECK(!info.parent_id); |
| 828 DCHECK(info.data_path.empty()); | 861 DCHECK(info.data_path.empty()); |
| 829 } else { | 862 } else { |
| 830 std::string child_key = GetChildLookupKey(info.parent_id, info.name); | 863 std::string child_key = GetChildLookupKey(info.parent_id, info.name); |
| 831 batch->Put(child_key, id_string); | 864 batch->Put(child_key, id_string); |
| 832 } | 865 } |
| 833 Pickle pickle; | 866 Pickle pickle; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 864 | 897 |
| 865 void FileSystemDirectoryDatabase::HandleError( | 898 void FileSystemDirectoryDatabase::HandleError( |
| 866 const tracked_objects::Location& from_here, | 899 const tracked_objects::Location& from_here, |
| 867 const leveldb::Status& status) { | 900 const leveldb::Status& status) { |
| 868 LOG(ERROR) << "FileSystemDirectoryDatabase failed at: " | 901 LOG(ERROR) << "FileSystemDirectoryDatabase failed at: " |
| 869 << from_here.ToString() << " with error: " << status.ToString(); | 902 << from_here.ToString() << " with error: " << status.ToString(); |
| 870 db_.reset(); | 903 db_.reset(); |
| 871 } | 904 } |
| 872 | 905 |
| 873 } // namespace fileapi | 906 } // namespace fileapi |
| OLD | NEW |