content/base/src/nsContentPolicy.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

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

mercurial