OLD | NEW |
1 // Copyright 2009, Google Inc. | 1 // Copyright 2009, Google Inc. |
2 // All rights reserved. | 2 // 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 are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 | 174 |
175 // Check for 32-bit overflow. | 175 // Check for 32-bit overflow. |
176 if (num > kuint32max) | 176 if (num > kuint32max) |
177 return CanonHostInfo::BROKEN; | 177 return CanonHostInfo::BROKEN; |
178 | 178 |
179 // No overflow. Success! | 179 // No overflow. Success! |
180 *number = static_cast<uint32>(num); | 180 *number = static_cast<uint32>(num); |
181 return CanonHostInfo::IPV4; | 181 return CanonHostInfo::IPV4; |
182 } | 182 } |
183 | 183 |
184 // Writes the given address (with each character representing one dotted | |
185 // part of an IPv4 address) to the output, and updating |*out_host| to | |
186 // identify the added portion. | |
187 void AppendIPv4Address(const unsigned char address[4], | |
188 CanonOutput* output, | |
189 url_parse::Component* out_host) { | |
190 out_host->begin = output->length(); | |
191 for (int i = 0; i < 4; i++) { | |
192 char str[16]; | |
193 _itoa_s(address[i], str, 10); | |
194 | |
195 for (int ch = 0; str[ch] != 0; ch++) | |
196 output->push_back(str[ch]); | |
197 | |
198 if (i != 3) | |
199 output->push_back('.'); | |
200 } | |
201 out_host->len = output->length() - out_host->begin; | |
202 } | |
203 | |
204 // See declaration of IPv4AddressToNumber for documentation. | 184 // See declaration of IPv4AddressToNumber for documentation. |
205 template<typename CHAR> | 185 template<typename CHAR> |
206 CanonHostInfo::Family DoIPv4AddressToNumber(const CHAR* spec, | 186 CanonHostInfo::Family DoIPv4AddressToNumber(const CHAR* spec, |
207 const url_parse::Component& host, | 187 const url_parse::Component& host, |
208 unsigned char address[4], | 188 unsigned char address[4], |
209 int* num_ipv4_components) { | 189 int* num_ipv4_components) { |
210 // The identified components. Not all may exist. | 190 // The identified components. Not all may exist. |
211 url_parse::Component components[4]; | 191 url_parse::Component components[4]; |
212 if (!FindIPv4Components(spec, host, components)) | 192 if (!FindIPv4Components(spec, host, components)) |
213 return CanonHostInfo::NEUTRAL; | 193 return CanonHostInfo::NEUTRAL; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 bool DoCanonicalizeIPv4Address(const CHAR* spec, | 254 bool DoCanonicalizeIPv4Address(const CHAR* spec, |
275 const url_parse::Component& host, | 255 const url_parse::Component& host, |
276 CanonOutput* output, | 256 CanonOutput* output, |
277 CanonHostInfo* host_info) { | 257 CanonHostInfo* host_info) { |
278 host_info->family = IPv4AddressToNumber( | 258 host_info->family = IPv4AddressToNumber( |
279 spec, host, host_info->address, &host_info->num_ipv4_components); | 259 spec, host, host_info->address, &host_info->num_ipv4_components); |
280 | 260 |
281 switch (host_info->family) { | 261 switch (host_info->family) { |
282 case CanonHostInfo::IPV4: | 262 case CanonHostInfo::IPV4: |
283 // Definitely an IPv4 address. | 263 // Definitely an IPv4 address. |
284 AppendIPv4Address(host_info->address, output, &host_info->out_host); | 264 host_info->out_host.begin = output->length(); |
| 265 AppendIPv4Address(host_info->address, output); |
| 266 host_info->out_host.len = output->length() - host_info->out_host.begin; |
285 return true; | 267 return true; |
286 case CanonHostInfo::BROKEN: | 268 case CanonHostInfo::BROKEN: |
287 // Definitely broken. | 269 // Definitely broken. |
288 return true; | 270 return true; |
289 default: | 271 default: |
290 // Could be IPv6 or a hostname. | 272 // Could be IPv6 or a hostname. |
291 return false; | 273 return false; |
292 } | 274 } |
293 } | 275 } |
294 | 276 |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 } | 598 } |
617 } | 599 } |
618 | 600 |
619 // No invalid characters. Could still be IPv4 or a hostname. | 601 // No invalid characters. Could still be IPv4 or a hostname. |
620 host_info->family = CanonHostInfo::NEUTRAL; | 602 host_info->family = CanonHostInfo::NEUTRAL; |
621 return false; | 603 return false; |
622 } | 604 } |
623 | 605 |
624 host_info->out_host.begin = output->length(); | 606 host_info->out_host.begin = output->length(); |
625 output->push_back('['); | 607 output->push_back('['); |
| 608 AppendIPv6Address(host_info->address, output); |
| 609 output->push_back(']'); |
| 610 host_info->out_host.len = output->length() - host_info->out_host.begin; |
626 | 611 |
627 // We will now output the address according to the rules in: | 612 host_info->family = CanonHostInfo::IPV6; |
| 613 return true; |
| 614 } |
| 615 |
| 616 } // namespace |
| 617 |
| 618 void AppendIPv4Address(const unsigned char address[4], CanonOutput* output) { |
| 619 for (int i = 0; i < 4; i++) { |
| 620 char str[16]; |
| 621 _itoa_s(address[i], str, 10); |
| 622 |
| 623 for (int ch = 0; str[ch] != 0; ch++) |
| 624 output->push_back(str[ch]); |
| 625 |
| 626 if (i != 3) |
| 627 output->push_back('.'); |
| 628 } |
| 629 } |
| 630 |
| 631 void AppendIPv6Address(const unsigned char address[16], CanonOutput* output) { |
| 632 // We will output the address according to the rules in: |
628 // http://tools.ietf.org/html/draft-kawamura-ipv6-text-representation-01#secti
on-4 | 633 // http://tools.ietf.org/html/draft-kawamura-ipv6-text-representation-01#secti
on-4 |
629 | 634 |
630 // Start by finding where to place the "::" contraction (if any). | 635 // Start by finding where to place the "::" contraction (if any). |
631 url_parse::Component contraction_range; | 636 url_parse::Component contraction_range; |
632 ChooseIPv6ContractionRange(host_info->address, &contraction_range); | 637 ChooseIPv6ContractionRange(address, &contraction_range); |
633 | 638 |
634 for (int i = 0; i <= 14;) { | 639 for (int i = 0; i <= 14;) { |
635 // We check 2 bytes at a time, from bytes (0, 1) to (14, 15), inclusive. | 640 // We check 2 bytes at a time, from bytes (0, 1) to (14, 15), inclusive. |
636 DCHECK(i % 2 == 0); | 641 DCHECK(i % 2 == 0); |
637 if (i == contraction_range.begin && contraction_range.len > 0) { | 642 if (i == contraction_range.begin && contraction_range.len > 0) { |
638 // Jump over the contraction. | 643 // Jump over the contraction. |
639 if (i == 0) | 644 if (i == 0) |
640 output->push_back(':'); | 645 output->push_back(':'); |
641 output->push_back(':'); | 646 output->push_back(':'); |
642 i = contraction_range.end(); | 647 i = contraction_range.end(); |
643 } else { | 648 } else { |
644 // Consume the next 16 bits from |host_info->address|. | 649 // Consume the next 16 bits from |address|. |
645 int x = host_info->address[i] << 8 | host_info->address[i + 1]; | 650 int x = address[i] << 8 | address[i + 1]; |
646 | 651 |
647 i += 2; | 652 i += 2; |
648 | 653 |
649 // Stringify the 16 bit number (at most requires 4 hex digits). | 654 // Stringify the 16 bit number (at most requires 4 hex digits). |
650 char str[5]; | 655 char str[5]; |
651 _itoa_s(x, str, 16); | 656 _itoa_s(x, str, 16); |
652 for (int ch = 0; str[ch] != 0; ++ch) | 657 for (int ch = 0; str[ch] != 0; ++ch) |
653 output->push_back(str[ch]); | 658 output->push_back(str[ch]); |
654 | 659 |
655 // Put a colon after each number, except the last. | 660 // Put a colon after each number, except the last. |
656 if (i < 16) | 661 if (i < 16) |
657 output->push_back(':'); | 662 output->push_back(':'); |
658 } | 663 } |
659 } | 664 } |
660 | |
661 output->push_back(']'); | |
662 host_info->out_host.len = output->length() - host_info->out_host.begin; | |
663 | |
664 host_info->family = CanonHostInfo::IPV6; | |
665 return true; | |
666 } | 665 } |
667 | 666 |
668 } // namespace | |
669 | |
670 bool FindIPv4Components(const char* spec, | 667 bool FindIPv4Components(const char* spec, |
671 const url_parse::Component& host, | 668 const url_parse::Component& host, |
672 url_parse::Component components[4]) { | 669 url_parse::Component components[4]) { |
673 return DoFindIPv4Components<char, unsigned char>(spec, host, components); | 670 return DoFindIPv4Components<char, unsigned char>(spec, host, components); |
674 } | 671 } |
675 | 672 |
676 bool FindIPv4Components(const char16* spec, | 673 bool FindIPv4Components(const char16* spec, |
677 const url_parse::Component& host, | 674 const url_parse::Component& host, |
678 url_parse::Component components[4]) { | 675 url_parse::Component components[4]) { |
679 return DoFindIPv4Components<char16, char16>(spec, host, components); | 676 return DoFindIPv4Components<char16, char16>(spec, host, components); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 unsigned char address[16]) { | 720 unsigned char address[16]) { |
724 return DoIPv6AddressToNumber<char, unsigned char>(spec, host, address); | 721 return DoIPv6AddressToNumber<char, unsigned char>(spec, host, address); |
725 } | 722 } |
726 | 723 |
727 bool IPv6AddressToNumber(const char16* spec, | 724 bool IPv6AddressToNumber(const char16* spec, |
728 const url_parse::Component& host, | 725 const url_parse::Component& host, |
729 unsigned char address[16]) { | 726 unsigned char address[16]) { |
730 return DoIPv6AddressToNumber<char16, char16>(spec, host, address); | 727 return DoIPv6AddressToNumber<char16, char16>(spec, host, address); |
731 } | 728 } |
732 | 729 |
733 | |
734 } // namespace url_canon | 730 } // namespace url_canon |
OLD | NEW |