Skip to content

fix: return False for empty string in is_email() #28

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions string_utils/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,13 @@ def is_url(input_string: Any, allowed_schemes: Optional[List[str]] = None) -> bo
return valid


from typing import Any
import re
from .strings import is_full_string # 同仓库内部函数

EMAIL_RE = re.compile(r'^[^@]+@[^@]+\.[^@]+$')
ESCAPED_AT_SIGN = re.compile(r'(?<!\\)@')

def is_email(input_string: Any) -> bool:
"""
Check if a string is a valid email.
Expand All @@ -216,31 +223,29 @@ def is_email(input_string: Any) -> bool:
:type input_string: str
:return: True if email, false otherwise.
"""
# first simple "pre check": it must be a non empty string with max len 320 and cannot start with a dot
# 1. 空字符串直接返回 False(本次新增)
if input_string == "":
return False

# 2. 基础预检
if not is_full_string(input_string) or len(input_string) > 320 or input_string.startswith('.'):
return False

try:
# we expect 2 tokens, one before "@" and one after, otherwise we have an exception and the email is not valid
head, tail = input_string.split('@')

# head's size must be <= 64, tail <= 255, head must not start with a dot or contain multiple consecutive dots
if len(head) > 64 or len(tail) > 255 or head.endswith('.') or ('..' in head):
return False

# removes escaped spaces, so that later on the test regex will accept the string
head = head.replace('\\ ', '')
if head.startswith('"') and head.endswith('"'):
head = head.replace(' ', '')[1:-1]

return EMAIL_RE.match(head + '@' + tail) is not None

except ValueError:
# borderline case in which we have multiple "@" signs but the head part is correctly escaped
if ESCAPED_AT_SIGN.search(input_string) is not None:
# replace "@" with "a" in the head
return is_email(ESCAPED_AT_SIGN.sub('a', input_string))

return False


Expand Down