Changeset 196350 in webkit


Ignore:
Timestamp:
Feb 9, 2016 5:21:18 PM (8 years ago)
Author:
dbates@webkit.org
Message:

CSP: Extract helper classes into their own files
https://bugs.webkit.org/show_bug.cgi?id=154040
<rdar://problem/24571189>

Reviewed by Brent Fulgham.

No functionality was changed. So, no new tests.

  • CMakeLists.txt: Add files ContentSecurityPolicy{DirectiveList, MediaListDirective, Source, SourceList, SourceListDirective}.cpp.
  • WebCore.xcodeproj/project.pbxproj: Ditto.
  • page/csp/ContentSecurityPolicy.cpp: Clean up #includes. Include header ParsingUtilities.h so that we can remove our own

variants of skip{Exactly, Until, While}(). Update code as necessary for class renames.
(WebCore::skipExactly): Deleted; instead use the analogous function in ParsingUtilities.h.
(WebCore::skipUntil): Deleted; instead use the analogous function in ParsingUtilities.h.
(WebCore::skipWhile): Deleted; instead use the analogous function in ParsingUtilities.h.
(WebCore::isSourceListNone): Moved to file ContentSecurityPolicySourceList.cpp.
(WebCore::CSPSource): Deleted; moved implementation to files ContentSecurityPolicySource.{cpp, h}.
(WebCore::CSPSourceList): Deleted; moved implementation to files ContentSecurityPolicySourceList.{cpp, h}.
(WebCore::CSPDirective): Deleted; moved implementation to file ContentSecurityPolicyDirective.h.
(WebCore::MediaListDirective): Deleted; moved implementation to files ContentSecurityPolicyMediaListDirective.{cpp, h}.
(WebCore::SourceListDirective): Deleted; moved implementation to files ContentSecurityPolicySourceListDirective.{cpp, h}.
(WebCore::CSPDirectiveList): Deleted; moved implementation to files ContentSecurityPolicyDirectiveList.{cpp, h}.

  • page/csp/ContentSecurityPolicy.h:
  • page/csp/ContentSecurityPolicyDirective.h: Added.
  • page/csp/ContentSecurityPolicyDirectiveList.cpp: Added; removed use of ternary operator where it made the code less readable.

Updated code to make use of the functions defined in ParsingUtilities.h.
(WebCore::isExperimentalDirectiveName): Moved from file ContentSecurityPolicy.cpp.
(WebCore::isCSPDirectiveName): Ditto.
(WebCore::isDirectiveNameCharacter): Ditto.
(WebCore::isDirectiveValueCharacter): Ditto.
(WebCore::isNotASCIISpace): Ditto.

  • page/csp/ContentSecurityPolicyDirectiveList.h: Added.
  • page/csp/ContentSecurityPolicyMediaListDirective.cpp: Added. Updated code to make use of the functions defined in ParsingUtilities.h.

(WebCore::isMediaTypeCharacter): Moved from file ContentSecurityPolicy.cpp.
(WebCore::isNotASCIISpace): Ditto.

  • page/csp/ContentSecurityPolicyMediaListDirective.h: Added.
  • page/csp/ContentSecurityPolicySource.cpp: Added.
  • page/csp/ContentSecurityPolicySource.h: Added.
  • page/csp/ContentSecurityPolicySourceList.cpp: Added. Updated code to make use of the functions defined in ParsingUtilities.h.

(WebCore::isSourceCharacter): Moved from file ContentSecurityPolicy.cpp.
(WebCore::isHostCharacter): Ditto.
(WebCore::isPathComponentCharacter): Ditto.
(WebCore::isSchemeContinuationCharacter): Ditto.
(WebCore::isNotColonOrSlash): Ditto.
(WebCore::isSourceListNone): Ditto.

  • page/csp/ContentSecurityPolicySourceList.h: Added.
  • page/csp/ContentSecurityPolicySourceListDirective.cpp: Added.
  • page/csp/ContentSecurityPolicySourceListDirective.h: Added.
Location:
trunk/Source/WebCore
Files:
11 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/CMakeLists.txt

    r196313 r196350  
    20742074
    20752075    page/csp/ContentSecurityPolicy.cpp
     2076    page/csp/ContentSecurityPolicyDirectiveList.cpp
     2077    page/csp/ContentSecurityPolicyMediaListDirective.cpp
    20762078    page/csp/ContentSecurityPolicyResponseHeaders.cpp
     2079    page/csp/ContentSecurityPolicySource.cpp
     2080    page/csp/ContentSecurityPolicySourceList.cpp
     2081    page/csp/ContentSecurityPolicySourceListDirective.cpp
    20772082
    20782083    page/scrolling/AxisScrollSnapOffsets.cpp
  • trunk/Source/WebCore/ChangeLog

    r196349 r196350  
     12016-02-09  Daniel Bates  <dabates@apple.com>
     2
     3        CSP: Extract helper classes into their own files
     4        https://bugs.webkit.org/show_bug.cgi?id=154040
     5        <rdar://problem/24571189>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        No functionality was changed. So, no new tests.
     10
     11        * CMakeLists.txt: Add files ContentSecurityPolicy{DirectiveList, MediaListDirective, Source, SourceList, SourceListDirective}.cpp.
     12        * WebCore.xcodeproj/project.pbxproj: Ditto.
     13        * page/csp/ContentSecurityPolicy.cpp: Clean up #includes. Include header ParsingUtilities.h so that we can remove our own
     14        variants of skip{Exactly, Until, While}(). Update code as necessary for class renames.
     15        (WebCore::skipExactly): Deleted; instead use the analogous function in ParsingUtilities.h.
     16        (WebCore::skipUntil): Deleted; instead use the analogous function in ParsingUtilities.h.
     17        (WebCore::skipWhile): Deleted; instead use the analogous function in ParsingUtilities.h.
     18        (WebCore::isSourceListNone): Moved to file ContentSecurityPolicySourceList.cpp.
     19        (WebCore::CSPSource): Deleted; moved implementation to files ContentSecurityPolicySource.{cpp, h}.
     20        (WebCore::CSPSourceList): Deleted; moved implementation to files ContentSecurityPolicySourceList.{cpp, h}.
     21        (WebCore::CSPDirective): Deleted; moved implementation to file ContentSecurityPolicyDirective.h.
     22        (WebCore::MediaListDirective): Deleted; moved implementation to files ContentSecurityPolicyMediaListDirective.{cpp, h}.
     23        (WebCore::SourceListDirective): Deleted; moved implementation to files ContentSecurityPolicySourceListDirective.{cpp, h}.
     24        (WebCore::CSPDirectiveList): Deleted; moved implementation to files ContentSecurityPolicyDirectiveList.{cpp, h}.
     25        * page/csp/ContentSecurityPolicy.h:
     26        * page/csp/ContentSecurityPolicyDirective.h: Added.
     27        * page/csp/ContentSecurityPolicyDirectiveList.cpp: Added; removed use of ternary operator where it made the code less readable.
     28        Updated code to make use of the functions defined in ParsingUtilities.h.
     29        (WebCore::isExperimentalDirectiveName): Moved from file ContentSecurityPolicy.cpp.
     30        (WebCore::isCSPDirectiveName): Ditto.
     31        (WebCore::isDirectiveNameCharacter): Ditto.
     32        (WebCore::isDirectiveValueCharacter): Ditto.
     33        (WebCore::isNotASCIISpace): Ditto.
     34        * page/csp/ContentSecurityPolicyDirectiveList.h: Added.
     35        * page/csp/ContentSecurityPolicyMediaListDirective.cpp: Added. Updated code to make use of the functions defined in ParsingUtilities.h.
     36        (WebCore::isMediaTypeCharacter): Moved from file ContentSecurityPolicy.cpp.
     37        (WebCore::isNotASCIISpace): Ditto.
     38        * page/csp/ContentSecurityPolicyMediaListDirective.h: Added.
     39        * page/csp/ContentSecurityPolicySource.cpp: Added.
     40        * page/csp/ContentSecurityPolicySource.h: Added.
     41        * page/csp/ContentSecurityPolicySourceList.cpp: Added. Updated code to make use of the functions defined in ParsingUtilities.h.
     42        (WebCore::isSourceCharacter): Moved from file ContentSecurityPolicy.cpp.
     43        (WebCore::isHostCharacter): Ditto.
     44        (WebCore::isPathComponentCharacter): Ditto.
     45        (WebCore::isSchemeContinuationCharacter): Ditto.
     46        (WebCore::isNotColonOrSlash): Ditto.
     47        (WebCore::isSourceListNone): Ditto.
     48        * page/csp/ContentSecurityPolicySourceList.h: Added.
     49        * page/csp/ContentSecurityPolicySourceListDirective.cpp: Added.
     50        * page/csp/ContentSecurityPolicySourceListDirective.h: Added.
     51
    1522016-02-09  Brady Eidson  <beidson@apple.com>
    253
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r196313 r196350  
    61826182                CE6DADF91C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE6DADF71C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp */; };
    61836183                CE6DADFA1C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = CE6DADF81C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h */; };
     6184                CE799F971C6A46BC0097B518 /* ContentSecurityPolicySourceList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE799F951C6A46BC0097B518 /* ContentSecurityPolicySourceList.cpp */; };
     6185                CE799F981C6A46BC0097B518 /* ContentSecurityPolicySourceList.h in Headers */ = {isa = PBXBuildFile; fileRef = CE799F961C6A46BC0097B518 /* ContentSecurityPolicySourceList.h */; };
     6186                CE799F9B1C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE799F991C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.cpp */; };
     6187                CE799F9C1C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.h in Headers */ = {isa = PBXBuildFile; fileRef = CE799F9A1C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.h */; };
     6188                CE799F9F1C6A4C160097B518 /* ContentSecurityPolicySource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE799F9D1C6A4C160097B518 /* ContentSecurityPolicySource.cpp */; };
     6189                CE799FA01C6A4C160097B518 /* ContentSecurityPolicySource.h in Headers */ = {isa = PBXBuildFile; fileRef = CE799F9E1C6A4C160097B518 /* ContentSecurityPolicySource.h */; };
     6190                CE799FA41C6A503A0097B518 /* ContentSecurityPolicyDirective.h in Headers */ = {isa = PBXBuildFile; fileRef = CE799FA21C6A503A0097B518 /* ContentSecurityPolicyDirective.h */; };
     6191                CE799FA71C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE799FA51C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.cpp */; };
     6192                CE799FA81C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.h in Headers */ = {isa = PBXBuildFile; fileRef = CE799FA61C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.h */; };
     6193                CE799FAB1C6A50660097B518 /* ContentSecurityPolicySourceListDirective.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE799FA91C6A50660097B518 /* ContentSecurityPolicySourceListDirective.cpp */; };
     6194                CE799FAC1C6A50660097B518 /* ContentSecurityPolicySourceListDirective.h in Headers */ = {isa = PBXBuildFile; fileRef = CE799FAA1C6A50660097B518 /* ContentSecurityPolicySourceListDirective.h */; };
    61846195                CE7B2DB31586ABAD0098B3FA /* AlternativeTextUIController.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7B2DAF1586ABAD0098B3FA /* AlternativeTextUIController.h */; settings = {ATTRIBUTES = (Private, ); }; };
    61856196                CE7B2DB41586ABAD0098B3FA /* AlternativeTextUIController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE7B2DB01586ABAD0098B3FA /* AlternativeTextUIController.mm */; };
     
    1413314144                CE6DADF71C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ContentSecurityPolicyResponseHeaders.cpp; path = csp/ContentSecurityPolicyResponseHeaders.cpp; sourceTree = "<group>"; };
    1413414145                CE6DADF81C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContentSecurityPolicyResponseHeaders.h; path = csp/ContentSecurityPolicyResponseHeaders.h; sourceTree = "<group>"; };
     14146                CE799F951C6A46BC0097B518 /* ContentSecurityPolicySourceList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ContentSecurityPolicySourceList.cpp; path = csp/ContentSecurityPolicySourceList.cpp; sourceTree = "<group>"; };
     14147                CE799F961C6A46BC0097B518 /* ContentSecurityPolicySourceList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContentSecurityPolicySourceList.h; path = csp/ContentSecurityPolicySourceList.h; sourceTree = "<group>"; };
     14148                CE799F991C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ContentSecurityPolicyDirectiveList.cpp; path = csp/ContentSecurityPolicyDirectiveList.cpp; sourceTree = "<group>"; };
     14149                CE799F9A1C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContentSecurityPolicyDirectiveList.h; path = csp/ContentSecurityPolicyDirectiveList.h; sourceTree = "<group>"; };
     14150                CE799F9D1C6A4C160097B518 /* ContentSecurityPolicySource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ContentSecurityPolicySource.cpp; path = csp/ContentSecurityPolicySource.cpp; sourceTree = "<group>"; };
     14151                CE799F9E1C6A4C160097B518 /* ContentSecurityPolicySource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContentSecurityPolicySource.h; path = csp/ContentSecurityPolicySource.h; sourceTree = "<group>"; };
     14152                CE799FA21C6A503A0097B518 /* ContentSecurityPolicyDirective.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContentSecurityPolicyDirective.h; path = csp/ContentSecurityPolicyDirective.h; sourceTree = "<group>"; };
     14153                CE799FA51C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ContentSecurityPolicyMediaListDirective.cpp; path = csp/ContentSecurityPolicyMediaListDirective.cpp; sourceTree = "<group>"; };
     14154                CE799FA61C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContentSecurityPolicyMediaListDirective.h; path = csp/ContentSecurityPolicyMediaListDirective.h; sourceTree = "<group>"; };
     14155                CE799FA91C6A50660097B518 /* ContentSecurityPolicySourceListDirective.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ContentSecurityPolicySourceListDirective.cpp; path = csp/ContentSecurityPolicySourceListDirective.cpp; sourceTree = "<group>"; };
     14156                CE799FAA1C6A50660097B518 /* ContentSecurityPolicySourceListDirective.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContentSecurityPolicySourceListDirective.h; path = csp/ContentSecurityPolicySourceListDirective.h; sourceTree = "<group>"; };
    1413514157                CE7B2DAF1586ABAD0098B3FA /* AlternativeTextUIController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlternativeTextUIController.h; sourceTree = "<group>"; };
    1413614158                CE7B2DB01586ABAD0098B3FA /* AlternativeTextUIController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AlternativeTextUIController.mm; sourceTree = "<group>"; };
     
    2302423046                                CE6DADF71C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp */,
    2302523047                                CE6DADF81C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h */,
     23048                                CE799FA21C6A503A0097B518 /* ContentSecurityPolicyDirective.h */,
     23049                                CE799F991C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.cpp */,
     23050                                CE799F9A1C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.h */,
     23051                                CE799FA51C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.cpp */,
     23052                                CE799FA61C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.h */,
     23053                                CE799F9D1C6A4C160097B518 /* ContentSecurityPolicySource.cpp */,
     23054                                CE799F9E1C6A4C160097B518 /* ContentSecurityPolicySource.h */,
     23055                                CE799F951C6A46BC0097B518 /* ContentSecurityPolicySourceList.cpp */,
     23056                                CE799F961C6A46BC0097B518 /* ContentSecurityPolicySourceList.h */,
     23057                                CE799FA91C6A50660097B518 /* ContentSecurityPolicySourceListDirective.cpp */,
     23058                                CE799FAA1C6A50660097B518 /* ContentSecurityPolicySourceListDirective.h */,
    2302623059                        );
    2302723060                        name = csp;
     
    2506525098                                7C93F34E1AA6BF0700A98BAB /* ContentExtensionCompiler.h in Headers */,
    2506625099                                7CFDC57D1AC1D80500E24A57 /* ContentExtensionError.h in Headers */,
    25067                                 CE6DADFA1C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h in Headers */,
    2506825100                                26F0C8981A2E724B002794F8 /* ContentExtensionParser.h in Headers */,
    2506925101                                26F0C89C1A2EC110002794F8 /* ContentExtensionRule.h in Headers */,
     
    2507425106                                A14090FD1AA51E480091191A /* ContentFilterUnblockHandler.h in Headers */,
    2507525107                                97C471DC12F925BD0086354B /* ContentSecurityPolicy.h in Headers */,
     25108                                CE799FA41C6A503A0097B518 /* ContentSecurityPolicyDirective.h in Headers */,
     25109                                CE799F9C1C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.h in Headers */,
     25110                                CE799FA81C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.h in Headers */,
     25111                                CE6DADFA1C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h in Headers */,
     25112                                CE799FA01C6A4C160097B518 /* ContentSecurityPolicySource.h in Headers */,
     25113                                CE799F981C6A46BC0097B518 /* ContentSecurityPolicySourceList.h in Headers */,
     25114                                CE799FAC1C6A50660097B518 /* ContentSecurityPolicySourceListDirective.h in Headers */,
    2507625115                                41D015CA0F4B5C71004A662F /* ContentType.h in Headers */,
    2507725116                                97627B8E14FB3CEE002CDCA1 /* ContextDestructionObserver.h in Headers */,
     
    2898529024                                A14090FB1AA51E1D0091191A /* ContentFilterUnblockHandlerCocoa.mm in Sources */,
    2898629025                                97C471DB12F925BD0086354B /* ContentSecurityPolicy.cpp in Sources */,
     29026                                CE799F9B1C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.cpp in Sources */,
     29027                                CE799FA71C6A50570097B518 /* ContentSecurityPolicyMediaListDirective.cpp in Sources */,
     29028                                CE6DADF91C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp in Sources */,
     29029                                CE799F9F1C6A4C160097B518 /* ContentSecurityPolicySource.cpp in Sources */,
     29030                                CE799F971C6A46BC0097B518 /* ContentSecurityPolicySourceList.cpp in Sources */,
     29031                                CE799FAB1C6A50660097B518 /* ContentSecurityPolicySourceListDirective.cpp in Sources */,
    2898729032                                41D015CB0F4B5C71004A662F /* ContentType.cpp in Sources */,
    2898829033                                97627B8D14FB3CEE002CDCA1 /* ContextDestructionObserver.cpp in Sources */,
     
    3177831823                                A5DEBDA316FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.cpp in Sources */,
    3177931824                                31C0FF240E4CEB6E007D6FE5 /* WebKitTransitionEvent.cpp in Sources */,
    31780                                 CE6DADF91C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp in Sources */,
    3178131825                                0FCF332E0F2B9A25004B6795 /* WebLayer.mm in Sources */,
    3178231826                                0709D78E1AE55554004E42F8 /* WebMediaSessionManager.cpp in Sources */,
  • trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp

    r196242 r196350  
    2828#include "ContentSecurityPolicy.h"
    2929
     30#include "ContentSecurityPolicyDirective.h"
     31#include "ContentSecurityPolicyDirectiveList.h"
     32#include "ContentSecurityPolicySource.h"
     33#include "ContentSecurityPolicySourceList.h"
    3034#include "DOMStringList.h"
    3135#include "Document.h"
     
    3539#include "InspectorInstrumentation.h"
    3640#include "JSMainThreadExecState.h"
     41#include "ParsingUtilities.h"
    3742#include "PingLoader.h"
    3843#include "RuntimeEnabledFeatures.h"
    3944#include "SchemeRegistry.h"
    40 #include "ScriptController.h"
    4145#include "SecurityOrigin.h"
    4246#include "SecurityPolicyViolationEvent.h"
     
    4448#include <inspector/ScriptCallStack.h>
    4549#include <inspector/ScriptCallStackFactory.h>
    46 #include <wtf/HashSet.h>
    47 #include <wtf/NeverDestroyed.h>
    4850#include <wtf/text/TextPosition.h>
    4951
     
    5153
    5254namespace WebCore {
    53 
    54 // Normally WebKit uses "static" for internal linkage, but using "static" for
    55 // these functions causes a compile error because these functions are used as
    56 // template parameters.
    57 namespace {
    58 
    59 bool isDirectiveNameCharacter(UChar c)
    60 {
    61     return isASCIIAlphanumeric(c) || c == '-';
    62 }
    63 
    64 bool isDirectiveValueCharacter(UChar c)
    65 {
    66     return isASCIISpace(c) || (c >= 0x21 && c <= 0x7e); // Whitespace + VCHAR
    67 }
    68 
    69 bool isSourceCharacter(UChar c)
    70 {
    71     return !isASCIISpace(c);
    72 }
    73 
    74 bool isPathComponentCharacter(UChar c)
    75 {
    76     return c != '?' && c != '#';
    77 }
    78 
    79 bool isHostCharacter(UChar c)
    80 {
    81     return isASCIIAlphanumeric(c) || c == '-';
    82 }
    83 
    84 bool isSchemeContinuationCharacter(UChar c)
    85 {
    86     return isASCIIAlphanumeric(c) || c == '+' || c == '-' || c == '.';
    87 }
    88 
    89 bool isNotASCIISpace(UChar c)
    90 {
    91     return !isASCIISpace(c);
    92 }
    93 
    94 bool isNotColonOrSlash(UChar c)
    95 {
    96     return c != ':' && c != '/';
    97 }
    98 
    99 bool isMediaTypeCharacter(UChar c)
    100 {
    101     return !isASCIISpace(c) && c != '/';
    102 }
    103 
    104 // CSP 1.0 Directives
    105 static const char connectSrc[] = "connect-src";
    106 static const char defaultSrc[] = "default-src";
    107 static const char fontSrc[] = "font-src";
    108 static const char frameSrc[] = "frame-src";
    109 static const char imgSrc[] = "img-src";
    110 static const char mediaSrc[] = "media-src";
    111 static const char objectSrc[] = "object-src";
    112 static const char reportURI[] = "report-uri";
    113 static const char sandbox[] = "sandbox";
    114 static const char scriptSrc[] = "script-src";
    115 static const char styleSrc[] = "style-src";
    116 
    117 // CSP 1.1 Directives
    118 static const char baseURI[] = "base-uri";
    119 static const char formAction[] = "form-action";
    120 static const char pluginTypes[] = "plugin-types";
    121 #if ENABLE(CSP_NEXT)
    122 static const char reflectedXSS[] = "reflected-xss";
    123 #endif
    124 
    125 #if ENABLE(CSP_NEXT)
    126 
    127 static inline bool isExperimentalDirectiveName(const String& name)
    128 {
    129     return equalLettersIgnoringASCIICase(name, baseURI)
    130         || equalLettersIgnoringASCIICase(name, formAction)
    131         || equalLettersIgnoringASCIICase(name, pluginTypes)
    132         || equalLettersIgnoringASCIICase(name, reflectedXSS);
    133 }
    134 
    135 #else
    136 
    137 static inline bool isExperimentalDirectiveName(const String&)
    138 {
    139     return false;
    140 }
    141 
    142 #endif
    143 
    144 bool isDirectiveName(const String& name)
    145 {
    146     return equalLettersIgnoringASCIICase(name, connectSrc)
    147         || equalLettersIgnoringASCIICase(name, defaultSrc)
    148         || equalLettersIgnoringASCIICase(name, fontSrc)
    149         || equalLettersIgnoringASCIICase(name, frameSrc)
    150         || equalLettersIgnoringASCIICase(name, imgSrc)
    151         || equalLettersIgnoringASCIICase(name, mediaSrc)
    152         || equalLettersIgnoringASCIICase(name, objectSrc)
    153         || equalLettersIgnoringASCIICase(name, reportURI)
    154         || equalLettersIgnoringASCIICase(name, sandbox)
    155         || equalLettersIgnoringASCIICase(name, scriptSrc)
    156         || equalLettersIgnoringASCIICase(name, styleSrc)
    157         || isExperimentalDirectiveName(name);
    158 }
    159 
    160 } // namespace
    161 
    162 static bool skipExactly(const UChar*& position, const UChar* end, UChar delimiter)
    163 {
    164     if (position < end && *position == delimiter) {
    165         ++position;
    166         return true;
    167     }
    168     return false;
    169 }
    170 
    171 template<bool characterPredicate(UChar)>
    172 static bool skipExactly(const UChar*& position, const UChar* end)
    173 {
    174     if (position < end && characterPredicate(*position)) {
    175         ++position;
    176         return true;
    177     }
    178     return false;
    179 }
    180 
    181 static void skipUntil(const UChar*& position, const UChar* end, UChar delimiter)
    182 {
    183     while (position < end && *position != delimiter)
    184         ++position;
    185 }
    186 
    187 template<bool characterPredicate(UChar)>
    188 static void skipWhile(const UChar*& position, const UChar* end)
    189 {
    190     while (position < end && characterPredicate(*position))
    191         ++position;
    192 }
    193 
    194 static bool isSourceListNone(const String& value)
    195 {
    196     auto characters = StringView(value).upconvertedCharacters();
    197     const UChar* begin = characters;
    198     const UChar* end = characters + value.length();
    199     skipWhile<isASCIISpace>(begin, end);
    200 
    201     const UChar* position = begin;
    202     skipWhile<isSourceCharacter>(position, end);
    203     if (!equalLettersIgnoringASCIICase(begin, position - begin, "'none'"))
    204         return false;
    205 
    206     skipWhile<isASCIISpace>(position, end);
    207     if (position != end)
    208         return false;
    209 
    210     return true;
    211 }
    212 
    213 class CSPSource {
    214 public:
    215     CSPSource(const ContentSecurityPolicy& policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard)
    216         : m_policy(policy)
    217         , m_scheme(scheme)
    218         , m_host(host)
    219         , m_port(port)
    220         , m_path(path)
    221         , m_hostHasWildcard(hostHasWildcard)
    222         , m_portHasWildcard(portHasWildcard)
    223     {
    224     }
    225 
    226     bool matches(const URL& url) const
    227     {
    228         if (!schemeMatches(url))
    229             return false;
    230         if (isSchemeOnly())
    231             return true;
    232         return hostMatches(url) && portMatches(url) && pathMatches(url);
    233     }
    234 
    235 private:
    236     bool schemeMatches(const URL& url) const
    237     {
    238         if (m_scheme.isEmpty())
    239             return m_policy.protocolMatchesSelf(url);
    240         return equalIgnoringASCIICase(url.protocol(), m_scheme);
    241     }
    242 
    243     bool hostMatches(const URL& url) const
    244     {
    245         const String& host = url.host();
    246         if (equalIgnoringASCIICase(host, m_host))
    247             return true;
    248         return m_hostHasWildcard && host.endsWith("." + m_host, false);
    249 
    250     }
    251 
    252     bool pathMatches(const URL& url) const
    253     {
    254         if (m_path.isEmpty())
    255             return true;
    256 
    257         String path = decodeURLEscapeSequences(url.path());
    258 
    259         if (m_path.endsWith("/"))
    260             return path.startsWith(m_path, false);
    261 
    262         return path == m_path;
    263     }
    264 
    265     bool portMatches(const URL& url) const
    266     {
    267         if (m_portHasWildcard)
    268             return true;
    269 
    270         int port = url.port();
    271 
    272         if (port == m_port)
    273             return true;
    274 
    275         if (!port)
    276             return isDefaultPortForProtocol(m_port, url.protocol());
    277 
    278         if (!m_port)
    279             return isDefaultPortForProtocol(port, url.protocol());
    280 
    281         return false;
    282     }
    283 
    284     bool isSchemeOnly() const { return m_host.isEmpty(); }
    285 
    286     const ContentSecurityPolicy& m_policy;
    287     String m_scheme;
    288     String m_host;
    289     int m_port;
    290     String m_path;
    291 
    292     bool m_hostHasWildcard;
    293     bool m_portHasWildcard;
    294 };
    295 
    296 class CSPSourceList {
    297 public:
    298     CSPSourceList(const ContentSecurityPolicy&, const String& directiveName);
    299 
    300     void parse(const String&);
    301     bool matches(const URL&);
    302     bool allowInline() const { return m_allowInline; }
    303     bool allowEval() const { return m_allowEval; }
    304     bool allowSelf() const { return m_allowSelf; }
    305 
    306 private:
    307     void parse(const UChar* begin, const UChar* end);
    308 
    309     bool parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard);
    310     bool parseScheme(const UChar* begin, const UChar* end, String& scheme);
    311     bool parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard);
    312     bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard);
    313     bool parsePath(const UChar* begin, const UChar* end, String& path);
    314 
    315     const ContentSecurityPolicy& m_policy;
    316     Vector<CSPSource> m_list;
    317     String m_directiveName;
    318     bool m_allowSelf { false };
    319     bool m_allowStar { false };
    320     bool m_allowInline { false };
    321     bool m_allowEval { false };
    322 };
    323 
    324 CSPSourceList::CSPSourceList(const ContentSecurityPolicy& policy, const String& directiveName)
    325     : m_policy(policy)
    326     , m_directiveName(directiveName)
    327 {
    328 }
    329 
    330 void CSPSourceList::parse(const String& value)
    331 {
    332     // We represent 'none' as an empty m_list.
    333     if (isSourceListNone(value))
    334         return;
    335     auto characters = StringView(value).upconvertedCharacters();
    336     parse(characters, characters + value.length());
    337 }
    338 
    339 bool CSPSourceList::matches(const URL& url)
    340 {
    341     if (m_allowStar)
    342         return true;
    343 
    344     URL effectiveURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url;
    345 
    346     if (m_allowSelf && m_policy.urlMatchesSelf(effectiveURL))
    347         return true;
    348 
    349     for (auto& entry : m_list) {
    350         if (entry.matches(effectiveURL))
    351             return true;
    352     }
    353 
    354     return false;
    355 }
    356 
    357 // source-list       = *WSP [ source *( 1*WSP source ) *WSP ]
    358 //                   / *WSP "'none'" *WSP
    359 //
    360 void CSPSourceList::parse(const UChar* begin, const UChar* end)
    361 {
    362     const UChar* position = begin;
    363 
    364     while (position < end) {
    365         skipWhile<isASCIISpace>(position, end);
    366         if (position == end)
    367             return;
    368 
    369         const UChar* beginSource = position;
    370         skipWhile<isSourceCharacter>(position, end);
    371 
    372         String scheme, host, path;
    373         int port = 0;
    374         bool hostHasWildcard = false;
    375         bool portHasWildcard = false;
    376 
    377         if (parseSource(beginSource, position, scheme, host, port, path, hostHasWildcard, portHasWildcard)) {
    378             // Wildcard hosts and keyword sources ('self', 'unsafe-inline',
    379             // etc.) aren't stored in m_list, but as attributes on the source
    380             // list itself.
    381             if (scheme.isEmpty() && host.isEmpty())
    382                 continue;
    383             if (isDirectiveName(host))
    384                 m_policy.reportDirectiveAsSourceExpression(m_directiveName, host);
    385             m_list.append(CSPSource(m_policy, scheme, host, port, path, hostHasWildcard, portHasWildcard));
    386         } else
    387             m_policy.reportInvalidSourceExpression(m_directiveName, String(beginSource, position - beginSource));
    388 
    389         ASSERT(position == end || isASCIISpace(*position));
    390      }
    391 }
    392 
    393 // source            = scheme ":"
    394 //                   / ( [ scheme "://" ] host [ port ] [ path ] )
    395 //                   / "'self'"
    396 //
    397 bool CSPSourceList::parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard)
    398 {
    399     if (begin == end)
    400         return false;
    401 
    402     if (equalLettersIgnoringASCIICase(begin, end - begin, "'none'"))
    403         return false;
    404 
    405     if (end - begin == 1 && *begin == '*') {
    406         m_allowStar = true;
    407         return true;
    408     }
    409 
    410     if (equalLettersIgnoringASCIICase(begin, end - begin, "'self'")) {
    411         m_allowSelf = true;
    412         return true;
    413     }
    414 
    415     if (equalLettersIgnoringASCIICase(begin, end - begin, "'unsafe-inline'")) {
    416         m_allowInline = true;
    417         return true;
    418     }
    419 
    420     if (equalLettersIgnoringASCIICase(begin, end - begin, "'unsafe-eval'")) {
    421         m_allowEval = true;
    422         return true;
    423     }
    424 
    425     const UChar* position = begin;
    426     const UChar* beginHost = begin;
    427     const UChar* beginPath = end;
    428     const UChar* beginPort = nullptr;
    429 
    430     skipWhile<isNotColonOrSlash>(position, end);
    431 
    432     if (position == end) {
    433         // host
    434         //     ^
    435         return parseHost(beginHost, position, host, hostHasWildcard);
    436     }
    437 
    438     if (position < end && *position == '/') {
    439         // host/path || host/ || /
    440         //     ^            ^    ^
    441         if (!parseHost(beginHost, position, host, hostHasWildcard)
    442             || !parsePath(position, end, path)
    443             || position != end)
    444             return false;
    445         return true;
    446     }
    447 
    448     if (position < end && *position == ':') {
    449         if (end - position == 1) {
    450             // scheme:
    451             //       ^
    452             return parseScheme(begin, position, scheme);
    453         }
    454 
    455         if (position[1] == '/') {
    456             // scheme://host || scheme://
    457             //       ^                ^
    458             if (!parseScheme(begin, position, scheme)
    459                 || !skipExactly(position, end, ':')
    460                 || !skipExactly(position, end, '/')
    461                 || !skipExactly(position, end, '/'))
    462                 return false;
    463             if (position == end)
    464                 return true;
    465             beginHost = position;
    466             skipWhile<isNotColonOrSlash>(position, end);
    467         }
    468 
    469         if (position < end && *position == ':') {
    470             // host:port || scheme://host:port
    471             //     ^                     ^
    472             beginPort = position;
    473             skipUntil(position, end, '/');
    474         }
    475     }
    476 
    477     if (position < end && *position == '/') {
    478         // scheme://host/path || scheme://host:port/path
    479         //              ^                          ^
    480         if (position == beginHost)
    481             return false;
    482 
    483         beginPath = position;
    484     }
    485 
    486     if (!parseHost(beginHost, beginPort ? beginPort : beginPath, host, hostHasWildcard))
    487         return false;
    488 
    489     if (beginPort) {
    490         if (!parsePort(beginPort, beginPath, port, portHasWildcard))
    491             return false;
    492     } else {
    493         port = 0;
    494     }
    495 
    496     if (beginPath != end) {
    497         if (!parsePath(beginPath, end, path))
    498             return false;
    499     }
    500 
    501     return true;
    502 }
    503 
    504 //                     ; <scheme> production from RFC 3986
    505 // scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
    506 //
    507 bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& scheme)
    508 {
    509     ASSERT(begin <= end);
    510     ASSERT(scheme.isEmpty());
    511 
    512     if (begin == end)
    513         return false;
    514 
    515     const UChar* position = begin;
    516 
    517     if (!skipExactly<isASCIIAlpha>(position, end))
    518         return false;
    519 
    520     skipWhile<isSchemeContinuationCharacter>(position, end);
    521 
    522     if (position != end)
    523         return false;
    524 
    525     scheme = String(begin, end - begin);
    526     return true;
    527 }
    528 
    529 // host              = [ "*." ] 1*host-char *( "." 1*host-char )
    530 //                   / "*"
    531 // host-char         = ALPHA / DIGIT / "-"
    532 //
    533 bool CSPSourceList::parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard)
    534 {
    535     ASSERT(begin <= end);
    536     ASSERT(host.isEmpty());
    537     ASSERT(!hostHasWildcard);
    538 
    539     if (begin == end)
    540         return false;
    541 
    542     const UChar* position = begin;
    543 
    544     if (skipExactly(position, end, '*')) {
    545         hostHasWildcard = true;
    546 
    547         if (position == end)
    548             return true;
    549 
    550         if (!skipExactly(position, end, '.'))
    551             return false;
    552     }
    553 
    554     const UChar* hostBegin = position;
    555 
    556     while (position < end) {
    557         if (!skipExactly<isHostCharacter>(position, end))
    558             return false;
    559 
    560         skipWhile<isHostCharacter>(position, end);
    561 
    562         if (position < end && !skipExactly(position, end, '.'))
    563             return false;
    564     }
    565 
    566     ASSERT(position == end);
    567     host = String(hostBegin, end - hostBegin);
    568     return true;
    569 }
    570 
    571 bool CSPSourceList::parsePath(const UChar* begin, const UChar* end, String& path)
    572 {
    573     ASSERT(begin <= end);
    574     ASSERT(path.isEmpty());
    575 
    576     const UChar* position = begin;
    577     skipWhile<isPathComponentCharacter>(position, end);
    578     // path/to/file.js?query=string || path/to/file.js#anchor
    579     //                ^                               ^
    580     if (position < end)
    581         m_policy.reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position);
    582 
    583     path = decodeURLEscapeSequences(String(begin, position - begin));
    584 
    585     ASSERT(position <= end);
    586     ASSERT(position == end || (*position == '#' || *position == '?'));
    587     return true;
    588 }
    589 
    590 // port              = ":" ( 1*DIGIT / "*" )
    591 //
    592 bool CSPSourceList::parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard)
    593 {
    594     ASSERT(begin <= end);
    595     ASSERT(!port);
    596     ASSERT(!portHasWildcard);
    597 
    598     if (!skipExactly(begin, end, ':'))
    599         ASSERT_NOT_REACHED();
    600 
    601     if (begin == end)
    602         return false;
    603 
    604     if (end - begin == 1 && *begin == '*') {
    605         port = 0;
    606         portHasWildcard = true;
    607         return true;
    608     }
    609 
    610     const UChar* position = begin;
    611     skipWhile<isASCIIDigit>(position, end);
    612 
    613     if (position != end)
    614         return false;
    615 
    616     bool ok;
    617     port = charactersToIntStrict(begin, end - begin, &ok);
    618     return ok;
    619 }
    620 
    621 class CSPDirective {
    622 public:
    623     CSPDirective(const String& name, const String& value, const ContentSecurityPolicy& policy)
    624         : m_name(name)
    625         , m_text(name + ' ' + value)
    626         , m_policy(policy)
    627     {
    628     }
    629 
    630     const String& text() const { return m_text; }
    631 
    632 protected:
    633     const ContentSecurityPolicy& policy() const { return m_policy; }
    634 
    635 private:
    636     String m_name;
    637     String m_text;
    638     const ContentSecurityPolicy& m_policy;
    639 };
    640 
    641 class MediaListDirective : public CSPDirective {
    642 public:
    643     MediaListDirective(const String& name, const String& value, const ContentSecurityPolicy& policy)
    644         : CSPDirective(name, value, policy)
    645     {
    646         parse(value);
    647     }
    648 
    649     bool allows(const String& type)
    650     {
    651         return m_pluginTypes.contains(type);
    652     }
    653 
    654 private:
    655     void parse(const String& value)
    656     {
    657         auto characters = StringView(value).upconvertedCharacters();
    658         const UChar* begin = characters;
    659         const UChar* position = begin;
    660         const UChar* end = begin + value.length();
    661 
    662         // 'plugin-types ____;' OR 'plugin-types;'
    663         if (value.isEmpty()) {
    664             policy().reportInvalidPluginTypes(value);
    665             return;
    666         }
    667 
    668         while (position < end) {
    669             // _____ OR _____mime1/mime1
    670             // ^        ^
    671             skipWhile<isASCIISpace>(position, end);
    672             if (position == end)
    673                 return;
    674 
    675             // mime1/mime1 mime2/mime2
    676             // ^
    677             begin = position;
    678             if (!skipExactly<isMediaTypeCharacter>(position, end)) {
    679                 skipWhile<isNotASCIISpace>(position, end);
    680                 policy().reportInvalidPluginTypes(String(begin, position - begin));
    681                 continue;
    682             }
    683             skipWhile<isMediaTypeCharacter>(position, end);
    684 
    685             // mime1/mime1 mime2/mime2
    686             //      ^
    687             if (!skipExactly(position, end, '/')) {
    688                 skipWhile<isNotASCIISpace>(position, end);
    689                 policy().reportInvalidPluginTypes(String(begin, position - begin));
    690                 continue;
    691             }
    692 
    693             // mime1/mime1 mime2/mime2
    694             //       ^
    695             if (!skipExactly<isMediaTypeCharacter>(position, end)) {
    696                 skipWhile<isNotASCIISpace>(position, end);
    697                 policy().reportInvalidPluginTypes(String(begin, position - begin));
    698                 continue;
    699             }
    700             skipWhile<isMediaTypeCharacter>(position, end);
    701 
    702             // mime1/mime1 mime2/mime2 OR mime1/mime1  OR mime1/mime1/error
    703             //            ^                          ^               ^
    704             if (position < end && isNotASCIISpace(*position)) {
    705                 skipWhile<isNotASCIISpace>(position, end);
    706                 policy().reportInvalidPluginTypes(String(begin, position - begin));
    707                 continue;
    708             }
    709             m_pluginTypes.add(String(begin, position - begin));
    710 
    711             ASSERT(position == end || isASCIISpace(*position));
    712         }
    713     }
    714 
    715     HashSet<String> m_pluginTypes;
    716 };
    717 
    718 class SourceListDirective : public CSPDirective {
    719 public:
    720     SourceListDirective(const String& name, const String& value, const ContentSecurityPolicy& policy)
    721         : CSPDirective(name, value, policy)
    722         , m_sourceList(policy, name)
    723     {
    724         m_sourceList.parse(value);
    725     }
    726 
    727     bool allows(const URL& url)
    728     {
    729         // FIXME: We should investigate returning false for an empty URL.
    730         if (url.isEmpty())
    731             return m_sourceList.allowSelf();
    732         return m_sourceList.matches(url);
    733     }
    734 
    735     bool allowInline() const { return m_sourceList.allowInline(); }
    736     bool allowEval() const { return m_sourceList.allowEval(); }
    737 
    738 private:
    739     CSPSourceList m_sourceList;
    740 };
    741 
    742 class CSPDirectiveList {
    743     WTF_MAKE_FAST_ALLOCATED;
    744 public:
    745     static std::unique_ptr<CSPDirectiveList> create(ContentSecurityPolicy&, const String&, ContentSecurityPolicyHeaderType);
    746     CSPDirectiveList(ContentSecurityPolicy&, ContentSecurityPolicyHeaderType);
    747 
    748     const String& header() const { return m_header; }
    749     ContentSecurityPolicyHeaderType headerType() const { return m_headerType; }
    750 
    751     bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
    752     bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
    753     bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
    754     bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
    755     bool allowEval(JSC::ExecState*, ContentSecurityPolicy::ReportingStatus) const;
    756     bool allowPluginType(const String& type, const String& typeAttribute, const URL&, ContentSecurityPolicy::ReportingStatus) const;
    757 
    758     bool allowScriptFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
    759     bool allowObjectFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
    760     bool allowChildFrameFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
    761     bool allowImageFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
    762     bool allowStyleFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
    763     bool allowFontFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
    764     bool allowMediaFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
    765     bool allowConnectToSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
    766     bool allowFormAction(const URL&, ContentSecurityPolicy::ReportingStatus) const;
    767     bool allowBaseURI(const URL&, ContentSecurityPolicy::ReportingStatus) const;
    768 
    769     const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
    770     ContentSecurityPolicy::ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflectedXSSDisposition; }
    771     bool isReportOnly() const { return m_reportOnly; }
    772     const Vector<String>& reportURIs() const { return m_reportURIs; }
    773 
    774 private:
    775     void parse(const String&);
    776 
    777     bool parseDirective(const UChar* begin, const UChar* end, String& name, String& value);
    778     void parseReportURI(const String& name, const String& value);
    779     void parsePluginTypes(const String& name, const String& value);
    780     void parseReflectedXSS(const String& name, const String& value);
    781     void addDirective(const String& name, const String& value);
    782     void applySandboxPolicy(const String& name, const String& sandboxPolicy);
    783 
    784     template <class CSPDirectiveType>
    785     void setCSPDirective(const String& name, const String& value, std::unique_ptr<CSPDirectiveType>&);
    786 
    787     SourceListDirective* operativeDirective(SourceListDirective*) const;
    788     void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL = URL(), const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const;
    789 
    790     bool checkEval(SourceListDirective*) const;
    791     bool checkInline(SourceListDirective*) const;
    792     bool checkSource(SourceListDirective*, const URL&) const;
    793     bool checkMediaType(MediaListDirective*, const String& type, const String& typeAttribute) const;
    794 
    795     void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisabledErrorMessage = errorMessage; }
    796 
    797     bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const;
    798     bool checkInlineAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const;
    799 
    800     bool checkSourceAndReportViolation(SourceListDirective*, const URL&, const String& effectiveDirective) const;
    801     bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& type, const String& typeAttribute, const String& consoleMessage) const;
    802 
    803     bool denyIfEnforcingPolicy() const { return m_reportOnly; }
    804 
    805     // FIXME: Make this a const reference once we teach applySandboxPolicy() to store its policy as opposed to applying it directly onto ContentSecurityPolicy.
    806     ContentSecurityPolicy& m_policy;
    807 
    808     String m_header;
    809     ContentSecurityPolicyHeaderType m_headerType;
    810 
    811     bool m_reportOnly;
    812     bool m_haveSandboxPolicy;
    813     ContentSecurityPolicy::ReflectedXSSDisposition m_reflectedXSSDisposition;
    814 
    815     std::unique_ptr<MediaListDirective> m_pluginTypes;
    816     std::unique_ptr<SourceListDirective> m_baseURI;
    817     std::unique_ptr<SourceListDirective> m_connectSrc;
    818     std::unique_ptr<SourceListDirective> m_defaultSrc;
    819     std::unique_ptr<SourceListDirective> m_fontSrc;
    820     std::unique_ptr<SourceListDirective> m_formAction;
    821     std::unique_ptr<SourceListDirective> m_frameSrc;
    822     std::unique_ptr<SourceListDirective> m_imgSrc;
    823     std::unique_ptr<SourceListDirective> m_mediaSrc;
    824     std::unique_ptr<SourceListDirective> m_objectSrc;
    825     std::unique_ptr<SourceListDirective> m_scriptSrc;
    826     std::unique_ptr<SourceListDirective> m_styleSrc;
    827 
    828     Vector<String> m_reportURIs;
    829 
    830     String m_evalDisabledErrorMessage;
    831 };
    832 
    833 CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy& policy, ContentSecurityPolicyHeaderType type)
    834     : m_policy(policy)
    835     , m_headerType(type)
    836     , m_reportOnly(false)
    837     , m_haveSandboxPolicy(false)
    838     , m_reflectedXSSDisposition(ContentSecurityPolicy::ReflectedXSSUnset)
    839 {
    840     m_reportOnly = (type == ContentSecurityPolicyHeaderType::Report || type == ContentSecurityPolicyHeaderType::PrefixedReport);
    841 }
    842 
    843 std::unique_ptr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy& policy, const String& header, ContentSecurityPolicyHeaderType type)
    844 {
    845     auto directives = std::make_unique<CSPDirectiveList>(policy, type);
    846     directives->parse(header);
    847 
    848     if (!directives->checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) {
    849         String message = makeString("Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"", directives->operativeDirective(directives->m_scriptSrc.get())->text(), "\".\n");
    850         directives->setEvalDisabledErrorMessage(message);
    851     }
    852 
    853     if (directives->isReportOnly() && directives->reportURIs().isEmpty())
    854         policy.reportMissingReportURI(header);
    855 
    856     return directives;
    857 }
    858 
    859 void CSPDirectiveList::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
    860 {
    861     String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
    862     m_policy.reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine, state);
    863 }
    864 
    865 bool CSPDirectiveList::checkEval(SourceListDirective* directive) const
    866 {
    867     return !directive || directive->allowEval();
    868 }
    869 
    870 bool CSPDirectiveList::checkInline(SourceListDirective* directive) const
    871 {
    872     return !directive || directive->allowInline();
    873 }
    874 
    875 bool CSPDirectiveList::checkSource(SourceListDirective* directive, const URL& url) const
    876 {
    877     return !directive || directive->allows(url);
    878 }
    879 
    880 bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const
    881 {
    882     if (!directive)
    883         return true;
    884     if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
    885         return false;
    886     return directive->allows(type);
    887 }
    888 
    889 SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive) const
    890 {
    891     return directive ? directive : m_defaultSrc.get();
    892 }
    893 
    894 bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
    895 {
    896     if (checkEval(directive))
    897         return true;
    898 
    899     String suffix = String();
    900     if (directive == m_defaultSrc.get())
    901         suffix = " Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.";
    902 
    903     reportViolation(directive->text(), scriptSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", URL(), contextURL, contextLine, state);
    904     if (!m_reportOnly) {
    905         m_policy.reportBlockedScriptExecutionToInspector(directive->text());
    906         return false;
    907     }
    908     return true;
    909 }
    910 
    911 bool CSPDirectiveList::checkMediaTypeAndReportViolation(MediaListDirective* directive, const String& type, const String& typeAttribute, const String& consoleMessage) const
    912 {
    913     if (checkMediaType(directive, type, typeAttribute))
    914         return true;
    915 
    916     String message = makeString(consoleMessage, '\'', directive->text(), "\'.");
    917     if (typeAttribute.isEmpty())
    918         message = message + " When enforcing the 'plugin-types' directive, the plugin's media type must be explicitly declared with a 'type' attribute on the containing element (e.g. '<object type=\"[TYPE GOES HERE]\" ...>').";
    919 
    920     reportViolation(directive->text(), pluginTypes, message + "\n", URL());
    921     return denyIfEnforcingPolicy();
    922 }
    923 
    924 bool CSPDirectiveList::checkInlineAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const
    925 {
    926     if (checkInline(directive))
    927         return true;
    928 
    929     String suffix = String();
    930     if (directive == m_defaultSrc.get())
    931         suffix = makeString(" Note that '", (isScript ? "script" : "style"), "-src' was not explicitly set, so 'default-src' is used as a fallback.");
    932 
    933     reportViolation(directive->text(), isScript ? scriptSrc : styleSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", URL(), contextURL, contextLine);
    934 
    935     if (!m_reportOnly) {
    936         if (isScript)
    937             m_policy.reportBlockedScriptExecutionToInspector(directive->text());
    938         return false;
    939     }
    940     return true;
    941 }
    942 
    943 bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* directive, const URL& url, const String& effectiveDirective) const
    944 {
    945     if (checkSource(directive, url))
    946         return true;
    947 
    948     const char* prefix;
    949     if (baseURI == effectiveDirective)
    950         prefix = "Refused to set the document's base URI to '";
    951     else if (connectSrc == effectiveDirective)
    952         prefix = "Refused to connect to '";
    953     else if (fontSrc == effectiveDirective)
    954         prefix = "Refused to load the font '";
    955     else if (formAction == effectiveDirective)
    956         prefix = "Refused to send form data to '";
    957     else if (frameSrc == effectiveDirective)
    958         prefix = "Refused to load frame '";
    959     else if (imgSrc == effectiveDirective)
    960         prefix = "Refused to load the image '";
    961     else if (mediaSrc == effectiveDirective)
    962         prefix = "Refused to load media from '";
    963     else if (objectSrc == effectiveDirective)
    964         prefix = "Refused to load plugin data from '";
    965     else if (scriptSrc == effectiveDirective)
    966         prefix = "Refused to load the script '";
    967     else if (styleSrc == effectiveDirective)
    968         prefix = "Refused to load the stylesheet '";
    969     else
    970         prefix = "";
    971 
    972     String suffix;
    973     if (directive == m_defaultSrc.get())
    974         suffix = " Note that '" + effectiveDirective + "' was not explicitly set, so 'default-src' is used as a fallback.";
    975 
    976     reportViolation(directive->text(), effectiveDirective, makeString(prefix, url.stringCenterEllipsizedToLength(), "' because it violates the following Content Security Policy directive: \"", directive->text(), "\".", suffix, '\n'), url);
    977     return denyIfEnforcingPolicy();
    978 }
    979 
    980 bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    981 {
    982     static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "));
    983     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    984         checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true)
    985         : (m_reportOnly || checkInline(operativeDirective(m_scriptSrc.get())));
    986 }
    987 
    988 bool CSPDirectiveList::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    989 {
    990     static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to execute inline event handler because it violates the following Content Security Policy directive: "));
    991     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    992         checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true)
    993         : (m_reportOnly || checkInline(operativeDirective(m_scriptSrc.get())));
    994 }
    995 
    996 bool CSPDirectiveList::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    997 {
    998     static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to execute inline script because it violates the following Content Security Policy directive: "));
    999     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1000         checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true) :
    1001         (m_reportOnly || checkInline(operativeDirective(m_scriptSrc.get())));
    1002 }
    1003 
    1004 bool CSPDirectiveList::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1005 {
    1006     static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to apply inline style because it violates the following Content Security Policy directive: "));
    1007     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1008         checkInlineAndReportViolation(operativeDirective(m_styleSrc.get()), consoleMessage, contextURL, contextLine, false) :
    1009         (m_reportOnly || checkInline(operativeDirective(m_styleSrc.get())));
    1010 }
    1011 
    1012 bool CSPDirectiveList::allowEval(JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1013 {
    1014     static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to evaluate script because it violates the following Content Security Policy directive: "));
    1015     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1016         checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, String(), WTF::OrdinalNumber::beforeFirst(), state) :
    1017         (m_reportOnly || checkEval(operativeDirective(m_scriptSrc.get())));
    1018 }
    1019 
    1020 bool CSPDirectiveList::allowPluginType(const String& type, const String& typeAttribute, const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1021 {
    1022     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1023         checkMediaTypeAndReportViolation(m_pluginTypes.get(), type, typeAttribute, "Refused to load '" + url.stringCenterEllipsizedToLength() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ") :
    1024         (m_reportOnly || checkMediaType(m_pluginTypes.get(), type, typeAttribute));
    1025 }
    1026 
    1027 bool CSPDirectiveList::allowScriptFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1028 {
    1029     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1030         checkSourceAndReportViolation(operativeDirective(m_scriptSrc.get()), url, scriptSrc) :
    1031         (m_reportOnly || checkSource(operativeDirective(m_scriptSrc.get()), url));
    1032 }
    1033 
    1034 bool CSPDirectiveList::allowObjectFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1035 {
    1036     if (url.isBlankURL())
    1037         return true;
    1038     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1039         checkSourceAndReportViolation(operativeDirective(m_objectSrc.get()), url, objectSrc) :
    1040         (m_reportOnly || checkSource(operativeDirective(m_objectSrc.get()), url));
    1041 }
    1042 
    1043 bool CSPDirectiveList::allowChildFrameFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1044 {
    1045     if (url.isBlankURL())
    1046         return true;
    1047     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1048         checkSourceAndReportViolation(operativeDirective(m_frameSrc.get()), url, frameSrc) :
    1049         (m_reportOnly || checkSource(operativeDirective(m_frameSrc.get()), url));
    1050 }
    1051 
    1052 bool CSPDirectiveList::allowImageFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1053 {
    1054     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1055         checkSourceAndReportViolation(operativeDirective(m_imgSrc.get()), url, imgSrc) :
    1056         (m_reportOnly || checkSource(operativeDirective(m_imgSrc.get()), url));
    1057 }
    1058 
    1059 bool CSPDirectiveList::allowStyleFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1060 {
    1061     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1062         checkSourceAndReportViolation(operativeDirective(m_styleSrc.get()), url, styleSrc) :
    1063         (m_reportOnly || checkSource(operativeDirective(m_styleSrc.get()), url));
    1064 }
    1065 
    1066 bool CSPDirectiveList::allowFontFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1067 {
    1068     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1069         checkSourceAndReportViolation(operativeDirective(m_fontSrc.get()), url, fontSrc) :
    1070         (m_reportOnly || checkSource(operativeDirective(m_fontSrc.get()), url));
    1071 }
    1072 
    1073 bool CSPDirectiveList::allowMediaFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1074 {
    1075     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1076         checkSourceAndReportViolation(operativeDirective(m_mediaSrc.get()), url, mediaSrc) :
    1077         (m_reportOnly || checkSource(operativeDirective(m_mediaSrc.get()), url));
    1078 }
    1079 
    1080 bool CSPDirectiveList::allowConnectToSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1081 {
    1082     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1083         checkSourceAndReportViolation(operativeDirective(m_connectSrc.get()), url, connectSrc) :
    1084         (m_reportOnly || checkSource(operativeDirective(m_connectSrc.get()), url));
    1085 }
    1086 
    1087 bool CSPDirectiveList::allowFormAction(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1088 {
    1089     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1090         checkSourceAndReportViolation(m_formAction.get(), url, formAction) :
    1091         (m_reportOnly || checkSource(m_formAction.get(), url));
    1092 }
    1093 
    1094 bool CSPDirectiveList::allowBaseURI(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1095 {
    1096     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
    1097         checkSourceAndReportViolation(m_baseURI.get(), url, baseURI) :
    1098         (m_reportOnly || checkSource(m_baseURI.get(), url));
    1099 }
    1100 
    1101 // policy            = directive-list
    1102 // directive-list    = [ directive *( ";" [ directive ] ) ]
    1103 //
    1104 void CSPDirectiveList::parse(const String& policy)
    1105 {
    1106     m_header = policy;
    1107     if (policy.isEmpty())
    1108         return;
    1109 
    1110     auto characters = StringView(policy).upconvertedCharacters();
    1111     const UChar* position = characters;
    1112     const UChar* end = position + policy.length();
    1113 
    1114     while (position < end) {
    1115         const UChar* directiveBegin = position;
    1116         skipUntil(position, end, ';');
    1117 
    1118         String name, value;
    1119         if (parseDirective(directiveBegin, position, name, value)) {
    1120             ASSERT(!name.isEmpty());
    1121             addDirective(name, value);
    1122         }
    1123 
    1124         ASSERT(position == end || *position == ';');
    1125         skipExactly(position, end, ';');
    1126     }
    1127 }
    1128 
    1129 // directive         = *WSP [ directive-name [ WSP directive-value ] ]
    1130 // directive-name    = 1*( ALPHA / DIGIT / "-" )
    1131 // directive-value   = *( WSP / <VCHAR except ";"> )
    1132 //
    1133 bool CSPDirectiveList::parseDirective(const UChar* begin, const UChar* end, String& name, String& value)
    1134 {
    1135     ASSERT(name.isEmpty());
    1136     ASSERT(value.isEmpty());
    1137 
    1138     const UChar* position = begin;
    1139     skipWhile<isASCIISpace>(position, end);
    1140 
    1141     // Empty directive (e.g. ";;;"). Exit early.
    1142     if (position == end)
    1143         return false;
    1144 
    1145     const UChar* nameBegin = position;
    1146     skipWhile<isDirectiveNameCharacter>(position, end);
    1147 
    1148     // The directive-name must be non-empty.
    1149     if (nameBegin == position) {
    1150         skipWhile<isNotASCIISpace>(position, end);
    1151         m_policy.reportUnsupportedDirective(String(nameBegin, position - nameBegin));
    1152         return false;
    1153     }
    1154 
    1155     name = String(nameBegin, position - nameBegin);
    1156 
    1157     if (position == end)
    1158         return true;
    1159 
    1160     if (!skipExactly<isASCIISpace>(position, end)) {
    1161         skipWhile<isNotASCIISpace>(position, end);
    1162         m_policy.reportUnsupportedDirective(String(nameBegin, position - nameBegin));
    1163         return false;
    1164     }
    1165 
    1166     skipWhile<isASCIISpace>(position, end);
    1167 
    1168     const UChar* valueBegin = position;
    1169     skipWhile<isDirectiveValueCharacter>(position, end);
    1170 
    1171     if (position != end) {
    1172         m_policy.reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
    1173         return false;
    1174     }
    1175 
    1176     // The directive-value may be empty.
    1177     if (valueBegin == position)
    1178         return true;
    1179 
    1180     value = String(valueBegin, position - valueBegin);
    1181     return true;
    1182 }
    1183 
    1184 void CSPDirectiveList::parseReportURI(const String& name, const String& value)
    1185 {
    1186     if (!m_reportURIs.isEmpty()) {
    1187         m_policy.reportDuplicateDirective(name);
    1188         return;
    1189     }
    1190 
    1191     auto characters = StringView(value).upconvertedCharacters();
    1192     const UChar* position = characters;
    1193     const UChar* end = position + value.length();
    1194 
    1195     while (position < end) {
    1196         skipWhile<isASCIISpace>(position, end);
    1197 
    1198         const UChar* urlBegin = position;
    1199         skipWhile<isNotASCIISpace>(position, end);
    1200 
    1201         if (urlBegin < position)
    1202             m_reportURIs.append(value.substring(urlBegin - characters, position - urlBegin));
    1203     }
    1204 }
    1205 
    1206 
    1207 template<class CSPDirectiveType>
    1208 void CSPDirectiveList::setCSPDirective(const String& name, const String& value, std::unique_ptr<CSPDirectiveType>& directive)
    1209 {
    1210     if (directive) {
    1211         m_policy.reportDuplicateDirective(name);
    1212         return;
    1213     }
    1214     directive = std::make_unique<CSPDirectiveType>(name, value, m_policy);
    1215 }
    1216 
    1217 void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sandboxPolicy)
    1218 {
    1219     if (m_haveSandboxPolicy) {
    1220         m_policy.reportDuplicateDirective(name);
    1221         return;
    1222     }
    1223     m_haveSandboxPolicy = true;
    1224     String invalidTokens;
    1225     m_policy.enforceSandboxFlags(SecurityContext::parseSandboxPolicy(sandboxPolicy, invalidTokens));
    1226     if (!invalidTokens.isNull())
    1227         m_policy.reportInvalidSandboxFlags(invalidTokens);
    1228 }
    1229 
    1230 void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value)
    1231 {
    1232     if (m_reflectedXSSDisposition != ContentSecurityPolicy::ReflectedXSSUnset) {
    1233         m_policy.reportDuplicateDirective(name);
    1234         m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
    1235         return;
    1236     }
    1237 
    1238     if (value.isEmpty()) {
    1239         m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
    1240         m_policy.reportInvalidReflectedXSS(value);
    1241         return;
    1242     }
    1243 
    1244     auto characters = StringView(value).upconvertedCharacters();
    1245     const UChar* position = characters;
    1246     const UChar* end = position + value.length();
    1247 
    1248     skipWhile<isASCIISpace>(position, end);
    1249     const UChar* begin = position;
    1250     skipWhile<isNotASCIISpace>(position, end);
    1251 
    1252     // value1
    1253     //       ^
    1254     if (equalLettersIgnoringASCIICase(begin, position - begin, "allow"))
    1255         m_reflectedXSSDisposition = ContentSecurityPolicy::AllowReflectedXSS;
    1256     else if (equalLettersIgnoringASCIICase(begin, position - begin, "filter"))
    1257         m_reflectedXSSDisposition = ContentSecurityPolicy::FilterReflectedXSS;
    1258     else if (equalLettersIgnoringASCIICase(begin, position - begin, "block"))
    1259         m_reflectedXSSDisposition = ContentSecurityPolicy::BlockReflectedXSS;
    1260     else {
    1261         m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
    1262         m_policy.reportInvalidReflectedXSS(value);
    1263         return;
    1264     }
    1265 
    1266     skipWhile<isASCIISpace>(position, end);
    1267     if (position == end && m_reflectedXSSDisposition != ContentSecurityPolicy::ReflectedXSSUnset)
    1268         return;
    1269 
    1270     // value1 value2
    1271     //        ^
    1272     m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
    1273     m_policy.reportInvalidReflectedXSS(value);
    1274 }
    1275 
    1276 void CSPDirectiveList::addDirective(const String& name, const String& value)
    1277 {
    1278     ASSERT(!name.isEmpty());
    1279 
    1280     if (equalLettersIgnoringASCIICase(name, defaultSrc))
    1281         setCSPDirective<SourceListDirective>(name, value, m_defaultSrc);
    1282     else if (equalLettersIgnoringASCIICase(name, scriptSrc))
    1283         setCSPDirective<SourceListDirective>(name, value, m_scriptSrc);
    1284     else if (equalLettersIgnoringASCIICase(name, objectSrc))
    1285         setCSPDirective<SourceListDirective>(name, value, m_objectSrc);
    1286     else if (equalLettersIgnoringASCIICase(name, frameSrc))
    1287         setCSPDirective<SourceListDirective>(name, value, m_frameSrc);
    1288     else if (equalLettersIgnoringASCIICase(name, imgSrc))
    1289         setCSPDirective<SourceListDirective>(name, value, m_imgSrc);
    1290     else if (equalLettersIgnoringASCIICase(name, styleSrc))
    1291         setCSPDirective<SourceListDirective>(name, value, m_styleSrc);
    1292     else if (equalLettersIgnoringASCIICase(name, fontSrc))
    1293         setCSPDirective<SourceListDirective>(name, value, m_fontSrc);
    1294     else if (equalLettersIgnoringASCIICase(name, mediaSrc))
    1295         setCSPDirective<SourceListDirective>(name, value, m_mediaSrc);
    1296     else if (equalLettersIgnoringASCIICase(name, connectSrc))
    1297         setCSPDirective<SourceListDirective>(name, value, m_connectSrc);
    1298     else if (equalLettersIgnoringASCIICase(name, sandbox))
    1299         applySandboxPolicy(name, value);
    1300     else if (equalLettersIgnoringASCIICase(name, reportURI))
    1301         parseReportURI(name, value);
    1302 #if ENABLE(CSP_NEXT)
    1303     else if (m_policy.experimentalFeaturesEnabled()) {
    1304         if (equalLettersIgnoringASCIICase(name, baseURI))
    1305             setCSPDirective<SourceListDirective>(name, value, m_baseURI);
    1306         else if (equalLettersIgnoringASCIICase(name, formAction))
    1307             setCSPDirective<SourceListDirective>(name, value, m_formAction);
    1308         else if (equalLettersIgnoringASCIICase(name, pluginTypes))
    1309             setCSPDirective<MediaListDirective>(name, value, m_pluginTypes);
    1310         else if (equalLettersIgnoringASCIICase(name, reflectedXSS))
    1311             parseReflectedXSS(name, value);
    1312         else
    1313             m_policy.reportUnsupportedDirective(name);
    1314     }
    1315 #endif
    1316     else
    1317         m_policy.reportUnsupportedDirective(name);
    1318 }
    131955
    132056ContentSecurityPolicy::ContentSecurityPolicy(ScriptExecutionContext& scriptExecutionContext)
     
    132561    auto& securityOrigin = *scriptExecutionContext.securityOrigin();
    132662    m_selfSourceProtocol = securityOrigin.protocol();
    1327     m_selfSource = std::make_unique<CSPSource>(*this, m_selfSourceProtocol, securityOrigin.host(), securityOrigin.port(), emptyString(), false, false);
     63    m_selfSource = std::make_unique<ContentSecurityPolicySource>(*this, m_selfSourceProtocol, securityOrigin.host(), securityOrigin.port(), emptyString(), false, false);
    132864}
    132965
     
    133268{
    133369    m_selfSourceProtocol = securityOrigin.protocol();
    1334     m_selfSource = std::make_unique<CSPSource>(*this, m_selfSourceProtocol, securityOrigin.host(), securityOrigin.port(), emptyString(), false, false);
     70    m_selfSource = std::make_unique<ContentSecurityPolicySource>(*this, m_selfSourceProtocol, securityOrigin.host(), securityOrigin.port(), emptyString(), false, false);
    133571}
    133672
     
    1371107    const UChar* end = begin + header.length();
    1372108    while (position < end) {
    1373         skipUntil(position, end, ',');
     109        skipUntil<UChar>(position, end, ',');
    1374110
    1375111        // header1,header2 OR header1
    1376112        //        ^                  ^
    1377         std::unique_ptr<CSPDirectiveList> policy = CSPDirectiveList::create(*this, String(begin, position - begin), type);
     113        std::unique_ptr<ContentSecurityPolicyDirectiveList> policy = ContentSecurityPolicyDirectiveList::create(*this, String(begin, position - begin), type);
    1378114        if (!policy->allowEval(0, ContentSecurityPolicy::ReportingStatus::SuppressReport))
    1379115            m_lastPolicyEvalDisabledErrorMessage = policy->evalDisabledErrorMessage();
     
    1383119        // Skip the comma, and begin the next header from the current position.
    1384120        ASSERT(position == end || *position == ',');
    1385         skipExactly(position, end, ',');
     121        skipExactly<UChar>(position, end, ',');
    1386122        begin = position;
    1387123    }
     
    1419155}
    1420156
    1421 template<bool (CSPDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatus) const>
     157template<bool (ContentSecurityPolicyDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatus) const>
    1422158bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolicy::ReportingStatus reportingStatus)
    1423159{
     
    1429165}
    1430166
    1431 template<bool (CSPDirectiveList::*allowed)(JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus) const>
     167template<bool (ContentSecurityPolicyDirectiveList::*allowed)(JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus) const>
    1432168bool isAllowedByAllWithState(const CSPDirectiveListVector& policies, JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus reportingStatus)
    1433169{
     
    1439175}
    1440176
    1441 template<bool (CSPDirectiveList::*allowed)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus) const>
     177template<bool (ContentSecurityPolicyDirectiveList::*allowed)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus) const>
    1442178bool isAllowedByAllWithContext(const CSPDirectiveListVector& policies, const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus)
    1443179{
     
    1449185}
    1450186
    1451 template<bool (CSPDirectiveList::*allowFromURL)(const URL&, ContentSecurityPolicy::ReportingStatus) const>
     187template<bool (ContentSecurityPolicyDirectiveList::*allowFromURL)(const URL&, ContentSecurityPolicy::ReportingStatus) const>
    1452188bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus)
    1453189{
     
    1464200bool ContentSecurityPolicy::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1465201{
    1466     return overrideContentSecurityPolicy || isAllowedByAllWithContext<&CSPDirectiveList::allowJavaScriptURLs>(m_policies, contextURL, contextLine, reportingStatus);
     202    return overrideContentSecurityPolicy || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowJavaScriptURLs>(m_policies, contextURL, contextLine, reportingStatus);
    1467203}
    1468204
    1469205bool ContentSecurityPolicy::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1470206{
    1471     return overrideContentSecurityPolicy || isAllowedByAllWithContext<&CSPDirectiveList::allowInlineEventHandlers>(m_policies, contextURL, contextLine, reportingStatus);
     207    return overrideContentSecurityPolicy || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineEventHandlers>(m_policies, contextURL, contextLine, reportingStatus);
    1472208}
    1473209
    1474210bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1475211{
    1476     return overrideContentSecurityPolicy || isAllowedByAllWithContext<&CSPDirectiveList::allowInlineScript>(m_policies, contextURL, contextLine, reportingStatus);
     212    return overrideContentSecurityPolicy || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineScript>(m_policies, contextURL, contextLine, reportingStatus);
    1477213}
    1478214
    1479215bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1480216{
    1481     return overrideContentSecurityPolicy || m_overrideInlineStyleAllowed || isAllowedByAllWithContext<&CSPDirectiveList::allowInlineStyle>(m_policies, contextURL, contextLine, reportingStatus);
     217    return overrideContentSecurityPolicy || m_overrideInlineStyleAllowed || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineStyle>(m_policies, contextURL, contextLine, reportingStatus);
    1482218}
    1483219
    1484220bool ContentSecurityPolicy::allowEval(JSC::ExecState* state, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1485221{
    1486     return overrideContentSecurityPolicy || isAllowedByAllWithState<&CSPDirectiveList::allowEval>(m_policies, state, reportingStatus);
     222    return overrideContentSecurityPolicy || isAllowedByAllWithState<&ContentSecurityPolicyDirectiveList::allowEval>(m_policies, state, reportingStatus);
    1487223}
    1488224
     
    1509245bool ContentSecurityPolicy::allowScriptFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1510246{
    1511     return overrideContentSecurityPolicy || isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, reportingStatus);
     247    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowScriptFromSource>(m_policies, url, reportingStatus);
    1512248}
    1513249
    1514250bool ContentSecurityPolicy::allowObjectFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1515251{
    1516     return overrideContentSecurityPolicy || isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(m_policies, url, reportingStatus);
     252    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowObjectFromSource>(m_policies, url, reportingStatus);
    1517253}
    1518254
    1519255bool ContentSecurityPolicy::allowChildFrameFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1520256{
    1521     return overrideContentSecurityPolicy || isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(m_policies, url, reportingStatus);
     257    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowChildFrameFromSource>(m_policies, url, reportingStatus);
    1522258}
    1523259
    1524260bool ContentSecurityPolicy::allowImageFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1525261{
    1526     return overrideContentSecurityPolicy || isAllowedByAllWithURL<&CSPDirectiveList::allowImageFromSource>(m_policies, url, reportingStatus);
     262    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowImageFromSource>(m_policies, url, reportingStatus);
    1527263}
    1528264
    1529265bool ContentSecurityPolicy::allowStyleFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1530266{
    1531     return overrideContentSecurityPolicy || isAllowedByAllWithURL<&CSPDirectiveList::allowStyleFromSource>(m_policies, url, reportingStatus);
     267    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowStyleFromSource>(m_policies, url, reportingStatus);
    1532268}
    1533269
    1534270bool ContentSecurityPolicy::allowFontFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1535271{
    1536     return overrideContentSecurityPolicy || isAllowedByAllWithURL<&CSPDirectiveList::allowFontFromSource>(m_policies, url, reportingStatus);
     272    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowFontFromSource>(m_policies, url, reportingStatus);
    1537273}
    1538274
    1539275bool ContentSecurityPolicy::allowMediaFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1540276{
    1541     return overrideContentSecurityPolicy || isAllowedByAllWithURL<&CSPDirectiveList::allowMediaFromSource>(m_policies, url, reportingStatus);
     277    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowMediaFromSource>(m_policies, url, reportingStatus);
    1542278}
    1543279
    1544280bool ContentSecurityPolicy::allowConnectToSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1545281{
    1546     return overrideContentSecurityPolicy || isAllowedByAllWithURL<&CSPDirectiveList::allowConnectToSource>(m_policies, url, reportingStatus);
     282    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowConnectToSource>(m_policies, url, reportingStatus);
    1547283}
    1548284
    1549285bool ContentSecurityPolicy::allowFormAction(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1550286{
    1551     return overrideContentSecurityPolicy || isAllowedByAllWithURL<&CSPDirectiveList::allowFormAction>(m_policies, url, reportingStatus);
     287    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowFormAction>(m_policies, url, reportingStatus);
    1552288}
    1553289
    1554290bool ContentSecurityPolicy::allowBaseURI(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
    1555291{
    1556     return overrideContentSecurityPolicy || isAllowedByAllWithURL<&CSPDirectiveList::allowBaseURI>(m_policies, url, reportingStatus);
     292    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowBaseURI>(m_policies, url, reportingStatus);
    1557293}
    1558294
  • trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h

    r196242 r196350  
    3939namespace WebCore {
    4040
    41 class CSPDirectiveList;
    42 class CSPSource;
     41class ContentSecurityPolicyDirectiveList;
     42class ContentSecurityPolicySource;
    4343class DOMStringList;
    4444class ScriptExecutionContext;
     
    4646class URL;
    4747
    48 typedef Vector<std::unique_ptr<CSPDirectiveList>> CSPDirectiveListVector;
     48typedef Vector<std::unique_ptr<ContentSecurityPolicyDirectiveList>> CSPDirectiveListVector;
    4949typedef int SandboxFlags;
    5050
     
    108108    // This class should traverse the directives, validating the policy, and applying it to the script execution context.
    109109
    110     // Used by MediaListDirective
     110    // Used by ContentSecurityPolicyMediaListDirective
    111111    void reportInvalidPluginTypes(const String&) const;
    112112
    113     // Used by CSPSourceList
     113    // Used by ContentSecurityPolicySourceList
    114114    void reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const;
    115115    void reportInvalidPathCharacter(const String& directiveName, const String& value, const char) const;
     
    117117    bool urlMatchesSelf(const URL&) const;
    118118
    119     // Used by CSPDirectiveList
     119    // Used by ContentSecurityPolicyDirectiveList
    120120    void reportDuplicateDirective(const String&) const;
    121121    void reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const;
     
    128128    void enforceSandboxFlags(SandboxFlags sandboxFlags) { m_sandboxFlags |= sandboxFlags; }
    129129
    130     // Used by CSPSource
     130    // Used by ContentSecurityPolicySource
    131131    bool protocolMatchesSelf(const URL&) const;
    132132
     
    136136
    137137    ScriptExecutionContext* m_scriptExecutionContext { nullptr };
    138     std::unique_ptr<CSPSource> m_selfSource;
     138    std::unique_ptr<ContentSecurityPolicySource> m_selfSource;
    139139    String m_selfSourceProtocol;
    140140    CSPDirectiveListVector m_policies;
Note: See TracChangeset for help on using the changeset viewer.