OLD | NEW |
1 /* | 1 /* |
2 * This file is part of the WebKit project. | 2 * This file is part of the WebKit project. |
3 * | 3 * |
4 * Copyright (C) 2009 Michelangelo De Simone <micdesim@gmail.com> | 4 * Copyright (C) 2009 Michelangelo De Simone <micdesim@gmail.com> |
5 * Copyright (C) 2010 Google Inc. All rights reserved. | 5 * Copyright (C) 2010 Google Inc. All rights reserved. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "InputTypeNames.h" | 27 #include "InputTypeNames.h" |
28 #include "bindings/v8/ScriptRegexp.h" | 28 #include "bindings/v8/ScriptRegexp.h" |
29 #include "core/html/HTMLInputElement.h" | 29 #include "core/html/HTMLInputElement.h" |
30 #include "core/html/parser/HTMLParserIdioms.h" | 30 #include "core/html/parser/HTMLParserIdioms.h" |
31 #include "core/page/Chrome.h" | 31 #include "core/page/Chrome.h" |
32 #include "core/page/ChromeClient.h" | 32 #include "core/page/ChromeClient.h" |
33 #include "platform/text/PlatformLocale.h" | 33 #include "platform/text/PlatformLocale.h" |
34 #include "public/platform/Platform.h" | 34 #include "public/platform/Platform.h" |
35 #include "wtf/PassOwnPtr.h" | 35 #include "wtf/PassOwnPtr.h" |
36 #include "wtf/text/StringBuilder.h" | 36 #include "wtf/text/StringBuilder.h" |
37 #include <unicode/uidna.h> | 37 #include <unicode/idna.h> |
| 38 #include <unicode/unistr.h> |
38 | 39 |
39 namespace WebCore { | 40 namespace WebCore { |
40 | 41 |
41 using blink::WebLocalizedString; | 42 using blink::WebLocalizedString; |
42 | 43 |
43 // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-typ
e-attribute.html#valid-e-mail-address | 44 // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-typ
e-attribute.html#valid-e-mail-address |
44 static const char localPartCharacters[] = "abcdefghijklmnopqrstuvwxyz0123456789!
#$%&'*+/=?^_`{|}~.-"; | 45 static const char localPartCharacters[] = "abcdefghijklmnopqrstuvwxyz0123456789!
#$%&'*+/=?^_`{|}~.-"; |
45 static const char emailPattern[] = | 46 static const char emailPattern[] = |
46 "[a-z0-9!#$%&'*+/=?^_`{|}~.-]+" // local part | 47 "[a-z0-9!#$%&'*+/=?^_`{|}~.-]+" // local part |
47 "@" | 48 "@" |
48 "[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?" // domain part | 49 "[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?" // domain part |
49 "(?:\\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*"; | 50 "(?:\\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*"; |
50 | 51 |
51 // RFC5321 says the maximum total length of a domain name is 255 octets. | 52 // RFC5321 says the maximum total length of a domain name is 255 octets. |
52 static const size_t maximumDomainNameLength = 255; | 53 static const int32_t maximumDomainNameLength = 255; |
53 static const int32_t idnaConversionOption = UIDNA_ALLOW_UNASSIGNED; | 54 // Use the same option as in url/url_canon_icu.cc |
| 55 static const int32_t idnaConversionOption = UIDNA_CHECK_BIDI; |
54 | 56 |
55 static String convertEmailAddressToASCII(const String& address) | 57 static String convertEmailAddressToASCII(const String& address) |
56 { | 58 { |
57 if (address.containsOnlyASCII()) | 59 if (address.containsOnlyASCII()) |
58 return address; | 60 return address; |
59 | 61 |
60 size_t atPosition = address.find('@'); | 62 size_t atPosition = address.find('@'); |
61 if (atPosition == kNotFound) | 63 if (atPosition == kNotFound) |
62 return address; | 64 return address; |
63 | 65 |
64 UErrorCode error = U_ZERO_ERROR; | 66 // UnicodeString ctor for copy-on-write does not work reliably (in debug |
65 UChar domainNameBuffer[maximumDomainNameLength]; | 67 // build.) TODO(jshin): In an unlikely case this is a perf-issue, treat |
66 int32_t domainNameLength = uidna_IDNToASCII(address.charactersWithNullTermin
ation().data() + atPosition + 1, address.length() - atPosition - 1, domainNameBu
ffer, WTF_ARRAY_LENGTH(domainNameBuffer), idnaConversionOption, 0, &error); | 68 // 8bit and non-8bit strings separately. |
67 if (error != U_ZERO_ERROR || domainNameLength <= 0) | 69 icu::UnicodeString idnDomainName(address.charactersWithNullTermination().dat
a() + atPosition + 1, address.length() - atPosition - 1); |
| 70 icu::UnicodeString domainName; |
| 71 |
| 72 // Leak |idna| at the end. |
| 73 UErrorCode errorCode = U_ZERO_ERROR; |
| 74 static icu::IDNA *idna = icu::IDNA::createUTS46Instance(idnaConversionOption
, errorCode); |
| 75 ASSERT(idna); |
| 76 icu::IDNAInfo idnaInfo; |
| 77 idna->nameToASCII(idnDomainName, domainName, idnaInfo, errorCode); |
| 78 if (U_FAILURE(errorCode) || idnaInfo.hasErrors() || domainName.length() > ma
ximumDomainNameLength) |
68 return address; | 79 return address; |
69 | 80 |
70 StringBuilder builder; | 81 StringBuilder builder; |
71 builder.append(address, 0, atPosition + 1); | 82 builder.append(address, 0, atPosition + 1); |
72 builder.append(domainNameBuffer, domainNameLength); | 83 builder.append(domainName.getBuffer(), domainName.length()); |
73 return builder.toString(); | 84 return builder.toString(); |
74 } | 85 } |
75 | 86 |
76 String EmailInputType::convertEmailAddressToUnicode(const String& address) const | 87 String EmailInputType::convertEmailAddressToUnicode(const String& address) const |
77 { | 88 { |
78 if (!address.containsOnlyASCII()) | 89 if (!address.containsOnlyASCII()) |
79 return address; | 90 return address; |
80 | 91 |
81 size_t atPosition = address.find('@'); | 92 size_t atPosition = address.find('@'); |
82 if (atPosition == kNotFound) | 93 if (atPosition == kNotFound) |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 builder.reserveCapacity(value.length()); | 292 builder.reserveCapacity(value.length()); |
282 for (size_t i = 0; i < addresses.size(); ++i) { | 293 for (size_t i = 0; i < addresses.size(); ++i) { |
283 if (i > 0) | 294 if (i > 0) |
284 builder.append(","); | 295 builder.append(","); |
285 builder.append(convertEmailAddressToUnicode(addresses[i])); | 296 builder.append(convertEmailAddressToUnicode(addresses[i])); |
286 } | 297 } |
287 return builder.toString(); | 298 return builder.toString(); |
288 } | 299 } |
289 | 300 |
290 } // namespace WebCore | 301 } // namespace WebCore |
OLD | NEW |