Add WTF::move()
[WebKit-https.git] / Source / WebCore / dom / SecurityContext.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY GOOGLE, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26
27 #include "config.h"
28 #include "SecurityContext.h"
29
30 #include "ContentSecurityPolicy.h"
31 #include "HTMLParserIdioms.h"
32 #include "SecurityOrigin.h"
33 #include <wtf/text/StringBuilder.h>
34
35 namespace WebCore {
36
37 SecurityContext::SecurityContext()
38     : m_haveInitializedSecurityOrigin(false)
39     , m_sandboxFlags(SandboxNone)
40 {
41 }
42
43 SecurityContext::~SecurityContext()
44 {
45 }
46
47 void SecurityContext::setSecurityOrigin(PassRefPtr<SecurityOrigin> securityOrigin)
48 {
49     m_securityOrigin = securityOrigin;
50     m_haveInitializedSecurityOrigin = true;
51 }
52
53 void SecurityContext::setContentSecurityPolicy(std::unique_ptr<ContentSecurityPolicy> contentSecurityPolicy)
54 {
55     m_contentSecurityPolicy = WTF::move(contentSecurityPolicy);
56 }
57
58 bool SecurityContext::isSecureTransitionTo(const URL& url) const
59 {
60     // If we haven't initialized our security origin by now, this is probably
61     // a new window created via the API (i.e., that lacks an origin and lacks
62     // a place to inherit the origin from).
63     if (!haveInitializedSecurityOrigin())
64         return true;
65
66     RefPtr<SecurityOrigin> other = SecurityOrigin::create(url);
67     return securityOrigin()->canAccess(other.get());
68 }
69
70 void SecurityContext::enforceSandboxFlags(SandboxFlags mask)
71 {
72     m_sandboxFlags |= mask;
73
74     // The SandboxOrigin is stored redundantly in the security origin.
75     if (isSandboxed(SandboxOrigin) && securityOrigin() && !securityOrigin()->isUnique())
76         setSecurityOrigin(SecurityOrigin::createUnique());
77 }
78
79 SandboxFlags SecurityContext::parseSandboxPolicy(const String& policy, String& invalidTokensErrorMessage)
80 {
81     // http://www.w3.org/TR/html5/the-iframe-element.html#attr-iframe-sandbox
82     // Parse the unordered set of unique space-separated tokens.
83     SandboxFlags flags = SandboxAll;
84     unsigned length = policy.length();
85     unsigned start = 0;
86     unsigned numberOfTokenErrors = 0;
87     StringBuilder tokenErrors;
88     while (true) {
89         while (start < length && isHTMLSpace(policy[start]))
90             ++start;
91         if (start >= length)
92             break;
93         unsigned end = start + 1;
94         while (end < length && !isHTMLSpace(policy[end]))
95             ++end;
96
97         // Turn off the corresponding sandbox flag if it's set as "allowed".
98         String sandboxToken = policy.substring(start, end - start);
99         if (equalIgnoringCase(sandboxToken, "allow-same-origin"))
100             flags &= ~SandboxOrigin;
101         else if (equalIgnoringCase(sandboxToken, "allow-forms"))
102             flags &= ~SandboxForms;
103         else if (equalIgnoringCase(sandboxToken, "allow-scripts")) {
104             flags &= ~SandboxScripts;
105             flags &= ~SandboxAutomaticFeatures;
106         } else if (equalIgnoringCase(sandboxToken, "allow-top-navigation"))
107             flags &= ~SandboxTopNavigation;
108         else if (equalIgnoringCase(sandboxToken, "allow-popups"))
109             flags &= ~SandboxPopups;
110         else if (equalIgnoringCase(sandboxToken, "allow-pointer-lock"))
111             flags &= ~SandboxPointerLock;
112         else {
113             if (numberOfTokenErrors)
114                 tokenErrors.appendLiteral(", '");
115             else
116                 tokenErrors.append('\'');
117             tokenErrors.append(sandboxToken);
118             tokenErrors.append('\'');
119             numberOfTokenErrors++;
120         }
121
122         start = end + 1;
123     }
124
125     if (numberOfTokenErrors) {
126         if (numberOfTokenErrors > 1)
127             tokenErrors.appendLiteral(" are invalid sandbox flags.");
128         else
129             tokenErrors.appendLiteral(" is an invalid sandbox flag.");
130         invalidTokensErrorMessage = tokenErrors.toString();
131     }
132
133     return flags;
134 }
135
136 }