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