OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
12 * | 12 * |
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 */ | 24 */ |
25 | 25 |
26 #include "config.h" | 26 #include "config.h" |
27 #include "core/page/UserContentURLPattern.h" | 27 #include "platform/URLPatternMatcher.h" |
28 | 28 |
29 #include "weborigin/KURL.h" | 29 #include "weborigin/KURL.h" |
30 #include "wtf/StdLibExtras.h" | 30 #include "wtf/StdLibExtras.h" |
31 | 31 |
32 namespace WebCore { | 32 namespace WebCore { |
33 | 33 |
34 bool UserContentURLPattern::matchesPatterns(const KURL& url, const Vector<String
>& whitelist, const Vector<String>& blacklist) | 34 bool URLPatternMatcher::matchesPatterns(const KURL& url, const Vector<String>& w
hitelist) |
35 { | 35 { |
36 // In order for a URL to be a match it has to be present in the whitelist an
d not present in the blacklist. | |
37 // If there is no whitelist at all, then all URLs are assumed to be in the w
hitelist. | 36 // If there is no whitelist at all, then all URLs are assumed to be in the w
hitelist. |
38 bool matchesWhitelist = whitelist.isEmpty(); | 37 if (whitelist.isEmpty()) |
39 if (!matchesWhitelist) { | 38 return true; |
40 size_t whitelistSize = whitelist.size(); | 39 |
41 for (size_t i = 0; i < whitelistSize; ++i) { | 40 for (size_t i = 0; i < whitelist.size(); ++i) { |
42 UserContentURLPattern contentPattern(whitelist[i]); | 41 URLPatternMatcher contentPattern(whitelist[i]); |
43 if (contentPattern.matches(url)) { | 42 if (contentPattern.matches(url)) |
44 matchesWhitelist = true; | 43 return true; |
45 break; | |
46 } | |
47 } | |
48 } | 44 } |
49 | 45 |
50 bool matchesBlacklist = false; | 46 return false; |
51 if (!blacklist.isEmpty()) { | |
52 size_t blacklistSize = blacklist.size(); | |
53 for (size_t i = 0; i < blacklistSize; ++i) { | |
54 UserContentURLPattern contentPattern(blacklist[i]); | |
55 if (contentPattern.matches(url)) { | |
56 matchesBlacklist = true; | |
57 break; | |
58 } | |
59 } | |
60 } | |
61 | |
62 return matchesWhitelist && !matchesBlacklist; | |
63 } | 47 } |
64 | 48 |
65 bool UserContentURLPattern::parse(const String& pattern) | 49 bool URLPatternMatcher::parse(const String& pattern) |
66 { | 50 { |
67 DEFINE_STATIC_LOCAL(const String, schemeSeparator, ("://")); | 51 DEFINE_STATIC_LOCAL(const String, schemeSeparator, ("://")); |
68 | 52 |
69 size_t schemeEndPos = pattern.find(schemeSeparator); | 53 size_t schemeEndPos = pattern.find(schemeSeparator); |
70 if (schemeEndPos == kNotFound) | 54 if (schemeEndPos == kNotFound) |
71 return false; | 55 return false; |
72 | 56 |
73 m_scheme = pattern.left(schemeEndPos); | 57 m_scheme = pattern.left(schemeEndPos); |
74 | 58 |
75 unsigned hostStartPos = schemeEndPos + schemeSeparator.length(); | 59 unsigned hostStartPos = schemeEndPos + schemeSeparator.length(); |
76 if (hostStartPos >= pattern.length()) | 60 if (hostStartPos >= pattern.length()) |
77 return false; | 61 return false; |
78 | 62 |
79 int pathStartPos = 0; | 63 int pathStartPos = 0; |
80 | 64 |
81 if (equalIgnoringCase(m_scheme, "file")) | 65 if (equalIgnoringCase(m_scheme, "file")) { |
82 pathStartPos = hostStartPos; | 66 pathStartPos = hostStartPos; |
83 else { | 67 } else { |
84 size_t hostEndPos = pattern.find("/", hostStartPos); | 68 size_t hostEndPos = pattern.find("/", hostStartPos); |
85 if (hostEndPos == kNotFound) | 69 if (hostEndPos == kNotFound) |
86 return false; | 70 return false; |
87 | 71 |
88 m_host = pattern.substring(hostStartPos, hostEndPos - hostStartPos); | 72 m_host = pattern.substring(hostStartPos, hostEndPos - hostStartPos); |
89 m_matchSubdomains = false; | 73 m_matchSubdomains = false; |
90 | 74 |
91 if (m_host == "*") { | 75 if (m_host == "*") { |
92 // The pattern can be just '*', which means match all domains. | 76 // The pattern can be just '*', which means match all domains. |
93 m_host = ""; | 77 m_host = ""; |
94 m_matchSubdomains = true; | 78 m_matchSubdomains = true; |
95 } else if (m_host.startsWith("*.")) { | 79 } else if (m_host.startsWith("*.")) { |
96 // The first component can be '*', which means to match all subdomai
ns. | 80 // The first component can be '*', which means to match all subdomai
ns. |
97 m_host = m_host.substring(2); // Length of "*." | 81 m_host = m_host.substring(2); // Length of "*." |
98 m_matchSubdomains = true; | 82 m_matchSubdomains = true; |
99 } | 83 } |
100 | 84 |
101 // No other '*' can occur in the host. | 85 // No other '*' can occur in the host. |
102 if (m_host.find("*") != kNotFound) | 86 if (m_host.find("*") != kNotFound) |
103 return false; | 87 return false; |
104 | 88 |
105 pathStartPos = hostEndPos; | 89 pathStartPos = hostEndPos; |
106 } | 90 } |
107 | 91 |
108 m_path = pattern.right(pattern.length() - pathStartPos); | 92 m_path = pattern.right(pattern.length() - pathStartPos); |
109 | 93 |
110 return true; | 94 return true; |
111 } | 95 } |
112 | 96 |
113 bool UserContentURLPattern::matches(const KURL& test) const | 97 bool URLPatternMatcher::matches(const KURL& test) const |
114 { | 98 { |
115 if (m_invalid) | 99 if (m_invalid) |
116 return false; | 100 return false; |
117 | 101 |
118 if (!equalIgnoringCase(test.protocol(), m_scheme)) | 102 if (!equalIgnoringCase(test.protocol(), m_scheme)) |
119 return false; | 103 return false; |
120 | 104 |
121 if (!equalIgnoringCase(m_scheme, "file") && !matchesHost(test)) | 105 if (!equalIgnoringCase(m_scheme, "file") && !matchesHost(test)) |
122 return false; | 106 return false; |
123 | 107 |
124 return matchesPath(test); | 108 return matchesPath(test); |
125 } | 109 } |
126 | 110 |
127 bool UserContentURLPattern::matchesHost(const KURL& test) const | 111 bool URLPatternMatcher::matchesHost(const KURL& test) const |
128 { | 112 { |
129 const String& host = test.host(); | 113 const String& host = test.host(); |
130 if (equalIgnoringCase(host, m_host)) | 114 if (equalIgnoringCase(host, m_host)) |
131 return true; | 115 return true; |
132 | 116 |
133 if (!m_matchSubdomains) | 117 if (!m_matchSubdomains) |
134 return false; | 118 return false; |
135 | 119 |
136 // If we're matching subdomains, and we have no host, that means the pattern | 120 // If we're matching subdomains, and we have no host, that means the pattern |
137 // was <scheme>://*/<whatever>, so we match anything. | 121 // was <scheme>://*/<whatever>, so we match anything. |
138 if (!m_host.length()) | 122 if (!m_host.length()) |
139 return true; | 123 return true; |
140 | 124 |
141 // Check if the domain is a subdomain of our host. | 125 // Check if the domain is a subdomain of our host. |
142 if (!host.endsWith(m_host, false)) | 126 if (!host.endsWith(m_host, false)) |
143 return false; | 127 return false; |
144 | 128 |
145 ASSERT(host.length() > m_host.length()); | 129 ASSERT(host.length() > m_host.length()); |
146 | 130 |
147 // Check that the character before the suffix is a period. | 131 // Check that the character before the suffix is a period. |
148 return host[host.length() - m_host.length() - 1] == '.'; | 132 return host[host.length() - m_host.length() - 1] == '.'; |
149 } | 133 } |
150 | 134 |
151 struct MatchTester | 135 struct MatchTester { |
152 { | |
153 const String m_pattern; | 136 const String m_pattern; |
154 unsigned m_patternIndex; | 137 unsigned m_patternIndex; |
155 | 138 |
156 const String m_test; | 139 const String m_test; |
157 unsigned m_testIndex; | 140 unsigned m_testIndex; |
158 | 141 |
159 MatchTester(const String& pattern, const String& test) | 142 MatchTester(const String& pattern, const String& test) |
160 : m_pattern(pattern) | 143 : m_pattern(pattern) |
161 , m_patternIndex(0) | 144 , m_patternIndex(0) |
162 , m_test(test) | 145 , m_test(test) |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 return false; | 194 return false; |
212 | 195 |
213 while (!testStringFinished()) { | 196 while (!testStringFinished()) { |
214 MatchTester nextMatch(*this); | 197 MatchTester nextMatch(*this); |
215 nextMatch.m_patternIndex++; | 198 nextMatch.m_patternIndex++; |
216 if (nextMatch.test()) | 199 if (nextMatch.test()) |
217 return true; | 200 return true; |
218 m_testIndex++; | 201 m_testIndex++; |
219 } | 202 } |
220 | 203 |
221 // We reached the end of the string. Let's see if the pattern contains
only | 204 // We reached the end of the string. Let's see if the pattern contains o
nly wildcards. |
222 // wildcards. | |
223 eatWildcard(); | 205 eatWildcard(); |
224 return patternStringFinished(); | 206 return patternStringFinished(); |
225 } | 207 } |
226 }; | 208 }; |
227 | 209 |
228 bool UserContentURLPattern::matchesPath(const KURL& test) const | 210 bool URLPatternMatcher::matchesPath(const KURL& test) const |
229 { | 211 { |
230 MatchTester match(m_path, test.path()); | 212 MatchTester match(m_path, test.path()); |
231 return match.test(); | 213 return match.test(); |
232 } | 214 } |
233 | 215 |
234 } // namespace WebCore | 216 } // namespace WebCore |
OLD | NEW |