LCOV - code coverage report
Current view: top level - dom/base - nsContentPolicyUtils.h (source / functions) Hit Total Coverage
Test: output.info Lines: 20 35 57.1 %
Date: 2017-07-14 16:53:18 Functions: 2 4 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       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             : /*
       7             :  * Utility routines for checking content load/process policy settings,
       8             :  * and routines helpful for content policy implementors.
       9             :  *
      10             :  * XXXbz it would be nice if some of this stuff could be out-of-lined in
      11             :  * nsContentUtils.  That would work for almost all the callers...
      12             :  */
      13             : 
      14             : #ifndef __nsContentPolicyUtils_h__
      15             : #define __nsContentPolicyUtils_h__
      16             : 
      17             : #include "nsContentUtils.h"
      18             : #include "nsIContentPolicy.h"
      19             : #include "nsIContent.h"
      20             : #include "nsIScriptSecurityManager.h"
      21             : #include "nsIURI.h"
      22             : #include "nsServiceManagerUtils.h"
      23             : 
      24             : //XXXtw sadly, this makes consumers of nsContentPolicyUtils depend on widget
      25             : #include "nsIDocument.h"
      26             : #include "nsPIDOMWindow.h"
      27             : 
      28             : class nsACString;
      29             : class nsIPrincipal;
      30             : 
      31             : #define NS_CONTENTPOLICY_CONTRACTID   "@mozilla.org/layout/content-policy;1"
      32             : #define NS_CONTENTPOLICY_CATEGORY "content-policy"
      33             : #define NS_SIMPLECONTENTPOLICY_CATEGORY "simple-content-policy"
      34             : #define NS_CONTENTPOLICY_CID                              \
      35             :   {0x0e3afd3d, 0xeb60, 0x4c2b,                            \
      36             :      { 0x96, 0x3b, 0x56, 0xd7, 0xc4, 0x39, 0xf1, 0x24 }}
      37             : 
      38             : /**
      39             :  * Evaluates to true if val is ACCEPT.
      40             :  *
      41             :  * @param val the status returned from shouldProcess/shouldLoad
      42             :  */
      43             : #define NS_CP_ACCEPTED(val) ((val) == nsIContentPolicy::ACCEPT)
      44             : 
      45             : /**
      46             :  * Evaluates to true if val is a REJECT_* status
      47             :  *
      48             :  * @param val the status returned from shouldProcess/shouldLoad
      49             :  */
      50             : #define NS_CP_REJECTED(val) ((val) != nsIContentPolicy::ACCEPT)
      51             : 
      52             : // Offer convenient translations of constants -> const char*
      53             : 
      54             : // convenience macro to reduce some repetative typing...
      55             : // name is the name of a constant from this interface
      56             : #define CASE_RETURN(name)          \
      57             :   case nsIContentPolicy:: name :   \
      58             :     return #name
      59             : 
      60             : /**
      61             :  * Returns a string corresponding to the name of the response constant, or
      62             :  * "<Unknown Response>" if an unknown response value is given.
      63             :  *
      64             :  * The return value is static and must not be freed.
      65             :  *
      66             :  * @param response the response code
      67             :  * @return the name of the given response code
      68             :  */
      69             : inline const char *
      70           0 : NS_CP_ResponseName(int16_t response)
      71             : {
      72           0 :   switch (response) {
      73           0 :     CASE_RETURN( REJECT_REQUEST );
      74           0 :     CASE_RETURN( REJECT_TYPE    );
      75           0 :     CASE_RETURN( REJECT_SERVER  );
      76           0 :     CASE_RETURN( REJECT_OTHER   );
      77           0 :     CASE_RETURN( ACCEPT         );
      78             :   default:
      79           0 :     return "<Unknown Response>";
      80             :   }
      81             : }
      82             : 
      83             : /**
      84             :  * Returns a string corresponding to the name of the content type constant, or
      85             :  * "<Unknown Type>" if an unknown content type value is given.
      86             :  *
      87             :  * The return value is static and must not be freed.
      88             :  *
      89             :  * @param contentType the content type code
      90             :  * @return the name of the given content type code
      91             :  */
      92             : inline const char *
      93             : NS_CP_ContentTypeName(uint32_t contentType)
      94             : {
      95             :   switch (contentType) {
      96             :     CASE_RETURN( TYPE_OTHER                       );
      97             :     CASE_RETURN( TYPE_SCRIPT                      );
      98             :     CASE_RETURN( TYPE_IMAGE                       );
      99             :     CASE_RETURN( TYPE_STYLESHEET                  );
     100             :     CASE_RETURN( TYPE_OBJECT                      );
     101             :     CASE_RETURN( TYPE_DOCUMENT                    );
     102             :     CASE_RETURN( TYPE_SUBDOCUMENT                 );
     103             :     CASE_RETURN( TYPE_REFRESH                     );
     104             :     CASE_RETURN( TYPE_XBL                         );
     105             :     CASE_RETURN( TYPE_PING                        );
     106             :     CASE_RETURN( TYPE_XMLHTTPREQUEST              );
     107             :     CASE_RETURN( TYPE_OBJECT_SUBREQUEST           );
     108             :     CASE_RETURN( TYPE_DTD                         );
     109             :     CASE_RETURN( TYPE_FONT                        );
     110             :     CASE_RETURN( TYPE_MEDIA                       );
     111             :     CASE_RETURN( TYPE_WEBSOCKET                   );
     112             :     CASE_RETURN( TYPE_CSP_REPORT                  );
     113             :     CASE_RETURN( TYPE_XSLT                        );
     114             :     CASE_RETURN( TYPE_BEACON                      );
     115             :     CASE_RETURN( TYPE_FETCH                       );
     116             :     CASE_RETURN( TYPE_IMAGESET                    );
     117             :     CASE_RETURN( TYPE_WEB_MANIFEST                );
     118             :     CASE_RETURN( TYPE_INTERNAL_SCRIPT             );
     119             :     CASE_RETURN( TYPE_INTERNAL_WORKER             );
     120             :     CASE_RETURN( TYPE_INTERNAL_SHARED_WORKER      );
     121             :     CASE_RETURN( TYPE_INTERNAL_EMBED              );
     122             :     CASE_RETURN( TYPE_INTERNAL_OBJECT             );
     123             :     CASE_RETURN( TYPE_INTERNAL_FRAME              );
     124             :     CASE_RETURN( TYPE_INTERNAL_IFRAME             );
     125             :     CASE_RETURN( TYPE_INTERNAL_AUDIO              );
     126             :     CASE_RETURN( TYPE_INTERNAL_VIDEO              );
     127             :     CASE_RETURN( TYPE_INTERNAL_TRACK              );
     128             :     CASE_RETURN( TYPE_INTERNAL_XMLHTTPREQUEST     );
     129             :     CASE_RETURN( TYPE_INTERNAL_EVENTSOURCE        );
     130             :     CASE_RETURN( TYPE_INTERNAL_SERVICE_WORKER     );
     131             :     CASE_RETURN( TYPE_INTERNAL_SCRIPT_PRELOAD     );
     132             :     CASE_RETURN( TYPE_INTERNAL_IMAGE              );
     133             :     CASE_RETURN( TYPE_INTERNAL_IMAGE_PRELOAD      );
     134             :     CASE_RETURN( TYPE_INTERNAL_IMAGE_FAVICON      );
     135             :     CASE_RETURN( TYPE_INTERNAL_STYLESHEET         );
     136             :     CASE_RETURN( TYPE_INTERNAL_STYLESHEET_PRELOAD );
     137             :     CASE_RETURN( TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS );
     138             :    default:
     139             :     return "<Unknown Type>";
     140             :   }
     141             : }
     142             : 
     143             : #undef CASE_RETURN
     144             : 
     145             : /* Passes on parameters from its "caller"'s context. */
     146             : #define CHECK_CONTENT_POLICY(action)                                          \
     147             :   PR_BEGIN_MACRO                                                              \
     148             :     nsCOMPtr<nsIContentPolicy> policy =                                       \
     149             :          do_GetService(NS_CONTENTPOLICY_CONTRACTID);                          \
     150             :     if (!policy)                                                              \
     151             :         return NS_ERROR_FAILURE;                                              \
     152             :                                                                               \
     153             :     return policy-> action (contentType, contentLocation, requestOrigin,      \
     154             :                             context, mimeType, extra, originPrincipal,        \
     155             :                             decision);                                        \
     156             :   PR_END_MACRO
     157             : 
     158             : /* Passes on parameters from its "caller"'s context. */
     159             : #define CHECK_CONTENT_POLICY_WITH_SERVICE(action, _policy)                    \
     160             :   PR_BEGIN_MACRO                                                              \
     161             :     return _policy-> action (contentType, contentLocation, requestOrigin,     \
     162             :                              context, mimeType, extra, originPrincipal,       \
     163             :                              decision);                                       \
     164             :   PR_END_MACRO
     165             : 
     166             : /**
     167             :  * Check whether we can short-circuit this check and bail out.  If not, get the
     168             :  * origin URI to use.
     169             :  *
     170             :  * Note: requestOrigin is scoped outside the PR_BEGIN_MACRO/PR_END_MACRO on
     171             :  * purpose */
     172             : #define CHECK_PRINCIPAL_AND_DATA(action)                                      \
     173             :   nsCOMPtr<nsIURI> requestOrigin;                                             \
     174             :   PR_BEGIN_MACRO                                                              \
     175             :   if (originPrincipal) {                                                      \
     176             :       nsCOMPtr<nsIScriptSecurityManager> secMan = aSecMan;                    \
     177             :       if (!secMan) {                                                          \
     178             :           secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);        \
     179             :       }                                                                       \
     180             :       if (secMan) {                                                           \
     181             :           bool isSystem;                                                      \
     182             :           nsresult rv = secMan->IsSystemPrincipal(originPrincipal,            \
     183             :                                                   &isSystem);                 \
     184             :           NS_ENSURE_SUCCESS(rv, rv);                                          \
     185             :           if (isSystem && contentType != nsIContentPolicy::TYPE_DOCUMENT) {   \
     186             :               *decision = nsIContentPolicy::ACCEPT;                           \
     187             :               nsCOMPtr<nsINode> n = do_QueryInterface(context);               \
     188             :               if (!n) {                                                       \
     189             :                   nsCOMPtr<nsPIDOMWindowOuter> win = do_QueryInterface(context);\
     190             :                   n = win ? win->GetExtantDoc() : nullptr;                    \
     191             :               }                                                               \
     192             :               if (n) {                                                        \
     193             :                   nsIDocument* d = n->OwnerDoc();                             \
     194             :                   if (d->IsLoadedAsData() || d->IsBeingUsedAsImage() ||       \
     195             :                       d->IsResourceDoc()) {                                   \
     196             :                       nsCOMPtr<nsIContentPolicy> dataPolicy =                 \
     197             :                           do_GetService(                                      \
     198             :                               "@mozilla.org/data-document-content-policy;1"); \
     199             :                       if (dataPolicy) {                                       \
     200             :                           nsContentPolicyType externalType =                  \
     201             :                               nsContentUtils::InternalContentPolicyTypeToExternal(contentType);\
     202             :                           dataPolicy-> action (externalType, contentLocation, \
     203             :                                                requestOrigin, context,        \
     204             :                                                mimeType, extra,               \
     205             :                                                originPrincipal, decision);    \
     206             :                       }                                                       \
     207             :                   }                                                           \
     208             :               }                                                               \
     209             :               return NS_OK;                                                   \
     210             :           }                                                                   \
     211             :       }                                                                       \
     212             :       nsresult rv = originPrincipal->GetURI(getter_AddRefs(requestOrigin));   \
     213             :       NS_ENSURE_SUCCESS(rv, rv);                                              \
     214             :   }                                                                           \
     215             :   PR_END_MACRO
     216             : 
     217             : /**
     218             :  * Alias for calling ShouldLoad on the content policy service.  Parameters are
     219             :  * the same as nsIContentPolicy::shouldLoad, except for the originPrincipal
     220             :  * parameter, which should be non-null if possible, and the last two
     221             :  * parameters, which can be used to pass in pointer to some useful services if
     222             :  * the caller already has them.  The origin URI to pass to shouldLoad will be
     223             :  * the URI of originPrincipal, unless originPrincipal is null (in which case a
     224             :  * null origin URI will be passed).
     225             :  */
     226             : inline nsresult
     227         210 : NS_CheckContentLoadPolicy(uint32_t          contentType,
     228             :                           nsIURI           *contentLocation,
     229             :                           nsIPrincipal     *originPrincipal,
     230             :                           nsISupports      *context,
     231             :                           const nsACString &mimeType,
     232             :                           nsISupports      *extra,
     233             :                           int16_t          *decision,
     234             :                           nsIContentPolicy *policyService = nullptr,
     235             :                           nsIScriptSecurityManager* aSecMan = nullptr)
     236             : {
     237         420 :     CHECK_PRINCIPAL_AND_DATA(ShouldLoad);
     238          23 :     if (policyService) {
     239          18 :         CHECK_CONTENT_POLICY_WITH_SERVICE(ShouldLoad, policyService);
     240             :     }
     241           5 :     CHECK_CONTENT_POLICY(ShouldLoad);
     242             : }
     243             : 
     244             : /**
     245             :  * Alias for calling ShouldProcess on the content policy service.  Parameters
     246             :  * are the same as nsIContentPolicy::shouldLoad, except for the originPrincipal
     247             :  * parameter, which should be non-null if possible, and the last two
     248             :  * parameters, which can be used to pass in pointer to some useful services if
     249             :  * the caller already has them.  The origin URI to pass to shouldLoad will be
     250             :  * the URI of originPrincipal, unless originPrincipal is null (in which case a
     251             :  * null origin URI will be passed).
     252             :  */
     253             : inline nsresult
     254           0 : NS_CheckContentProcessPolicy(uint32_t          contentType,
     255             :                              nsIURI           *contentLocation,
     256             :                              nsIPrincipal     *originPrincipal,
     257             :                              nsISupports      *context,
     258             :                              const nsACString &mimeType,
     259             :                              nsISupports      *extra,
     260             :                              int16_t          *decision,
     261             :                              nsIContentPolicy *policyService = nullptr,
     262             :                              nsIScriptSecurityManager* aSecMan = nullptr)
     263             : {
     264           0 :     CHECK_PRINCIPAL_AND_DATA(ShouldProcess);
     265           0 :     if (policyService) {
     266           0 :         CHECK_CONTENT_POLICY_WITH_SERVICE(ShouldProcess, policyService);
     267             :     }
     268           0 :     CHECK_CONTENT_POLICY(ShouldProcess);
     269             : }
     270             : 
     271             : #undef CHECK_CONTENT_POLICY
     272             : #undef CHECK_CONTENT_POLICY_WITH_SERVICE
     273             : 
     274             : /**
     275             :  * Helper function to get an nsIDocShell given a context.
     276             :  * If the context is a document or window, the corresponding docshell will be
     277             :  * returned.
     278             :  * If the context is a non-document DOM node, the docshell of its ownerDocument
     279             :  * will be returned.
     280             :  *
     281             :  * @param aContext the context to find a docshell for (can be null)
     282             :  *
     283             :  * @return a WEAK pointer to the docshell, or nullptr if it could
     284             :  *     not be obtained
     285             :  *
     286             :  * @note  As of this writing, calls to nsIContentPolicy::Should{Load,Process}
     287             :  * for TYPE_DOCUMENT and TYPE_SUBDOCUMENT pass in an aContext that either
     288             :  * points to the frameElement of the window the load is happening in
     289             :  * (in which case NS_CP_GetDocShellFromContext will return the parent of the
     290             :  * docshell the load is happening in), or points to the window the load is
     291             :  * happening in (in which case NS_CP_GetDocShellFromContext will return
     292             :  * the docshell the load is happening in).  It's up to callers to QI aContext
     293             :  * and handle things accordingly if they want the docshell the load is
     294             :  * happening in.  These are somewhat odd semantics, and bug 466687 has been
     295             :  * filed to consider improving them.
     296             :  */
     297             : inline nsIDocShell*
     298          35 : NS_CP_GetDocShellFromContext(nsISupports *aContext)
     299             : {
     300          35 :     if (!aContext) {
     301          13 :         return nullptr;
     302             :     }
     303             : 
     304          44 :     nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(aContext);
     305             : 
     306          22 :     if (!window) {
     307             :         // our context might be a document (which also QIs to nsIDOMNode), so
     308             :         // try that first
     309          36 :         nsCOMPtr<nsIDocument> doc = do_QueryInterface(aContext);
     310          18 :         if (!doc) {
     311             :             // we were not a document after all, get our ownerDocument,
     312             :             // hopefully
     313          20 :             nsCOMPtr<nsIContent> content = do_QueryInterface(aContext);
     314          10 :             if (content) {
     315          10 :                 doc = content->OwnerDoc();
     316             :             }
     317             :         }
     318             : 
     319          18 :         if (doc) {
     320          18 :             if (doc->GetDisplayDocument()) {
     321           0 :                 doc = doc->GetDisplayDocument();
     322             :             }
     323             : 
     324          18 :             window = doc->GetWindow();
     325             :         }
     326             :     }
     327             : 
     328          22 :     if (!window) {
     329           0 :         return nullptr;
     330             :     }
     331             : 
     332          22 :     return window->GetDocShell();
     333             : }
     334             : 
     335             : #endif /* __nsContentPolicyUtils_h__ */

Generated by: LCOV version 1.13