| OLD | NEW |
| 1 /* Based on nsURLParsers.cc from Mozilla | 1 /* Based on nsURLParsers.cc from Mozilla |
| 2 * ------------------------------------- | 2 * ------------------------------------- |
| 3 * The contents of this file are subject to the Mozilla Public License Version | 3 * The contents of this file are subject to the Mozilla Public License Version |
| 4 * 1.1 (the "License"); you may not use this file except in compliance with | 4 * 1.1 (the "License"); you may not use this file except in compliance with |
| 5 * the License. You may obtain a copy of the License at | 5 * the License. You may obtain a copy of the License at |
| 6 * http://www.mozilla.org/MPL/ | 6 * http://www.mozilla.org/MPL/ |
| 7 * | 7 * |
| 8 * Software distributed under the License is distributed on an "AS IS" basis, | 8 * Software distributed under the License is distributed on an "AS IS" basis, |
| 9 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | 9 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| 10 * for the specific language governing rights and limitations under the | 10 * for the specific language governing rights and limitations under the |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 const Component& serverinfo, | 140 const Component& serverinfo, |
| 141 Component* hostname, | 141 Component* hostname, |
| 142 Component* port_num) { | 142 Component* port_num) { |
| 143 if (serverinfo.len == 0) { | 143 if (serverinfo.len == 0) { |
| 144 // No server info, host name is empty. | 144 // No server info, host name is empty. |
| 145 hostname->reset(); | 145 hostname->reset(); |
| 146 port_num->reset(); | 146 port_num->reset(); |
| 147 return; | 147 return; |
| 148 } | 148 } |
| 149 | 149 |
| 150 // Search backwards for a ':' but stop on ']' (IPv6 address literal | 150 // If the host starts with a left-bracket, assume the entire host is an |
| 151 // delimiter). | 151 // IPv6 literal. Otherwise, assume none of the host is an IPv6 literal. |
| 152 int i = serverinfo.begin + serverinfo.len - 1; | 152 // This assumption will be overridden if we find a right-bracket. |
| 153 int colon = -1, bracket = -1; | 153 // |
| 154 while (i >= serverinfo.begin && colon < 0) { | 154 // Our IPv6 address canonicalization code requires both brackets to exist, |
| 155 // but the ability to locate an incomplete address can still be useful. |
| 156 int ipv6_terminator = spec[serverinfo.begin] == '[' ? serverinfo.end() : -1; |
| 157 int colon = -1; |
| 158 |
| 159 // Find the last right-bracket, and the last colon. |
| 160 for (int i = serverinfo.begin; i < serverinfo.end(); i++) { |
| 155 switch (spec[i]) { | 161 switch (spec[i]) { |
| 156 case ']': | 162 case ']': |
| 157 bracket = i; | 163 ipv6_terminator = i; |
| 158 break; | 164 break; |
| 159 case ':': | 165 case ':': |
| 160 if (bracket < 0) | 166 colon = i; |
| 161 colon = i; // Will cause loop to terminate. | |
| 162 break; | 167 break; |
| 163 } | 168 } |
| 164 i--; | |
| 165 } | 169 } |
| 166 | 170 |
| 167 if (colon >= 0) { | 171 if (colon > ipv6_terminator) { |
| 168 // Found a port number: <hostname>:<port> | 172 // Found a port number: <hostname>:<port> |
| 169 int host_len = colon - serverinfo.begin; | 173 *hostname = MakeRange(serverinfo.begin, colon); |
| 170 if (host_len) | 174 if (hostname->len == 0) |
| 171 *hostname = MakeRange(serverinfo.begin, colon); | |
| 172 else | |
| 173 hostname->reset(); | 175 hostname->reset(); |
| 174 *port_num = MakeRange(colon + 1, serverinfo.begin + serverinfo.len); | 176 *port_num = MakeRange(colon + 1, serverinfo.end()); |
| 175 } else { | 177 } else { |
| 176 // No port: <hostname> | 178 // No port: <hostname> |
| 177 *hostname = serverinfo; | 179 *hostname = serverinfo; |
| 178 port_num->reset(); | 180 port_num->reset(); |
| 179 } | 181 } |
| 180 } | 182 } |
| 181 | 183 |
| 182 // Given an already-identified auth section, breaks it into its consituent | 184 // Given an already-identified auth section, breaks it into its consituent |
| 183 // parts. The port number will be parsed and the resulting integer will be | 185 // parts. The port number will be parsed and the resulting integer will be |
| 184 // filled into the given *port variable, or -1 if there is no port number or it | 186 // filled into the given *port variable, or -1 if there is no port number or it |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 void DoParseMailtoURL(const CHAR* spec, int spec_len, Parsed* parsed) { | 381 void DoParseMailtoURL(const CHAR* spec, int spec_len, Parsed* parsed) { |
| 380 DCHECK(spec_len >= 0); | 382 DCHECK(spec_len >= 0); |
| 381 | 383 |
| 382 // Get the non-path and non-scheme parts of the URL out of the way, we never | 384 // Get the non-path and non-scheme parts of the URL out of the way, we never |
| 383 // use them. | 385 // use them. |
| 384 parsed->username.reset(); | 386 parsed->username.reset(); |
| 385 parsed->password.reset(); | 387 parsed->password.reset(); |
| 386 parsed->host.reset(); | 388 parsed->host.reset(); |
| 387 parsed->port.reset(); | 389 parsed->port.reset(); |
| 388 parsed->ref.reset(); | 390 parsed->ref.reset(); |
| 389 parsed->query.reset(); // May use this; reset for convenience. | 391 parsed->query.reset(); // May use this; reset for convenience. |
| 390 | 392 |
| 391 // Strip leading & trailing spaces and control characters. | 393 // Strip leading & trailing spaces and control characters. |
| 392 int begin = 0; | 394 int begin = 0; |
| 393 TrimURL(spec, &begin, &spec_len); | 395 TrimURL(spec, &begin, &spec_len); |
| 394 | 396 |
| 395 // Handle empty specs or ones that contain only whitespace or control chars. | 397 // Handle empty specs or ones that contain only whitespace or control chars. |
| 396 if (begin == spec_len) { | 398 if (begin == spec_len) { |
| 397 parsed->scheme.reset(); | 399 parsed->scheme.reset(); |
| 398 parsed->path.reset(); | 400 parsed->path.reset(); |
| 399 return; | 401 return; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 } | 439 } |
| 438 } | 440 } |
| 439 | 441 |
| 440 // Converts a port number in a string to an integer. We'd like to just call | 442 // Converts a port number in a string to an integer. We'd like to just call |
| 441 // sscanf but our input is not NULL-terminated, which sscanf requires. Instead, | 443 // sscanf but our input is not NULL-terminated, which sscanf requires. Instead, |
| 442 // we copy the digits to a small stack buffer (since we know the maximum number | 444 // we copy the digits to a small stack buffer (since we know the maximum number |
| 443 // of digits in a valid port number) that we can NULL terminate. | 445 // of digits in a valid port number) that we can NULL terminate. |
| 444 template<typename CHAR> | 446 template<typename CHAR> |
| 445 int DoParsePort(const CHAR* spec, const Component& component) { | 447 int DoParsePort(const CHAR* spec, const Component& component) { |
| 446 // Easy success case when there is no port. | 448 // Easy success case when there is no port. |
| 447 const int max_digits = 5; | 449 const int kMaxDigits = 5; |
| 448 if (!component.is_nonempty()) | 450 if (!component.is_nonempty()) |
| 449 return PORT_UNSPECIFIED; | 451 return PORT_UNSPECIFIED; |
| 450 | 452 |
| 451 // Skip over any leading 0s. | 453 // Skip over any leading 0s. |
| 452 Component digits_comp(component.end(), 0); | 454 Component digits_comp(component.end(), 0); |
| 453 for (int i = 0; i < component.len; i++) { | 455 for (int i = 0; i < component.len; i++) { |
| 454 if (spec[component.begin + i] != '0') { | 456 if (spec[component.begin + i] != '0') { |
| 455 digits_comp = MakeRange(component.begin + i, component.end()); | 457 digits_comp = MakeRange(component.begin + i, component.end()); |
| 456 break; | 458 break; |
| 457 } | 459 } |
| 458 } | 460 } |
| 459 if (digits_comp.len == 0) | 461 if (digits_comp.len == 0) |
| 460 return 0; // All digits were 0. | 462 return 0; // All digits were 0. |
| 461 | 463 |
| 462 // Verify we don't have too many digits (we'll be copying to our buffer so | 464 // Verify we don't have too many digits (we'll be copying to our buffer so |
| 463 // we need to double-check). | 465 // we need to double-check). |
| 464 if (digits_comp.len > max_digits) | 466 if (digits_comp.len > kMaxDigits) |
| 465 return PORT_INVALID; | 467 return PORT_INVALID; |
| 466 | 468 |
| 467 // Copy valid digits to the buffer. | 469 // Copy valid digits to the buffer. |
| 468 char digits[max_digits + 1]; // +1 for null terminator | 470 char digits[kMaxDigits + 1]; // +1 for null terminator |
| 469 for (int i = 0; i < digits_comp.len; i++) { | 471 for (int i = 0; i < digits_comp.len; i++) { |
| 470 CHAR ch = spec[digits_comp.begin + i]; | 472 CHAR ch = spec[digits_comp.begin + i]; |
| 471 if (!IsPortDigit(ch)) { | 473 if (!IsPortDigit(ch)) { |
| 472 // Invalid port digit, fail. | 474 // Invalid port digit, fail. |
| 473 return PORT_INVALID; | 475 return PORT_INVALID; |
| 474 } | 476 } |
| 475 digits[i] = static_cast<char>(ch); | 477 digits[i] = static_cast<char>(ch); |
| 476 } | 478 } |
| 477 | 479 |
| 478 // Null-terminate the string and convert to integer. Since we guarantee | 480 // Null-terminate the string and convert to integer. Since we guarantee |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 } | 748 } |
| 747 | 749 |
| 748 void ParseAfterScheme(const char16* spec, | 750 void ParseAfterScheme(const char16* spec, |
| 749 int spec_len, | 751 int spec_len, |
| 750 int after_scheme, | 752 int after_scheme, |
| 751 Parsed* parsed) { | 753 Parsed* parsed) { |
| 752 DoParseAfterScheme(spec, spec_len, after_scheme, parsed); | 754 DoParseAfterScheme(spec, spec_len, after_scheme, parsed); |
| 753 } | 755 } |
| 754 | 756 |
| 755 } // namespace url_parse | 757 } // namespace url_parse |
| OLD | NEW |