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

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

Issue 7608011: Simplify directory path accounting. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rolled in CR feedback. Created 9 years, 4 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 | « no previous file | webkit/fileapi/file_system_file_util_unittest.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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_file_util.h" 5 #include "webkit/fileapi/file_system_file_util.h"
6 6
7 #include <stack> 7 #include <stack>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/file_util_proxy.h" 10 #include "base/file_util_proxy.h"
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 // http://code.google.com/p/chromium-os/issues/detail?id=15948 129 // http://code.google.com/p/chromium-os/issues/detail?id=15948
130 // This currently just prevents a file from showing up at all 130 // This currently just prevents a file from showing up at all
131 // if it's a link, hence preventing arbitary 'read' exploits. 131 // if it's a link, hence preventing arbitary 'read' exploits.
132 if (!file_util::IsLink(file_path.Append(entry.name))) 132 if (!file_util::IsLink(file_path.Append(entry.name)))
133 entries->push_back(entry); 133 entries->push_back(entry);
134 } 134 }
135 return base::PLATFORM_FILE_OK; 135 return base::PLATFORM_FILE_OK;
136 } 136 }
137 137
138 PlatformFileError FileSystemFileUtil::CreateDirectory( 138 PlatformFileError FileSystemFileUtil::CreateDirectory(
139 FileSystemOperationContext* fs_context, 139 FileSystemOperationContext* unused,
140 const FilePath& file_path, 140 const FilePath& file_path,
141 bool exclusive, 141 bool exclusive,
142 bool recursive) { 142 bool recursive) {
143 if (fs_context->do_not_write_actually())
144 return base::PLATFORM_FILE_OK;
145
146 // If parent dir of file doesn't exist. 143 // If parent dir of file doesn't exist.
147 if (!recursive && !file_util::PathExists(file_path.DirName())) 144 if (!recursive && !file_util::PathExists(file_path.DirName()))
148 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 145 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
149 146
150 bool path_exists = file_util::PathExists(file_path); 147 bool path_exists = file_util::PathExists(file_path);
151 if (exclusive && path_exists) 148 if (exclusive && path_exists)
152 return base::PLATFORM_FILE_ERROR_EXISTS; 149 return base::PLATFORM_FILE_ERROR_EXISTS;
153 150
154 // If file exists at the path. 151 // If file exists at the path.
155 if (path_exists && !file_util::DirectoryExists(file_path)) 152 if (path_exists && !file_util::DirectoryExists(file_path))
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 PlatformFileError 243 PlatformFileError
247 FileSystemFileUtil::PerformCommonCheckAndPreparationForMoveAndCopy( 244 FileSystemFileUtil::PerformCommonCheckAndPreparationForMoveAndCopy(
248 FileSystemOperationContext* context, 245 FileSystemOperationContext* context,
249 const FilePath& src_file_path, 246 const FilePath& src_file_path,
250 const FilePath& dest_file_path) { 247 const FilePath& dest_file_path) {
251 bool same_file_system = 248 bool same_file_system =
252 (context->src_origin_url() == context->dest_origin_url()) && 249 (context->src_origin_url() == context->dest_origin_url()) &&
253 (context->src_type() == context->dest_type()); 250 (context->src_type() == context->dest_type());
254 FileSystemFileUtil* dest_util = context->dest_file_system_file_util(); 251 FileSystemFileUtil* dest_util = context->dest_file_system_file_util();
255 DCHECK(dest_util); 252 DCHECK(dest_util);
256 if (same_file_system) 253 scoped_ptr<FileSystemOperationContext> local_dest_context;
254 FileSystemOperationContext* dest_context = NULL;
255 if (same_file_system) {
256 dest_context = context;
257 DCHECK(context->src_file_system_file_util() == 257 DCHECK(context->src_file_system_file_util() ==
258 context->dest_file_system_file_util()); 258 context->dest_file_system_file_util());
259 // All the single-path virtual FSFU methods expect the context information 259 } else {
260 // to be in the src_* variables, not the dest_* variables, so we have to 260 local_dest_context.reset(context->CreateInheritedContextForDest());
261 // make a new context if we want to call them on the dest_file_path. 261 // All the single-path virtual FSFU methods expect the context information
262 scoped_ptr<FileSystemOperationContext> dest_context( 262 // to be in the src_* variables, not the dest_* variables, so we have to
263 context->CreateInheritedContextForDest()); 263 // make a new context if we want to call them on the dest_file_path.
264 dest_context = local_dest_context.get();
265 }
264 266
265 // Exits earlier if the source path does not exist. 267 // Exits earlier if the source path does not exist.
266 if (!PathExists(context, src_file_path)) 268 if (!PathExists(context, src_file_path))
267 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 269 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
268 270
269 // The parent of the |dest_file_path| does not exist. 271 // The parent of the |dest_file_path| does not exist.
270 if (!ParentExists(dest_context.get(), dest_util, dest_file_path)) 272 if (!ParentExists(dest_context, dest_util, dest_file_path))
271 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 273 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
272 274
273 // It is an error to try to copy/move an entry into its child. 275 // It is an error to try to copy/move an entry into its child.
274 if (same_file_system && src_file_path.IsParent(dest_file_path)) 276 if (same_file_system && src_file_path.IsParent(dest_file_path))
275 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; 277 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
276 278
277 // Now it is ok to return if the |dest_file_path| does not exist. 279 // Now it is ok to return if the |dest_file_path| does not exist.
278 if (!dest_util->PathExists(dest_context.get(), dest_file_path)) 280 if (!dest_util->PathExists(dest_context, dest_file_path))
279 return base::PLATFORM_FILE_OK; 281 return base::PLATFORM_FILE_OK;
280 282
281 // |src_file_path| exists and is a directory. 283 // |src_file_path| exists and is a directory.
282 // |dest_file_path| exists and is a file. 284 // |dest_file_path| exists and is a file.
283 bool src_is_directory = DirectoryExists(context, src_file_path); 285 bool src_is_directory = DirectoryExists(context, src_file_path);
284 bool dest_is_directory = 286 bool dest_is_directory =
285 dest_util->DirectoryExists(dest_context.get(), dest_file_path); 287 dest_util->DirectoryExists(dest_context, dest_file_path);
286 if (src_is_directory && !dest_is_directory) 288 if (src_is_directory && !dest_is_directory)
287 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; 289 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
288 290
289 // |src_file_path| exists and is a file. 291 // |src_file_path| exists and is a file.
290 // |dest_file_path| exists and is a directory. 292 // |dest_file_path| exists and is a directory.
291 if (!src_is_directory && dest_is_directory) 293 if (!src_is_directory && dest_is_directory)
292 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; 294 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
293 295
294 // It is an error to copy/move an entry into the same path. 296 // It is an error to copy/move an entry into the same path.
295 if (same_file_system && (src_file_path.value() == dest_file_path.value())) 297 if (same_file_system && (src_file_path.value() == dest_file_path.value()))
296 return base::PLATFORM_FILE_ERROR_EXISTS; 298 return base::PLATFORM_FILE_ERROR_EXISTS;
297 299
298 if (dest_is_directory) { 300 if (dest_is_directory) {
299 // It is an error to copy/move an entry to a non-empty directory. 301 // It is an error to copy/move an entry to a non-empty directory.
300 // Otherwise the copy/move attempt must overwrite the destination, but 302 // Otherwise the copy/move attempt must overwrite the destination, but
301 // the file_util's Copy or Move method doesn't perform overwrite 303 // the file_util's Copy or Move method doesn't perform overwrite
302 // on all platforms, so we delete the destination directory here. 304 // on all platforms, so we delete the destination directory here.
303 // TODO(kinuko): may be better to change the file_util::{Copy,Move}. 305 // TODO(kinuko): may be better to change the file_util::{Copy,Move}.
304 PlatformFileError error = dest_util->Delete( 306 if (base::PLATFORM_FILE_OK !=
305 dest_context.get(), dest_file_path, false /* recursive */); 307 dest_util->Delete(dest_context, dest_file_path,
306 context->ImportAllowedBytesGrowth(*dest_context); 308 false /* recursive */)) {
307 if (base::PLATFORM_FILE_OK != error) { 309 if (!dest_util->IsDirectoryEmpty(dest_context, dest_file_path))
308 if (!dest_util->IsDirectoryEmpty(dest_context.get(), dest_file_path))
309 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; 310 return base::PLATFORM_FILE_ERROR_NOT_EMPTY;
310 return base::PLATFORM_FILE_ERROR_FAILED; 311 return base::PLATFORM_FILE_ERROR_FAILED;
311 } 312 }
313 // Reflect changes in usage back to the original context.
314 if (!same_file_system)
315 context->set_allowed_bytes_growth(dest_context->allowed_bytes_growth());
312 } 316 }
313 return base::PLATFORM_FILE_OK; 317 return base::PLATFORM_FILE_OK;
314 } 318 }
315 319
316 PlatformFileError FileSystemFileUtil::CopyOrMoveFile( 320 PlatformFileError FileSystemFileUtil::CopyOrMoveFile(
317 FileSystemOperationContext* unused, 321 FileSystemOperationContext* unused,
318 const FilePath& src_file_path, 322 const FilePath& src_file_path,
319 const FilePath& dest_file_path, 323 const FilePath& dest_file_path,
320 bool copy) { 324 bool copy) {
321 if (copy) { 325 if (copy) {
(...skipping 13 matching lines...) Expand all
335 const FilePath& dest_file_path) { 339 const FilePath& dest_file_path) {
336 return CopyOrMoveFile(context, src_file_path, dest_file_path, true); 340 return CopyOrMoveFile(context, src_file_path, dest_file_path, true);
337 } 341 }
338 342
339 PlatformFileError FileSystemFileUtil::CopyOrMoveDirectory( 343 PlatformFileError FileSystemFileUtil::CopyOrMoveDirectory(
340 FileSystemOperationContext* context, 344 FileSystemOperationContext* context,
341 const FilePath& src_file_path, 345 const FilePath& src_file_path,
342 const FilePath& dest_file_path, 346 const FilePath& dest_file_path,
343 bool copy) { 347 bool copy) {
344 FileSystemFileUtil* dest_util = context->dest_file_system_file_util(); 348 FileSystemFileUtil* dest_util = context->dest_file_system_file_util();
349 // All the single-path virtual FSFU methods expect the context information to
350 // be in the src_* variables, not the dest_* variables, so we have to make a
351 // new context if we want to call them on the dest_file_path.
345 scoped_ptr<FileSystemOperationContext> dest_context( 352 scoped_ptr<FileSystemOperationContext> dest_context(
346 context->CreateInheritedContextForDest()); 353 context->CreateInheritedContextForDest());
347 354
348 // Re-check PerformCommonCheckAndPreparationForMoveAndCopy() by DCHECK. 355 // Re-check PerformCommonCheckAndPreparationForMoveAndCopy() by DCHECK.
349 DCHECK(DirectoryExists(context, src_file_path)); 356 DCHECK(DirectoryExists(context, src_file_path));
350 DCHECK(ParentExists(dest_context.get(), dest_util, dest_file_path)); 357 DCHECK(ParentExists(dest_context.get(), dest_util, dest_file_path));
351 DCHECK(!dest_util->PathExists(dest_context.get(), dest_file_path)); 358 DCHECK(!dest_util->PathExists(dest_context.get(), dest_file_path));
352 if ((context->src_origin_url() == context->dest_origin_url()) && 359 if ((context->src_origin_url() == context->dest_origin_url()) &&
353 (context->src_type() == context->dest_type())) 360 (context->src_type() == context->dest_type()))
354 DCHECK(!src_file_path.IsParent(dest_file_path)); 361 DCHECK(!src_file_path.IsParent(dest_file_path));
355 362
356 if (!dest_util->DirectoryExists(dest_context.get(), dest_file_path)) { 363 if (!dest_util->DirectoryExists(dest_context.get(), dest_file_path)) {
357 PlatformFileError error = dest_util->CreateDirectory(dest_context.get(), 364 PlatformFileError error = dest_util->CreateDirectory(dest_context.get(),
358 dest_file_path, false, false); 365 dest_file_path, false, false);
359 context->ImportAllowedBytesGrowth(*dest_context);
360 if (error != base::PLATFORM_FILE_OK) 366 if (error != base::PLATFORM_FILE_OK)
361 return error; 367 return error;
368 // Reflect changes in usage back to the original context.
369 context->set_allowed_bytes_growth(dest_context->allowed_bytes_growth());
362 } 370 }
363 371
364 scoped_ptr<AbstractFileEnumerator> file_enum( 372 scoped_ptr<AbstractFileEnumerator> file_enum(
365 CreateFileEnumerator(context, src_file_path)); 373 CreateFileEnumerator(context, src_file_path));
366 FilePath src_file_path_each; 374 FilePath src_file_path_each;
367 while (!(src_file_path_each = file_enum->Next()).empty()) { 375 while (!(src_file_path_each = file_enum->Next()).empty()) {
368 FilePath dest_file_path_each(dest_file_path); 376 FilePath dest_file_path_each(dest_file_path);
369 src_file_path.AppendRelativePath(src_file_path_each, &dest_file_path_each); 377 src_file_path.AppendRelativePath(src_file_path_each, &dest_file_path_each);
370 378
371 if (file_enum->IsDirectory()) { 379 if (file_enum->IsDirectory()) {
372 scoped_ptr<FileSystemOperationContext> new_directory_context( 380 PlatformFileError error = dest_util->CreateDirectory(dest_context.get(),
373 dest_context->CreateInheritedContextWithNewVirtualPaths( 381 dest_file_path_each, false, false);
374 dest_file_path_each, FilePath()));
375 PlatformFileError error = dest_util->CreateDirectory(
376 new_directory_context.get(), dest_file_path_each, false, false);
377 context->ImportAllowedBytesGrowth(*new_directory_context);
378 if (error != base::PLATFORM_FILE_OK) 382 if (error != base::PLATFORM_FILE_OK)
379 return error; 383 return error;
384 // Reflect changes in usage back to the original context.
385 context->set_allowed_bytes_growth(dest_context->allowed_bytes_growth());
380 } else { 386 } else {
381 scoped_ptr<FileSystemOperationContext> copy_context(
382 context->CreateInheritedContextWithNewVirtualPaths(
383 src_file_path_each, dest_file_path_each));
384 PlatformFileError error = CopyOrMoveFileHelper( 387 PlatformFileError error = CopyOrMoveFileHelper(
385 copy_context.get(), src_file_path_each, dest_file_path_each, copy); 388 context, src_file_path_each, dest_file_path_each, copy);
386 context->ImportAllowedBytesGrowth(*copy_context);
387 if (error != base::PLATFORM_FILE_OK) 389 if (error != base::PLATFORM_FILE_OK)
388 return error; 390 return error;
389 } 391 }
390 } 392 }
391 393
392 if (!copy) { 394 if (!copy) {
393 PlatformFileError error = Delete(context, src_file_path, true); 395 PlatformFileError error = Delete(context, src_file_path, true);
394 if (error != base::PLATFORM_FILE_OK) 396 if (error != base::PLATFORM_FILE_OK)
395 return error; 397 return error;
396 } 398 }
399
397 return base::PLATFORM_FILE_OK; 400 return base::PLATFORM_FILE_OK;
398 } 401 }
399 402
400 PlatformFileError FileSystemFileUtil::CopyOrMoveFileHelper( 403 PlatformFileError FileSystemFileUtil::CopyOrMoveFileHelper(
401 FileSystemOperationContext* context, 404 FileSystemOperationContext* context,
402 const FilePath& src_file_path, 405 const FilePath& src_file_path,
403 const FilePath& dest_file_path, 406 const FilePath& dest_file_path,
404 bool copy) { 407 bool copy) {
405 // CopyOrMoveFile here is the virtual overridden member function. 408 // CopyOrMoveFile here is the virtual overridden member function.
406 if ((context->src_origin_url() == context->dest_origin_url()) && 409 if ((context->src_origin_url() == context->dest_origin_url()) &&
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 scoped_ptr<AbstractFileEnumerator> file_enum( 465 scoped_ptr<AbstractFileEnumerator> file_enum(
463 CreateFileEnumerator(context, file_path)); 466 CreateFileEnumerator(context, file_path));
464 FilePath file_path_each; 467 FilePath file_path_each;
465 468
466 std::stack<FilePath> directories; 469 std::stack<FilePath> directories;
467 while (!(file_path_each = file_enum->Next()).empty()) { 470 while (!(file_path_each = file_enum->Next()).empty()) {
468 if (file_enum->IsDirectory()) { 471 if (file_enum->IsDirectory()) {
469 directories.push(file_path_each); 472 directories.push(file_path_each);
470 } else { 473 } else {
471 // DeleteFile here is the virtual overridden member function. 474 // DeleteFile here is the virtual overridden member function.
472 scoped_ptr<FileSystemOperationContext> inherited_context( 475 PlatformFileError error = DeleteFile(context, file_path_each);
473 context->CreateInheritedContextWithNewVirtualPaths(
474 file_path_each, FilePath()));
475 PlatformFileError error =
476 DeleteFile(inherited_context.get(), file_path_each);
477 context->ImportAllowedBytesGrowth(*inherited_context);
478 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) 476 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND)
479 return base::PLATFORM_FILE_ERROR_FAILED; 477 return base::PLATFORM_FILE_ERROR_FAILED;
480 else if (error != base::PLATFORM_FILE_OK) 478 else if (error != base::PLATFORM_FILE_OK)
481 return error; 479 return error;
482 } 480 }
483 } 481 }
484 482
485 while (!directories.empty()) { 483 while (!directories.empty()) {
486 scoped_ptr<FileSystemOperationContext> inherited_context( 484 PlatformFileError error = DeleteSingleDirectory(context, directories.top());
487 context->CreateInheritedContextWithNewVirtualPaths(
488 directories.top(), FilePath()));
489 PlatformFileError error =
490 DeleteSingleDirectory(inherited_context.get(), directories.top());
491 context->ImportAllowedBytesGrowth(*inherited_context);
492 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) 485 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND)
493 return base::PLATFORM_FILE_ERROR_FAILED; 486 return base::PLATFORM_FILE_ERROR_FAILED;
494 else if (error != base::PLATFORM_FILE_OK) 487 else if (error != base::PLATFORM_FILE_OK)
495 return error; 488 return error;
496 directories.pop(); 489 directories.pop();
497 } 490 }
498 return DeleteSingleDirectory(context, file_path); 491 return DeleteSingleDirectory(context, file_path);
499 } 492 }
500 493
501 bool FileSystemFileUtil::PathExists( 494 bool FileSystemFileUtil::PathExists(
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 FileSystemFileUtil::CreateFileEnumerator( 541 FileSystemFileUtil::CreateFileEnumerator(
549 FileSystemOperationContext* unused, 542 FileSystemOperationContext* unused,
550 const FilePath& root_path) { 543 const FilePath& root_path) {
551 return new FileSystemFileEnumerator( 544 return new FileSystemFileEnumerator(
552 root_path, true, static_cast<file_util::FileEnumerator::FileType>( 545 root_path, true, static_cast<file_util::FileEnumerator::FileType>(
553 file_util::FileEnumerator::FILES | 546 file_util::FileEnumerator::FILES |
554 file_util::FileEnumerator::DIRECTORIES)); 547 file_util::FileEnumerator::DIRECTORIES));
555 } 548 }
556 549
557 } // namespace fileapi 550 } // namespace fileapi
OLDNEW
« no previous file with comments | « no previous file | webkit/fileapi/file_system_file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698