Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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/. */
6 #include "nsContextMenuInfo.h"
8 #include "nsIImageLoadingContent.h"
9 #include "imgLoader.h"
10 #include "nsIDOMDocument.h"
11 #include "nsIDOMHTMLDocument.h"
12 #include "nsIDOMHTMLElement.h"
13 #include "nsIDOMHTMLHtmlElement.h"
14 #include "nsIDOMHTMLAnchorElement.h"
15 #include "nsIDOMHTMLImageElement.h"
16 #include "nsIDOMHTMLAreaElement.h"
17 #include "nsIDOMHTMLLinkElement.h"
18 #include "nsIDOMWindow.h"
19 #include "nsIDOMCSSStyleDeclaration.h"
20 #include "nsIDOMCSSValue.h"
21 #include "nsIDOMCSSPrimitiveValue.h"
22 #include "nsNetUtil.h"
23 #include "nsUnicharUtils.h"
24 #include "nsIDocument.h"
25 #include "nsIPrincipal.h"
26 #include "nsIChannelPolicy.h"
27 #include "nsIContentSecurityPolicy.h"
28 #include "nsIContentPolicy.h"
29 #include "nsAutoPtr.h"
30 #include "imgRequestProxy.h"
31 #include "mozIThirdPartyUtil.h"
33 //*****************************************************************************
34 // class nsContextMenuInfo
35 //*****************************************************************************
37 NS_IMPL_ISUPPORTS(nsContextMenuInfo, nsIContextMenuInfo)
39 nsContextMenuInfo::nsContextMenuInfo()
40 {
41 }
43 nsContextMenuInfo::~nsContextMenuInfo()
44 {
45 }
47 /* readonly attribute nsIDOMEvent mouseEvent; */
48 NS_IMETHODIMP
49 nsContextMenuInfo::GetMouseEvent(nsIDOMEvent **aEvent)
50 {
51 NS_ENSURE_ARG_POINTER(aEvent);
52 NS_IF_ADDREF(*aEvent = mMouseEvent);
53 return NS_OK;
54 }
56 /* readonly attribute nsIDOMNode targetNode; */
57 NS_IMETHODIMP
58 nsContextMenuInfo::GetTargetNode(nsIDOMNode **aNode)
59 {
60 NS_ENSURE_ARG_POINTER(aNode);
61 NS_IF_ADDREF(*aNode = mDOMNode);
62 return NS_OK;
63 }
65 /* readonly attribute AString associatedLink; */
66 NS_IMETHODIMP
67 nsContextMenuInfo::GetAssociatedLink(nsAString& aHRef)
68 {
69 NS_ENSURE_STATE(mAssociatedLink);
70 aHRef.Truncate(0);
72 nsCOMPtr<nsIDOMElement> content(do_QueryInterface(mAssociatedLink));
73 nsAutoString localName;
74 if (content)
75 content->GetLocalName(localName);
77 nsCOMPtr<nsIDOMElement> linkContent;
78 ToLowerCase(localName);
79 if (localName.EqualsLiteral("a") ||
80 localName.EqualsLiteral("area") ||
81 localName.EqualsLiteral("link")) {
82 bool hasAttr;
83 content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
84 if (hasAttr) {
85 linkContent = content;
86 nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(linkContent));
87 if (anchor)
88 anchor->GetHref(aHRef);
89 else {
90 nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(linkContent));
91 if (area)
92 area->GetHref(aHRef);
93 else {
94 nsCOMPtr<nsIDOMHTMLLinkElement> link(do_QueryInterface(linkContent));
95 if (link)
96 link->GetHref(aHRef);
97 }
98 }
99 }
100 }
101 else {
102 nsCOMPtr<nsIDOMNode> curr;
103 mAssociatedLink->GetParentNode(getter_AddRefs(curr));
104 while (curr) {
105 content = do_QueryInterface(curr);
106 if (!content)
107 break;
108 content->GetLocalName(localName);
109 ToLowerCase(localName);
110 if (localName.EqualsLiteral("a")) {
111 bool hasAttr;
112 content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
113 if (hasAttr) {
114 linkContent = content;
115 nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(linkContent));
116 if (anchor)
117 anchor->GetHref(aHRef);
118 }
119 else
120 linkContent = nullptr; // Links can't be nested.
121 break;
122 }
124 nsCOMPtr<nsIDOMNode> temp = curr;
125 temp->GetParentNode(getter_AddRefs(curr));
126 }
127 }
129 return NS_OK;
130 }
132 /* readonly attribute imgIContainer imageContainer; */
133 NS_IMETHODIMP
134 nsContextMenuInfo::GetImageContainer(imgIContainer **aImageContainer)
135 {
136 NS_ENSURE_ARG_POINTER(aImageContainer);
137 NS_ENSURE_STATE(mDOMNode);
139 nsCOMPtr<imgIRequest> request;
140 GetImageRequest(mDOMNode, getter_AddRefs(request));
141 if (request)
142 return request->GetImage(aImageContainer);
144 return NS_ERROR_FAILURE;
145 }
147 /* readonly attribute nsIURI imageSrc; */
148 NS_IMETHODIMP
149 nsContextMenuInfo::GetImageSrc(nsIURI **aURI)
150 {
151 NS_ENSURE_ARG_POINTER(aURI);
152 NS_ENSURE_STATE(mDOMNode);
154 nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(mDOMNode));
155 NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
156 return content->GetCurrentURI(aURI);
157 }
159 /* readonly attribute imgIContainer backgroundImageContainer; */
160 NS_IMETHODIMP
161 nsContextMenuInfo::GetBackgroundImageContainer(imgIContainer **aImageContainer)
162 {
163 NS_ENSURE_ARG_POINTER(aImageContainer);
164 NS_ENSURE_STATE(mDOMNode);
166 nsRefPtr<imgRequestProxy> request;
167 GetBackgroundImageRequest(mDOMNode, getter_AddRefs(request));
168 if (request)
169 return request->GetImage(aImageContainer);
171 return NS_ERROR_FAILURE;
172 }
174 /* readonly attribute nsIURI backgroundImageSrc; */
175 NS_IMETHODIMP
176 nsContextMenuInfo::GetBackgroundImageSrc(nsIURI **aURI)
177 {
178 NS_ENSURE_ARG_POINTER(aURI);
179 NS_ENSURE_STATE(mDOMNode);
181 nsRefPtr<imgRequestProxy> request;
182 GetBackgroundImageRequest(mDOMNode, getter_AddRefs(request));
183 if (request)
184 return request->GetURI(aURI);
186 return NS_ERROR_FAILURE;
187 }
189 //*****************************************************************************
191 nsresult
192 nsContextMenuInfo::GetImageRequest(nsIDOMNode *aDOMNode, imgIRequest **aRequest)
193 {
194 NS_ENSURE_ARG(aDOMNode);
195 NS_ENSURE_ARG_POINTER(aRequest);
197 // Get content
198 nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(aDOMNode));
199 NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
201 return content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
202 aRequest);
203 }
205 bool
206 nsContextMenuInfo::HasBackgroundImage(nsIDOMNode * aDOMNode)
207 {
208 NS_ENSURE_TRUE(aDOMNode, false);
210 nsRefPtr<imgRequestProxy> request;
211 GetBackgroundImageRequest(aDOMNode, getter_AddRefs(request));
213 return (request != nullptr);
214 }
216 nsresult
217 nsContextMenuInfo::GetBackgroundImageRequest(nsIDOMNode *aDOMNode, imgRequestProxy **aRequest)
218 {
220 NS_ENSURE_ARG(aDOMNode);
221 NS_ENSURE_ARG_POINTER(aRequest);
223 nsCOMPtr<nsIDOMNode> domNode = aDOMNode;
225 // special case for the <html> element: if it has no background-image
226 // we'll defer to <body>
227 nsCOMPtr<nsIDOMHTMLHtmlElement> htmlElement = do_QueryInterface(domNode);
228 if (htmlElement) {
229 nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(domNode);
230 nsAutoString nameSpace;
231 element->GetNamespaceURI(nameSpace);
232 if (nameSpace.IsEmpty()) {
233 nsresult rv = GetBackgroundImageRequestInternal(domNode, aRequest);
234 if (NS_SUCCEEDED(rv) && *aRequest)
235 return NS_OK;
237 // no background-image found
238 nsCOMPtr<nsIDOMDocument> document;
239 domNode->GetOwnerDocument(getter_AddRefs(document));
240 nsCOMPtr<nsIDOMHTMLDocument> htmlDocument(do_QueryInterface(document));
241 NS_ENSURE_TRUE(htmlDocument, NS_ERROR_FAILURE);
243 nsCOMPtr<nsIDOMHTMLElement> body;
244 htmlDocument->GetBody(getter_AddRefs(body));
245 domNode = do_QueryInterface(body);
246 NS_ENSURE_TRUE(domNode, NS_ERROR_FAILURE);
247 }
248 }
249 return GetBackgroundImageRequestInternal(domNode, aRequest);
250 }
252 nsresult
253 nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode *aDOMNode, imgRequestProxy **aRequest)
254 {
255 NS_ENSURE_ARG_POINTER(aDOMNode);
257 nsCOMPtr<nsIDOMNode> domNode = aDOMNode;
258 nsCOMPtr<nsIDOMNode> parentNode;
260 nsCOMPtr<nsIDOMDocument> document;
261 domNode->GetOwnerDocument(getter_AddRefs(document));
262 NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
264 nsCOMPtr<nsIDOMWindow> window;
265 document->GetDefaultView(getter_AddRefs(window));
266 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
268 nsCOMPtr<nsIDOMCSSPrimitiveValue> primitiveValue;
269 nsAutoString bgStringValue;
271 // get Content Security Policy to pass to LoadImage
272 nsCOMPtr<nsIDocument> doc(do_QueryInterface(document));
273 nsCOMPtr<nsIPrincipal> principal;
274 nsCOMPtr<nsIChannelPolicy> channelPolicy;
275 nsCOMPtr<nsIContentSecurityPolicy> csp;
276 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
278 principal = doc->NodePrincipal();
279 nsresult rv = principal->GetCsp(getter_AddRefs(csp));
280 NS_ENSURE_SUCCESS(rv, rv);
281 if (csp) {
282 channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
283 channelPolicy->SetContentSecurityPolicy(csp);
284 channelPolicy->SetLoadType(nsIContentPolicy::TYPE_IMAGE);
285 }
287 while (true) {
288 nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(domNode));
289 // bail for the parent node of the root element or null argument
290 if (!domElement)
291 break;
293 nsCOMPtr<nsIDOMCSSStyleDeclaration> computedStyle;
294 window->GetComputedStyle(domElement, EmptyString(),
295 getter_AddRefs(computedStyle));
296 if (computedStyle) {
297 nsCOMPtr<nsIDOMCSSValue> cssValue;
298 computedStyle->GetPropertyCSSValue(NS_LITERAL_STRING("background-image"),
299 getter_AddRefs(cssValue));
300 primitiveValue = do_QueryInterface(cssValue);
301 if (primitiveValue) {
302 primitiveValue->GetStringValue(bgStringValue);
303 if (!bgStringValue.EqualsLiteral("none")) {
304 nsCOMPtr<nsIURI> bgUri;
305 NS_NewURI(getter_AddRefs(bgUri), bgStringValue);
306 NS_ENSURE_TRUE(bgUri, NS_ERROR_FAILURE);
308 nsRefPtr<imgLoader> il = imgLoader::GetInstance();
309 NS_ENSURE_TRUE(il, NS_ERROR_FAILURE);
310 nsCOMPtr<nsIURI> firstPartyIsolationURI;
311 nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc
312 = do_GetService(THIRDPARTYUTIL_CONTRACTID);
313 thirdPartySvc->GetFirstPartyIsolationURI(nullptr, doc,
314 getter_AddRefs(firstPartyIsolationURI));
315 return il->LoadImage(bgUri, firstPartyIsolationURI, nullptr, principal, nullptr,
316 nullptr, nullptr, nsIRequest::LOAD_NORMAL,
317 nullptr, channelPolicy, EmptyString(), aRequest);
318 }
319 }
321 // bail if we encounter non-transparent background-color
322 computedStyle->GetPropertyCSSValue(NS_LITERAL_STRING("background-color"),
323 getter_AddRefs(cssValue));
324 primitiveValue = do_QueryInterface(cssValue);
325 if (primitiveValue) {
326 primitiveValue->GetStringValue(bgStringValue);
327 if (!bgStringValue.EqualsLiteral("transparent"))
328 return NS_ERROR_FAILURE;
329 }
330 }
332 domNode->GetParentNode(getter_AddRefs(parentNode));
333 domNode = parentNode;
334 }
336 return NS_ERROR_FAILURE;
337 }