Skip to content

Commit

Permalink
fix #627: PermissionError may occur on Windows when binding ports fro…
Browse files Browse the repository at this point in the history
…m a pre-configured PASV range.
  • Loading branch information
giampaolo committed Jun 21, 2024
1 parent 15bb392 commit 90773a3
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 4 deletions.
5 changes: 5 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ Version: 1.5.10 - (UNRELEASED)
* #626: use argparse instead of deprecated optparse.
* #628: use pytest instead of unittest.

**Bug fixes**

* #627: PermissionError may occur on Windows when binding ports from a
pre-configured PASV range.

Version: 1.5.9 - 2023-10-25
===========================

Expand Down
13 changes: 9 additions & 4 deletions pyftpdlib/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def callable(obj):
FileNotFoundError = FileNotFoundError # NOQA
FileExistsError = FileExistsError # NOQA
InterruptedError = InterruptedError # NOQA
PermissionError = PermissionError # NOQA
else:
# https://github.com/PythonCharmers/python-future/blob/exceptions/
# src/future/types/exceptions/pep3151.py
Expand Down Expand Up @@ -96,14 +97,18 @@ def __subclasscheck__(cls, classinfo):
def FileNotFoundError(inst):
return getattr(inst, 'errno', _SENTINEL) == errno.ENOENT

@_instance_checking_exception(EnvironmentError)
def FileExistsError(inst):
return getattr(inst, 'errno', _SENTINEL) == errno.EEXIST

@_instance_checking_exception(EnvironmentError)
def InterruptedError(inst):
return getattr(inst, 'errno', _SENTINEL) == errno.EINTR

@_instance_checking_exception(EnvironmentError)
def PermissionError(inst):
return getattr(inst, 'errno', _SENTINEL) in (errno.EACCES, errno.EPERM)

@_instance_checking_exception(EnvironmentError)
def FileExistsError(inst):
return getattr(inst, 'errno', _SENTINEL) == errno.EEXIST

if platform.python_implementation() != "CPython":
try:
raise OSError(errno.EEXIST, "perm")
Expand Down
6 changes: 6 additions & 0 deletions pyftpdlib/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

from . import __ver__
from ._compat import PY3
from ._compat import PermissionError
from ._compat import b
from ._compat import getcwdu
from ._compat import super
Expand Down Expand Up @@ -477,6 +478,11 @@ def __init__(self, cmd_channel, extmode=False):
self.set_reuse_addr()
try:
self.bind((local_ip, port))
except PermissionError:
self.cmd_channel.log(
"ignoring EPERM when bind()ing port %s" % port,
logfun=logger.debug,
)
except socket.error as err:
if err.errno == errno.EADDRINUSE: # port already in use
if ports:
Expand Down

0 comments on commit 90773a3

Please sign in to comment.