1 // Copyright 2016 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 "ios/chrome/browser/browser_about_rewriter.h"
6 
7 #include <string>
8 
9 #include "base/check.h"
10 #include "base/feature_list.h"
11 #include "base/stl_util.h"
12 #include "components/url_formatter/url_fixer.h"
13 #include "ios/chrome/browser/chrome_url_constants.h"
14 #include "ios/chrome/browser/ui/ui_feature_flags.h"
15 #include "ios/components/webui/web_ui_url_constants.h"
16 #include "url/url_constants.h"
17 
18 namespace {
19 
20 const struct HostReplacement {
21   const char* old_host_name;
22   const char* new_host_name;
23 } kHostReplacements[] = {
24     {"about", kChromeUIChromeURLsHost},
25     {"sync", kChromeUISyncInternalsHost},
26 };
27 
28 }  // namespace
29 
WillHandleWebBrowserAboutURL(GURL * url,web::BrowserState * browser_state)30 bool WillHandleWebBrowserAboutURL(GURL* url, web::BrowserState* browser_state) {
31   GURL original_url = *url;
32 
33   // Ensure that any cleanup done by FixupURL happens before the rewriting
34   // phase that determines the virtual URL, by including it in an initial
35   // URLHandler.  This prevents minor changes from producing a virtual URL,
36   // which could lead to a URL spoof.
37   *url = url_formatter::FixupURL(url->possibly_invalid_spec(), std::string());
38 
39   // Check that about: URLs are fixed up to chrome: by url_formatter::FixupURL.
40   // 'about:blank' is special-cased in various places in the code so it
41   // shouldn't be transformed.
42   DCHECK(!url->SchemeIs(url::kAboutScheme) ||
43          (url->path() == url::kAboutBlankPath));
44 
45   // url_formatter::FixupURL translates about:foo into chrome://foo/.
46   if (!url->SchemeIs(kChromeUIScheme))
47     return false;
48 
49   // Translate chrome://newtab back into about://newtab so the WebState shows a
50   // blank page under the NTP.
51   if (url->GetOrigin() == kChromeUINewTabURL) {
52     GURL::Replacements replacements;
53     replacements.SetSchemeStr(url::kAboutScheme);
54     *url = url->ReplaceComponents(replacements);
55     return *url != original_url;
56   }
57 
58   std::string host(url->host());
59   for (size_t i = 0; i < base::size(kHostReplacements); ++i) {
60     if (host != kHostReplacements[i].old_host_name)
61       continue;
62 
63     host.assign(kHostReplacements[i].new_host_name);
64     break;
65   }
66 
67   GURL::Replacements replacements;
68   replacements.SetHostStr(host);
69   *url = url->ReplaceComponents(replacements);
70 
71   // Having re-written the URL, make the chrome: handler process it.
72   return false;
73 }
74