blob: 3bb3fde8aa492602d2333543291360c3f430737c [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 },
185 // Can't do anything useful with this.
186 { ":b005::68]", "",
[email protected]b45334502014-04-30 19:44:05187 url::Component(0, 0), // scheme
188 url::Component(), // username
189 url::Component(), // password
190 url::Component(), // host
191 url::Component(), // port
192 url::Component(), // path
193 url::Component(), // query
194 url::Component(), // ref
[email protected]c1991302009-06-04 03:57:39195 },
initial.commit09911bf2008-07-26 23:55:29196};
197
[email protected]9b5b1d602014-06-12 14:29:02198typedef testing::Test URLFixerTest;
[email protected]78977682014-05-10 18:42:25199
[email protected]9b5b1d602014-06-12 14:29:02200TEST(URLFixerTest, SegmentURL) {
[email protected]b1c33f82009-01-23 01:51:23201 std::string result;
[email protected]b45334502014-04-30 19:44:05202 url::Parsed parts;
initial.commit09911bf2008-07-26 23:55:29203
[email protected]b1c33f82009-01-23 01:51:23204 for (size_t i = 0; i < arraysize(segment_cases); ++i) {
[email protected]dc7d3052013-05-31 21:23:28205 SegmentCase value = segment_cases[i];
rsleevi24f64dc22015-08-07 21:39:21206 result = url_formatter::SegmentURL(value.input, &parts);
initial.commit09911bf2008-07-26 23:55:29207 EXPECT_EQ(value.result, result);
208 EXPECT_EQ(value.scheme, parts.scheme);
209 EXPECT_EQ(value.username, parts.username);
210 EXPECT_EQ(value.password, parts.password);
211 EXPECT_EQ(value.host, parts.host);
212 EXPECT_EQ(value.port, parts.port);
213 EXPECT_EQ(value.path, parts.path);
214 EXPECT_EQ(value.query, parts.query);
215 EXPECT_EQ(value.ref, parts.ref);
216 }
217}
218
219// Creates a file and returns its full name as well as the decomposed
220// version. Example:
221// full_path = "c:\foo\bar.txt"
222// dir = "c:\foo"
223// file_name = "bar.txt"
[email protected]650b2d52013-02-10 03:41:45224static bool MakeTempFile(const base::FilePath& dir,
225 const base::FilePath& file_name,
226 base::FilePath* full_path) {
[email protected]b1c33f82009-01-23 01:51:23227 *full_path = dir.Append(file_name);
[email protected]e5c2a22e2014-03-06 20:42:30228 return base::WriteFile(*full_path, "", 0) == 0;
initial.commit09911bf2008-07-26 23:55:29229}
230
231// Returns true if the given URL is a file: URL that matches the given file
[email protected]b1c33f82009-01-23 01:51:23232static bool IsMatchingFileURL(const std::string& url,
[email protected]650b2d52013-02-10 03:41:45233 const base::FilePath& full_file_path) {
initial.commit09911bf2008-07-26 23:55:29234 if (url.length() <= 8)
235 return false;
[email protected]b1c33f82009-01-23 01:51:23236 if (std::string("file:///") != url.substr(0, 8))
initial.commit09911bf2008-07-26 23:55:29237 return false; // no file:/// prefix
[email protected]b1c33f82009-01-23 01:51:23238 if (url.find('\\') != std::string::npos)
initial.commit09911bf2008-07-26 23:55:29239 return false; // contains backslashes
240
[email protected]650b2d52013-02-10 03:41:45241 base::FilePath derived_path;
[email protected]56741852008-12-17 19:04:50242 net::FileURLToFilePath(GURL(url), &derived_path);
[email protected]b1c33f82009-01-23 01:51:23243
[email protected]650b2d52013-02-10 03:41:45244 return base::FilePath::CompareEqualIgnoreCase(derived_path.value(),
[email protected]eccb9d12009-10-28 05:40:09245 full_file_path.value());
initial.commit09911bf2008-07-26 23:55:29246}
247
[email protected]dc7d3052013-05-31 21:23:28248struct FixupCase {
[email protected]b1c33f82009-01-23 01:51:23249 const std::string input;
[email protected]b1c33f82009-01-23 01:51:23250 const std::string output;
initial.commit09911bf2008-07-26 23:55:29251} fixup_cases[] = {
[email protected]78977682014-05-10 18:42:25252 {"www.google.com", "http://www.google.com/"},
253 {" www.google.com ", "http://www.google.com/"},
254 {" foo.com/asdf bar", "http://foo.com/asdf%20%20bar"},
255 {"..www.google.com..", "http://www.google.com./"},
256 {"http://......", "http://....../"},
257 {"http://host.com:ninety-two/", "http://host.com:ninety-two/"},
258 {"http://host.com:ninety-two?foo", "http://host.com:ninety-two/?foo"},
259 {"google.com:123", "http://google.com:123/"},
260 {"about:", "chrome://version/"},
261 {"about:foo", "chrome://foo/"},
262 {"about:version", "chrome://version/"},
263 {"about:blank", "about:blank"},
264 {"about:usr:pwd@hst/pth?qry#ref", "chrome://usr:pwd@hst/pth?qry#ref"},
265 {"about://usr:pwd@hst/pth?qry#ref", "chrome://usr:pwd@hst/pth?qry#ref"},
266 {"chrome:usr:pwd@hst/pth?qry#ref", "chrome://usr:pwd@hst/pth?qry#ref"},
267 {"chrome://usr:pwd@hst/pth?qry#ref", "chrome://usr:pwd@hst/pth?qry#ref"},
268 {"www:123", "http://www:123/"},
269 {" www:123", "http://www:123/"},
270 {"www.google.com?foo", "http://www.google.com/?foo"},
271 {"www.google.com#foo", "http://www.google.com/#foo"},
272 {"www.google.com?", "http://www.google.com/?"},
273 {"www.google.com#", "http://www.google.com/#"},
274 {"www.google.com:123?foo#bar", "http://www.google.com:123/?foo#bar"},
275 {"[email protected]", "http://[email protected]/"},
276 {"\xE6\xB0\xB4.com", "http://xn--1rw.com/"},
initial.commit09911bf2008-07-26 23:55:29277 // It would be better if this next case got treated as http, but I don't see
278 // a clean way to guess this isn't the new-and-exciting "user" scheme.
[email protected]78977682014-05-10 18:42:25279 {"user:[email protected]:8080/", "user:[email protected]:8080/"},
280 // {"file:///c:/foo/bar%20baz.txt", "file:///C:/foo/bar%20baz.txt"},
281 {"ftp.google.com", "ftp://ftp.google.com/"},
282 {" ftp.google.com", "ftp://ftp.google.com/"},
283 {"FTP.GooGle.com", "ftp://ftp.google.com/"},
284 {"ftpblah.google.com", "http://ftpblah.google.com/"},
285 {"ftp", "http://ftp/"},
286 {"google.ftp.com", "http://google.ftp.com/"},
[email protected]90f933a2009-03-05 03:41:51287 // URLs which end with 0x85 (NEL in ISO-8859).
[email protected]78977682014-05-10 18:42:25288 {"http://foo.com/s?q=\xd0\x85", "http://foo.com/s?q=%D0%85"},
289 {"http://foo.com/s?q=\xec\x97\x85", "http://foo.com/s?q=%EC%97%85"},
290 {"http://foo.com/s?q=\xf0\x90\x80\x85", "http://foo.com/s?q=%F0%90%80%85"},
[email protected]90f933a2009-03-05 03:41:51291 // URLs which end with 0xA0 (non-break space in ISO-8859).
[email protected]78977682014-05-10 18:42:25292 {"http://foo.com/s?q=\xd0\xa0", "http://foo.com/s?q=%D0%A0"},
293 {"http://foo.com/s?q=\xec\x97\xa0", "http://foo.com/s?q=%EC%97%A0"},
294 {"http://foo.com/s?q=\xf0\x90\x80\xa0", "http://foo.com/s?q=%F0%90%80%A0"},
[email protected]818071ce2009-05-18 01:25:25295 // URLs containing IPv6 literals.
[email protected]78977682014-05-10 18:42:25296 {"[2001:db8::2]", "http://[2001:db8::2]/"},
297 {"[::]:80", "http://[::]/"},
298 {"[::]:80/path", "http://[::]/path"},
299 {"[::]:180/path", "http://[::]:180/path"},
[email protected]818071ce2009-05-18 01:25:25300 // TODO(pmarks): Maybe we should parse bare IPv6 literals someday.
[email protected]78977682014-05-10 18:42:25301 {"::1", "::1"},
[email protected]ae8e3672013-03-20 09:00:08302 // Semicolon as scheme separator for standard schemes.
[email protected]78977682014-05-10 18:42:25303 {"http;//www.google.com/", "http://www.google.com/"},
304 {"about;chrome", "chrome://chrome/"},
a-v-y3abb13a2016-05-03 05:36:42305 // Semicolon in non-standard schemes is not replaced by colon.
306 {"whatsup;//fool", "http://whatsup%3B//fool"},
[email protected]ae8e3672013-03-20 09:00:08307 // Semicolon left as-is in URL itself.
[email protected]78977682014-05-10 18:42:25308 {"http://host/port?query;moar", "http://host/port?query;moar"},
[email protected]ae8e3672013-03-20 09:00:08309 // Fewer slashes than expected.
[email protected]78977682014-05-10 18:42:25310 {"http;www.google.com/", "http://www.google.com/"},
311 {"http;/www.google.com/", "http://www.google.com/"},
[email protected]ae8e3672013-03-20 09:00:08312 // Semicolon at start.
[email protected]78977682014-05-10 18:42:25313 {";http://www.google.com/", "http://%3Bhttp//www.google.com/"},
initial.commit09911bf2008-07-26 23:55:29314};
315
[email protected]9b5b1d602014-06-12 14:29:02316TEST(URLFixerTest, FixupURL) {
[email protected]b1c33f82009-01-23 01:51:23317 for (size_t i = 0; i < arraysize(fixup_cases); ++i) {
[email protected]dc7d3052013-05-31 21:23:28318 FixupCase value = fixup_cases[i];
[email protected]78977682014-05-10 18:42:25319 EXPECT_EQ(value.output,
rsleevi24f64dc22015-08-07 21:39:21320 url_formatter::FixupURL(value.input, "").possibly_invalid_spec())
[email protected]ae8e3672013-03-20 09:00:08321 << "input: " << value.input;
initial.commit09911bf2008-07-26 23:55:29322 }
323
[email protected]78977682014-05-10 18:42:25324 // Check the TLD-appending functionality.
[email protected]dc7d3052013-05-31 21:23:28325 FixupCase tld_cases[] = {
[email protected]91bf0c12014-08-12 14:49:24326 {"somedomainthatwillnotbeagtld",
327 "http://www.somedomainthatwillnotbeagtld.com/"},
328 {"somedomainthatwillnotbeagtld.",
329 "http://www.somedomainthatwillnotbeagtld.com/"},
330 {"somedomainthatwillnotbeagtld..",
331 "http://www.somedomainthatwillnotbeagtld.com/"},
332 {".somedomainthatwillnotbeagtld",
333 "http://www.somedomainthatwillnotbeagtld.com/"},
334 {"www.somedomainthatwillnotbeagtld",
335 "http://www.somedomainthatwillnotbeagtld.com/"},
336 {"somedomainthatwillnotbeagtld.com",
337 "http://somedomainthatwillnotbeagtld.com/"},
338 {"http://somedomainthatwillnotbeagtld",
339 "http://www.somedomainthatwillnotbeagtld.com/"},
340 {"..somedomainthatwillnotbeagtld..",
341 "http://www.somedomainthatwillnotbeagtld.com/"},
342 {"http://www.somedomainthatwillnotbeagtld",
343 "http://www.somedomainthatwillnotbeagtld.com/"},
344 {"9999999999999999", "http://www.9999999999999999.com/"},
345 {"somedomainthatwillnotbeagtld/foo",
346 "http://www.somedomainthatwillnotbeagtld.com/foo"},
347 {"somedomainthatwillnotbeagtld.com/foo",
348 "http://somedomainthatwillnotbeagtld.com/foo"},
349 {"somedomainthatwillnotbeagtld/?foo=.com",
350 "http://www.somedomainthatwillnotbeagtld.com/?foo=.com"},
351 {"www.somedomainthatwillnotbeagtld/?foo=www.",
352 "http://www.somedomainthatwillnotbeagtld.com/?foo=www."},
353 {"somedomainthatwillnotbeagtld.com/?foo=.com",
354 "http://somedomainthatwillnotbeagtld.com/?foo=.com"},
355 {"http://www.somedomainthatwillnotbeagtld.com",
356 "http://www.somedomainthatwillnotbeagtld.com/"},
357 {"somedomainthatwillnotbeagtld:123",
358 "http://www.somedomainthatwillnotbeagtld.com:123/"},
359 {"http://somedomainthatwillnotbeagtld:123",
360 "http://www.somedomainthatwillnotbeagtld.com:123/"},
initial.commit09911bf2008-07-26 23:55:29361 };
[email protected]b1c33f82009-01-23 01:51:23362 for (size_t i = 0; i < arraysize(tld_cases); ++i) {
[email protected]dc7d3052013-05-31 21:23:28363 FixupCase value = tld_cases[i];
rsleevi24f64dc22015-08-07 21:39:21364 EXPECT_EQ(value.output, url_formatter::FixupURL(value.input, "com")
365 .possibly_invalid_spec());
initial.commit09911bf2008-07-26 23:55:29366 }
367}
368
369// Test different types of file inputs to URIFixerUpper::FixupURL. This
370// doesn't go into the nice array of fixups above since the file input
371// has to exist.
[email protected]9b5b1d602014-06-12 14:29:02372TEST(URLFixerTest, FixupFile) {
initial.commit09911bf2008-07-26 23:55:29373 // this "original" filename is the one we tweak to get all the variations
[email protected]97803e1b2014-07-25 01:52:14374 base::ScopedTempDir temp_dir_;
375 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
[email protected]650b2d52013-02-10 03:41:45376 base::FilePath original;
[email protected]d3216442009-03-05 21:07:27377 ASSERT_TRUE(MakeTempFile(
vabr8c498ea42016-09-15 12:41:58378 temp_dir_.GetPath(),
[email protected]650b2d52013-02-10 03:41:45379 base::FilePath(FILE_PATH_LITERAL("url fixer upper existing file.txt")),
[email protected]d3216442009-03-05 21:07:27380 &original));
initial.commit09911bf2008-07-26 23:55:29381
382 // reference path
[email protected]76e7da22010-06-18 22:44:49383 GURL golden(net::FilePathToFileURL(original));
initial.commit09911bf2008-07-26 23:55:29384
385 // c:\foo\bar.txt -> file:///c:/foo/bar.txt (basic)
rsleevi24f64dc22015-08-07 21:39:21386 GURL fixedup(url_formatter::FixupURL(original.AsUTF8Unsafe(), std::string()));
initial.commit09911bf2008-07-26 23:55:29387 EXPECT_EQ(golden, fixedup);
388
[email protected]b1c33f82009-01-23 01:51:23389 // TODO(port): Make some equivalent tests for posix.
390#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29391 // c|/foo\bar.txt -> file:///c:/foo/bar.txt (pipe allowed instead of colon)
[email protected]036a5f32013-12-25 00:26:11392 std::string cur(base::WideToUTF8(original.value()));
initial.commit09911bf2008-07-26 23:55:29393 EXPECT_EQ(':', cur[1]);
394 cur[1] = '|';
rsleevi24f64dc22015-08-07 21:39:21395 EXPECT_EQ(golden, url_formatter::FixupURL(cur, std::string()));
initial.commit09911bf2008-07-26 23:55:29396
[email protected]78977682014-05-10 18:42:25397 FixupCase cases[] = {
398 {"c:\\Non-existent%20file.txt", "file:///C:/Non-existent%2520file.txt"},
initial.commit09911bf2008-07-26 23:55:29399
400 // \\foo\bar.txt -> file://foo/bar.txt
401 // UNC paths, this file won't exist, but since there are no escapes, it
402 // should be returned just converted to a file: URL.
[email protected]78977682014-05-10 18:42:25403 {"\\\\NonexistentHost\\foo\\bar.txt", "file://nonexistenthost/foo/bar.txt"},
[email protected]7fc13ed2010-03-06 05:06:20404 // We do this strictly, like IE8, which only accepts this form using
[email protected]76e7da22010-06-18 22:44:49405 // backslashes and not forward ones. Turning "//foo" into "http" matches
406 // Firefox and IE, silly though it may seem (it falls out of adding "http"
407 // as the default protocol if you haven't entered one).
[email protected]78977682014-05-10 18:42:25408 {"//NonexistentHost\\foo/bar.txt", "http://nonexistenthost/foo/bar.txt"},
409 {"file:///C:/foo/bar", "file:///C:/foo/bar"},
initial.commit09911bf2008-07-26 23:55:29410
[email protected]76e7da22010-06-18 22:44:49411 // Much of the work here comes from GURL's canonicalization stage.
[email protected]78977682014-05-10 18:42:25412 {"file://C:/foo/bar", "file:///C:/foo/bar"},
413 {"file:c:", "file:///C:/"},
414 {"file:c:WINDOWS", "file:///C:/WINDOWS"},
415 {"file:c|Program Files", "file:///C:/Program%20Files"},
416 {"file:/file", "file://file/"},
417 {"file:////////c:\\foo", "file:///C:/foo"},
418 {"file://server/folder/file", "file://server/folder/file"},
[email protected]76e7da22010-06-18 22:44:49419
initial.commit09911bf2008-07-26 23:55:29420 // These are fixups we don't do, but could consider:
[email protected]78977682014-05-10 18:42:25421 // {"file:///foo:/bar", "file://foo/bar"},
422 // {"file:/\\/server\\folder/file", "file://server/folder/file"},
initial.commit09911bf2008-07-26 23:55:29423 };
[email protected]ba1321d12009-04-21 22:42:29424#elif defined(OS_POSIX)
[email protected]762c5542009-10-21 16:45:38425
426#if defined(OS_MACOSX)
427#define HOME "/Users/"
428#else
429#define HOME "/home/"
430#endif
rsleevi24f64dc22015-08-07 21:39:21431 url_formatter::home_directory_override = "/foo";
[email protected]78977682014-05-10 18:42:25432 FixupCase cases[] = {
[email protected]ba1321d12009-04-21 22:42:29433 // File URLs go through GURL, which tries to escape intelligently.
[email protected]78977682014-05-10 18:42:25434 {"/A%20non-existent file.txt", "file:///A%2520non-existent%20file.txt"},
[email protected]ba1321d12009-04-21 22:42:29435 // A plain "/" refers to the root.
[email protected]78977682014-05-10 18:42:25436 {"/", "file:///"},
[email protected]762c5542009-10-21 16:45:38437
438 // These rely on the above home_directory_override.
[email protected]78977682014-05-10 18:42:25439 {"~", "file:///foo"},
440 {"~/bar", "file:///foo/bar"},
[email protected]762c5542009-10-21 16:45:38441
442 // References to other users' homedirs.
[email protected]78977682014-05-10 18:42:25443 {"~foo", "file://" HOME "foo"},
444 {"~x/blah", "file://" HOME "x/blah"},
[email protected]ba1321d12009-04-21 22:42:29445 };
446#endif
[email protected]78977682014-05-10 18:42:25447
448 for (size_t i = 0; i < arraysize(cases); i++) {
449 EXPECT_EQ(cases[i].output,
rsleevi24f64dc22015-08-07 21:39:21450 url_formatter::FixupURL(cases[i].input, std::string())
451 .possibly_invalid_spec());
initial.commit09911bf2008-07-26 23:55:29452 }
453
[email protected]dd3aa792013-07-16 19:10:23454 EXPECT_TRUE(base::DeleteFile(original, false));
initial.commit09911bf2008-07-26 23:55:29455}
456
[email protected]9b5b1d602014-06-12 14:29:02457TEST(URLFixerTest, FixupRelativeFile) {
[email protected]97803e1b2014-07-25 01:52:14458 base::FilePath full_path;
[email protected]650b2d52013-02-10 03:41:45459 base::FilePath file_part(
460 FILE_PATH_LITERAL("url_fixer_upper_existing_file.txt"));
[email protected]97803e1b2014-07-25 01:52:14461 base::ScopedTempDir temp_dir_;
462 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
vabr8c498ea42016-09-15 12:41:58463 ASSERT_TRUE(MakeTempFile(temp_dir_.GetPath(), file_part, &full_path));
[email protected]15476932013-04-12 05:17:15464 full_path = base::MakeAbsoluteFilePath(full_path);
465 ASSERT_FALSE(full_path.empty());
initial.commit09911bf2008-07-26 23:55:29466
467 // make sure we pass through good URLs
[email protected]b1c33f82009-01-23 01:51:23468 for (size_t i = 0; i < arraysize(fixup_cases); ++i) {
[email protected]dc7d3052013-05-31 21:23:28469 FixupCase value = fixup_cases[i];
[email protected]0b58a812013-05-31 01:15:17470 base::FilePath input = base::FilePath::FromUTF8Unsafe(value.input);
[email protected]76e7da22010-06-18 22:44:49471 EXPECT_EQ(value.output,
vabr8c498ea42016-09-15 12:41:58472 url_formatter::FixupRelativeFile(temp_dir_.GetPath(), input)
473 .possibly_invalid_spec());
initial.commit09911bf2008-07-26 23:55:29474 }
475
476 // make sure the existing file got fixed-up to a file URL, and that there
477 // are no backslashes
[email protected]9b5b1d602014-06-12 14:29:02478 EXPECT_TRUE(IsMatchingFileURL(
vabr8c498ea42016-09-15 12:41:58479 url_formatter::FixupRelativeFile(temp_dir_.GetPath(), file_part)
480 .possibly_invalid_spec(),
481 full_path));
[email protected]dd3aa792013-07-16 19:10:23482 EXPECT_TRUE(base::DeleteFile(full_path, false));
initial.commit09911bf2008-07-26 23:55:29483
484 // create a filename we know doesn't exist and make sure it doesn't get
485 // fixed up to a file URL
[email protected]650b2d52013-02-10 03:41:45486 base::FilePath nonexistent_file(
[email protected]d3216442009-03-05 21:07:27487 FILE_PATH_LITERAL("url_fixer_upper_nonexistent_file.txt"));
vabr8c498ea42016-09-15 12:41:58488 std::string fixedup(
489 url_formatter::FixupRelativeFile(temp_dir_.GetPath(), nonexistent_file)
490 .possibly_invalid_spec());
[email protected]b1c33f82009-01-23 01:51:23491 EXPECT_NE(std::string("file:///"), fixedup.substr(0, 8));
initial.commit09911bf2008-07-26 23:55:29492 EXPECT_FALSE(IsMatchingFileURL(fixedup, nonexistent_file));
493
494 // make a subdir to make sure relative paths with directories work, also
[email protected]d3216442009-03-05 21:07:27495 // test spaces:
496 // "app_dir\url fixer-upper dir\url fixer-upper existing file.txt"
[email protected]650b2d52013-02-10 03:41:45497 base::FilePath sub_dir(FILE_PATH_LITERAL("url fixer-upper dir"));
498 base::FilePath sub_file(
499 FILE_PATH_LITERAL("url fixer-upper existing file.txt"));
vabr8c498ea42016-09-15 12:41:58500 base::FilePath new_dir = temp_dir_.GetPath().Append(sub_dir);
[email protected]426d1c92013-12-03 20:08:54501 base::CreateDirectory(new_dir);
initial.commit09911bf2008-07-26 23:55:29502 ASSERT_TRUE(MakeTempFile(new_dir, sub_file, &full_path));
[email protected]15476932013-04-12 05:17:15503 full_path = base::MakeAbsoluteFilePath(full_path);
504 ASSERT_FALSE(full_path.empty());
initial.commit09911bf2008-07-26 23:55:29505
506 // test file in the subdir
[email protected]650b2d52013-02-10 03:41:45507 base::FilePath relative_file = sub_dir.Append(sub_file);
[email protected]9b5b1d602014-06-12 14:29:02508 EXPECT_TRUE(IsMatchingFileURL(
vabr8c498ea42016-09-15 12:41:58509 url_formatter::FixupRelativeFile(temp_dir_.GetPath(), relative_file)
510 .possibly_invalid_spec(),
511 full_path));
initial.commit09911bf2008-07-26 23:55:29512
[email protected]b1c33f82009-01-23 01:51:23513 // test file in the subdir with different slashes and escaping.
[email protected]650b2d52013-02-10 03:41:45514 base::FilePath::StringType relative_file_str = sub_dir.value() +
[email protected]b1c33f82009-01-23 01:51:23515 FILE_PATH_LITERAL("/") + sub_file.value();
brettwe6dae462015-06-24 20:54:45516 base::ReplaceSubstringsAfterOffset(&relative_file_str, 0,
[email protected]b1c33f82009-01-23 01:51:23517 FILE_PATH_LITERAL(" "), FILE_PATH_LITERAL("%20"));
[email protected]9b5b1d602014-06-12 14:29:02518 EXPECT_TRUE(IsMatchingFileURL(
vabr8c498ea42016-09-15 12:41:58519 url_formatter::FixupRelativeFile(temp_dir_.GetPath(),
520 base::FilePath(relative_file_str))
521 .possibly_invalid_spec(),
522 full_path));
initial.commit09911bf2008-07-26 23:55:29523
524 // test relative directories and duplicate slashes
525 // (should resolve to the same file as above)
[email protected]b1c33f82009-01-23 01:51:23526 relative_file_str = sub_dir.value() + FILE_PATH_LITERAL("/../") +
527 sub_dir.value() + FILE_PATH_LITERAL("///./") + sub_file.value();
[email protected]9b5b1d602014-06-12 14:29:02528 EXPECT_TRUE(IsMatchingFileURL(
vabr8c498ea42016-09-15 12:41:58529 url_formatter::FixupRelativeFile(temp_dir_.GetPath(),
530 base::FilePath(relative_file_str))
531 .possibly_invalid_spec(),
532 full_path));
initial.commit09911bf2008-07-26 23:55:29533
534 // done with the subdir
[email protected]dd3aa792013-07-16 19:10:23535 EXPECT_TRUE(base::DeleteFile(full_path, false));
536 EXPECT_TRUE(base::DeleteFile(new_dir, true));
[email protected]a64c3cf2011-08-06 05:25:55537
538 // Test that an obvious HTTP URL isn't accidentally treated as an absolute
539 // file path (on account of system-specific craziness).
[email protected]650b2d52013-02-10 03:41:45540 base::FilePath empty_path;
541 base::FilePath http_url_path(FILE_PATH_LITERAL("http://../"));
rsleevi24f64dc22015-08-07 21:39:21542 EXPECT_TRUE(url_formatter::FixupRelativeFile(empty_path, http_url_path)
543 .SchemeIs("http"));
initial.commit09911bf2008-07-26 23:55:29544}