|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 // See also: docshell/base/nsAboutRedirector.cpp |
|
7 |
|
8 #include "AboutRedirector.h" |
|
9 #include "nsNetUtil.h" |
|
10 #include "nsIScriptSecurityManager.h" |
|
11 #include "mozilla/ArrayUtils.h" |
|
12 |
|
13 namespace mozilla { |
|
14 namespace browser { |
|
15 |
|
16 NS_IMPL_ISUPPORTS(AboutRedirector, nsIAboutModule) |
|
17 |
|
18 struct RedirEntry { |
|
19 const char* id; |
|
20 const char* url; |
|
21 uint32_t flags; |
|
22 }; |
|
23 |
|
24 /* |
|
25 Entries which do not have URI_SAFE_FOR_UNTRUSTED_CONTENT will run with chrome |
|
26 privileges. This is potentially dangerous. Please use |
|
27 URI_SAFE_FOR_UNTRUSTED_CONTENT in the third argument to each map item below |
|
28 unless your about: page really needs chrome privileges. Security review is |
|
29 required before adding new map entries without |
|
30 URI_SAFE_FOR_UNTRUSTED_CONTENT. Also note, however, that adding |
|
31 URI_SAFE_FOR_UNTRUSTED_CONTENT will allow random web sites to link to that |
|
32 URI. Perhaps we should separate the two concepts out... |
|
33 */ |
|
34 static RedirEntry kRedirMap[] = { |
|
35 #ifdef MOZ_SAFE_BROWSING |
|
36 { "blocked", "chrome://browser/content/blockedSite.xhtml", |
|
37 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | |
|
38 nsIAboutModule::ALLOW_SCRIPT | |
|
39 nsIAboutModule::HIDE_FROM_ABOUTABOUT }, |
|
40 #endif |
|
41 { "certerror", "chrome://browser/content/certerror/aboutCertError.xhtml", |
|
42 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | |
|
43 nsIAboutModule::ALLOW_SCRIPT | |
|
44 nsIAboutModule::HIDE_FROM_ABOUTABOUT }, |
|
45 { "socialerror", "chrome://browser/content/aboutSocialError.xhtml", |
|
46 nsIAboutModule::ALLOW_SCRIPT | |
|
47 nsIAboutModule::HIDE_FROM_ABOUTABOUT }, |
|
48 { "tabcrashed", "chrome://browser/content/aboutTabCrashed.xhtml", |
|
49 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | |
|
50 nsIAboutModule::ALLOW_SCRIPT | |
|
51 nsIAboutModule::HIDE_FROM_ABOUTABOUT }, |
|
52 { "feeds", "chrome://browser/content/feeds/subscribe.xhtml", |
|
53 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | |
|
54 nsIAboutModule::ALLOW_SCRIPT | |
|
55 nsIAboutModule::HIDE_FROM_ABOUTABOUT }, |
|
56 { "privatebrowsing", "chrome://browser/content/aboutPrivateBrowsing.xhtml", |
|
57 nsIAboutModule::ALLOW_SCRIPT }, |
|
58 { "rights", |
|
59 #ifdef MOZ_OFFICIAL_BRANDING |
|
60 "chrome://global/content/aboutRights.xhtml", |
|
61 #else |
|
62 "chrome://global/content/aboutRights-unbranded.xhtml", |
|
63 #endif |
|
64 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | |
|
65 nsIAboutModule::ALLOW_SCRIPT }, |
|
66 { "robots", "chrome://browser/content/aboutRobots.xhtml", |
|
67 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | |
|
68 nsIAboutModule::ALLOW_SCRIPT }, |
|
69 { "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml", |
|
70 nsIAboutModule::ALLOW_SCRIPT }, |
|
71 { "welcomeback", "chrome://browser/content/aboutWelcomeBack.xhtml", |
|
72 nsIAboutModule::ALLOW_SCRIPT }, |
|
73 #ifdef MOZ_SERVICES_SYNC |
|
74 { "sync-progress", "chrome://browser/content/sync/progress.xhtml", |
|
75 nsIAboutModule::ALLOW_SCRIPT }, |
|
76 { "sync-tabs", "chrome://browser/content/sync/aboutSyncTabs.xul", |
|
77 nsIAboutModule::ALLOW_SCRIPT }, |
|
78 #endif |
|
79 { "home", "chrome://browser/content/abouthome/aboutHome.xhtml", |
|
80 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | |
|
81 nsIAboutModule::ALLOW_SCRIPT }, |
|
82 { "newtab", "chrome://browser/content/newtab/newTab.xul", |
|
83 nsIAboutModule::ALLOW_SCRIPT }, |
|
84 { "permissions", "chrome://browser/content/preferences/aboutPermissions.xul", |
|
85 nsIAboutModule::ALLOW_SCRIPT }, |
|
86 { "preferences", "chrome://browser/content/preferences/in-content/preferences.xul", |
|
87 nsIAboutModule::ALLOW_SCRIPT }, |
|
88 { "downloads", "chrome://browser/content/downloads/contentAreaDownloadsView.xul", |
|
89 nsIAboutModule::ALLOW_SCRIPT }, |
|
90 #ifdef MOZ_SERVICES_HEALTHREPORT |
|
91 { "healthreport", "chrome://browser/content/abouthealthreport/abouthealth.xhtml", |
|
92 nsIAboutModule::ALLOW_SCRIPT }, |
|
93 #endif |
|
94 { "accounts", "chrome://browser/content/aboutaccounts/aboutaccounts.xhtml", |
|
95 nsIAboutModule::ALLOW_SCRIPT }, |
|
96 { "app-manager", "chrome://browser/content/devtools/app-manager/index.xul", |
|
97 nsIAboutModule::ALLOW_SCRIPT }, |
|
98 { "customizing", "chrome://browser/content/customizableui/aboutCustomizing.xul", |
|
99 nsIAboutModule::ALLOW_SCRIPT }, |
|
100 }; |
|
101 static const int kRedirTotal = ArrayLength(kRedirMap); |
|
102 |
|
103 static nsAutoCString |
|
104 GetAboutModuleName(nsIURI *aURI) |
|
105 { |
|
106 nsAutoCString path; |
|
107 aURI->GetPath(path); |
|
108 |
|
109 int32_t f = path.FindChar('#'); |
|
110 if (f >= 0) |
|
111 path.SetLength(f); |
|
112 |
|
113 f = path.FindChar('?'); |
|
114 if (f >= 0) |
|
115 path.SetLength(f); |
|
116 |
|
117 ToLowerCase(path); |
|
118 return path; |
|
119 } |
|
120 |
|
121 NS_IMETHODIMP |
|
122 AboutRedirector::NewChannel(nsIURI *aURI, nsIChannel **result) |
|
123 { |
|
124 NS_ENSURE_ARG_POINTER(aURI); |
|
125 NS_ASSERTION(result, "must not be null"); |
|
126 |
|
127 nsAutoCString path = GetAboutModuleName(aURI); |
|
128 |
|
129 nsresult rv; |
|
130 nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv); |
|
131 NS_ENSURE_SUCCESS(rv, rv); |
|
132 |
|
133 for (int i = 0; i < kRedirTotal; i++) { |
|
134 if (!strcmp(path.get(), kRedirMap[i].id)) { |
|
135 nsCOMPtr<nsIChannel> tempChannel; |
|
136 rv = ioService->NewChannel(nsDependentCString(kRedirMap[i].url), |
|
137 nullptr, nullptr, getter_AddRefs(tempChannel)); |
|
138 NS_ENSURE_SUCCESS(rv, rv); |
|
139 |
|
140 tempChannel->SetOriginalURI(aURI); |
|
141 |
|
142 NS_ADDREF(*result = tempChannel); |
|
143 return rv; |
|
144 } |
|
145 } |
|
146 |
|
147 return NS_ERROR_ILLEGAL_VALUE; |
|
148 } |
|
149 |
|
150 NS_IMETHODIMP |
|
151 AboutRedirector::GetURIFlags(nsIURI *aURI, uint32_t *result) |
|
152 { |
|
153 NS_ENSURE_ARG_POINTER(aURI); |
|
154 |
|
155 nsAutoCString name = GetAboutModuleName(aURI); |
|
156 |
|
157 for (int i = 0; i < kRedirTotal; i++) { |
|
158 if (name.Equals(kRedirMap[i].id)) { |
|
159 *result = kRedirMap[i].flags; |
|
160 return NS_OK; |
|
161 } |
|
162 } |
|
163 |
|
164 return NS_ERROR_ILLEGAL_VALUE; |
|
165 } |
|
166 |
|
167 nsresult |
|
168 AboutRedirector::Create(nsISupports *aOuter, REFNSIID aIID, void **result) |
|
169 { |
|
170 AboutRedirector* about = new AboutRedirector(); |
|
171 if (about == nullptr) |
|
172 return NS_ERROR_OUT_OF_MEMORY; |
|
173 NS_ADDREF(about); |
|
174 nsresult rv = about->QueryInterface(aIID, result); |
|
175 NS_RELEASE(about); |
|
176 return rv; |
|
177 } |
|
178 |
|
179 } // namespace browser |
|
180 } // namespace mozilla |