OLD | NEW |
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/file_system_util.h" | 5 #include "webkit/fileapi/file_system_util.h" |
6 | 6 |
7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
8 | 8 |
9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
12 #include "base/sys_string_conversions.h" | 12 #include "base/sys_string_conversions.h" |
13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
14 #include "googleurl/src/gurl.h" | 14 #include "googleurl/src/gurl.h" |
15 #include "net/base/escape.h" | 15 #include "net/base/escape.h" |
16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h
" | 16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h
" |
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" | 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" | 18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" |
19 #include "webkit/fileapi/file_system_types.h" | 19 #include "webkit/fileapi/file_system_types.h" |
20 | 20 |
21 namespace fileapi { | 21 namespace fileapi { |
22 | 22 |
23 const char kPersistentDir[] = "/persistent/"; | 23 const char kPersistentDir[] = "/persistent"; |
24 const char kTemporaryDir[] = "/temporary/"; | 24 const char kTemporaryDir[] = "/temporary"; |
25 const char kIsolatedDir[] = "/isolated/"; | 25 const char kIsolatedDir[] = "/isolated"; |
26 const char kExternalDir[] = "/external/"; | 26 const char kExternalDir[] = "/external"; |
27 | 27 |
28 const char kPersistentName[] = "Persistent"; | 28 const char kPersistentName[] = "Persistent"; |
29 const char kTemporaryName[] = "Temporary"; | 29 const char kTemporaryName[] = "Temporary"; |
30 const char kIsolatedName[] = "Isolated"; | 30 const char kIsolatedName[] = "Isolated"; |
31 const char kExternalName[] = "External"; | 31 const char kExternalName[] = "External"; |
32 | 32 |
33 bool CrackFileSystemURL(const GURL& url, GURL* origin_url, FileSystemType* type, | 33 bool CrackFileSystemURL(const GURL& url, GURL* origin_url, FileSystemType* type, |
34 FilePath* file_path) { | 34 FilePath* file_path) { |
35 GURL origin; | 35 GURL origin; |
36 FileSystemType file_system_type = kFileSystemTypeUnknown; | 36 FileSystemType file_system_type = kFileSystemTypeUnknown; |
37 | 37 |
38 if (url.scheme() != "filesystem") | 38 if (!url.is_valid() || !url.SchemeIsFileSystem()) |
39 return false; | 39 return false; |
| 40 DCHECK(url.inner_url()); |
40 | 41 |
41 std::string temp = url.path(); | 42 std::string inner_path = url.inner_url()->path(); |
42 // TODO(ericu): This should probably be done elsewhere after the stackable | |
43 // layers are properly in. We're supposed to reject any paths that contain | |
44 // '..' segments, but the GURL constructor is helpfully resolving them for us. | |
45 // Make sure there aren't any before we call it. | |
46 size_t pos = temp.find(".."); | |
47 for (; pos != std::string::npos; pos = temp.find("..", pos + 1)) { | |
48 if ((pos == 0 || temp[pos - 1] == '/') && | |
49 (pos == temp.length() - 2 || temp[pos + 2] == '/')) | |
50 return false; | |
51 } | |
52 | |
53 // bare_url will look something like: | |
54 // http://example.com/temporary/dir/file.txt. | |
55 GURL bare_url(temp); | |
56 | |
57 // The input URL was malformed, bail out early. | |
58 if (bare_url.path().empty()) | |
59 return false; | |
60 | |
61 origin = bare_url.GetOrigin(); | |
62 | |
63 // The input URL was malformed, bail out early. | |
64 if (origin.is_empty()) | |
65 return false; | |
66 | |
67 std::string path = net::UnescapeURLComponent(bare_url.path(), | |
68 net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS | | |
69 net::UnescapeRule::CONTROL_CHARS); | |
70 | 43 |
71 const struct { | 44 const struct { |
72 FileSystemType type; | 45 FileSystemType type; |
73 const char* dir; | 46 const char* dir; |
74 } kValidTypes[] = { | 47 } kValidTypes[] = { |
75 { kFileSystemTypePersistent, kPersistentDir }, | 48 { kFileSystemTypePersistent, kPersistentDir }, |
76 { kFileSystemTypeTemporary, kTemporaryDir }, | 49 { kFileSystemTypeTemporary, kTemporaryDir }, |
77 { kFileSystemTypeIsolated, kIsolatedDir }, | 50 { kFileSystemTypeIsolated, kIsolatedDir }, |
78 { kFileSystemTypeExternal, kExternalDir }, | 51 { kFileSystemTypeExternal, kExternalDir }, |
79 }; | 52 }; |
80 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidTypes); ++i) { | 53 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidTypes); ++i) { |
81 if (StartsWithASCII(path, kValidTypes[i].dir, true)) { | 54 if (StartsWithASCII(inner_path, kValidTypes[i].dir, true)) { |
82 file_system_type = kValidTypes[i].type; | 55 file_system_type = kValidTypes[i].type; |
83 path = path.substr(strlen(kValidTypes[i].dir)); | |
84 break; | 56 break; |
85 } | 57 } |
86 } | 58 } |
87 | 59 |
88 if (file_system_type == kFileSystemTypeUnknown) | 60 if (file_system_type == kFileSystemTypeUnknown) |
89 return false; | 61 return false; |
90 | 62 |
| 63 std::string path = net::UnescapeURLComponent(url.path(), |
| 64 net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS | |
| 65 net::UnescapeRule::CONTROL_CHARS); |
| 66 |
91 // Ensure the path is relative. | 67 // Ensure the path is relative. |
92 while (!path.empty() && path[0] == '/') | 68 while (!path.empty() && path[0] == '/') |
93 path.erase(0, 1); | 69 path.erase(0, 1); |
94 | 70 |
| 71 FilePath converted_path = FilePath::FromUTF8Unsafe(path); |
| 72 |
| 73 // All parent references should have been resolved in the renderer. |
| 74 if (converted_path.ReferencesParent()) |
| 75 return false; |
| 76 |
95 if (origin_url) | 77 if (origin_url) |
96 *origin_url = origin; | 78 *origin_url = url.GetOrigin(); |
97 if (type) | 79 if (type) |
98 *type = file_system_type; | 80 *type = file_system_type; |
99 if (file_path) | 81 if (file_path) |
100 *file_path = FilePath::FromUTF8Unsafe(path). | 82 *file_path = converted_path.NormalizePathSeparators(). |
101 NormalizePathSeparators().StripTrailingSeparators(); | 83 StripTrailingSeparators(); |
102 | 84 |
103 return true; | 85 return true; |
104 } | 86 } |
105 | 87 |
106 //TODO(ericu): Consider removing support for '\', even on Windows, if possible. | 88 //TODO(ericu): Consider removing support for '\', even on Windows, if possible. |
107 // There's a lot of test code that will need reworking, and we may have trouble | 89 // There's a lot of test code that will need reworking, and we may have trouble |
108 // with FilePath elsewhere [e.g. DirName and other methods may also need | 90 // with FilePath elsewhere [e.g. DirName and other methods may also need |
109 // replacement]. | 91 // replacement]. |
110 FilePath VirtualPath::BaseName(const FilePath& virtual_path) { | 92 FilePath VirtualPath::BaseName(const FilePath& virtual_path) { |
111 FilePath::StringType path = virtual_path.value(); | 93 FilePath::StringType path = virtual_path.value(); |
(...skipping 30 matching lines...) Expand all Loading... |
142 base = BaseName(current); | 124 base = BaseName(current); |
143 ret_val.push_back(base.value()); | 125 ret_val.push_back(base.value()); |
144 current = current.DirName(); | 126 current = current.DirName(); |
145 } | 127 } |
146 | 128 |
147 *components = | 129 *components = |
148 std::vector<FilePath::StringType>(ret_val.rbegin(), ret_val.rend()); | 130 std::vector<FilePath::StringType>(ret_val.rbegin(), ret_val.rend()); |
149 } | 131 } |
150 | 132 |
151 GURL GetFileSystemRootURI(const GURL& origin_url, FileSystemType type) { | 133 GURL GetFileSystemRootURI(const GURL& origin_url, FileSystemType type) { |
152 std::string path("filesystem:"); | 134 // origin_url is based on a security origin, so http://foo.com or file:/// |
153 path += origin_url.spec(); | 135 // instead of the corresponding filesystem URL. |
| 136 DCHECK(!origin_url.SchemeIsFileSystem()); |
| 137 |
| 138 std::string url = "filesystem:" + origin_url.GetWithEmptyPath().spec(); |
154 switch (type) { | 139 switch (type) { |
155 case kFileSystemTypeTemporary: | 140 case kFileSystemTypeTemporary: |
156 path += (kTemporaryDir + 1); // We don't want the leading slash. | 141 url += (kTemporaryDir + 1); // We don't want the leading slash. |
157 return GURL(path); | 142 return GURL(url + "/"); |
158 case kFileSystemTypePersistent: | 143 case kFileSystemTypePersistent: |
159 path += (kPersistentDir + 1); // We don't want the leading slash. | 144 url += (kPersistentDir + 1); // We don't want the leading slash. |
160 return GURL(path); | 145 return GURL(url + "/"); |
161 case kFileSystemTypeExternal: | 146 case kFileSystemTypeExternal: |
162 path += (kExternalDir + 1); // We don't want the leading slash. | 147 url += (kExternalDir + 1); // We don't want the leading slash. |
163 return GURL(path); | 148 return GURL(url + "/"); |
164 case kFileSystemTypeIsolated: | 149 case kFileSystemTypeIsolated: |
165 // Falling through; we won't call this for isolated filesystems. | 150 // Falling through; we won't call this for isolated filesystems. |
166 case kFileSystemTypeUnknown: | 151 case kFileSystemTypeUnknown: |
167 NOTREACHED(); | 152 NOTREACHED(); |
168 } | 153 } |
169 NOTREACHED(); | 154 NOTREACHED(); |
170 return GURL(); | 155 return GURL(); |
171 } | 156 } |
172 | 157 |
173 std::string GetFileSystemName(const GURL& origin_url, FileSystemType type) { | 158 std::string GetFileSystemName(const GURL& origin_url, FileSystemType type) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 | 232 |
248 FilePath StringToFilePath(const std::string& file_path_string) { | 233 FilePath StringToFilePath(const std::string& file_path_string) { |
249 #if defined(OS_WIN) | 234 #if defined(OS_WIN) |
250 return FilePath(UTF8ToUTF16(file_path_string)); | 235 return FilePath(UTF8ToUTF16(file_path_string)); |
251 #elif defined(OS_POSIX) | 236 #elif defined(OS_POSIX) |
252 return FilePath(file_path_string); | 237 return FilePath(file_path_string); |
253 #endif | 238 #endif |
254 } | 239 } |
255 | 240 |
256 } // namespace fileapi | 241 } // namespace fileapi |
OLD | NEW |