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

Side by Side Diff: webkit/fileapi/obfuscated_file_util.cc

Issue 10701094: Don't keep file system directories around if they contain unrelated files. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 8 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « webkit/fileapi/obfuscated_file_util.h ('k') | webkit/fileapi/sandbox_mount_point_provider.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 (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/obfuscated_file_util.h" 5 #include "webkit/fileapi/obfuscated_file_util.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 return FilePath(); 901 return FilePath();
902 FilePath::StringType type_string = GetDirectoryNameForType(type); 902 FilePath::StringType type_string = GetDirectoryNameForType(type);
903 if (type_string.empty()) { 903 if (type_string.empty()) {
904 LOG(WARNING) << "Unknown filesystem type requested:" << type; 904 LOG(WARNING) << "Unknown filesystem type requested:" << type;
905 905
906 if (error_code) 906 if (error_code)
907 *error_code = base::PLATFORM_FILE_ERROR_INVALID_URL; 907 *error_code = base::PLATFORM_FILE_ERROR_INVALID_URL;
908 return FilePath(); 908 return FilePath();
909 } 909 }
910 FilePath path = origin_dir.Append(type_string); 910 FilePath path = origin_dir.Append(type_string);
911 base::PlatformFileError error = base::PLATFORM_FILE_OK;
911 if (!file_util::DirectoryExists(path) && 912 if (!file_util::DirectoryExists(path) &&
912 (!create || !file_util::CreateDirectory(path))) { 913 (!create || !file_util::CreateDirectory(path))) {
913 if (error_code) { 914 error = create ?
914 *error_code = create ?
915 base::PLATFORM_FILE_ERROR_FAILED : 915 base::PLATFORM_FILE_ERROR_FAILED :
916 base::PLATFORM_FILE_ERROR_NOT_FOUND; 916 base::PLATFORM_FILE_ERROR_NOT_FOUND;
917 }
918 return FilePath();
919 } 917 }
920 918
921 if (error_code) 919 if (error_code)
922 *error_code = base::PLATFORM_FILE_OK; 920 *error_code = error;
923 return path; 921 return path;
924 } 922 }
925 923
926 bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType( 924 bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType(
927 const GURL& origin, FileSystemType type) { 925 const GURL& origin, FileSystemType type) {
928 FilePath origin_type_path = GetDirectoryForOriginAndType(origin, type, false); 926 base::PlatformFileError error = base::PLATFORM_FILE_OK;
929 if (!file_util::PathExists(origin_type_path)) 927 FilePath origin_type_path = GetDirectoryForOriginAndType(origin, type, false,
928 &error);
929 if (origin_type_path.empty())
930 return true; 930 return true;
931 931
932 // TODO(dmikurube): Consider the return value of DestroyDirectoryDatabase. 932 if (error != base::PLATFORM_FILE_ERROR_NOT_FOUND) {
933 // We ignore its error now since 1) it doesn't matter the final result, and 933 // TODO(dmikurube): Consider the return value of DestroyDirectoryDatabase.
934 // 2) it always returns false in Windows because of LevelDB's implementation. 934 // We ignore its error now since 1) it doesn't matter the final result, and
935 // Information about failure would be useful for debugging. 935 // 2) it always returns false in Windows because of LevelDB's
936 DestroyDirectoryDatabase(origin, type); 936 // implementation.
937 if (!file_util::Delete(origin_type_path, true /* recursive */)) 937 // Information about failure would be useful for debugging.
938 return false; 938 DestroyDirectoryDatabase(origin, type);
939 if (!file_util::Delete(origin_type_path, true /* recursive */))
940 return false;
941 }
939 942
940 FilePath origin_path = origin_type_path.DirName(); 943 FilePath origin_path = origin_type_path.DirName();
941 DCHECK_EQ(origin_path.value(), 944 DCHECK_EQ(origin_path.value(),
942 GetDirectoryForOrigin(origin, false, NULL).value()); 945 GetDirectoryForOrigin(origin, false, NULL).value());
943 946
944 // Delete the origin directory if the deleted one was the last remaining 947 // Delete the origin directory if the deleted one was the last remaining
945 // type for the origin. 948 // type for the origin, i.e. if the *other* type doesn't exist.
946 if (file_util::Delete(origin_path, false /* recursive */)) { 949 FileSystemType other_type = kFileSystemTypeUnknown;
950 switch (type) {
951 case kFileSystemTypeTemporary:
952 other_type = kFileSystemTypePersistent;
953 break;
954 case kFileSystemTypePersistent:
955 other_type = kFileSystemTypeTemporary;
956 break;
957 // These types shouldn't be used.
958 case kFileSystemTypeUnknown:
959 case kFileSystemTypeIsolated:
960 case kFileSystemTypeExternal:
961 case kFileSystemTypeTest:
962 NOTREACHED();
963 }
964 if (!file_util::DirectoryExists(
965 origin_path.Append(GetDirectoryNameForType(other_type)))) {
947 InitOriginDatabase(false); 966 InitOriginDatabase(false);
948 if (origin_database_.get()) 967 if (origin_database_.get())
949 origin_database_->RemovePathForOrigin(GetOriginIdentifierFromURL(origin)); 968 origin_database_->RemovePathForOrigin(GetOriginIdentifierFromURL(origin));
969 if (!file_util::Delete(origin_path, true /* recursive */))
970 return false;
950 } 971 }
951 972
952 // At this point we are sure we had successfully deleted the origin/type 973 // At this point we are sure we had successfully deleted the origin/type
953 // directory, so just returning true here. 974 // directory, so just returning true here.
954 return true; 975 return true;
955 } 976 }
956 977
957 bool ObfuscatedFileUtil::MigrateFromOldSandbox( 978 bool ObfuscatedFileUtil::MigrateFromOldSandbox(
958 const GURL& origin_url, FileSystemType type, const FilePath& src_root) { 979 const GURL& origin_url, FileSystemType type, const FilePath& src_root) {
959 if (!DestroyDirectoryDatabase(origin_url, type)) 980 if (!DestroyDirectoryDatabase(origin_url, type))
960 return false; 981 return false;
961 FilePath dest_root = GetDirectoryForOriginAndType(origin_url, type, true); 982 base::PlatformFileError error = base::PLATFORM_FILE_OK;
962 if (dest_root.empty()) 983 FilePath dest_root = GetDirectoryForOriginAndType(origin_url, type, true,
984 &error);
985 if (error != base::PLATFORM_FILE_OK)
963 return false; 986 return false;
964 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( 987 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
965 origin_url, type, true); 988 origin_url, type, true);
966 if (!db) 989 if (!db)
967 return false; 990 return false;
968 991
969 file_util::FileEnumerator file_enum(src_root, true, 992 file_util::FileEnumerator file_enum(src_root, true,
970 static_cast<file_util::FileEnumerator::FileType>( 993 static_cast<file_util::FileEnumerator::FileType>(
971 file_util::FileEnumerator::FILES | 994 file_util::FileEnumerator::FILES |
972 file_util::FileEnumerator::DIRECTORIES)); 995 file_util::FileEnumerator::DIRECTORIES));
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 return true; 1079 return true;
1057 } 1080 }
1058 std::string key = GetOriginIdentifierFromURL(origin) + type_string; 1081 std::string key = GetOriginIdentifierFromURL(origin) + type_string;
1059 DirectoryMap::iterator iter = directories_.find(key); 1082 DirectoryMap::iterator iter = directories_.find(key);
1060 if (iter != directories_.end()) { 1083 if (iter != directories_.end()) {
1061 FileSystemDirectoryDatabase* database = iter->second; 1084 FileSystemDirectoryDatabase* database = iter->second;
1062 directories_.erase(iter); 1085 directories_.erase(iter);
1063 delete database; 1086 delete database;
1064 } 1087 }
1065 1088
1066 FilePath path = GetDirectoryForOriginAndType(origin, type, false); 1089 PlatformFileError error = base::PLATFORM_FILE_OK;
1067 if (path.empty()) 1090 FilePath path = GetDirectoryForOriginAndType(origin, type, false, &error);
1068 return true; 1091 if (path.empty() || error == base::PLATFORM_FILE_ERROR_NOT_FOUND)
1069 if (!file_util::DirectoryExists(path))
1070 return true; 1092 return true;
1071 return FileSystemDirectoryDatabase::DestroyDatabase(path); 1093 return FileSystemDirectoryDatabase::DestroyDatabase(path);
1072 } 1094 }
1073 1095
1074 // static 1096 // static
1075 int64 ObfuscatedFileUtil::ComputeFilePathCost(const FilePath& path) { 1097 int64 ObfuscatedFileUtil::ComputeFilePathCost(const FilePath& path) {
1076 return UsageForPath(VirtualPath::BaseName(path).value().size()); 1098 return UsageForPath(VirtualPath::BaseName(path).value().size());
1077 } 1099 }
1078 1100
1079 PlatformFileError ObfuscatedFileUtil::GetFileInfoInternal( 1101 PlatformFileError ObfuscatedFileUtil::GetFileInfoInternal(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 FileSystemOperationContext* context, 1152 FileSystemOperationContext* context,
1131 const FilePath& src_file_path, 1153 const FilePath& src_file_path,
1132 const GURL& dest_origin, 1154 const GURL& dest_origin,
1133 FileSystemType dest_type, 1155 FileSystemType dest_type,
1134 FileInfo* dest_file_info, int file_flags, PlatformFile* handle) { 1156 FileInfo* dest_file_info, int file_flags, PlatformFile* handle) {
1135 if (handle) 1157 if (handle)
1136 *handle = base::kInvalidPlatformFileValue; 1158 *handle = base::kInvalidPlatformFileValue;
1137 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( 1159 FileSystemDirectoryDatabase* db = GetDirectoryDatabase(
1138 dest_origin, dest_type, true); 1160 dest_origin, dest_type, true);
1139 1161
1140 FilePath root = GetDirectoryForOriginAndType(dest_origin, dest_type, false); 1162 PlatformFileError error = base::PLATFORM_FILE_OK;
1141 if (root.empty()) 1163 FilePath root = GetDirectoryForOriginAndType(dest_origin, dest_type, false,
1164 &error);
1165 if (error != base::PLATFORM_FILE_OK)
1142 return base::PLATFORM_FILE_ERROR_FAILED; 1166 return base::PLATFORM_FILE_ERROR_FAILED;
kinuko 2012/07/10 11:12:24 Maybe we should just return the error?
Bernhard Bauer 2012/07/10 11:56:38 Done.
1143 1167
1144 FilePath dest_local_path; 1168 FilePath dest_local_path;
1145 PlatformFileError error = GenerateNewLocalPath( 1169 error = GenerateNewLocalPath(db, context, dest_origin, dest_type,
1146 db, context, dest_origin, dest_type, &dest_local_path); 1170 &dest_local_path);
1147 if (error != base::PLATFORM_FILE_OK) 1171 if (error != base::PLATFORM_FILE_OK)
1148 return error; 1172 return error;
1149 1173
1150 bool created = false; 1174 bool created = false;
1151 if (!src_file_path.empty()) { 1175 if (!src_file_path.empty()) {
1152 DCHECK(!file_flags); 1176 DCHECK(!file_flags);
1153 DCHECK(!handle); 1177 DCHECK(!handle);
1154 error = NativeFileUtil::CopyOrMoveFile( 1178 error = NativeFileUtil::CopyOrMoveFile(
1155 src_file_path, dest_local_path, true /* copy */); 1179 src_file_path, dest_local_path, true /* copy */);
1156 created = true; 1180 created = true;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 file_util::Delete(dest_local_path, false /* recursive */); 1224 file_util::Delete(dest_local_path, false /* recursive */);
1201 return base::PLATFORM_FILE_ERROR_FAILED; 1225 return base::PLATFORM_FILE_ERROR_FAILED;
1202 } 1226 }
1203 TouchDirectory(db, dest_file_info->parent_id); 1227 TouchDirectory(db, dest_file_info->parent_id);
1204 1228
1205 return base::PLATFORM_FILE_OK; 1229 return base::PLATFORM_FILE_OK;
1206 } 1230 }
1207 1231
1208 FilePath ObfuscatedFileUtil::DataPathToLocalPath( 1232 FilePath ObfuscatedFileUtil::DataPathToLocalPath(
1209 const GURL& origin, FileSystemType type, const FilePath& data_path) { 1233 const GURL& origin, FileSystemType type, const FilePath& data_path) {
1210 FilePath root = GetDirectoryForOriginAndType(origin, type, false); 1234 PlatformFileError error = base::PLATFORM_FILE_OK;
1211 if (root.empty()) 1235 FilePath root = GetDirectoryForOriginAndType(origin, type, false, &error);
1212 return root; 1236 if (error != base::PLATFORM_FILE_OK)
1237 return FilePath();
1213 return root.Append(data_path); 1238 return root.Append(data_path);
1214 } 1239 }
1215 1240
1216 // TODO: How to do the whole validation-without-creation thing? We may not have 1241 // TODO: How to do the whole validation-without-creation thing? We may not have
1217 // quota even to create the database. Ah, in that case don't even get here? 1242 // quota even to create the database. Ah, in that case don't even get here?
1218 // Still doesn't answer the quota issue, though. 1243 // Still doesn't answer the quota issue, though.
1219 FileSystemDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase( 1244 FileSystemDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase(
1220 const GURL& origin, FileSystemType type, bool create) { 1245 const GURL& origin, FileSystemType type, bool create) {
1221 std::string type_string = GetFileSystemTypeString(type); 1246 std::string type_string = GetFileSystemTypeString(type);
1222 if (type_string.empty()) { 1247 if (type_string.empty()) {
1223 LOG(WARNING) << "Unknown filesystem type requested:" << type; 1248 LOG(WARNING) << "Unknown filesystem type requested:" << type;
1224 return NULL; 1249 return NULL;
1225 } 1250 }
1226 std::string key = GetOriginIdentifierFromURL(origin) + type_string; 1251 std::string key = GetOriginIdentifierFromURL(origin) + type_string;
1227 DirectoryMap::iterator iter = directories_.find(key); 1252 DirectoryMap::iterator iter = directories_.find(key);
1228 if (iter != directories_.end()) { 1253 if (iter != directories_.end()) {
1229 MarkUsed(); 1254 MarkUsed();
1230 return iter->second; 1255 return iter->second;
1231 } 1256 }
1232 1257
1233 FilePath path = GetDirectoryForOriginAndType(origin, type, create); 1258 PlatformFileError error = base::PLATFORM_FILE_OK;
1234 if (path.empty()) 1259 FilePath path = GetDirectoryForOriginAndType(origin, type, create, &error);
1260 if (error != base::PLATFORM_FILE_OK)
1235 return NULL; 1261 return NULL;
1236 if (!file_util::DirectoryExists(path)) {
1237 if (!file_util::CreateDirectory(path)) {
1238 LOG(WARNING) << "Failed to origin+type directory: " << path.value();
kinuko 2012/07/10 11:12:24 Can we preserve this WARNING when error != OK case
Bernhard Bauer 2012/07/10 11:56:38 Done.
1239 return NULL;
1240 }
1241 }
1242 MarkUsed(); 1262 MarkUsed();
1243 FileSystemDirectoryDatabase* database = new FileSystemDirectoryDatabase(path); 1263 FileSystemDirectoryDatabase* database = new FileSystemDirectoryDatabase(path);
1244 directories_[key] = database; 1264 directories_[key] = database;
1245 return database; 1265 return database;
1246 } 1266 }
1247 1267
1248 FilePath ObfuscatedFileUtil::GetDirectoryForOrigin( 1268 FilePath ObfuscatedFileUtil::GetDirectoryForOrigin(
1249 const GURL& origin, bool create, base::PlatformFileError* error_code) { 1269 const GURL& origin, bool create, base::PlatformFileError* error_code) {
1250 if (!InitOriginDatabase(create)) { 1270 if (!InitOriginDatabase(create)) {
1251 if (error_code) { 1271 if (error_code) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1339 FileSystemDirectoryDatabase* db, 1359 FileSystemDirectoryDatabase* db,
1340 FileSystemOperationContext* context, 1360 FileSystemOperationContext* context,
1341 const GURL& origin, 1361 const GURL& origin,
1342 FileSystemType type, 1362 FileSystemType type,
1343 FilePath* local_path) { 1363 FilePath* local_path) {
1344 DCHECK(local_path); 1364 DCHECK(local_path);
1345 int64 number; 1365 int64 number;
1346 if (!db || !db->GetNextInteger(&number)) 1366 if (!db || !db->GetNextInteger(&number))
1347 return base::PLATFORM_FILE_ERROR_FAILED; 1367 return base::PLATFORM_FILE_ERROR_FAILED;
1348 1368
1369 PlatformFileError error = base::PLATFORM_FILE_OK;
1370 FilePath new_local_path = GetDirectoryForOriginAndType(origin, type, false,
1371 &error);
1372 if (error != base::PLATFORM_FILE_OK)
1373 return base::PLATFORM_FILE_ERROR_FAILED;
1374
1349 // We use the third- and fourth-to-last digits as the directory. 1375 // We use the third- and fourth-to-last digits as the directory.
1350 int64 directory_number = number % 10000 / 100; 1376 int64 directory_number = number % 10000 / 100;
1351 FilePath new_local_path = GetDirectoryForOriginAndType(origin, type, false);
1352 if (new_local_path.empty())
1353 return base::PLATFORM_FILE_ERROR_FAILED;
1354
1355 new_local_path = new_local_path.AppendASCII( 1377 new_local_path = new_local_path.AppendASCII(
1356 StringPrintf("%02" PRId64, directory_number)); 1378 StringPrintf("%02" PRId64, directory_number));
1357 1379
1358 PlatformFileError error = NativeFileUtil::CreateDirectory( 1380 error = NativeFileUtil::CreateDirectory(
1359 new_local_path, false /* exclusive */, false /* recursive */); 1381 new_local_path, false /* exclusive */, false /* recursive */);
1360 if (error != base::PLATFORM_FILE_OK) 1382 if (error != base::PLATFORM_FILE_OK)
1361 return error; 1383 return error;
1362 1384
1363 *local_path = new_local_path.AppendASCII(StringPrintf("%08" PRId64, number)); 1385 *local_path = new_local_path.AppendASCII(StringPrintf("%08" PRId64, number));
1364 return base::PLATFORM_FILE_OK; 1386 return base::PLATFORM_FILE_OK;
1365 } 1387 }
1366 1388
1367 } // namespace fileapi 1389 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/obfuscated_file_util.h ('k') | webkit/fileapi/sandbox_mount_point_provider.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698