1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "webkit/fileapi/file_system_util.h"
#include "build/build_config.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "base/sys_string_conversions.h"
#include "googleurl/src/gurl.h"
#include "net/base/escape.h"
#include "webkit/fileapi/file_system_types.h"
namespace fileapi {
const char kPersistentDir[] = "/persistent/";
const char kTemporaryDir[] = "/temporary/";
const char kExternalDir[] = "/external/";
const char kPersistentName[] = "Persistent";
const char kTemporaryName[] = "Temporary";
const char kExternalName[] = "External";
bool CrackFileSystemURL(const GURL& url, GURL* origin_url, FileSystemType* type,
FilePath* file_path) {
GURL origin;
FileSystemType file_system_type;
if (url.scheme() != "filesystem")
return false;
std::string temp = url.path();
// TODO(ericu) remove this code when that ceases to be true, which should be
// soon.
// On Windows, this will have backslashes for now.
// url will look something like:
// filesystem:http://example.com/temporary/\dir\file.txt
// temp will look something like:
// http://example.com/temporary/\dir\file.txt
// On posix, url will look something like:
// filesystem:http://example.com/temporary/dir/file.txt
// temp will look something like:
// http://example.com/temporary/dir/file.txt
size_t pos = temp.find('\\');
for (; pos != std::string::npos; pos = temp.find('\\', pos + 1)) {
temp[pos] = '/';
}
// TODO(ericu): This should probably be done elsewhere after the stackable
// layers are properly in. We're supposed to reject any paths that contain
// '..' segments, but the GURL constructor is helpfully resolving them for us.
// Make sure there aren't any before we call it.
pos = temp.find("..");
for (; pos != std::string::npos; pos = temp.find("..", pos + 1)) {
if ((pos == 0 || temp[pos - 1] == '/') &&
(pos == temp.length() - 2 || temp[pos + 2] == '/'))
return false;
}
// bare_url will look something like:
// http://example.com/temporary//dir/file.txt [on Windows; the double slash
// before dir will be single on posix].
GURL bare_url(temp);
// The input URL was malformed, bail out early.
if (bare_url.path().empty())
return false;
origin = bare_url.GetOrigin();
// The input URL was malformed, bail out early.
if (origin.is_empty())
return false;
std::string path = UnescapeURLComponent(bare_url.path(),
UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS);
if (path.compare(0, strlen(kPersistentDir), kPersistentDir) == 0) {
file_system_type = kFileSystemTypePersistent;
path = path.substr(strlen(kPersistentDir));
} else if (path.compare(0, strlen(kTemporaryDir), kTemporaryDir) == 0) {
file_system_type = kFileSystemTypeTemporary;
path = path.substr(strlen(kTemporaryDir));
} else if (path.compare(0, strlen(kExternalDir), kExternalDir) == 0) {
file_system_type = kFileSystemTypeExternal;
path = path.substr(strlen(kExternalDir));
} else {
return false;
}
// Ensure the path is relative.
while (!path.empty() && path[0] == '/')
path.erase(0, 1);
if (origin_url)
*origin_url = origin;
if (type)
*type = file_system_type;
if (file_path)
#if defined(OS_WIN)
*file_path = FilePath(base::SysUTF8ToWide(path)).
NormalizeWindowsPathSeparators();
#elif defined(OS_POSIX)
*file_path = FilePath(path);
#endif
return true;
}
GURL GetFileSystemRootURI(
const GURL& origin_url, fileapi::FileSystemType type) {
std::string path("filesystem:");
path += origin_url.spec();
switch (type) {
case kFileSystemTypeTemporary:
path += (kTemporaryDir + 1); // We don't want the leading slash.
break;
case kFileSystemTypePersistent:
path += (kPersistentDir + 1); // We don't want the leading slash.
break;
case kFileSystemTypeExternal:
path += (kExternalDir + 1); // We don't want the leading slash.
break;
default:
NOTREACHED();
return GURL();
}
return GURL(path);
}
} // namespace fileapi
|