| Index: webkit/browser/fileapi/dragged_file_util.cc
|
| diff --git a/webkit/browser/fileapi/dragged_file_util.cc b/webkit/browser/fileapi/dragged_file_util.cc
|
| index 0243b3d15d8df6ea88a2a550e2e7117579ef30c2..80b30b81bcebc70214b199ada0fcff8c3b574be4 100644
|
| --- a/webkit/browser/fileapi/dragged_file_util.cc
|
| +++ b/webkit/browser/fileapi/dragged_file_util.cc
|
| @@ -8,6 +8,7 @@
|
| #include <vector>
|
|
|
| #include "base/file_util.h"
|
| +#include "base/files/file_enumerator.h"
|
| #include "webkit/browser/fileapi/file_system_context.h"
|
| #include "webkit/browser/fileapi/file_system_operation_context.h"
|
| #include "webkit/browser/fileapi/file_system_url.h"
|
| @@ -51,12 +52,77 @@ class SetFileEnumerator : public FileSystemFileUtil::AbstractFileEnumerator {
|
| base::File::Info file_info_;
|
| };
|
|
|
| +// Like fileapi::LocalFileEnumerator, but without skipping symbolic links.
|
| +class FollowSymlinksLocalFileEnumerator
|
| + : public FileSystemFileUtil::AbstractFileEnumerator {
|
| + public:
|
| + FollowSymlinksLocalFileEnumerator(
|
| + const base::FilePath& platform_root_path,
|
| + const base::FilePath& virtual_root_path,
|
| + int file_type)
|
| + : file_enum_(platform_root_path, false /* recursive */, file_type),
|
| + platform_root_path_(platform_root_path),
|
| + virtual_root_path_(virtual_root_path) {
|
| + }
|
| +
|
| + virtual ~FollowSymlinksLocalFileEnumerator() {}
|
| +
|
| + virtual base::FilePath Next() OVERRIDE;
|
| + virtual int64 Size() OVERRIDE;
|
| + virtual base::Time LastModifiedTime() OVERRIDE;
|
| + virtual bool IsDirectory() OVERRIDE;
|
| +
|
| + private:
|
| + base::FileEnumerator file_enum_;
|
| + base::FileEnumerator::FileInfo file_util_info_;
|
| + base::FilePath platform_root_path_;
|
| + base::FilePath virtual_root_path_;
|
| +};
|
| +
|
| } // namespace
|
|
|
| //-------------------------------------------------------------------------
|
|
|
| +base::FilePath FollowSymlinksLocalFileEnumerator::Next() {
|
| + base::FilePath next = file_enum_.Next();
|
| +
|
| + if (next.empty())
|
| + return next;
|
| + file_util_info_ = file_enum_.GetInfo();
|
| +
|
| + base::FilePath path;
|
| + platform_root_path_.AppendRelativePath(next, &path);
|
| + return virtual_root_path_.Append(path);
|
| +}
|
| +
|
| +int64 FollowSymlinksLocalFileEnumerator::Size() {
|
| + return file_util_info_.GetSize();
|
| +}
|
| +
|
| +base::Time FollowSymlinksLocalFileEnumerator::LastModifiedTime() {
|
| + return file_util_info_.GetLastModifiedTime();
|
| +}
|
| +
|
| +bool FollowSymlinksLocalFileEnumerator::IsDirectory() {
|
| + return file_util_info_.IsDirectory();
|
| +}
|
| +
|
| DraggedFileUtil::DraggedFileUtil() {}
|
|
|
| +base::File::Error DraggedFileUtil::CreateOrOpen(
|
| + FileSystemOperationContext* context,
|
| + const FileSystemURL& url, int file_flags,
|
| + base::PlatformFile* file_handle, bool* created) {
|
| + *created = false;
|
| + base::FilePath file_path;
|
| + base::File::Error error = GetLocalFilePath(context, url, &file_path);
|
| + if (error != base::File::FILE_OK)
|
| + return error;
|
| +
|
| + return NativeFileUtil::CreateOrOpen(file_path, file_flags, file_handle,
|
| + created);
|
| +}
|
| +
|
| base::File::Error DraggedFileUtil::GetFileInfo(
|
| FileSystemOperationContext* context,
|
| const FileSystemURL& url,
|
| @@ -78,10 +144,6 @@ base::File::Error DraggedFileUtil::GetFileInfo(
|
| }
|
| base::File::Error error =
|
| NativeFileUtil::GetFileInfo(url.path(), file_info);
|
| - if (base::IsLink(url.path()) && !base::FilePath().IsParent(url.path())) {
|
| - // Don't follow symlinks unless it's the one that are selected by the user.
|
| - return base::File::FILE_ERROR_NOT_FOUND;
|
| - }
|
| if (error == base::File::FILE_OK)
|
| *platform_path = url.path();
|
| return error;
|
| @@ -92,8 +154,19 @@ scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator>
|
| FileSystemOperationContext* context,
|
| const FileSystemURL& root) {
|
| DCHECK(root.is_valid());
|
| - if (!root.path().empty())
|
| - return LocalFileUtil::CreateFileEnumerator(context, root);
|
| + if (!root.path().empty()) {
|
| + base::FilePath file_path;
|
| + if (GetLocalFilePath(context, root, &file_path) !=
|
| + base::File::FILE_OK) {
|
| + return make_scoped_ptr(new EmptyFileEnumerator)
|
| + .PassAs<FileSystemFileUtil::AbstractFileEnumerator>();
|
| + }
|
| +
|
| + return make_scoped_ptr(new FollowSymlinksLocalFileEnumerator(
|
| + file_path, root.path(),
|
| + base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES))
|
| + .PassAs<FileSystemFileUtil::AbstractFileEnumerator>();
|
| + }
|
|
|
| // Root path case.
|
| std::vector<FileInfo> toplevels;
|
|
|