Skip to content

Update ftplib to CPython 3.11.5 #5073

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

Merged
merged 1 commit into from
Oct 1, 2023
Merged
Show file tree
Hide file tree
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
55 changes: 32 additions & 23 deletions Lib/ftplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,17 @@ class error_proto(Error): pass # response does not begin with [1-5]

# The class itself
class FTP:

'''An FTP client class.

To create a connection, call the class using these arguments:
host, user, passwd, acct, timeout
host, user, passwd, acct, timeout, source_address, encoding

The first four arguments are all strings, and have default value ''.
timeout must be numeric and defaults to None if not passed,
meaning that no timeout will be set on any ftp socket(s)
The parameter ´timeout´ must be numeric and defaults to None if not
passed, meaning that no timeout will be set on any ftp socket(s).
If a timeout is passed, then this is now the default timeout for all ftp
socket operations for this instance.
The last parameter is the encoding of filenames, which defaults to utf-8.

Then use self.connect() with optional host and port argument.

Expand All @@ -102,15 +102,19 @@ class FTP:
sock = None
file = None
welcome = None
passiveserver = 1
encoding = "latin-1"
passiveserver = True
# Disables https://bugs.python.org/issue43285 security if set to True.
trust_server_pasv_ipv4_address = False

# Initialization method (called by class instantiation).
# Initialize host to localhost, port to standard ftp port
# Optional arguments are host (for connect()),
# and user, passwd, acct (for login())
def __init__(self, host='', user='', passwd='', acct='',
timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=None):
timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=None, *,
encoding='utf-8'):
"""Initialization method (called by class instantiation).
Initialize host to localhost, port to standard ftp port.
Optional arguments are host (for connect()),
and user, passwd, acct (for login()).
"""
self.encoding = encoding
self.source_address = source_address
self.timeout = timeout
if host:
Expand Down Expand Up @@ -146,6 +150,8 @@ def connect(self, host='', port=0, timeout=-999, source_address=None):
self.port = port
if timeout != -999:
self.timeout = timeout
if self.timeout is not None and not self.timeout:
raise ValueError('Non-blocking socket (timeout=0) is not supported')
if source_address is not None:
self.source_address = source_address
sys.audit("ftplib.connect", self, self.host, self.port)
Expand Down Expand Up @@ -316,8 +322,13 @@ def makeport(self):
return sock

def makepasv(self):
"""Internal: Does the PASV or EPSV handshake -> (address, port)"""
if self.af == socket.AF_INET:
host, port = parse227(self.sendcmd('PASV'))
untrusted_host, port = parse227(self.sendcmd('PASV'))
if self.trust_server_pasv_ipv4_address:
host = untrusted_host
else:
host = self.sock.getpeername()[0]
else:
host, port = parse229(self.sendcmd('EPSV'), self.sock.getpeername())
return host, port
Expand Down Expand Up @@ -704,9 +715,10 @@ class FTP_TLS(FTP):
'''
ssl_version = ssl.PROTOCOL_TLS_CLIENT

def __init__(self, host='', user='', passwd='', acct='', keyfile=None,
certfile=None, context=None,
timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=None):
def __init__(self, host='', user='', passwd='', acct='',
keyfile=None, certfile=None, context=None,
timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=None, *,
encoding='utf-8'):
if context is not None and keyfile is not None:
raise ValueError("context and keyfile arguments are mutually "
"exclusive")
Expand All @@ -725,12 +737,13 @@ def __init__(self, host='', user='', passwd='', acct='', keyfile=None,
keyfile=keyfile)
self.context = context
self._prot_p = False
FTP.__init__(self, host, user, passwd, acct, timeout, source_address)
super().__init__(host, user, passwd, acct,
timeout, source_address, encoding=encoding)

def login(self, user='', passwd='', acct='', secure=True):
if secure and not isinstance(self.sock, ssl.SSLSocket):
self.auth()
return FTP.login(self, user, passwd, acct)
return super().login(user, passwd, acct)

def auth(self):
'''Set up secure control connection by using TLS/SSL.'''
Expand All @@ -740,8 +753,7 @@ def auth(self):
resp = self.voidcmd('AUTH TLS')
else:
resp = self.voidcmd('AUTH SSL')
self.sock = self.context.wrap_socket(self.sock,
server_hostname=self.host)
self.sock = self.context.wrap_socket(self.sock, server_hostname=self.host)
self.file = self.sock.makefile(mode='r', encoding=self.encoding)
return resp

Expand Down Expand Up @@ -778,7 +790,7 @@ def prot_c(self):
# --- Overridden FTP methods

def ntransfercmd(self, cmd, rest=None):
conn, size = FTP.ntransfercmd(self, cmd, rest)
conn, size = super().ntransfercmd(cmd, rest)
if self._prot_p:
conn = self.context.wrap_socket(conn,
server_hostname=self.host)
Expand Down Expand Up @@ -823,7 +835,6 @@ def parse227(resp):
'''Parse the '227' response for a PASV request.
Raises error_proto if it does not contain '(h1,h2,h3,h4,p1,p2)'
Return ('host.addr.as.numbers', port#) tuple.'''

if resp[:3] != '227':
raise error_reply(resp)
global _227_re
Expand All @@ -843,7 +854,6 @@ def parse229(resp, peer):
'''Parse the '229' response for an EPSV request.
Raises error_proto if it does not contain '(|||port|)'
Return ('host.addr.as.numbers', port#) tuple.'''

if resp[:3] != '229':
raise error_reply(resp)
left = resp.find('(')
Expand All @@ -865,7 +875,6 @@ def parse257(resp):
'''Parse the '257' response for a MKD or PWD request.
This is a response to a MKD or PWD request: a directory name.
Returns the directoryname in the 257 reply.'''

if resp[:3] != '257':
raise error_reply(resp)
if resp[3:5] != ' "':
Expand Down
Loading