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

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

Issue 6603034: Stop returning the true root path of each filesystem from openFileSystem.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 9 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "webkit/fileapi/sandbox_mount_point_provider.h"
6
7 #include "base/rand_util.h"
8 #include "base/logging.h"
9 #include "base/message_loop.h"
10 #include "base/message_loop_proxy.h"
11 #include "base/scoped_callback_factory.h"
12 #include "base/scoped_ptr.h"
13 #include "base/stringprintf.h"
14 #include "base/string_util.h"
15 #include "base/utf_string_conversions.h"
16 #include "googleurl/src/gurl.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystem.h"
kinuko 2011/03/14 11:03:57 not needed?
ericu 2011/03/15 02:43:11 Done.
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
20 #include "webkit/fileapi/file_system_path_manager.h"
21 #include "webkit/fileapi/file_system_util.h"
22 #include "webkit/glue/webkit_glue.h"
23
24 namespace {
25
26 static const FilePath::CharType kFileSystemUniqueNamePrefix[] =
27 FILE_PATH_LITERAL("chrome-");
28 static const int kFileSystemUniqueLength = 16;
29 static const unsigned kFileSystemUniqueDirectoryNameLength =
30 kFileSystemUniqueLength + arraysize(kFileSystemUniqueNamePrefix) - 1;
31
32 // Restricted names.
33 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions
34 static const char* const kRestrictedNames[] = {
35 "con", "prn", "aux", "nul",
36 "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9",
37 "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9",
38 };
39
40 // Restricted chars.
41 static const FilePath::CharType kRestrictedChars[] = {
42 '/', '\\', '<', '>', ':', '?', '*', '"', '|',
43 };
44
45 inline std::string FilePathStringToASCII(
46 const FilePath::StringType& path_string) {
47 #if defined(OS_WIN)
48 return WideToASCII(path_string);
49 #elif defined(OS_POSIX)
50 return path_string;
51 #endif
52 }
53
54 FilePath::StringType CreateUniqueDirectoryName(const GURL& origin_url) {
55 // This can be anything but need to be unpredictable.
56 static const FilePath::CharType letters[] = FILE_PATH_LITERAL(
57 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
58 FilePath::StringType unique(kFileSystemUniqueNamePrefix);
59 for (int i = 0; i < kFileSystemUniqueLength; ++i)
60 unique += letters[base::RandInt(0, arraysize(letters) - 2)];
61 return unique;
62 }
63
64 bool ReadOriginDirectory(const FilePath& base_path,
65 const GURL& origin_url,
66 FilePath* unique) {
67 file_util::FileEnumerator file_enum(
68 base_path, false /* recursive */,
69 file_util::FileEnumerator::DIRECTORIES,
70 FilePath::StringType(kFileSystemUniqueNamePrefix) +
71 FILE_PATH_LITERAL("*"));
72 FilePath current;
73 bool found = false;
74 while (!(current = file_enum.Next()).empty()) {
75 if (current.BaseName().value().length() !=
76 kFileSystemUniqueDirectoryNameLength)
77 continue;
78 if (found) {
79 // TODO(kinuko): Should notify the user to ask for some action.
80 LOG(WARNING) << "Unexpectedly found more than one FileSystem "
81 << "directories for " << origin_url;
82 return false;
83 }
84 found = true;
85 *unique = current;
86 }
87 return !unique->empty();
88 }
89
90 FilePath GetFileSystemRootPathOnFileThreadHelper(
91 const GURL& origin_url, const FilePath &origin_base_path, bool create) {
92 FilePath root;
93 if (ReadOriginDirectory(origin_base_path, origin_url, &root))
94 return root;
95
96 if (!create)
97 return FilePath();
98
99 // Creates the root directory.
100 root = origin_base_path.Append(CreateUniqueDirectoryName(origin_url));
101 if (!file_util::CreateDirectory(root))
102 return FilePath();
103
104 return root;
105 }
106
107 } // anonymous namespace
108
109 namespace fileapi {
110
111 const FilePath::CharType SandboxMountPointProvider::kFileSystemDirectory[] =
112 FILE_PATH_LITERAL("FileSystem");
113
114 const char SandboxMountPointProvider::kPersistentName[] = "Persistent";
115 const char SandboxMountPointProvider::kTemporaryName[] = "Temporary";
116
117 SandboxMountPointProvider::SandboxMountPointProvider(
118 FileSystemPathManager* path_manager,
119 scoped_refptr<base::MessageLoopProxy> file_message_loop,
120 const FilePath& profile_path)
121 : path_manager_(path_manager),
122 file_message_loop_(file_message_loop),
123 base_path_(profile_path.Append(kFileSystemDirectory)) {
124 }
125
126 bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url) {
127 // We essentially depend on quota to do our access controls.
128 return path_manager_->IsAllowedScheme(origin_url);
129 }
130
131 class SandboxMountPointProvider::GetFileSystemRootPathTask
132 : public base::RefCountedThreadSafe<
133 SandboxMountPointProvider::GetFileSystemRootPathTask> {
134 public:
135 GetFileSystemRootPathTask(
136 scoped_refptr<base::MessageLoopProxy> file_message_loop,
137 const std::string& name,
138 FileSystemPathManager::GetRootPathCallback* callback)
139 : file_message_loop_(file_message_loop),
140 origin_message_loop_proxy_(
141 base::MessageLoopProxy::CreateForCurrentThread()),
142 name_(name),
143 callback_(callback) {
144 }
145
146 void Start(const GURL& origin_url,
147 const FilePath& origin_base_path,
148 bool create) {
149 file_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
150 &GetFileSystemRootPathTask::GetFileSystemRootPathOnFileThread,
151 origin_url, origin_base_path, create));
152 }
153
154 private:
155 void GetFileSystemRootPathOnFileThread(
156 const GURL& origin_url,
157 const FilePath& origin_base_path,
158 bool create) {
159 DispatchCallbackOnCallerThread(
160 GetFileSystemRootPathOnFileThreadHelper(
161 origin_url, origin_base_path, create));
162 }
163
164 void DispatchCallbackOnCallerThread(const FilePath& root_path) {
165 origin_message_loop_proxy_->PostTask(FROM_HERE,
166 NewRunnableMethod(this, &GetFileSystemRootPathTask::DispatchCallback,
167 root_path));
168 }
169
170 void DispatchCallback(const FilePath& root_path) {
171 callback_->Run(!root_path.empty(), root_path, name_);
172 callback_.reset();
173 }
174
175 scoped_refptr<base::MessageLoopProxy> file_message_loop_;
176 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_;
177 std::string name_;
178 scoped_ptr<FileSystemPathManager::GetRootPathCallback> callback_;
179 };
180
181 // static
kinuko 2011/03/14 11:03:57 please remove this comment
ericu 2011/03/15 02:43:11 Done.
182 bool SandboxMountPointProvider::IsRestrictedFileName(const FilePath& filename) {
183 if (filename.value().empty())
184 return false;
185
186 if (IsWhitespace(filename.value()[filename.value().size() - 1]) ||
187 filename.value()[filename.value().size() - 1] == '.')
188 return true;
189
190 std::string filename_lower = StringToLowerASCII(
191 FilePathStringToASCII(filename.value()));
192
193 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) {
194 // Exact match.
195 if (filename_lower == kRestrictedNames[i])
196 return true;
197 // Starts with "RESTRICTED_NAME.".
198 if (filename_lower.find(std::string(kRestrictedNames[i]) + ".") == 0)
199 return true;
200 }
201
202 for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) {
203 if (filename.value().find(kRestrictedChars[i]) !=
204 FilePath::StringType::npos)
205 return true;
206 }
207
208 return false;
209 }
210
211 void SandboxMountPointProvider::GetFileSystemRootPath(
212 const GURL& origin_url, fileapi::FileSystemType type,
213 bool create, FileSystemPathManager::GetRootPathCallback* callback_ptr) {
214 scoped_ptr<FileSystemPathManager::GetRootPathCallback> callback(callback_ptr);
215 std::string name;
216 FilePath origin_base_path;
217
218 if (!GetOriginBasePathAndName(origin_url, &origin_base_path, type, &name)) {
219 callback->Run(false, FilePath(), std::string());
220 return;
221 }
222
223 scoped_refptr<GetFileSystemRootPathTask> task(
224 new GetFileSystemRootPathTask(file_message_loop_,
225 name,
226 callback.release()));
227 task->Start(origin_url, origin_base_path, create);
228 };
229
230 FilePath SandboxMountPointProvider::GetFileSystemRootPathOnFileThread(
231 const GURL& origin_url, FileSystemType type, bool create) {
232 FilePath origin_base_path;
233 if (!GetOriginBasePathAndName(origin_url, &origin_base_path, type, NULL)) {
234 return FilePath();
235 }
236 return GetFileSystemRootPathOnFileThreadHelper(
237 origin_url, origin_base_path, create);
238 }
239
240 // static
241 std::string SandboxMountPointProvider::GetOriginIdentifierFromURL(
242 const GURL& url) {
243 WebKit::WebSecurityOrigin web_security_origin =
244 WebKit::WebSecurityOrigin::createFromString(UTF8ToUTF16(url.spec()));
245 return web_security_origin.databaseIdentifier().utf8();
246 }
247
248 // static
249 FilePath SandboxMountPointProvider::GetFileSystemBaseDirectoryForOriginAndType(
250 const FilePath& base_path, const std::string& origin_identifier,
251 fileapi::FileSystemType type) {
252 if (origin_identifier.empty())
253 return FilePath();
254 std::string type_string =
255 FileSystemPathManager::GetFileSystemTypeString(type);
256 if (type_string.empty()) {
257 LOG(WARNING) << "Unknown filesystem type is requested:" << type;
258 return FilePath();
259 }
260 return base_path.AppendASCII(origin_identifier)
261 .AppendASCII(type_string);
262 }
263
264 SandboxMountPointProvider::OriginEnumerator::OriginEnumerator(
265 const FilePath& base_path)
266 : enumerator_(base_path, false /* recursive */,
267 file_util::FileEnumerator::DIRECTORIES) {
268 }
269
270 std::string SandboxMountPointProvider::OriginEnumerator::Next() {
271 current_ = enumerator_.Next();
272 return FilePathStringToASCII(current_.BaseName().value());
273 }
274
275 bool SandboxMountPointProvider::OriginEnumerator::HasTemporary() {
276 return !current_.empty() && file_util::DirectoryExists(current_.AppendASCII(
277 SandboxMountPointProvider::kTemporaryName));
278 }
279
280 bool SandboxMountPointProvider::OriginEnumerator::HasPersistent() {
281 return !current_.empty() && file_util::DirectoryExists(current_.AppendASCII(
282 SandboxMountPointProvider::kPersistentName));
283 }
284
285 bool SandboxMountPointProvider::GetOriginBasePathAndName(
286 const GURL& origin_url,
287 FilePath* origin_base_path,
288 FileSystemType type,
289 std::string* name) {
290
291 if (path_manager_->is_incognito())
292 // TODO(kinuko): return an isolated temporary directory.
293 return false;
294
295 if (!path_manager_->IsAllowedScheme(origin_url))
296 return false;
297
298 std::string origin_identifier = GetOriginIdentifierFromURL(origin_url);
299 *origin_base_path = GetFileSystemBaseDirectoryForOriginAndType(
300 base_path(), origin_identifier, type);
301 if (origin_base_path->empty())
302 return false;
303
304 std::string type_string =
305 FileSystemPathManager::GetFileSystemTypeString(type);
306 DCHECK(!type_string.empty());
307 if (name)
308 *name = origin_identifier + ":" + type_string;
309 return true;
310 }
311
312 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698