Skip to content

Command.get raises TypeError on the first lowercase FTP command, so a valid RFC 959 request cannot be parsed #582

Description

@JarryShaw

Command.get normalises the key it registers but not the key it looks up, so the first lowercase or mixed-case FTP command in a capture raises TypeError instead of parsing.

Mechanism

pcapkit/const/ftp/command.py:297-298:

if key not in Command._member_map_:
    return extend_enum(Command, key.upper(), default if default is not None else key)
return Command[key]

The membership test uses key, the registration uses key.upper(). For key='retr' the test misses — _member_map_ holds RETR — so it calls extend_enum(Command, 'RETR', ...), and RETR is already a member.

This is reachable from real wire data, not just from a direct get() call. pcapkit/protocols/application/ftp.py:36 compiles the request pattern with re.I:

FTP_REQUEST = re.compile(rb'^(?P<cmmd>[A-Z]{3,4})( +(?P<args>.*))?\r\n$', re.I)

so a lowercase command matches, and ftp.py:99 passes the matched text verbatim: cmmd_val = Enum_Command.get(cmmd).

RFC 959 section 5.3 defines FTP commands as case-insensitive -- "Upper and lower case alphabetic characters are to be treated identically", so retr file.txt is a valid request that this library cannot parse.

Reproduction

>>> from pcapkit.const.ftp.command import Command
>>> Command.get('retr')
TypeError: 'RETR' already in use as <Command.RETR: Retrieve>

Executed on origin/main (9c240a60e), CPython 3.14.7, aenum 3.1.17. It fails on the first call, not on a second — the collision is against the statically defined member, so nothing needs to have been registered first.

Notes

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssues reporting a defect (set by the bug report template; a default, not an assessment)

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions