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 |