fix: handle long inline keys in server.user_authorized_keys - #1908
Open
wowi42 wants to merge 1 commit into
Open
Conversation
Commit 4a7440e replaced os.path.exists with Path.exists in read_any_pub_key_file. On Python < 3.14, pathlib.Path.exists re-raises OSError (ENAMETOOLONG) for paths exceeding NAME_MAX, so passing a long inline public key (eg a full RSA key) crashed the operation instead of being used as a key. os.path.exists swallows OSError and returns False, which is the correct semantic here ("is this string a file?"). Fixes pyinfra-dev#1907
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1907.
Problem
Since v3.10, passing a long inline public key (e.g. a full RSA key) to
server.user_authorized_keys/server.user(public_keys=...)crashes withOSError: [Errno 36] File name too longon Python 3.11–3.13.4a7440e(os.path → pathlib refactor) changedos.path.exists(try_path)toPath(try_path).exists()inread_any_pub_key_file. Inline keys are tried as file paths first, and a long key exceedsNAME_MAX. The two APIs handleENAMETOOLONGdifferently:os.path.exists()catches allOSError→ returnsFalsepathlib.Path.exists()(Python ≤ 3.13) only swallowsENOENT/ENOTDIR/EBADF/ELOOPand re-raisesENAMETOOLONGPython 3.14 is unaffected because
pathlibthere catches allOSErrorinexists(), which matches the reporter's observations.Fix
Revert that check to
os.path.exists()— semantically the right API for "does this string happen to be a file?" — with a comment explaining why, and drop the now-unusedpathlibimport.Test
New fixture
tests/operations/server.user_authorized_keys/long_inline_key_not_a_file.yamlcovering a >255-char inline key. Verified manually against the real filesystem on Python 3.13.14 (old code raisesENAMETOOLONG, fixed code returnsFalse) and 3.14.6; the full suite passes on both.