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
5 #include "chrome/browser/chromeos/fileapi/external_file_url_util.h"
6
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/test/base/testing_browser_process.h"
9 #include "chrome/test/base/testing_profile_manager.h"
10 #include "components/drive/file_system_core_util.h"
11 #include "content/public/common/url_constants.h"
12 #include "content/public/test/browser_task_environment.h"
13 #include "storage/browser/file_system/file_system_url.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace chromeos {
17
18 namespace {
19
20 // Sets up ProfileManager for testing and marks the current thread as UI by
21 // BrowserTaskEnvironment. We need the thread since Profile objects must be
22 // touched from UI and hence has CHECK/DCHECKs for it.
23 class ExternalFileURLUtilTest : public testing::Test {
24 protected:
ExternalFileURLUtilTest()25 ExternalFileURLUtilTest()
26 : testing_profile_manager_(TestingBrowserProcess::GetGlobal()) {}
27
SetUp()28 void SetUp() override { ASSERT_TRUE(testing_profile_manager_.SetUp()); }
29
testing_profile_manager()30 TestingProfileManager& testing_profile_manager() {
31 return testing_profile_manager_;
32 }
33
CreateExpectedURL(const base::FilePath & path)34 storage::FileSystemURL CreateExpectedURL(const base::FilePath& path) {
35 return storage::FileSystemURL::CreateForTest(
36 url::Origin::Create(GURL("chrome-extension://xxx")),
37 storage::kFileSystemTypeExternal,
38 base::FilePath("arc-documents-provider").Append(path), "",
39 storage::kFileSystemTypeArcDocumentsProvider, base::FilePath(), "",
40 storage::FileSystemMountOption());
41 }
42
43 private:
44 content::BrowserTaskEnvironment task_environment_;
45 TestingProfileManager testing_profile_manager_;
46 };
47
48 } // namespace
49
TEST_F(ExternalFileURLUtilTest,FilePathToExternalFileURL)50 TEST_F(ExternalFileURLUtilTest, FilePathToExternalFileURL) {
51 storage::FileSystemURL url;
52
53 // Path with alphabets and numbers.
54 url = CreateExpectedURL(base::FilePath("foo/bar012.txt"));
55 EXPECT_EQ(url.virtual_path(),
56 ExternalFileURLToVirtualPath(FileSystemURLToExternalFileURL(url)));
57
58 // Path with symbols.
59 url = CreateExpectedURL(base::FilePath(" !\"#$%&'()*+,-.:;<=>?@[\\]^_`{|}~"));
60 EXPECT_EQ(url.virtual_path(),
61 ExternalFileURLToVirtualPath(FileSystemURLToExternalFileURL(url)));
62
63 // Path with '%'.
64 url = CreateExpectedURL(base::FilePath("%19%20%21.txt"));
65 EXPECT_EQ(url.virtual_path(),
66 ExternalFileURLToVirtualPath(FileSystemURLToExternalFileURL(url)));
67
68 // Path with multi byte characters.
69 base::string16 utf16_string;
70 utf16_string.push_back(0x307b); // HIRAGANA_LETTER_HO
71 utf16_string.push_back(0x3052); // HIRAGANA_LETTER_GE
72 url = CreateExpectedURL(
73 base::FilePath::FromUTF8Unsafe(base::UTF16ToUTF8(utf16_string) + ".txt"));
74 EXPECT_EQ(url.virtual_path().AsUTF8Unsafe(),
75 ExternalFileURLToVirtualPath(FileSystemURLToExternalFileURL(url))
76 .AsUTF8Unsafe());
77 }
78
79 // Tests that given virtual path is encoded to an expected externalfile: URL
80 // and then the original path is reconstructed from it.
ExpectVirtualPathRoundtrip(const base::FilePath::StringType & virtual_path_string,std::string expected_url)81 void ExpectVirtualPathRoundtrip(
82 const base::FilePath::StringType& virtual_path_string,
83 std::string expected_url) {
84 base::FilePath virtual_path(virtual_path_string);
85 GURL result = VirtualPathToExternalFileURL(virtual_path);
86 EXPECT_TRUE(result.is_valid());
87 EXPECT_EQ(content::kExternalFileScheme, result.scheme());
88 EXPECT_EQ(expected_url, result.path());
89 EXPECT_EQ(virtual_path.value(), ExternalFileURLToVirtualPath(result).value());
90 }
91
TEST_F(ExternalFileURLUtilTest,VirtualPathToExternalFileURL)92 TEST_F(ExternalFileURLUtilTest, VirtualPathToExternalFileURL) {
93 ExpectVirtualPathRoundtrip(FILE_PATH_LITERAL("foo/bar012.txt"),
94 "foo/bar012.txt");
95
96 // Path containing precent character, which is also used for URL encoding.
97 ExpectVirtualPathRoundtrip(FILE_PATH_LITERAL("foo/bar012%41%.txt"),
98 "foo/bar012%2541%25.txt");
99
100 // Path containing some ASCII characters that are escaped by URL enconding.
101 ExpectVirtualPathRoundtrip(FILE_PATH_LITERAL("foo/bar \"#<>?`{}.txt"),
102 "foo/bar%20%22%23%3C%3E%3F%60%7B%7D.txt");
103
104 // (U+3000) IDEOGRAPHIC SPACE and (U+1F512) LOCK are examples of characters
105 // potentially used for URL spoofing. Those are blacklisted from unescaping
106 // when a URL is displayed, but this should not prevent it from being
107 // unescaped when converting a URL to a virtual file path. See
108 // crbug.com/585422 for detail.
109 ExpectVirtualPathRoundtrip(FILE_PATH_LITERAL("foo/bar/space\u3000lock.zip"),
110 "foo/bar/space%E3%80%80lock%F0%9F%94%92.zip");
111 }
112
113 } // namespace chromeos
114