content/base/src/nsContentPolicy.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 // vim: ft=cpp tw=78 sw=4 et ts=8
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 /*
michael@0 8 * Implementation of the "@mozilla.org/layout/content-policy;1" contract.
michael@0 9 */
michael@0 10
michael@0 11 #include "prlog.h"
michael@0 12
michael@0 13 #include "nsISupports.h"
michael@0 14 #include "nsXPCOM.h"
michael@0 15 #include "nsContentPolicyUtils.h"
michael@0 16 #include "nsContentPolicy.h"
michael@0 17 #include "nsIURI.h"
michael@0 18 #include "nsIDOMNode.h"
michael@0 19 #include "nsIDOMWindow.h"
michael@0 20 #include "nsIContent.h"
michael@0 21 #include "nsCOMArray.h"
michael@0 22
michael@0 23 NS_IMPL_ISUPPORTS(nsContentPolicy, nsIContentPolicy)
michael@0 24
michael@0 25 #ifdef PR_LOGGING
michael@0 26 static PRLogModuleInfo* gConPolLog;
michael@0 27 #endif
michael@0 28
michael@0 29 nsresult
michael@0 30 NS_NewContentPolicy(nsIContentPolicy **aResult)
michael@0 31 {
michael@0 32 *aResult = new nsContentPolicy;
michael@0 33 if (!*aResult)
michael@0 34 return NS_ERROR_OUT_OF_MEMORY;
michael@0 35 NS_ADDREF(*aResult);
michael@0 36 return NS_OK;
michael@0 37 }
michael@0 38
michael@0 39 nsContentPolicy::nsContentPolicy()
michael@0 40 : mPolicies(NS_CONTENTPOLICY_CATEGORY)
michael@0 41 {
michael@0 42 #ifdef PR_LOGGING
michael@0 43 if (! gConPolLog) {
michael@0 44 gConPolLog = PR_NewLogModule("nsContentPolicy");
michael@0 45 }
michael@0 46 #endif
michael@0 47 }
michael@0 48
michael@0 49 nsContentPolicy::~nsContentPolicy()
michael@0 50 {
michael@0 51 }
michael@0 52
michael@0 53 #ifdef DEBUG
michael@0 54 #define WARN_IF_URI_UNINITIALIZED(uri,name) \
michael@0 55 PR_BEGIN_MACRO \
michael@0 56 if ((uri)) { \
michael@0 57 nsAutoCString spec; \
michael@0 58 (uri)->GetAsciiSpec(spec); \
michael@0 59 if (spec.IsEmpty()) { \
michael@0 60 NS_WARNING(name " is uninitialized, fix caller"); \
michael@0 61 } \
michael@0 62 } \
michael@0 63 PR_END_MACRO
michael@0 64
michael@0 65 #else // ! defined(DEBUG)
michael@0 66
michael@0 67 #define WARN_IF_URI_UNINITIALIZED(uri,name)
michael@0 68
michael@0 69 #endif // defined(DEBUG)
michael@0 70
michael@0 71 inline nsresult
michael@0 72 nsContentPolicy::CheckPolicy(CPMethod policyMethod,
michael@0 73 uint32_t contentType,
michael@0 74 nsIURI *contentLocation,
michael@0 75 nsIURI *requestingLocation,
michael@0 76 nsISupports *requestingContext,
michael@0 77 const nsACString &mimeType,
michael@0 78 nsISupports *extra,
michael@0 79 nsIPrincipal *requestPrincipal,
michael@0 80 int16_t *decision)
michael@0 81 {
michael@0 82 //sanity-check passed-through parameters
michael@0 83 NS_PRECONDITION(decision, "Null out pointer");
michael@0 84 WARN_IF_URI_UNINITIALIZED(contentLocation, "Request URI");
michael@0 85 WARN_IF_URI_UNINITIALIZED(requestingLocation, "Requesting URI");
michael@0 86
michael@0 87 #ifdef DEBUG
michael@0 88 {
michael@0 89 nsCOMPtr<nsIDOMNode> node(do_QueryInterface(requestingContext));
michael@0 90 nsCOMPtr<nsIDOMWindow> window(do_QueryInterface(requestingContext));
michael@0 91 NS_ASSERTION(!requestingContext || node || window,
michael@0 92 "Context should be a DOM node or a DOM window!");
michael@0 93 }
michael@0 94 #endif
michael@0 95
michael@0 96 /*
michael@0 97 * There might not be a requestinglocation. This can happen for
michael@0 98 * iframes with an image as src. Get the uri from the dom node.
michael@0 99 * See bug 254510
michael@0 100 */
michael@0 101 if (!requestingLocation) {
michael@0 102 nsCOMPtr<nsIDocument> doc;
michael@0 103 nsCOMPtr<nsIContent> node = do_QueryInterface(requestingContext);
michael@0 104 if (node) {
michael@0 105 doc = node->OwnerDoc();
michael@0 106 }
michael@0 107 if (!doc) {
michael@0 108 doc = do_QueryInterface(requestingContext);
michael@0 109 }
michael@0 110 if (doc) {
michael@0 111 requestingLocation = doc->GetDocumentURI();
michael@0 112 }
michael@0 113 }
michael@0 114
michael@0 115 /*
michael@0 116 * Enumerate mPolicies and ask each of them, taking the logical AND of
michael@0 117 * their permissions.
michael@0 118 */
michael@0 119 nsresult rv;
michael@0 120 nsCOMArray<nsIContentPolicy> entries;
michael@0 121 mPolicies.GetEntries(entries);
michael@0 122 int32_t count = entries.Count();
michael@0 123 for (int32_t i = 0; i < count; i++) {
michael@0 124 /* check the appropriate policy */
michael@0 125 rv = (entries[i]->*policyMethod)(contentType, contentLocation,
michael@0 126 requestingLocation, requestingContext,
michael@0 127 mimeType, extra, requestPrincipal,
michael@0 128 decision);
michael@0 129
michael@0 130 if (NS_SUCCEEDED(rv) && NS_CP_REJECTED(*decision)) {
michael@0 131 /* policy says no, no point continuing to check */
michael@0 132 return NS_OK;
michael@0 133 }
michael@0 134 }
michael@0 135
michael@0 136 // everyone returned failure, or no policies: sanitize result
michael@0 137 *decision = nsIContentPolicy::ACCEPT;
michael@0 138 return NS_OK;
michael@0 139 }
michael@0 140
michael@0 141 #ifdef PR_LOGGING
michael@0 142
michael@0 143 //uses the parameters from ShouldXYZ to produce and log a message
michael@0 144 //logType must be a literal string constant
michael@0 145 #define LOG_CHECK(logType) \
michael@0 146 PR_BEGIN_MACRO \
michael@0 147 /* skip all this nonsense if the call failed */ \
michael@0 148 if (NS_SUCCEEDED(rv)) { \
michael@0 149 const char *resultName; \
michael@0 150 if (decision) { \
michael@0 151 resultName = NS_CP_ResponseName(*decision); \
michael@0 152 } else { \
michael@0 153 resultName = "(null ptr)"; \
michael@0 154 } \
michael@0 155 nsAutoCString spec("None"); \
michael@0 156 if (contentLocation) { \
michael@0 157 contentLocation->GetSpec(spec); \
michael@0 158 } \
michael@0 159 nsAutoCString refSpec("None"); \
michael@0 160 if (requestingLocation) { \
michael@0 161 requestingLocation->GetSpec(refSpec); \
michael@0 162 } \
michael@0 163 PR_LOG(gConPolLog, PR_LOG_DEBUG, \
michael@0 164 ("Content Policy: " logType ": <%s> <Ref:%s> result=%s", \
michael@0 165 spec.get(), refSpec.get(), resultName) \
michael@0 166 ); \
michael@0 167 } \
michael@0 168 PR_END_MACRO
michael@0 169
michael@0 170 #else //!defined(PR_LOGGING)
michael@0 171
michael@0 172 #define LOG_CHECK(logType)
michael@0 173
michael@0 174 #endif //!defined(PR_LOGGING)
michael@0 175
michael@0 176 NS_IMETHODIMP
michael@0 177 nsContentPolicy::ShouldLoad(uint32_t contentType,
michael@0 178 nsIURI *contentLocation,
michael@0 179 nsIURI *requestingLocation,
michael@0 180 nsISupports *requestingContext,
michael@0 181 const nsACString &mimeType,
michael@0 182 nsISupports *extra,
michael@0 183 nsIPrincipal *requestPrincipal,
michael@0 184 int16_t *decision)
michael@0 185 {
michael@0 186 // ShouldProcess does not need a content location, but we do
michael@0 187 NS_PRECONDITION(contentLocation, "Must provide request location");
michael@0 188 nsresult rv = CheckPolicy(&nsIContentPolicy::ShouldLoad, contentType,
michael@0 189 contentLocation, requestingLocation,
michael@0 190 requestingContext, mimeType, extra,
michael@0 191 requestPrincipal, decision);
michael@0 192 LOG_CHECK("ShouldLoad");
michael@0 193
michael@0 194 return rv;
michael@0 195 }
michael@0 196
michael@0 197 NS_IMETHODIMP
michael@0 198 nsContentPolicy::ShouldProcess(uint32_t contentType,
michael@0 199 nsIURI *contentLocation,
michael@0 200 nsIURI *requestingLocation,
michael@0 201 nsISupports *requestingContext,
michael@0 202 const nsACString &mimeType,
michael@0 203 nsISupports *extra,
michael@0 204 nsIPrincipal *requestPrincipal,
michael@0 205 int16_t *decision)
michael@0 206 {
michael@0 207 nsresult rv = CheckPolicy(&nsIContentPolicy::ShouldProcess, contentType,
michael@0 208 contentLocation, requestingLocation,
michael@0 209 requestingContext, mimeType, extra,
michael@0 210 requestPrincipal, decision);
michael@0 211 LOG_CHECK("ShouldProcess");
michael@0 212
michael@0 213 return rv;
michael@0 214 }

mercurial