1313# limitations under the License.
1414
1515import math
16+ import re
1617import typing
17- from email .utils import parseaddr
1818from ipaddress import IPv4Address , IPv4Network , IPv6Address , IPv6Network , ip_address , ip_network
1919from urllib import parse as urlparse
2020
2323
2424from protovalidate .internal import string_format
2525
26+ # See https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
27+ _email_regex = re .compile (
28+ r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
29+ )
30+
2631
2732def _validate_hostname (host ):
2833 if not host :
@@ -49,23 +54,6 @@ def _validate_hostname(host):
4954 return not all_digits
5055
5156
52- def validate_email (addr ):
53- parts = parseaddr (addr )
54- if addr != parts [1 ]:
55- return False
56-
57- addr = parts [1 ]
58- if len (addr ) > 254 :
59- return False
60-
61- parts = addr .split ("@" )
62- if len (parts ) != 2 :
63- return False
64- if len (parts [0 ]) > 64 :
65- return False
66- return _validate_hostname (parts [1 ])
67-
68-
6957def validate_host_and_port (string : str , * , port_required : bool ) -> bool :
7058 if not string :
7159 return False
@@ -157,10 +145,19 @@ def is_ip_prefix(val: celtypes.Value, *args) -> celpy.Result:
157145
158146
159147def is_email (string : celtypes .Value ) -> celpy .Result :
148+ """Returns true if the string is an email address, for example "[email protected] ". 149+
150+ Conforms to the definition for a valid email address from the HTML standard.
151+ Note that this standard willfully deviates from RFC 5322, which allows many
152+ unexpected forms of email addresses and will easily match a typographical
153+ error.
154+ """
155+
160156 if not isinstance (string , celtypes .StringType ):
161157 msg = "invalid argument, expected string"
162158 raise celpy .CELEvalError (msg )
163- return celtypes .BoolType (validate_email (string ))
159+ m = _email_regex .match (string ) is not None
160+ return celtypes .BoolType (m )
164161
165162
166163def is_uri (string : celtypes .Value ) -> celpy .Result :
0 commit comments