forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfile_path_sanitization_unittest.cc
158 lines (135 loc) · 6.32 KB
/
file_path_sanitization_unittest.cc
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Copyright 2018 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 "chrome/chrome_cleaner/os/file_path_sanitization.h"
#include <shlobj.h>
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chrome_cleaner {
namespace {
std::wstring FirstComponent(const std::wstring& original) {
return original.substr(0, original.find(L"\\"));
}
TEST(FilePathSanitizationTests, NormalizePath) {
base::FilePath expected_path =
base::FilePath(L"c:\\program files\\desktop.ini");
EXPECT_EQ(NormalizePath(base::FilePath(L"C:\\PROGRA~1\\DESKTOP.INI")),
expected_path);
EXPECT_EQ(NormalizePath(base::FilePath(L"c:\\pRoGrAm FiLeS\\desktop.INI")),
expected_path);
base::FilePath empty_path;
EXPECT_EQ(NormalizePath(empty_path), empty_path);
}
TEST(FilePathSanitizationTests, NormalizePathUnicode) {
EXPECT_EQ(
NormalizePath(
base::FilePath(L"C:\\\u03b1\u03c1\u03c7\u03b5\u03b9\u03b1 "
L"\u03c0\u03c1\u03bf\u03b3\u03c1"
L"\u03b1\u03bc\u03bc\u03b1\u03c4\u03bf\u03c2\\u03b5"
L"\u03c0\u03b9\u03c6"
L"\u03ac\u03bd\u03b5\u03b9\u03b1 "
L"\u03b5\u03c1\u03b3\u03b1\u03c3\u03af"
L"\u03b1\u03c2.iNi"))
.value(),
L"c:\\\u03b1\u03c1\u03c7\u03b5\u03b9\u03b1 \u03c0\u03c1\u03bf\u03b3\u03c1"
L"\u03b1\u03bc\u03bc\u03b1\u03c4\u03bf\u03c2\\u03b5\u03c0\u03b9\u03c6"
L"\u03ac\u03bd\u03b5\u03b9\u03b1 \u03b5\u03c1\u03b3\u03b1\u03c3\u03af"
L"\u03b1\u03c2.ini");
}
TEST(FilePathSanitizationTests, SanitizePath) {
base::FilePath programfiles_folder;
ASSERT_TRUE(base::PathService::Get(CsidlToPathServiceKey(CSIDL_PROGRAM_FILES),
&programfiles_folder));
base::FilePath absolute(L"C:\\Dummy\\Dummy.exe");
std::wstring result = SanitizePath(absolute);
EXPECT_EQ(NormalizePath(absolute).value(), result);
base::FilePath relative(programfiles_folder.Append(L"Dummy\\Dummy.exe"));
std::wstring sanitized_relative = SanitizePath(relative);
EXPECT_NE(sanitized_relative, relative.value());
EXPECT_EQ(L"CSIDL_PROGRAM_FILES\\dummy\\dummy.exe", sanitized_relative);
base::FilePath empty_path;
EXPECT_EQ(L"", SanitizePath(empty_path));
}
TEST(FilePathSanitizationTests, SanitizePathConsistency) {
// Loop over all the rewrite rules used by sanitize path to make sure all the
// rules work correctly. In particular this test verifies each rule is not
// masked by another.
base::FilePath arbitrary_path = NormalizePath(base::FilePath(L"Desktop.ini"));
for (auto* rule = sanitization_internal::rewrite_rules; rule->path; ++rule) {
base::FilePath expanded_path;
base::PathService::Get(rule->id, &expanded_path);
expanded_path = expanded_path.Append(arbitrary_path);
const auto sanitized_path = chrome_cleaner::SanitizePath(expanded_path);
// The FirstComponent here is the label string used to sanitize the path. It
// is extracted to verify the correct label string is being used.
//
// For example:
// C:\Program Files (x86)\Common Files\Desktop.ini
// maps to
// CSIDL_PROGRAM_FILES_COMMON (CSIDL_PROGRAM_FILES_COMMON\Desktop.ini)
// and shouldn't map to
// CSIDL_PROGRAM_FILES (CSIDL_PROGRAM_FILES\Common Files\Desktop.ini)
// or it will clash with
// C:\Program Files (x86)\Desktop.ini
// which maps to
// CSIDL_PROGRAM_FILES (CSIDL_PROGRAM_FILES\desktop.ini)
const auto first_dir = FirstComponent(sanitized_path);
if (first_dir != rule->path) {
ADD_FAILURE() << base::WideToUTF8(expanded_path.value())
<< " is being Sanitized to "
<< base::WideToUTF8(sanitized_path) << " instead of using "
<< rule->path;
}
}
}
TEST(FilePathSanitizationTests, SanitizeCommandLine) {
base::CommandLine switches =
base::CommandLine::FromString(L"dummy.exe --arg=value --flag ");
base::CommandLine already_sanitized(switches);
already_sanitized.SetProgram(base::FilePath(L"c:\\dummy\\dummy.exe"));
std::wstring result = SanitizeCommandLine(already_sanitized);
EXPECT_EQ(already_sanitized.GetCommandLineString(), result);
base::FilePath programfiles_folder;
ASSERT_TRUE(base::PathService::Get(CsidlToPathServiceKey(CSIDL_PROGRAM_FILES),
&programfiles_folder));
base::FilePath exe_in_programfiles =
programfiles_folder.Append(L"dummy\\dummy.exe");
base::CommandLine to_sanitize(switches);
to_sanitize.SetProgram(exe_in_programfiles);
std::wstring sanitized_cmd = SanitizeCommandLine(to_sanitize);
EXPECT_NE(to_sanitize.GetCommandLineString(), sanitized_cmd);
EXPECT_EQ(sanitized_cmd.find(exe_in_programfiles.value()), std::wstring::npos)
<< sanitized_cmd;
switches.AppendSwitchPath("path", exe_in_programfiles);
switches.AppendArgPath(exe_in_programfiles);
to_sanitize = base::CommandLine(switches);
sanitized_cmd = SanitizeCommandLine(to_sanitize);
EXPECT_NE(to_sanitize.GetCommandLineString(), sanitized_cmd);
EXPECT_EQ(sanitized_cmd.find(exe_in_programfiles.value()), std::wstring::npos)
<< sanitized_cmd;
}
TEST(FilePathSanitizationTests, ExpandSpecialFolderPath) {
base::FilePath arbitrary_path(L"Desktop.ini");
for (auto* rule = sanitization_internal::rewrite_rules; rule->path; ++rule) {
// Skip non-CSIDL entries.
if (rule->id < sanitization_internal::PATH_CSIDL_START ||
rule->id >= sanitization_internal::PATH_CSIDL_END) {
continue;
}
// Fetch and validate expected path.
base::FilePath expected_path;
ASSERT_TRUE(base::PathService::Get(rule->id, &expected_path));
ASSERT_FALSE(expected_path.empty());
expected_path = expected_path.Append(arbitrary_path);
int csidl = rule->id - sanitization_internal::PATH_CSIDL_START;
base::FilePath expanded_path =
ExpandSpecialFolderPath(csidl, arbitrary_path);
EXPECT_EQ(expected_path, expanded_path)
<< "Failed special folder path expansion. Got: \""
<< base::WideToUTF8(expanded_path.value())
<< "\", but expected: " << base::WideToUTF8(expected_path.value());
}
}
} // namespace
} // namespace chrome_cleaner