mem: ReadFile returns an error when filename is a directory#633
Open
amitmishra11 wants to merge 1 commit into
Open
mem: ReadFile returns an error when filename is a directory#633amitmishra11 wants to merge 1 commit into
amitmishra11 wants to merge 1 commit into
Conversation
MemMapFs's in-memory directory entries have an empty data buffer, the
same as an empty regular file. File.ReadAt had no directory check, so
reading a directory returned (0, io.EOF) just like reading an empty
file would, and ReadFile (which treats Read's first EOF as a normal
empty read, not an error) silently returned ("", nil) instead of an
error.
Add a directory check to File.ReadAt that returns a PathError wrapping
syscall.EISDIR, matching the real os.File's behavior of erroring when
Read is called on a directory.
Added TestReadFileOnDirectory, which calls Afero.ReadFile on a path
created with MkdirAll and asserts an error is returned. Verified the
test catches the regression by temporarily removing the directory
check: the test fails exactly as described in the issue (no error,
empty contents).
Fixes spf13#201
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 #201
Bug
afero.ReadFileon aMemMapFssilently succeeds with empty content when the path is a directory, instead of returning an error like the realos.ReadFiledoes (EISDIR).Root cause
An in-memory directory's
FileData.databuffer is empty, the same as an empty regular file.mem.File.ReadAthad no check forfileData.dir, so reading a directory returned(0, io.EOF)exactly like reading an empty file would.File.Readandafero.ReadFile's underlyingreadAlltreat a firstio.EOFas a normal empty read (not an error), so the whole call chain returns("", nil)with no indication anything was wrong.Readdiralready has the equivalent inverse check (if !f.fileData.dir { return error }), so this bringsReadAtin line with that existing convention.Fix
Added a directory check at the top of
mem.File.ReadAtthat returns&os.PathError{Op: "read", Path: ..., Err: syscall.EISDIR}, matching the realos.File's behavior whenReadis called on a directory.Scoped to the read path only (matching the issue title/report) — did not touch
Write/WriteAt, which is a separate question not raised by this issue.Tests
Added
TestReadFileOnDirectoryinioutil_test.go, following the existingTestReadFilepattern: creates a directory viaMkdirAll, callsAfero.ReadFileon it, and asserts an error is returned.I verified the test actually catches the regression: temporarily removed the new directory check in
ReadAtand reran the test — it failed withReadFile somedir: error expected, got nil (contents=""), reproducing the exact symptom from the issue. Restoring the fix makes it pass again.Verification
go build ./...— cleango vet ./...— cleango test ./...— all pass exceptTestLstatIfPossible/TestSymlinkIfPossible/TestReadlinkIfPossible, which fail identically on unmodifiedmasterin my environment (Windows, no privilege to create symlinks) — confirmed pre-existing and unrelated by stashing my changes and rerunning.