fix(sftp): handle Bitvise strict SFTP compliance for directory navigation - #50
Merged
Conversation
…tion Bitvise SSH Server negotiates SFTP v4+ where file type is communicated via a separate `type` field rather than embedded in the Unix permission bits. The existing code only checked `attrs.permissions` with `stat.S_ISDIR()`, which returns False when the file type bits are absent — causing directories like .ssh to appear as regular files and making navigation silently fail. Changes: - list_dir: check attrs.type (SFTP v4+ type field) as fallback when permissions lack file type bits, for both directories and symlinks - chdir: validate target is a directory via stat() after realpath() instead of blindly trusting the canonicalised path - stat: use attrs.type fallback for is_dir detection Closes #46 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ted event loop dispatch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced Mar 2, 2026
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.
Summary
Fixes #46 — cannot enter
.sshdirectory on Bitvise SSH Server after asyncssh migration.Root cause: Bitvise negotiates SFTP v4+ where file type (
directory,regular,symlink) is communicated via a separateattrs.typefield rather than being embedded in Unix permission bits (attrs.permissions). The existing code only checkedstat.S_ISDIR(attrs.permissions), which returnsFalsewhen the type bits are absent — causing directories like.sshto appear as regular files and making navigation silently fail (click tries download instead of chdir).Changes:
list_dir: checkattrs.type(SFTP v4+ file type constant) as fallback when permissions lack file type bits, for both directory and symlink detectionchdir: validate the target is actually a directory viastat()afterrealpath(), instead of blindly trusting the canonicalised path. SurfacesNotADirectoryErrorandPermissionErrorto the UIstat: useattrs.typefallback foris_dirdetectionTest plan
TestSFTPBitviseComplianceclass with 8 tests covering:list_dirdetects directories viatypefield when permissions areNonelist_dirdetects directories viatypefield when permissions lackS_IFDIRbitstype=REGULARstay as files (no false positives)typefield fallbackchdiraccepts directories identified viatypefieldchdiraccepts directories identified via permissions (backward compat)chdirsurfacesPermissionErrorfrom statstat()detects directories viatypefieldchdirrejects non-directories withNotADirectoryErrorchdirvalidates viastat()call🤖 Generated with Claude Code