URLPatternGlue.cpp (8311B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include "mozilla/net/URLPatternGlue.h" 6 7 mozilla::LazyLogModule gUrlPatternLog("urlpattern"); 8 9 namespace mozilla::net { 10 11 UrlpInput CreateUrlpInput(const nsACString& url) { 12 UrlpInput input; 13 input.string_or_init_type = UrlpStringOrInitType::String; 14 input.str = url; 15 return input; 16 } 17 18 UrlpInput CreateUrlpInput(const UrlpInit& init) { 19 UrlpInput input; 20 input.string_or_init_type = UrlpStringOrInitType::Init; 21 input.init = init; 22 return input; 23 } 24 25 MaybeString CreateMaybeString(const nsACString& str, bool valid) { 26 return MaybeString{.string = nsCString(str), .valid = valid}; 27 } 28 29 MaybeString CreateMaybeStringNone() { 30 return MaybeString{.string = ""_ns, .valid = false}; 31 } 32 33 nsAutoCString UrlpGetProtocol(const UrlpPattern aPattern) { 34 UrlpComponent component; 35 urlp_get_protocol_component(aPattern, &component); 36 return nsAutoCString(component.pattern_string); 37 } 38 39 nsAutoCString UrlpGetUsername(const UrlpPattern aPattern) { 40 UrlpComponent component; 41 urlp_get_username_component(aPattern, &component); 42 return nsAutoCString(component.pattern_string); 43 } 44 45 nsAutoCString UrlpGetPassword(const UrlpPattern aPattern) { 46 UrlpComponent component; 47 urlp_get_password_component(aPattern, &component); 48 return nsAutoCString(component.pattern_string); 49 } 50 51 nsAutoCString UrlpGetHostname(const UrlpPattern aPattern) { 52 UrlpComponent component; 53 urlp_get_hostname_component(aPattern, &component); 54 return nsAutoCString(component.pattern_string); 55 } 56 57 nsAutoCString UrlpGetPort(const UrlpPattern aPattern) { 58 UrlpComponent component; 59 urlp_get_port_component(aPattern, &component); 60 return nsAutoCString(component.pattern_string); 61 } 62 63 nsAutoCString UrlpGetPathname(const UrlpPattern aPattern) { 64 UrlpComponent component; 65 urlp_get_pathname_component(aPattern, &component); 66 return nsAutoCString(component.pattern_string); 67 } 68 69 nsAutoCString UrlpGetSearch(const UrlpPattern aPattern) { 70 UrlpComponent component; 71 urlp_get_search_component(aPattern, &component); 72 return nsAutoCString(component.pattern_string); 73 } 74 75 nsAutoCString UrlpGetHash(const UrlpPattern aPattern) { 76 UrlpComponent component; 77 urlp_get_hash_component(aPattern, &component); 78 return nsAutoCString(component.pattern_string); 79 } 80 81 // https://urlpattern.spec.whatwg.org/#create-a-component-match-result 82 Maybe<UrlpComponentResult> ComponentMatches(UrlpComponent& aComponent, 83 nsACString& aInput, 84 bool aIgnoreCase) { 85 UrlpComponentResult res; 86 if (aComponent.regexp_string == "^$") { // empty string 87 if (aInput != "") { 88 return Nothing(); 89 } 90 } else { // check deeper match 91 nsTArray<MaybeString> matches; 92 if (!urlp_matcher_matches_component(&aComponent.matcher, &aInput, 93 aIgnoreCase, &matches)) { 94 return Nothing(); 95 } 96 for (size_t i = 0; i < matches.Length(); i++) { 97 nsAutoCString key; 98 key.Assign(aComponent.group_name_list[i]); 99 res.mGroups.InsertOrUpdate(key, matches[i]); 100 } 101 } 102 res.mInput = aInput; 103 return Some(res); 104 } 105 106 Maybe<UrlpResult> AllComponentMatches(const UrlpPattern aPattern, 107 UrlpMatchInput& aMatchInput, 108 bool aIgnoreCase) { 109 UrlpResult res; 110 UrlpComponent componentProtocol{}; 111 urlp_get_protocol_component(aPattern, &componentProtocol); 112 res.mProtocol = 113 ComponentMatches(componentProtocol, aMatchInput.protocol, aIgnoreCase); 114 if (res.mProtocol.isNothing()) { 115 return Nothing(); 116 } 117 118 UrlpComponent componentUsername{}; 119 urlp_get_username_component(aPattern, &componentUsername); 120 res.mUsername = 121 ComponentMatches(componentUsername, aMatchInput.username, aIgnoreCase); 122 if (res.mUsername.isNothing()) { 123 return Nothing(); 124 } 125 126 UrlpComponent componentPassword{}; 127 urlp_get_password_component(aPattern, &componentPassword); 128 res.mPassword = 129 ComponentMatches(componentPassword, aMatchInput.password, aIgnoreCase); 130 if (res.mPassword.isNothing()) { 131 return Nothing(); 132 } 133 134 UrlpComponent componentHostname{}; 135 urlp_get_hostname_component(aPattern, &componentHostname); 136 res.mHostname = 137 ComponentMatches(componentHostname, aMatchInput.hostname, aIgnoreCase); 138 if (res.mHostname.isNothing()) { 139 return Nothing(); 140 } 141 142 UrlpComponent componentPort{}; 143 urlp_get_port_component(aPattern, &componentPort); 144 res.mPort = ComponentMatches(componentPort, aMatchInput.port, aIgnoreCase); 145 if (res.mPort.isNothing()) { 146 return Nothing(); 147 } 148 149 UrlpComponent componentPathname{}; 150 urlp_get_pathname_component(aPattern, &componentPathname); 151 res.mPathname = 152 ComponentMatches(componentPathname, aMatchInput.pathname, aIgnoreCase); 153 if (res.mPathname.isNothing()) { 154 return Nothing(); 155 } 156 157 UrlpComponent componentSearch{}; 158 urlp_get_search_component(aPattern, &componentSearch); 159 res.mSearch = 160 ComponentMatches(componentSearch, aMatchInput.search, aIgnoreCase); 161 if (res.mSearch.isNothing()) { 162 return Nothing(); 163 } 164 165 UrlpComponent componentHash{}; 166 urlp_get_hash_component(aPattern, &componentHash); 167 res.mHash = ComponentMatches(componentHash, aMatchInput.hash, aIgnoreCase); 168 if (res.mHash.isNothing()) { 169 return Nothing(); 170 } 171 172 return Some(res); 173 } 174 175 Maybe<UrlpResult> UrlpPatternExec(UrlpPattern aPattern, const UrlpInput& aInput, 176 Maybe<nsAutoCString> aMaybeBaseUrl, 177 bool aIgnoreCase) { 178 MOZ_LOG(gUrlPatternLog, LogLevel::Debug, ("UrlpPatternExec()...\n")); 179 UrlpMatchInputAndInputs matchInputAndInputs; 180 if (aInput.string_or_init_type == UrlpStringOrInitType::Init) { 181 MOZ_ASSERT(aMaybeBaseUrl.isNothing()); 182 if (!urlp_process_match_input_from_init(&aInput.init, nullptr, 183 &matchInputAndInputs)) { 184 return Nothing(); 185 } 186 } else { 187 nsAutoCString* baseUrl = nullptr; 188 if (aMaybeBaseUrl.isSome()) { 189 baseUrl = &aMaybeBaseUrl.ref(); 190 } 191 if (!urlp_process_match_input_from_string(&aInput.str, baseUrl, 192 &matchInputAndInputs)) { 193 return Nothing(); 194 } 195 } 196 197 // shouldn't be any need to convert the urlpatternwrapper to quirks wrapper 198 // the all_component_matches signature should be able to receive as a wrapper 199 Maybe<UrlpResult> res = 200 AllComponentMatches(aPattern, matchInputAndInputs.input, aIgnoreCase); 201 if (res.isNothing()) { 202 return Nothing(); 203 } 204 205 if (matchInputAndInputs.inputs.string_or_init_type == 206 UrlpStringOrInitType::Init) { 207 res->mInputs.AppendElement( 208 CreateUrlpInput(matchInputAndInputs.inputs.init)); 209 } else { 210 res->mInputs.AppendElement(CreateUrlpInput(matchInputAndInputs.inputs.str)); 211 if (matchInputAndInputs.inputs.base.valid) { 212 res->mInputs.AppendElement( 213 CreateUrlpInput(matchInputAndInputs.inputs.base.string)); 214 } 215 } 216 217 return res; 218 } 219 220 bool UrlpPatternTest(UrlpPattern aPattern, const UrlpInput& aInput, 221 Maybe<nsAutoCString> aMaybeBaseUrl, bool aIgnoreCase) { 222 MOZ_LOG(gUrlPatternLog, LogLevel::Debug, ("UrlpPatternTest()...\n")); 223 UrlpMatchInputAndInputs matchInputAndInputs; 224 if (aInput.string_or_init_type == UrlpStringOrInitType::Init) { 225 MOZ_ASSERT(aMaybeBaseUrl.isNothing()); 226 if (!urlp_process_match_input_from_init(&aInput.init, nullptr, 227 &matchInputAndInputs)) { 228 return false; 229 } 230 } else { 231 nsAutoCString* baseUrl = nullptr; 232 if (aMaybeBaseUrl.isSome()) { 233 baseUrl = &aMaybeBaseUrl.ref(); 234 } 235 if (!urlp_process_match_input_from_string(&aInput.str, baseUrl, 236 &matchInputAndInputs)) { 237 return false; 238 } 239 } 240 241 // shouldn't be any need to convert the urlpatternwrapper to quirks wrapper 242 // the all_component_matches signature should be able to receive as a wrapper 243 Maybe<UrlpResult> res = 244 AllComponentMatches(aPattern, matchInputAndInputs.input, aIgnoreCase); 245 return !res.isNothing(); 246 } 247 248 } // namespace mozilla::net