blob: 5415d19f31b4579fc5663dd1351e2b62b95deb6d [file] [log] [blame]
[email protected]89f550b2011-06-08 18:34:031// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
avi5dd91f82015-12-25 22:30:465#include <stddef.h>
initial.commit09911bf2008-07-26 23:55:296#include <stdlib.h>
initial.commit09911bf2008-07-26 23:55:297
[email protected]9b5b1d602014-06-12 14:29:028#include "base/base_paths.h"
[email protected]9b5b1d602014-06-12 14:29:029#include "base/files/file_path.h"
thestig819adcc82014-09-10 22:24:5310#include "base/files/file_util.h"
[email protected]97803e1b2014-07-25 01:52:1411#include "base/files/scoped_temp_dir.h"
avi5dd91f82015-12-25 22:30:4612#include "base/macros.h"
[email protected]f9b294362013-06-10 20:22:3113#include "base/strings/string_util.h"
[email protected]112158af2013-06-07 23:46:1814#include "base/strings/utf_string_conversions.h"
avi5dd91f82015-12-25 22:30:4615#include "build/build_config.h"
rsleevi24f64dc22015-08-07 21:39:2116#include "components/url_formatter/url_fixer.h"
[email protected]d96cf752014-04-09 04:05:2817#include "net/base/filename_util.h"
initial.commit09911bf2008-07-26 23:55:2918#include "testing/gtest/include/gtest/gtest.h"
[email protected]761fa4702013-07-02 15:25:1519#include "url/gurl.h"
tfarina018de6e2015-05-26 17:41:2020#include "url/third_party/mozilla/url_parse.h"
initial.commit09911bf2008-07-26 23:55:2921
[email protected]0318f922014-04-22 00:09:2322namespace url {
[email protected]46cf4be92010-10-01 11:23:2023
24std::ostream& operator<<(std::ostream& os, const Component& part) {
initial.commit09911bf2008-07-26 23:55:2925 return os << "(begin=" << part.begin << ", len=" << part.len << ")";
26}
27
[email protected]0318f922014-04-22 00:09:2328} // namespace url
[email protected]46cf4be92010-10-01 11:23:2029
[email protected]dc7d3052013-05-31 21:23:2830struct SegmentCase {
[email protected]b1c33f82009-01-23 01:51:2331 const std::string input;
32 const std::string result;
[email protected]b45334502014-04-30 19:44:0533 const url::Component scheme;
34 const url::Component username;
35 const url::Component password;
36 const url::Component host;
37 const url::Component port;
38 const url::Component path;
39 const url::Component query;
40 const url::Component ref;
initial.commit09911bf2008-07-26 23:55:2941};
42
[email protected]dc7d3052013-05-31 21:23:2843static const SegmentCase segment_cases[] = {
[email protected]b1c33f82009-01-23 01:51:2344 { "http://www.google.com/", "http",
[email protected]b45334502014-04-30 19:44:0545 url::Component(0, 4), // scheme
46 url::Component(), // username
47 url::Component(), // password
48 url::Component(7, 14), // host
49 url::Component(), // port
50 url::Component(21, 1), // path
51 url::Component(), // query
52 url::Component(), // ref
initial.commit09911bf2008-07-26 23:55:2953 },
[email protected]b1c33f82009-01-23 01:51:2354 { "aBoUt:vErSiOn", "about",
[email protected]b45334502014-04-30 19:44:0555 url::Component(0, 5), // scheme
56 url::Component(), // username
57 url::Component(), // password
58 url::Component(6, 7), // host
59 url::Component(), // port
60 url::Component(), // path
61 url::Component(), // query
62 url::Component(), // ref
initial.commit09911bf2008-07-26 23:55:2963 },
[email protected]89f550b2011-06-08 18:34:0364 { "about:host/path?query#ref", "about",
[email protected]b45334502014-04-30 19:44:0565 url::Component(0, 5), // scheme
66 url::Component(), // username
67 url::Component(), // password
68 url::Component(6, 4), // host
69 url::Component(), // port
70 url::Component(10, 5), // path
71 url::Component(16, 5), // query
72 url::Component(22, 3), // ref
[email protected]89f550b2011-06-08 18:34:0373 },
74 { "about://host/path?query#ref", "about",
[email protected]b45334502014-04-30 19:44:0575 url::Component(0, 5), // scheme
76 url::Component(), // username
77 url::Component(), // password
78 url::Component(8, 4), // host
79 url::Component(), // port
80 url::Component(12, 5), // path
81 url::Component(18, 5), // query
82 url::Component(24, 3), // ref
[email protected]89f550b2011-06-08 18:34:0383 },
84 { "chrome:host/path?query#ref", "chrome",
[email protected]b45334502014-04-30 19:44:0585 url::Component(0, 6), // scheme
86 url::Component(), // username
87 url::Component(), // password
88 url::Component(7, 4), // host
89 url::Component(), // port
90 url::Component(11, 5), // path
91 url::Component(17, 5), // query
92 url::Component(23, 3), // ref
[email protected]89f550b2011-06-08 18:34:0393 },
94 { "chrome://host/path?query#ref", "chrome",
[email protected]b45334502014-04-30 19:44:0595 url::Component(0, 6), // scheme
96 url::Component(), // username
97 url::Component(), // password
98 url::Component(9, 4), // host
99 url::Component(), // port
100 url::Component(13, 5), // path
101 url::Component(19, 5), // query
102 url::Component(25, 3), // ref
[email protected]89f550b2011-06-08 18:34:03103 },
[email protected]b1c33f82009-01-23 01:51:23104 { " www.google.com:124?foo#", "http",
[email protected]b45334502014-04-30 19:44:05105 url::Component(), // scheme
106 url::Component(), // username
107 url::Component(), // password
108 url::Component(4, 14), // host
109 url::Component(19, 3), // port
110 url::Component(), // path
111 url::Component(23, 3), // query
112 url::Component(27, 0), // ref
initial.commit09911bf2008-07-26 23:55:29113 },
[email protected]b1c33f82009-01-23 01:51:23114 { "[email protected]", "http",
[email protected]b45334502014-04-30 19:44:05115 url::Component(), // scheme
116 url::Component(0, 4), // username
117 url::Component(), // password
118 url::Component(5, 14), // host
119 url::Component(), // port
120 url::Component(), // path
121 url::Component(), // query
122 url::Component(), // ref
initial.commit09911bf2008-07-26 23:55:29123 },
[email protected]b1c33f82009-01-23 01:51:23124 { "ftp:/user:P:[email protected]...::23///pub?foo#bar", "ftp",
[email protected]b45334502014-04-30 19:44:05125 url::Component(0, 3), // scheme
126 url::Component(5, 4), // username
127 url::Component(10, 7), // password
128 url::Component(18, 20), // host
129 url::Component(39, 2), // port
130 url::Component(41, 6), // path
131 url::Component(48, 3), // query
132 url::Component(52, 3), // ref
initial.commit09911bf2008-07-26 23:55:29133 },
[email protected]818071ce2009-05-18 01:25:25134 { "[2001:db8::1]/path", "http",
[email protected]b45334502014-04-30 19:44:05135 url::Component(), // scheme
136 url::Component(), // username
137 url::Component(), // password
138 url::Component(0, 13), // host
139 url::Component(), // port
140 url::Component(13, 5), // path
141 url::Component(), // query
142 url::Component(), // ref
[email protected]818071ce2009-05-18 01:25:25143 },
144 { "[::1]", "http",
[email protected]b45334502014-04-30 19:44:05145 url::Component(), // scheme
146 url::Component(), // username
147 url::Component(), // password
148 url::Component(0, 5), // host
149 url::Component(), // port
150 url::Component(), // path
151 url::Component(), // query
152 url::Component(), // ref
[email protected]818071ce2009-05-18 01:25:25153 },
[email protected]c1991302009-06-04 03:57:39154 // Incomplete IPv6 addresses (will not canonicalize).
155 { "[2001:4860:", "http",
[email protected]b45334502014-04-30 19:44:05156 url::Component(), // scheme
157 url::Component(), // username
158 url::Component(), // password
159 url::Component(0, 11), // host
160 url::Component(), // port
161 url::Component(), // path
162 url::Component(), // query
163 url::Component(), // ref
[email protected]c1991302009-06-04 03:57:39164 },
165 { "[2001:4860:/foo", "http",
[email protected]b45334502014-04-30 19:44:05166 url::Component(), // scheme
167 url::Component(), // username
168 url::Component(), // password
169 url::Component(0, 11), // host
170 url::Component(), // port
171 url::Component(11, 4), // path
172 url::Component(), // query
173 url::Component(), // ref
[email protected]c1991302009-06-04 03:57:39174 },
175 { "http://:b005::68]", "http",
[email protected]b45334502014-04-30 19:44:05176 url::Component(0, 4), // scheme
177 url::Component(), // username
178 url::Component(), // password
179 url::Component(7, 10), // host
180 url::Component(), // port
181 url::Component(), // path
182 url::Component(), // query
183 url::Component(), // ref
[email protected]c1991302009-06-04 03:57:39184 },
brettw46f9b832016-10-05 19:22:48185 { ":b005::68]", "http",
186 url::Component(), // scheme
[email protected]b45334502014-04-30 19:44:05187 url::Component(), // username
188 url::Component(), // password
brettw46f9b832016-10-05 19:22:48189 url::Component(1, 9), // host
[email protected]b45334502014-04-30 19:44:05190 url::Component(), // port
191 url::Component(), // path
192 url::Component(), // query
193 url::Component(), // ref
[email protected]c1991302009-06-04 03:57:39194 },
Kevin Bailey13622d52018-05-10 16:25:04195 {
196 "file://host/path/file#ref", "file", url::Component(0, 4), // scheme
197 url::Component(), // username
198 url::Component(), // password
199 url::Component(7, 4), // host
200 url::Component(), // port
201 url::Component(11, 10), // path
202 url::Component(), // query
203 url::Component(22, 3), // ref
204 },
205 {
206 "file:///notahost/path/file#ref", "file",
207 url::Component(0, 4), // scheme
208 url::Component(), // username
209 url::Component(), // password
210 url::Component(), // host
211 url::Component(), // port
212 url::Component(7, 19), // path
213 url::Component(), // query
214 url::Component(27, 3), // ref
215 },
216#if defined(OS_WIN)
217 {
218 "c:/notahost/path/file#ref", "file",
219 url::Component(), // scheme
220 url::Component(), // username
221 url::Component(), // password
222 url::Component(), // host
223 url::Component(), // port
224 url::Component(0, 21), // path
225 url::Component(), // query
226 url::Component(22, 3), // ref
227 },
228#elif defined(OS_POSIX)
229 {
230 "~/notahost/path/file#ref", "file",
231 url::Component(), // scheme
232 url::Component(), // username
233 url::Component(), // password
234 url::Component(), // host
235 url::Component(), // port
236 url::Component(0, 20), // path
237 url::Component(), // query
238 url::Component(21, 3), // ref
239 },
240#endif
initial.commit09911bf2008-07-26 23:55:29241};
242
[email protected]9b5b1d602014-06-12 14:29:02243typedef testing::Test URLFixerTest;
[email protected]78977682014-05-10 18:42:25244
[email protected]9b5b1d602014-06-12 14:29:02245TEST(URLFixerTest, SegmentURL) {
[email protected]b1c33f82009-01-23 01:51:23246 std::string result;
[email protected]b45334502014-04-30 19:44:05247 url::Parsed parts;
initial.commit09911bf2008-07-26 23:55:29248
[email protected]b1c33f82009-01-23 01:51:23249 for (size_t i = 0; i < arraysize(segment_cases); ++i) {
[email protected]dc7d3052013-05-31 21:23:28250 SegmentCase value = segment_cases[i];
rsleevi24f64dc22015-08-07 21:39:21251 result = url_formatter::SegmentURL(value.input, &parts);
initial.commit09911bf2008-07-26 23:55:29252 EXPECT_EQ(value.result, result);
253 EXPECT_EQ(value.scheme, parts.scheme);
254 EXPECT_EQ(value.username, parts.username);
255 EXPECT_EQ(value.password, parts.password);
256 EXPECT_EQ(value.host, parts.host);
257 EXPECT_EQ(value.port, parts.port);
258 EXPECT_EQ(value.path, parts.path);
259 EXPECT_EQ(value.query, parts.query);
260 EXPECT_EQ(value.ref, parts.ref);
261 }
262}
263
264// Creates a file and returns its full name as well as the decomposed
265// version. Example:
266// full_path = "c:\foo\bar.txt"
267// dir = "c:\foo"
268// file_name = "bar.txt"
[email protected]650b2d52013-02-10 03:41:45269static bool MakeTempFile(const base::FilePath& dir,
270 const base::FilePath& file_name,
271 base::FilePath* full_path) {
[email protected]b1c33f82009-01-23 01:51:23272 *full_path = dir.Append(file_name);
[email protected]e5c2a22e2014-03-06 20:42:30273 return base::WriteFile(*full_path, "", 0) == 0;
initial.commit09911bf2008-07-26 23:55:29274}
275
276// Returns true if the given URL is a file: URL that matches the given file
[email protected]b1c33f82009-01-23 01:51:23277static bool IsMatchingFileURL(const std::string& url,
[email protected]650b2d52013-02-10 03:41:45278 const base::FilePath& full_file_path) {
initial.commit09911bf2008-07-26 23:55:29279 if (url.length() <= 8)
280 return false;
[email protected]b1c33f82009-01-23 01:51:23281 if (std::string("file:///") != url.substr(0, 8))
initial.commit09911bf2008-07-26 23:55:29282 return false; // no file:/// prefix
[email protected]b1c33f82009-01-23 01:51:23283 if (url.find('\\') != std::string::npos)
initial.commit09911bf2008-07-26 23:55:29284 return false; // contains backslashes
285
[email protected]650b2d52013-02-10 03:41:45286 base::FilePath derived_path;
[email protected]56741852008-12-17 19:04:50287 net::FileURLToFilePath(GURL(url), &derived_path);
[email protected]b1c33f82009-01-23 01:51:23288
[email protected]650b2d52013-02-10 03:41:45289 return base::FilePath::CompareEqualIgnoreCase(derived_path.value(),
[email protected]eccb9d12009-10-28 05:40:09290 full_file_path.value());
initial.commit09911bf2008-07-26 23:55:29291}
292
[email protected]dc7d3052013-05-31 21:23:28293struct FixupCase {
[email protected]b1c33f82009-01-23 01:51:23294 const std::string input;
[email protected]b1c33f82009-01-23 01:51:23295 const std::string output;
initial.commit09911bf2008-07-26 23:55:29296} fixup_cases[] = {
Nick Carterff69a102018-04-04 00:15:17297 {"www.google.com", "http://www.google.com/"},
298 {" www.google.com ", "http://www.google.com/"},
299 {" foo.com/asdf bar", "http://foo.com/asdf%20%20bar"},
300 {"..www.google.com..", "http://www.google.com./"},
301 {"http://......", "http://....../"},
302 {"http://host.com:ninety-two/", "http://host.com:ninety-two/"},
303 {"http://host.com:ninety-two?foo", "http://host.com:ninety-two/?foo"},
304 {"google.com:123", "http://google.com:123/"},
305 {"about:", "chrome://version/"},
306 {"about:foo", "chrome://foo/"},
307 {"about:version", "chrome://version/"},
308 {"about:blank", "about:blank"},
309 {"about:usr:pwd@hst:20/pth?qry#ref", "chrome://hst/pth?qry#ref"},
310 {"about://usr:pwd@hst/pth?qry#ref", "chrome://hst/pth?qry#ref"},
311 {"chrome:usr:pwd@hst/pth?qry#ref", "chrome://hst/pth?qry#ref"},
312 {"chrome://usr:pwd@hst/pth?qry#ref", "chrome://hst/pth?qry#ref"},
313 {"www:123", "http://www:123/"},
314 {" www:123", "http://www:123/"},
315 {"www.google.com?foo", "http://www.google.com/?foo"},
316 {"www.google.com#foo", "http://www.google.com/#foo"},
317 {"www.google.com?", "http://www.google.com/?"},
318 {"www.google.com#", "http://www.google.com/#"},
319 {"www.google.com:123?foo#bar", "http://www.google.com:123/?foo#bar"},
320 {"[email protected]", "http://[email protected]/"},
321 {"\xE6\xB0\xB4.com", "http://xn--1rw.com/"},
322 // It would be better if this next case got treated as http, but I don't see
323 // a clean way to guess this isn't the new-and-exciting "user" scheme.
324 {"user:[email protected]:8080/", "user:[email protected]:8080/"},
325 // {"file:///c:/foo/bar%20baz.txt", "file:///C:/foo/bar%20baz.txt"},
326 // URLs which end with 0x85 (NEL in ISO-8859).
327 {"http://foo.com/s?q=\xd0\x85", "http://foo.com/s?q=%D0%85"},
328 {"http://foo.com/s?q=\xec\x97\x85", "http://foo.com/s?q=%EC%97%85"},
329 {"http://foo.com/s?q=\xf0\x90\x80\x85", "http://foo.com/s?q=%F0%90%80%85"},
330 // URLs which end with 0xA0 (non-break space in ISO-8859).
331 {"http://foo.com/s?q=\xd0\xa0", "http://foo.com/s?q=%D0%A0"},
332 {"http://foo.com/s?q=\xec\x97\xa0", "http://foo.com/s?q=%EC%97%A0"},
333 {"http://foo.com/s?q=\xf0\x90\x80\xa0", "http://foo.com/s?q=%F0%90%80%A0"},
334 // URLs containing IPv6 literals.
335 {"[2001:db8::2]", "http://[2001:db8::2]/"},
336 {"[::]:80", "http://[::]/"},
337 {"[::]:80/path", "http://[::]/path"},
338 {"[::]:180/path", "http://[::]:180/path"},
339 // TODO(pmarks): Maybe we should parse bare IPv6 literals someday. Currently
340 // the first colon is treated as a scheme separator, and we default
341 // unspecified schemes to "http".
342 {"::1", "http://:1/"},
343 // Semicolon as scheme separator for standard schemes.
344 {"http;//www.google.com/", "http://www.google.com/"},
345 {"about;chrome", "chrome://chrome/"},
346 // Semicolon in non-standard schemes is not replaced by colon.
347 {"whatsup;//fool", "http://whatsup%3B//fool"},
348 // Semicolon left as-is in URL itself.
349 {"http://host/port?query;moar", "http://host/port?query;moar"},
350 // Fewer slashes than expected.
351 {"http;www.google.com/", "http://www.google.com/"},
352 {"http;/www.google.com/", "http://www.google.com/"},
353 // Semicolon at start.
354 {";http://www.google.com/", "http://%3Bhttp//www.google.com/"},
initial.commit09911bf2008-07-26 23:55:29355};
356
[email protected]9b5b1d602014-06-12 14:29:02357TEST(URLFixerTest, FixupURL) {
[email protected]b1c33f82009-01-23 01:51:23358 for (size_t i = 0; i < arraysize(fixup_cases); ++i) {
[email protected]dc7d3052013-05-31 21:23:28359 FixupCase value = fixup_cases[i];
[email protected]78977682014-05-10 18:42:25360 EXPECT_EQ(value.output,
rsleevi24f64dc22015-08-07 21:39:21361 url_formatter::FixupURL(value.input, "").possibly_invalid_spec())
[email protected]ae8e3672013-03-20 09:00:08362 << "input: " << value.input;
initial.commit09911bf2008-07-26 23:55:29363 }
364
[email protected]78977682014-05-10 18:42:25365 // Check the TLD-appending functionality.
[email protected]dc7d3052013-05-31 21:23:28366 FixupCase tld_cases[] = {
[email protected]91bf0c12014-08-12 14:49:24367 {"somedomainthatwillnotbeagtld",
368 "http://www.somedomainthatwillnotbeagtld.com/"},
369 {"somedomainthatwillnotbeagtld.",
370 "http://www.somedomainthatwillnotbeagtld.com/"},
371 {"somedomainthatwillnotbeagtld..",
372 "http://www.somedomainthatwillnotbeagtld.com/"},
373 {".somedomainthatwillnotbeagtld",
374 "http://www.somedomainthatwillnotbeagtld.com/"},
375 {"www.somedomainthatwillnotbeagtld",
376 "http://www.somedomainthatwillnotbeagtld.com/"},
377 {"somedomainthatwillnotbeagtld.com",
378 "http://somedomainthatwillnotbeagtld.com/"},
379 {"http://somedomainthatwillnotbeagtld",
380 "http://www.somedomainthatwillnotbeagtld.com/"},
381 {"..somedomainthatwillnotbeagtld..",
382 "http://www.somedomainthatwillnotbeagtld.com/"},
383 {"http://www.somedomainthatwillnotbeagtld",
384 "http://www.somedomainthatwillnotbeagtld.com/"},
385 {"9999999999999999", "http://www.9999999999999999.com/"},
386 {"somedomainthatwillnotbeagtld/foo",
387 "http://www.somedomainthatwillnotbeagtld.com/foo"},
388 {"somedomainthatwillnotbeagtld.com/foo",
389 "http://somedomainthatwillnotbeagtld.com/foo"},
390 {"somedomainthatwillnotbeagtld/?foo=.com",
391 "http://www.somedomainthatwillnotbeagtld.com/?foo=.com"},
392 {"www.somedomainthatwillnotbeagtld/?foo=www.",
393 "http://www.somedomainthatwillnotbeagtld.com/?foo=www."},
394 {"somedomainthatwillnotbeagtld.com/?foo=.com",
395 "http://somedomainthatwillnotbeagtld.com/?foo=.com"},
396 {"http://www.somedomainthatwillnotbeagtld.com",
397 "http://www.somedomainthatwillnotbeagtld.com/"},
398 {"somedomainthatwillnotbeagtld:123",
399 "http://www.somedomainthatwillnotbeagtld.com:123/"},
400 {"http://somedomainthatwillnotbeagtld:123",
401 "http://www.somedomainthatwillnotbeagtld.com:123/"},
initial.commit09911bf2008-07-26 23:55:29402 };
[email protected]b1c33f82009-01-23 01:51:23403 for (size_t i = 0; i < arraysize(tld_cases); ++i) {
[email protected]dc7d3052013-05-31 21:23:28404 FixupCase value = tld_cases[i];
rsleevi24f64dc22015-08-07 21:39:21405 EXPECT_EQ(value.output, url_formatter::FixupURL(value.input, "com")
406 .possibly_invalid_spec());
initial.commit09911bf2008-07-26 23:55:29407 }
408}
409
410// Test different types of file inputs to URIFixerUpper::FixupURL. This
411// doesn't go into the nice array of fixups above since the file input
412// has to exist.
[email protected]9b5b1d602014-06-12 14:29:02413TEST(URLFixerTest, FixupFile) {
initial.commit09911bf2008-07-26 23:55:29414 // this "original" filename is the one we tweak to get all the variations
[email protected]97803e1b2014-07-25 01:52:14415 base::ScopedTempDir temp_dir_;
416 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
[email protected]650b2d52013-02-10 03:41:45417 base::FilePath original;
[email protected]d3216442009-03-05 21:07:27418 ASSERT_TRUE(MakeTempFile(
vabr8c498ea42016-09-15 12:41:58419 temp_dir_.GetPath(),
[email protected]650b2d52013-02-10 03:41:45420 base::FilePath(FILE_PATH_LITERAL("url fixer upper existing file.txt")),
[email protected]d3216442009-03-05 21:07:27421 &original));
initial.commit09911bf2008-07-26 23:55:29422
423 // reference path
[email protected]76e7da22010-06-18 22:44:49424 GURL golden(net::FilePathToFileURL(original));
initial.commit09911bf2008-07-26 23:55:29425
426 // c:\foo\bar.txt -> file:///c:/foo/bar.txt (basic)
rsleevi24f64dc22015-08-07 21:39:21427 GURL fixedup(url_formatter::FixupURL(original.AsUTF8Unsafe(), std::string()));
initial.commit09911bf2008-07-26 23:55:29428 EXPECT_EQ(golden, fixedup);
429
[email protected]b1c33f82009-01-23 01:51:23430 // TODO(port): Make some equivalent tests for posix.
431#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29432 // c|/foo\bar.txt -> file:///c:/foo/bar.txt (pipe allowed instead of colon)
[email protected]036a5f32013-12-25 00:26:11433 std::string cur(base::WideToUTF8(original.value()));
initial.commit09911bf2008-07-26 23:55:29434 EXPECT_EQ(':', cur[1]);
435 cur[1] = '|';
rsleevi24f64dc22015-08-07 21:39:21436 EXPECT_EQ(golden, url_formatter::FixupURL(cur, std::string()));
initial.commit09911bf2008-07-26 23:55:29437
[email protected]78977682014-05-10 18:42:25438 FixupCase cases[] = {
439 {"c:\\Non-existent%20file.txt", "file:///C:/Non-existent%2520file.txt"},
initial.commit09911bf2008-07-26 23:55:29440
441 // \\foo\bar.txt -> file://foo/bar.txt
442 // UNC paths, this file won't exist, but since there are no escapes, it
443 // should be returned just converted to a file: URL.
[email protected]78977682014-05-10 18:42:25444 {"\\\\NonexistentHost\\foo\\bar.txt", "file://nonexistenthost/foo/bar.txt"},
[email protected]7fc13ed2010-03-06 05:06:20445 // We do this strictly, like IE8, which only accepts this form using
[email protected]76e7da22010-06-18 22:44:49446 // backslashes and not forward ones. Turning "//foo" into "http" matches
447 // Firefox and IE, silly though it may seem (it falls out of adding "http"
448 // as the default protocol if you haven't entered one).
[email protected]78977682014-05-10 18:42:25449 {"//NonexistentHost\\foo/bar.txt", "http://nonexistenthost/foo/bar.txt"},
450 {"file:///C:/foo/bar", "file:///C:/foo/bar"},
initial.commit09911bf2008-07-26 23:55:29451
[email protected]76e7da22010-06-18 22:44:49452 // Much of the work here comes from GURL's canonicalization stage.
[email protected]78977682014-05-10 18:42:25453 {"file://C:/foo/bar", "file:///C:/foo/bar"},
454 {"file:c:", "file:///C:/"},
455 {"file:c:WINDOWS", "file:///C:/WINDOWS"},
456 {"file:c|Program Files", "file:///C:/Program%20Files"},
457 {"file:/file", "file://file/"},
458 {"file:////////c:\\foo", "file:///C:/foo"},
459 {"file://server/folder/file", "file://server/folder/file"},
[email protected]76e7da22010-06-18 22:44:49460
initial.commit09911bf2008-07-26 23:55:29461 // These are fixups we don't do, but could consider:
[email protected]78977682014-05-10 18:42:25462 // {"file:///foo:/bar", "file://foo/bar"},
463 // {"file:/\\/server\\folder/file", "file://server/folder/file"},
initial.commit09911bf2008-07-26 23:55:29464 };
[email protected]ba1321d12009-04-21 22:42:29465#elif defined(OS_POSIX)
[email protected]762c5542009-10-21 16:45:38466
467#if defined(OS_MACOSX)
468#define HOME "/Users/"
469#else
470#define HOME "/home/"
471#endif
rsleevi24f64dc22015-08-07 21:39:21472 url_formatter::home_directory_override = "/foo";
[email protected]78977682014-05-10 18:42:25473 FixupCase cases[] = {
[email protected]ba1321d12009-04-21 22:42:29474 // File URLs go through GURL, which tries to escape intelligently.
[email protected]78977682014-05-10 18:42:25475 {"/A%20non-existent file.txt", "file:///A%2520non-existent%20file.txt"},
[email protected]ba1321d12009-04-21 22:42:29476 // A plain "/" refers to the root.
[email protected]78977682014-05-10 18:42:25477 {"/", "file:///"},
[email protected]762c5542009-10-21 16:45:38478
479 // These rely on the above home_directory_override.
[email protected]78977682014-05-10 18:42:25480 {"~", "file:///foo"},
481 {"~/bar", "file:///foo/bar"},
[email protected]762c5542009-10-21 16:45:38482
483 // References to other users' homedirs.
[email protected]78977682014-05-10 18:42:25484 {"~foo", "file://" HOME "foo"},
485 {"~x/blah", "file://" HOME "x/blah"},
[email protected]ba1321d12009-04-21 22:42:29486 };
487#endif
[email protected]78977682014-05-10 18:42:25488
489 for (size_t i = 0; i < arraysize(cases); i++) {
490 EXPECT_EQ(cases[i].output,
rsleevi24f64dc22015-08-07 21:39:21491 url_formatter::FixupURL(cases[i].input, std::string())
492 .possibly_invalid_spec());
initial.commit09911bf2008-07-26 23:55:29493 }
494
[email protected]dd3aa792013-07-16 19:10:23495 EXPECT_TRUE(base::DeleteFile(original, false));
initial.commit09911bf2008-07-26 23:55:29496}
497
[email protected]9b5b1d602014-06-12 14:29:02498TEST(URLFixerTest, FixupRelativeFile) {
[email protected]97803e1b2014-07-25 01:52:14499 base::FilePath full_path;
[email protected]650b2d52013-02-10 03:41:45500 base::FilePath file_part(
501 FILE_PATH_LITERAL("url_fixer_upper_existing_file.txt"));
[email protected]97803e1b2014-07-25 01:52:14502 base::ScopedTempDir temp_dir_;
503 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
vabr8c498ea42016-09-15 12:41:58504 ASSERT_TRUE(MakeTempFile(temp_dir_.GetPath(), file_part, &full_path));
[email protected]15476932013-04-12 05:17:15505 full_path = base::MakeAbsoluteFilePath(full_path);
506 ASSERT_FALSE(full_path.empty());
initial.commit09911bf2008-07-26 23:55:29507
508 // make sure we pass through good URLs
[email protected]b1c33f82009-01-23 01:51:23509 for (size_t i = 0; i < arraysize(fixup_cases); ++i) {
[email protected]dc7d3052013-05-31 21:23:28510 FixupCase value = fixup_cases[i];
[email protected]0b58a812013-05-31 01:15:17511 base::FilePath input = base::FilePath::FromUTF8Unsafe(value.input);
[email protected]76e7da22010-06-18 22:44:49512 EXPECT_EQ(value.output,
vabr8c498ea42016-09-15 12:41:58513 url_formatter::FixupRelativeFile(temp_dir_.GetPath(), input)
514 .possibly_invalid_spec());
initial.commit09911bf2008-07-26 23:55:29515 }
516
517 // make sure the existing file got fixed-up to a file URL, and that there
518 // are no backslashes
[email protected]9b5b1d602014-06-12 14:29:02519 EXPECT_TRUE(IsMatchingFileURL(
vabr8c498ea42016-09-15 12:41:58520 url_formatter::FixupRelativeFile(temp_dir_.GetPath(), file_part)
521 .possibly_invalid_spec(),
522 full_path));
[email protected]dd3aa792013-07-16 19:10:23523 EXPECT_TRUE(base::DeleteFile(full_path, false));
initial.commit09911bf2008-07-26 23:55:29524
525 // create a filename we know doesn't exist and make sure it doesn't get
526 // fixed up to a file URL
[email protected]650b2d52013-02-10 03:41:45527 base::FilePath nonexistent_file(
[email protected]d3216442009-03-05 21:07:27528 FILE_PATH_LITERAL("url_fixer_upper_nonexistent_file.txt"));
vabr8c498ea42016-09-15 12:41:58529 std::string fixedup(
530 url_formatter::FixupRelativeFile(temp_dir_.GetPath(), nonexistent_file)
531 .possibly_invalid_spec());
[email protected]b1c33f82009-01-23 01:51:23532 EXPECT_NE(std::string("file:///"), fixedup.substr(0, 8));
initial.commit09911bf2008-07-26 23:55:29533 EXPECT_FALSE(IsMatchingFileURL(fixedup, nonexistent_file));
534
535 // make a subdir to make sure relative paths with directories work, also
[email protected]d3216442009-03-05 21:07:27536 // test spaces:
537 // "app_dir\url fixer-upper dir\url fixer-upper existing file.txt"
[email protected]650b2d52013-02-10 03:41:45538 base::FilePath sub_dir(FILE_PATH_LITERAL("url fixer-upper dir"));
539 base::FilePath sub_file(
540 FILE_PATH_LITERAL("url fixer-upper existing file.txt"));
vabr8c498ea42016-09-15 12:41:58541 base::FilePath new_dir = temp_dir_.GetPath().Append(sub_dir);
[email protected]426d1c92013-12-03 20:08:54542 base::CreateDirectory(new_dir);
initial.commit09911bf2008-07-26 23:55:29543 ASSERT_TRUE(MakeTempFile(new_dir, sub_file, &full_path));
[email protected]15476932013-04-12 05:17:15544 full_path = base::MakeAbsoluteFilePath(full_path);
545 ASSERT_FALSE(full_path.empty());
initial.commit09911bf2008-07-26 23:55:29546
547 // test file in the subdir
[email protected]650b2d52013-02-10 03:41:45548 base::FilePath relative_file = sub_dir.Append(sub_file);
[email protected]9b5b1d602014-06-12 14:29:02549 EXPECT_TRUE(IsMatchingFileURL(
vabr8c498ea42016-09-15 12:41:58550 url_formatter::FixupRelativeFile(temp_dir_.GetPath(), relative_file)
551 .possibly_invalid_spec(),
552 full_path));
initial.commit09911bf2008-07-26 23:55:29553
[email protected]b1c33f82009-01-23 01:51:23554 // test file in the subdir with different slashes and escaping.
[email protected]650b2d52013-02-10 03:41:45555 base::FilePath::StringType relative_file_str = sub_dir.value() +
[email protected]b1c33f82009-01-23 01:51:23556 FILE_PATH_LITERAL("/") + sub_file.value();
brettwe6dae462015-06-24 20:54:45557 base::ReplaceSubstringsAfterOffset(&relative_file_str, 0,
[email protected]b1c33f82009-01-23 01:51:23558 FILE_PATH_LITERAL(" "), FILE_PATH_LITERAL("%20"));
[email protected]9b5b1d602014-06-12 14:29:02559 EXPECT_TRUE(IsMatchingFileURL(
vabr8c498ea42016-09-15 12:41:58560 url_formatter::FixupRelativeFile(temp_dir_.GetPath(),
561 base::FilePath(relative_file_str))
562 .possibly_invalid_spec(),
563 full_path));
initial.commit09911bf2008-07-26 23:55:29564
565 // test relative directories and duplicate slashes
566 // (should resolve to the same file as above)
[email protected]b1c33f82009-01-23 01:51:23567 relative_file_str = sub_dir.value() + FILE_PATH_LITERAL("/../") +
568 sub_dir.value() + FILE_PATH_LITERAL("///./") + sub_file.value();
[email protected]9b5b1d602014-06-12 14:29:02569 EXPECT_TRUE(IsMatchingFileURL(
vabr8c498ea42016-09-15 12:41:58570 url_formatter::FixupRelativeFile(temp_dir_.GetPath(),
571 base::FilePath(relative_file_str))
572 .possibly_invalid_spec(),
573 full_path));
initial.commit09911bf2008-07-26 23:55:29574
575 // done with the subdir
[email protected]dd3aa792013-07-16 19:10:23576 EXPECT_TRUE(base::DeleteFile(full_path, false));
577 EXPECT_TRUE(base::DeleteFile(new_dir, true));
[email protected]a64c3cf2011-08-06 05:25:55578
579 // Test that an obvious HTTP URL isn't accidentally treated as an absolute
580 // file path (on account of system-specific craziness).
[email protected]650b2d52013-02-10 03:41:45581 base::FilePath empty_path;
582 base::FilePath http_url_path(FILE_PATH_LITERAL("http://../"));
rsleevi24f64dc22015-08-07 21:39:21583 EXPECT_TRUE(url_formatter::FixupRelativeFile(empty_path, http_url_path)
584 .SchemeIs("http"));
initial.commit09911bf2008-07-26 23:55:29585}