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; |