| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2006-2008 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 <string> | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "chrome/browser/download_manager.h" | |
| 9 #include "chrome/browser/download_util.h" | |
| 10 #include "testing/gtest/include/gtest/gtest.h" | |
| 11 | |
| 12 class DownloadManagerTest : public testing::Test { | |
| 13 public: | |
| 14 DownloadManagerTest() { | |
| 15 download_manager_ = new DownloadManager(); | |
| 16 download_util::InitializeExeTypes(&download_manager_->exe_types_); | |
| 17 } | |
| 18 | |
| 19 void GetGeneratedFilename(const std::string& content_disposition, | |
| 20 const std::wstring& url, | |
| 21 const std::string& mime_type, | |
| 22 std::wstring* generated_name) { | |
| 23 DownloadCreateInfo info; | |
| 24 info.content_disposition = content_disposition; | |
| 25 info.url = url; | |
| 26 info.mime_type = mime_type; | |
| 27 download_manager_->GenerateFilename(&info, generated_name); | |
| 28 } | |
| 29 | |
| 30 protected: | |
| 31 scoped_refptr<DownloadManager> download_manager_; | |
| 32 MessageLoopForUI message_loop_; | |
| 33 | |
| 34 DISALLOW_EVIL_CONSTRUCTORS(DownloadManagerTest); | |
| 35 }; | |
| 36 | |
| 37 static const struct { | |
| 38 const char* disposition; | |
| 39 const wchar_t* url; | |
| 40 const char* mime_type; | |
| 41 const wchar_t* expected_name; | |
| 42 } kGeneratedFiles[] = { | |
| 43 // No 'filename' keyword in the disposition, use the URL | |
| 44 {"a_file_name.txt", | |
| 45 L"http://www.evil.com/my_download.txt", | |
| 46 "text/plain", | |
| 47 L"my_download.txt"}, | |
| 48 | |
| 49 // Disposition has relative paths, remove them | |
| 50 {"filename=../../../../././../a_file_name.txt", | |
| 51 L"http://www.evil.com/my_download.txt", | |
| 52 "text/plain", | |
| 53 L"a_file_name.txt"}, | |
| 54 | |
| 55 // Disposition has parent directories, remove them | |
| 56 {"filename=dir1/dir2/a_file_name.txt", | |
| 57 L"http://www.evil.com/my_download.txt", | |
| 58 "text/plain", | |
| 59 L"a_file_name.txt"}, | |
| 60 | |
| 61 // No useful information in disposition or URL, use default | |
| 62 {"", L"http://www.truncated.com/path/", "text/plain", L"download.txt"}, | |
| 63 | |
| 64 // Spaces in the disposition file name | |
| 65 {"filename=My Downloaded File.exe", | |
| 66 L"http://www.frontpagehacker.com/a_download.exe", | |
| 67 "application/octet-stream", | |
| 68 L"My Downloaded File.exe"}, | |
| 69 | |
| 70 {"filename=my-cat", | |
| 71 L"http://www.example.com/my-cat", | |
| 72 "image/jpeg", | |
| 73 L"my-cat.jpg"}, | |
| 74 | |
| 75 {"filename=my-cat", | |
| 76 L"http://www.example.com/my-cat", | |
| 77 "text/plain", | |
| 78 L"my-cat.txt"}, | |
| 79 | |
| 80 {"filename=my-cat", | |
| 81 L"http://www.example.com/my-cat", | |
| 82 "text/html", | |
| 83 L"my-cat.htm"}, | |
| 84 | |
| 85 {"filename=my-cat", | |
| 86 L"http://www.example.com/my-cat", | |
| 87 "dance/party", | |
| 88 L"my-cat"}, | |
| 89 | |
| 90 {"filename=my-cat.jpg", | |
| 91 L"http://www.example.com/my-cat.jpg", | |
| 92 "text/plain", | |
| 93 L"my-cat.jpg"}, | |
| 94 | |
| 95 {"filename=evil.exe", | |
| 96 L"http://www.goodguy.com/evil.exe", | |
| 97 "image/jpeg", | |
| 98 L"evil.jpg"}, | |
| 99 | |
| 100 {"filename=evil.exe.exe", | |
| 101 L"http://www.goodguy.com/evil.exe.exe", | |
| 102 "dance/party", | |
| 103 L"evil.exe.download"}, | |
| 104 | |
| 105 {"filename=evil.exe", | |
| 106 L"http://www.goodguy.com/evil.exe", | |
| 107 "application/xml", | |
| 108 L"evil.xml"}, | |
| 109 | |
| 110 {"filename=evil.exe", | |
| 111 L"http://www.goodguy.com/evil.exe", | |
| 112 "application/html+xml", | |
| 113 L"evil.download"}, | |
| 114 | |
| 115 {"filename=evil.exe", | |
| 116 L"http://www.goodguy.com/evil.exe", | |
| 117 "application/rss+xml", | |
| 118 L"evil.download"}, | |
| 119 | |
| 120 {"filename=utils.js", | |
| 121 L"http://www.goodguy.com/utils.js", | |
| 122 "application/x-javascript", | |
| 123 L"utils.js"}, | |
| 124 | |
| 125 {"filename=contacts.js", | |
| 126 L"http://www.goodguy.com/contacts.js", | |
| 127 "application/json", | |
| 128 L"contacts.js"}, | |
| 129 | |
| 130 {"filename=utils.js", | |
| 131 L"http://www.goodguy.com/utils.js", | |
| 132 "text/javascript", | |
| 133 L"utils.js"}, | |
| 134 | |
| 135 {"filename=utils.js", | |
| 136 L"http://www.goodguy.com/utils.js", | |
| 137 "text/javascript;version=2", | |
| 138 L"utils.js"}, | |
| 139 | |
| 140 {"filename=utils.js", | |
| 141 L"http://www.goodguy.com/utils.js", | |
| 142 "application/ecmascript", | |
| 143 L"utils.js"}, | |
| 144 | |
| 145 {"filename=utils.js", | |
| 146 L"http://www.goodguy.com/utils.js", | |
| 147 "application/ecmascript;version=4", | |
| 148 L"utils.js"}, | |
| 149 | |
| 150 {"filename=program.exe", | |
| 151 L"http://www.goodguy.com/program.exe", | |
| 152 "application/foo-bar", | |
| 153 L"program.exe"}, | |
| 154 | |
| 155 {"filename=../foo.txt", | |
| 156 L"http://www.evil.com/../foo.txt", | |
| 157 "text/plain", | |
| 158 L"foo.txt"}, | |
| 159 | |
| 160 {"filename=..\\foo.txt", | |
| 161 L"http://www.evil.com/..\\foo.txt", | |
| 162 "text/plain", | |
| 163 L"foo.txt"}, | |
| 164 | |
| 165 {"filename=.hidden", | |
| 166 L"http://www.evil.com/.hidden", | |
| 167 "text/plain", | |
| 168 L"hidden.txt"}, | |
| 169 | |
| 170 {"filename=trailing.", | |
| 171 L"http://www.evil.com/trailing.", | |
| 172 "dance/party", | |
| 173 L"trailing"}, | |
| 174 | |
| 175 {"filename=trailing.", | |
| 176 L"http://www.evil.com/trailing.", | |
| 177 "text/plain", | |
| 178 L"trailing.txt"}, | |
| 179 | |
| 180 {"filename=.", | |
| 181 L"http://www.evil.com/.", | |
| 182 "dance/party", | |
| 183 L"download"}, | |
| 184 | |
| 185 {"filename=..", | |
| 186 L"http://www.evil.com/..", | |
| 187 "dance/party", | |
| 188 L"download"}, | |
| 189 | |
| 190 {"filename=...", | |
| 191 L"http://www.evil.com/...", | |
| 192 "dance/party", | |
| 193 L"download"}, | |
| 194 | |
| 195 {"a_file_name.txt", | |
| 196 L"http://www.evil.com/", | |
| 197 "image/jpeg", | |
| 198 L"download.jpg"}, | |
| 199 | |
| 200 {"filename=", | |
| 201 L"http://www.evil.com/", | |
| 202 "image/jpeg", | |
| 203 L"download.jpg"}, | |
| 204 | |
| 205 {"filename=simple", | |
| 206 L"http://www.example.com/simple", | |
| 207 "application/octet-stream", | |
| 208 L"simple"}, | |
| 209 | |
| 210 {"filename=COM1", | |
| 211 L"http://www.goodguy.com/COM1", | |
| 212 "application/foo-bar", | |
| 213 L"_COM1"}, | |
| 214 | |
| 215 {"filename=COM4.txt", | |
| 216 L"http://www.goodguy.com/COM4.txt", | |
| 217 "text/plain", | |
| 218 L"_COM4.txt"}, | |
| 219 | |
| 220 {"filename=lpt1.TXT", | |
| 221 L"http://www.goodguy.com/lpt1.TXT", | |
| 222 "text/plain", | |
| 223 L"_lpt1.TXT"}, | |
| 224 | |
| 225 {"filename=clock$.txt", | |
| 226 L"http://www.goodguy.com/clock$.txt", | |
| 227 "text/plain", | |
| 228 L"_clock$.txt"}, | |
| 229 | |
| 230 {"filename=mycom1.foo", | |
| 231 L"http://www.goodguy.com/mycom1.foo", | |
| 232 "text/plain", | |
| 233 L"mycom1.foo"}, | |
| 234 | |
| 235 {"filename=Setup.exe.local", | |
| 236 L"http://www.badguy.com/Setup.exe.local", | |
| 237 "application/foo-bar", | |
| 238 L"Setup.exe.download"}, | |
| 239 | |
| 240 {"filename=Setup.exe.local.local", | |
| 241 L"http://www.badguy.com/Setup.exe.local", | |
| 242 "application/foo-bar", | |
| 243 L"Setup.exe.local.download"}, | |
| 244 | |
| 245 {"filename=Setup.exe.lnk", | |
| 246 L"http://www.badguy.com/Setup.exe.lnk", | |
| 247 "application/foo-bar", | |
| 248 L"Setup.exe.download"}, | |
| 249 | |
| 250 {"filename=Desktop.ini", | |
| 251 L"http://www.badguy.com/Desktop.ini", | |
| 252 "application/foo-bar", | |
| 253 L"_Desktop.ini"}, | |
| 254 | |
| 255 {"filename=Thumbs.db", | |
| 256 L"http://www.badguy.com/Thumbs.db", | |
| 257 "application/foo-bar", | |
| 258 L"_Thumbs.db"}, | |
| 259 | |
| 260 {"filename=source.srf", | |
| 261 L"http://www.hotmail.com", | |
| 262 "image/jpeg", | |
| 263 L"source.srf.jpg"}, | |
| 264 | |
| 265 {"filename=source.jpg", | |
| 266 L"http://www.hotmail.com", | |
| 267 "application/x-javascript", | |
| 268 L"source.jpg"}, | |
| 269 | |
| 270 // NetUtilTest.{GetSuggestedFilename, GetFileNameFromCD} test these | |
| 271 // more thoroughly. Tested below are a small set of samples. | |
| 272 {"attachment; filename=\"%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg\"", | |
| 273 L"http://www.examples.com/", | |
| 274 "image/jpeg", | |
| 275 L"\uc608\uc220 \uc608\uc220.jpg"}, | |
| 276 | |
| 277 {"attachment; name=abc de.pdf", | |
| 278 L"http://www.examples.com/q.cgi?id=abc", | |
| 279 "application/octet-stream", | |
| 280 L"abc de.pdf"}, | |
| 281 | |
| 282 {"filename=\"=?EUC-JP?Q?=B7=DD=BD=D13=2Epng?=\"", | |
| 283 L"http://www.example.com/path", | |
| 284 "image/png", | |
| 285 L"\x82b8\x8853" L"3.png"}, | |
| 286 | |
| 287 // The following two have invalid CD headers and filenames come | |
| 288 // from the URL. | |
| 289 {"attachment; filename==?iiso88591?Q?caf=EG?=", | |
| 290 L"http://www.example.com/test%20123", | |
| 291 "image/jpeg", | |
| 292 L"test 123.jpg"}, | |
| 293 | |
| 294 {"malformed_disposition", | |
| 295 L"http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg", | |
| 296 "image/jpeg", | |
| 297 L"\uc608\uc220 \uc608\uc220.jpg"}, | |
| 298 | |
| 299 // Invalid C-D. No filename from URL. Falls back to 'download'. | |
| 300 {"attachment; filename==?iso88591?Q?caf=E3?", | |
| 301 L"http://www.google.com/path1/path2/", | |
| 302 "image/jpeg", | |
| 303 L"download.jpg"}, | |
| 304 | |
| 305 // TODO(darin): Add some raw 8-bit Content-Disposition tests. | |
| 306 }; | |
| 307 | |
| 308 // Tests to ensure that the file names we generate from hints from the server | |
| 309 // (content-disposition, URL name, etc) don't cause security holes. | |
| 310 TEST_F(DownloadManagerTest, TestDownloadFilename) { | |
| 311 for (int i = 0; i < arraysize(kGeneratedFiles); ++i) { | |
| 312 std::wstring file_name; | |
| 313 GetGeneratedFilename(kGeneratedFiles[i].disposition, | |
| 314 kGeneratedFiles[i].url, | |
| 315 kGeneratedFiles[i].mime_type, | |
| 316 &file_name); | |
| 317 EXPECT_EQ(kGeneratedFiles[i].expected_name, file_name); | |
| 318 } | |
| 319 } | |
| 320 | |
| OLD | NEW |