file_system_util_unittest.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. // Copyright 2014 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. #include "storage/common/file_system/file_system_util.h"
  5. #include <stddef.h>
  6. #include "base/files/file_path.h"
  7. #include "testing/gtest/include/gtest/gtest.h"
  8. #include "url/gurl.h"
  9. using storage::CrackIsolatedFileSystemName;
  10. using storage::GetExternalFileSystemRootURIString;
  11. using storage::GetIsolatedFileSystemName;
  12. using storage::GetIsolatedFileSystemRootURIString;
  13. using storage::ValidateIsolatedFileSystemId;
  14. using storage::VirtualPath;
  15. namespace content {
  16. namespace {
  17. class FileSystemUtilTest : public testing::Test {};
  18. TEST_F(FileSystemUtilTest, ParseFileSystemSchemeURL) {
  19. GURL uri("filesystem:http://chromium.org/temporary/foo/bar");
  20. GURL origin_url;
  21. storage::FileSystemType type;
  22. base::FilePath virtual_path;
  23. ParseFileSystemSchemeURL(uri, &origin_url, &type, &virtual_path);
  24. EXPECT_EQ(GURL("http://chromium.org"), origin_url);
  25. EXPECT_EQ(storage::kFileSystemTypeTemporary, type);
  26. #if defined(FILE_PATH_USES_WIN_SEPARATORS)
  27. base::FilePath expected_path(FILE_PATH_LITERAL("foo\\bar"));
  28. #else
  29. base::FilePath expected_path(FILE_PATH_LITERAL("foo/bar"));
  30. #endif
  31. EXPECT_EQ(expected_path, virtual_path);
  32. }
  33. TEST_F(FileSystemUtilTest, GetTempFileSystemRootURI) {
  34. GURL origin_url("http://chromium.org");
  35. storage::FileSystemType type = storage::kFileSystemTypeTemporary;
  36. GURL uri = GURL("filesystem:http://chromium.org/temporary/");
  37. EXPECT_EQ(uri, GetFileSystemRootURI(origin_url, type));
  38. }
  39. TEST_F(FileSystemUtilTest, GetPersistentFileSystemRootURI) {
  40. GURL origin_url("http://chromium.org");
  41. storage::FileSystemType type = storage::kFileSystemTypePersistent;
  42. GURL uri = GURL("filesystem:http://chromium.org/persistent/");
  43. EXPECT_EQ(uri, GetFileSystemRootURI(origin_url, type));
  44. }
  45. TEST_F(FileSystemUtilTest, VirtualPathBaseName) {
  46. struct test_data {
  47. const base::FilePath::StringType path;
  48. const base::FilePath::StringType base_name;
  49. } test_cases[] = {
  50. {FILE_PATH_LITERAL("foo/bar"), FILE_PATH_LITERAL("bar")},
  51. {FILE_PATH_LITERAL("foo/b:bar"), FILE_PATH_LITERAL("b:bar")},
  52. {FILE_PATH_LITERAL(""), FILE_PATH_LITERAL("")},
  53. {FILE_PATH_LITERAL("/"), FILE_PATH_LITERAL("/")},
  54. {FILE_PATH_LITERAL("foo//////bar"), FILE_PATH_LITERAL("bar")},
  55. {FILE_PATH_LITERAL("foo/bar/"), FILE_PATH_LITERAL("bar")},
  56. {FILE_PATH_LITERAL("foo/bar/////"), FILE_PATH_LITERAL("bar")},
  57. {FILE_PATH_LITERAL("/bar/////"), FILE_PATH_LITERAL("bar")},
  58. {FILE_PATH_LITERAL("bar/////"), FILE_PATH_LITERAL("bar")},
  59. {FILE_PATH_LITERAL("bar/"), FILE_PATH_LITERAL("bar")},
  60. {FILE_PATH_LITERAL("/bar"), FILE_PATH_LITERAL("bar")},
  61. {FILE_PATH_LITERAL("////bar"), FILE_PATH_LITERAL("bar")},
  62. {FILE_PATH_LITERAL("bar"), FILE_PATH_LITERAL("bar")}};
  63. for (const auto& test_case : test_cases) {
  64. base::FilePath input = base::FilePath(test_case.path);
  65. base::FilePath base_name = VirtualPath::BaseName(input);
  66. EXPECT_EQ(test_case.base_name, base_name.value());
  67. }
  68. }
  69. TEST_F(FileSystemUtilTest, VirtualPathDirName) {
  70. struct test_data {
  71. const base::FilePath::StringType path;
  72. const base::FilePath::StringType dir_name;
  73. } test_cases[] = {
  74. {FILE_PATH_LITERAL("foo/bar"), FILE_PATH_LITERAL("foo")},
  75. {FILE_PATH_LITERAL("foo/b:bar"), FILE_PATH_LITERAL("foo")},
  76. {FILE_PATH_LITERAL(""), FILE_PATH_LITERAL(".")},
  77. {FILE_PATH_LITERAL("/"), FILE_PATH_LITERAL("/")},
  78. {FILE_PATH_LITERAL("foo//////bar"), FILE_PATH_LITERAL("foo")},
  79. {FILE_PATH_LITERAL("foo/bar/"), FILE_PATH_LITERAL("foo")},
  80. {FILE_PATH_LITERAL("foo/bar/////"), FILE_PATH_LITERAL("foo")},
  81. {FILE_PATH_LITERAL("/bar/////"), FILE_PATH_LITERAL("/")},
  82. {FILE_PATH_LITERAL("bar/////"), FILE_PATH_LITERAL(".")},
  83. {FILE_PATH_LITERAL("bar/"), FILE_PATH_LITERAL(".")},
  84. {FILE_PATH_LITERAL("/bar"), FILE_PATH_LITERAL("/")},
  85. {FILE_PATH_LITERAL("////bar"), FILE_PATH_LITERAL("/")},
  86. {FILE_PATH_LITERAL("bar"), FILE_PATH_LITERAL(".")},
  87. {FILE_PATH_LITERAL("c:bar"), FILE_PATH_LITERAL(".")},
  88. #ifdef FILE_PATH_USES_WIN_SEPARATORS
  89. {FILE_PATH_LITERAL("foo\\bar"), FILE_PATH_LITERAL("foo")},
  90. {FILE_PATH_LITERAL("foo\\b:bar"), FILE_PATH_LITERAL("foo")},
  91. {FILE_PATH_LITERAL("\\"), FILE_PATH_LITERAL("\\")},
  92. {FILE_PATH_LITERAL("foo\\\\\\\\\\\\bar"), FILE_PATH_LITERAL("foo")},
  93. {FILE_PATH_LITERAL("foo\\bar\\"), FILE_PATH_LITERAL("foo")},
  94. {FILE_PATH_LITERAL("foo\\bar\\\\\\\\\\"), FILE_PATH_LITERAL("foo")},
  95. {FILE_PATH_LITERAL("\\bar\\\\\\\\\\"), FILE_PATH_LITERAL("\\")},
  96. {FILE_PATH_LITERAL("bar\\\\\\\\\\"), FILE_PATH_LITERAL(".")},
  97. {FILE_PATH_LITERAL("bar\\"), FILE_PATH_LITERAL(".")},
  98. {FILE_PATH_LITERAL("\\bar"), FILE_PATH_LITERAL("\\")},
  99. {FILE_PATH_LITERAL("\\\\\\\\bar"), FILE_PATH_LITERAL("\\")},
  100. #endif
  101. };
  102. for (const auto& test_case : test_cases) {
  103. base::FilePath input = base::FilePath(test_case.path);
  104. base::FilePath dir_name = VirtualPath::DirName(input);
  105. EXPECT_EQ(test_case.dir_name, dir_name.value());
  106. }
  107. }
  108. TEST_F(FileSystemUtilTest, GetNormalizedFilePath) {
  109. struct test_data {
  110. const base::FilePath::StringType path;
  111. const base::FilePath::StringType normalized_path;
  112. } test_cases[] = {
  113. {FILE_PATH_LITERAL(""), FILE_PATH_LITERAL("/")},
  114. {FILE_PATH_LITERAL("/"), FILE_PATH_LITERAL("/")},
  115. {FILE_PATH_LITERAL("foo/bar"), FILE_PATH_LITERAL("/foo/bar")},
  116. {FILE_PATH_LITERAL("/foo/bar"), FILE_PATH_LITERAL("/foo/bar")},
  117. #if defined(FILE_PATH_USES_WIN_SEPARATORS)
  118. {FILE_PATH_LITERAL("\\foo"), FILE_PATH_LITERAL("/foo")},
  119. #endif
  120. };
  121. for (const auto& test_case : test_cases) {
  122. base::FilePath input = base::FilePath(test_case.path);
  123. base::FilePath::StringType normalized_path_string =
  124. VirtualPath::GetNormalizedFilePath(input);
  125. EXPECT_EQ(test_case.normalized_path, normalized_path_string);
  126. }
  127. }
  128. TEST_F(FileSystemUtilTest, IsAbsolutePath) {
  129. EXPECT_TRUE(VirtualPath::IsAbsolute(FILE_PATH_LITERAL("/")));
  130. EXPECT_TRUE(VirtualPath::IsAbsolute(FILE_PATH_LITERAL("/foo/bar")));
  131. EXPECT_FALSE(VirtualPath::IsAbsolute(base::FilePath::StringType()));
  132. EXPECT_FALSE(VirtualPath::IsAbsolute(FILE_PATH_LITERAL("foo/bar")));
  133. }
  134. TEST_F(FileSystemUtilTest, IsRootPath) {
  135. EXPECT_TRUE(VirtualPath::IsRootPath(base::FilePath(FILE_PATH_LITERAL(""))));
  136. EXPECT_TRUE(VirtualPath::IsRootPath(base::FilePath()));
  137. EXPECT_TRUE(VirtualPath::IsRootPath(base::FilePath(FILE_PATH_LITERAL("/"))));
  138. EXPECT_TRUE(VirtualPath::IsRootPath(base::FilePath(FILE_PATH_LITERAL("//"))));
  139. EXPECT_FALSE(
  140. VirtualPath::IsRootPath(base::FilePath(FILE_PATH_LITERAL("c:/"))));
  141. #if defined(FILE_PATH_USES_WIN_SEPARATORS)
  142. EXPECT_TRUE(VirtualPath::IsRootPath(base::FilePath(FILE_PATH_LITERAL("\\"))));
  143. EXPECT_FALSE(
  144. VirtualPath::IsRootPath(base::FilePath(FILE_PATH_LITERAL("c:\\"))));
  145. #endif
  146. }
  147. TEST_F(FileSystemUtilTest, VirtualPathGetComponents) {
  148. struct test_data {
  149. const base::FilePath::StringType path;
  150. size_t count;
  151. const base::FilePath::StringType components[2];
  152. } test_cases[] = {
  153. {FILE_PATH_LITERAL("foo/bar"),
  154. 2,
  155. {FILE_PATH_LITERAL("foo"), FILE_PATH_LITERAL("bar")}},
  156. {FILE_PATH_LITERAL("foo"),
  157. 1,
  158. {FILE_PATH_LITERAL("foo"), FILE_PATH_LITERAL("")}},
  159. {FILE_PATH_LITERAL("foo////bar"),
  160. 2,
  161. {FILE_PATH_LITERAL("foo"), FILE_PATH_LITERAL("bar")}},
  162. {FILE_PATH_LITERAL("foo/c:bar"),
  163. 2,
  164. {FILE_PATH_LITERAL("foo"), FILE_PATH_LITERAL("c:bar")}},
  165. {FILE_PATH_LITERAL("c:foo/bar"),
  166. 2,
  167. {FILE_PATH_LITERAL("c:foo"), FILE_PATH_LITERAL("bar")}},
  168. {FILE_PATH_LITERAL("foo/bar"),
  169. 2,
  170. {FILE_PATH_LITERAL("foo"), FILE_PATH_LITERAL("bar")}},
  171. {FILE_PATH_LITERAL("/foo/bar"),
  172. 2,
  173. {FILE_PATH_LITERAL("foo"), FILE_PATH_LITERAL("bar")}},
  174. {FILE_PATH_LITERAL("c:/bar"),
  175. 2,
  176. {FILE_PATH_LITERAL("c:"), FILE_PATH_LITERAL("bar")}},
  177. #ifdef FILE_PATH_USES_WIN_SEPARATORS
  178. {FILE_PATH_LITERAL("c:\\bar"),
  179. 2,
  180. {FILE_PATH_LITERAL("c:"), FILE_PATH_LITERAL("bar")}},
  181. #endif
  182. };
  183. for (const auto& test_case : test_cases) {
  184. base::FilePath input = base::FilePath(test_case.path);
  185. std::vector<base::FilePath::StringType> components =
  186. VirtualPath::GetComponents(input);
  187. EXPECT_EQ(test_case.count, components.size());
  188. for (size_t j = 0; j < components.size(); ++j)
  189. EXPECT_EQ(test_case.components[j], components[j]);
  190. }
  191. for (const auto& test_case : test_cases) {
  192. base::FilePath input = base::FilePath(test_case.path);
  193. std::vector<std::string> components =
  194. VirtualPath::GetComponentsUTF8Unsafe(input);
  195. EXPECT_EQ(test_case.count, components.size());
  196. for (size_t j = 0; j < components.size(); ++j) {
  197. EXPECT_EQ(base::FilePath(test_case.components[j]).AsUTF8Unsafe(),
  198. components[j]);
  199. }
  200. }
  201. }
  202. TEST_F(FileSystemUtilTest, GetIsolatedFileSystemName) {
  203. GURL origin_url("http://foo");
  204. std::string fsname1 = GetIsolatedFileSystemName(origin_url, "bar");
  205. EXPECT_EQ("http_foo_0:Isolated_bar", fsname1);
  206. }
  207. TEST_F(FileSystemUtilTest, CrackIsolatedFileSystemName) {
  208. std::string fsid;
  209. EXPECT_TRUE(CrackIsolatedFileSystemName("foo:Isolated_bar", &fsid));
  210. EXPECT_EQ("bar", fsid);
  211. EXPECT_TRUE(CrackIsolatedFileSystemName("foo:isolated_bar", &fsid));
  212. EXPECT_EQ("bar", fsid);
  213. EXPECT_TRUE(CrackIsolatedFileSystemName("foo:Isolated__bar", &fsid));
  214. EXPECT_EQ("_bar", fsid);
  215. EXPECT_TRUE(CrackIsolatedFileSystemName("foo::Isolated_bar", &fsid));
  216. EXPECT_EQ("bar", fsid);
  217. }
  218. TEST_F(FileSystemUtilTest, RejectBadIsolatedFileSystemName) {
  219. std::string fsid;
  220. EXPECT_FALSE(CrackIsolatedFileSystemName("foobar", &fsid));
  221. EXPECT_FALSE(CrackIsolatedFileSystemName("foo:_bar", &fsid));
  222. EXPECT_FALSE(CrackIsolatedFileSystemName("foo:Isolatedbar", &fsid));
  223. EXPECT_FALSE(CrackIsolatedFileSystemName("fooIsolatedbar", &fsid));
  224. EXPECT_FALSE(CrackIsolatedFileSystemName("foo:Persistent", &fsid));
  225. EXPECT_FALSE(CrackIsolatedFileSystemName("foo:Temporary", &fsid));
  226. EXPECT_FALSE(CrackIsolatedFileSystemName("foo:External", &fsid));
  227. EXPECT_FALSE(CrackIsolatedFileSystemName(":Isolated_bar", &fsid));
  228. EXPECT_FALSE(CrackIsolatedFileSystemName("foo:Isolated_", &fsid));
  229. }
  230. TEST_F(FileSystemUtilTest, ValidateIsolatedFileSystemId) {
  231. EXPECT_TRUE(ValidateIsolatedFileSystemId("ABCDEF0123456789ABCDEF0123456789"));
  232. EXPECT_TRUE(ValidateIsolatedFileSystemId("ABCDEFABCDEFABCDEFABCDEFABCDEFAB"));
  233. EXPECT_TRUE(ValidateIsolatedFileSystemId("01234567890123456789012345678901"));
  234. const size_t kExpectedFileSystemIdSize = 32;
  235. // Should not contain lowercase characters.
  236. const std::string kLowercaseId = "abcdef0123456789abcdef0123456789";
  237. EXPECT_EQ(kExpectedFileSystemIdSize, kLowercaseId.size());
  238. EXPECT_FALSE(ValidateIsolatedFileSystemId(kLowercaseId));
  239. // Should not be shorter/longer than expected.
  240. EXPECT_FALSE(ValidateIsolatedFileSystemId(std::string()));
  241. const std::string kShorterId = "ABCDEF0123456789ABCDEF";
  242. EXPECT_GT(kExpectedFileSystemIdSize, kShorterId.size());
  243. EXPECT_FALSE(ValidateIsolatedFileSystemId(kShorterId));
  244. const std::string kLongerId = "ABCDEF0123456789ABCDEF0123456789ABCDEF";
  245. EXPECT_LT(kExpectedFileSystemIdSize, kLongerId.size());
  246. EXPECT_FALSE(ValidateIsolatedFileSystemId(kLongerId));
  247. // Should not contain not alphabetical nor numerical characters.
  248. const std::string kSlashId = "ABCD/EFGH/IJKL/MNOP/QRST/UVWX/YZ";
  249. EXPECT_EQ(kExpectedFileSystemIdSize, kSlashId.size());
  250. EXPECT_FALSE(ValidateIsolatedFileSystemId(kSlashId));
  251. const std::string kBackslashId = "ABCD\\EFGH\\IJKL\\MNOP\\QRST\\UVWX\\YZ";
  252. EXPECT_EQ(kExpectedFileSystemIdSize, kBackslashId.size());
  253. EXPECT_FALSE(ValidateIsolatedFileSystemId(kBackslashId));
  254. const std::string kSpaceId = "ABCD EFGH IJKL MNOP QRST UVWX YZ";
  255. EXPECT_EQ(kExpectedFileSystemIdSize, kSpaceId.size());
  256. EXPECT_FALSE(ValidateIsolatedFileSystemId(kSpaceId));
  257. }
  258. TEST_F(FileSystemUtilTest, GetIsolatedFileSystemRootURIString) {
  259. const GURL kOriginURL("http://foo");
  260. // Percents must be escaped, otherwise they will be unintentionally unescaped.
  261. const std::string kFileSystemId = "A%20B";
  262. const std::string kRootName = "C%20D";
  263. const std::string url_string =
  264. GetIsolatedFileSystemRootURIString(kOriginURL, kFileSystemId, kRootName);
  265. EXPECT_EQ("filesystem:http://foo/isolated/A%2520B/C%2520D/", url_string);
  266. }
  267. TEST_F(FileSystemUtilTest, GetExternalFileSystemRootURIString) {
  268. const GURL kOriginURL("http://foo");
  269. // Percents must be escaped, otherwise they will be unintentionally unescaped.
  270. const std::string kMountName = "X%20Y";
  271. const std::string url_string =
  272. GetExternalFileSystemRootURIString(kOriginURL, kMountName);
  273. EXPECT_EQ("filesystem:http://foo/external/X%2520Y/", url_string);
  274. }
  275. } // namespace
  276. } // namespace content