From 7b70cb1dbc448a35297bb6ae4595315b9947e0ce Mon Sep 17 00:00:00 2001 From: John Starich Date: Sat, 11 Jul 2020 18:13:38 -0500 Subject: [PATCH 1/3] Fix MemMapFs.Chmod changing non-perm bits --- memmap.go | 22 ++++++++++++++++++---- memmap_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/memmap.go b/memmap.go index b7b1474b..39b1e75d 100644 --- a/memmap.go +++ b/memmap.go @@ -141,9 +141,7 @@ func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error { m.registerWithParent(item) m.mu.Unlock() - m.Chmod(name, perm|os.ModeDir) - - return nil + return m.unrestrictedChmod(name, perm|os.ModeDir) } func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error { @@ -240,7 +238,7 @@ func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, erro } } if chmod { - m.Chmod(name, perm) + return file, m.unrestrictedChmod(name, perm) } return file, nil } @@ -321,6 +319,22 @@ func (m *MemMapFs) Stat(name string) (os.FileInfo, error) { } func (m *MemMapFs) Chmod(name string, mode os.FileMode) error { + const chmodBits = os.ModePerm | os.ModeSetuid | os.ModeSetgid | os.ModeSticky // Only a subset of bits are allowed to be changed. Documented under os.Chmod() + mode &= chmodBits + + m.mu.RLock() + f, ok := m.getData()[name] + m.mu.RUnlock() + if !ok { + return &os.PathError{Op: "chmod", Path: name, Err: ErrFileNotFound} + } + prevOtherBits := mem.GetFileInfo(f).Mode() & ^chmodBits + + mode = prevOtherBits | mode + return m.unrestrictedChmod(name, mode) +} + +func (m *MemMapFs) unrestrictedChmod(name string, mode os.FileMode) error { name = normalizePath(name) m.mu.RLock() diff --git a/memmap_test.go b/memmap_test.go index a88ea30b..76a712db 100644 --- a/memmap_test.go +++ b/memmap_test.go @@ -472,3 +472,34 @@ func TestMemFsUnexpectedEOF(t *testing.T) { t.Fatal("Expected ErrUnexpectedEOF") } } + +func TestMemFsChmod(t *testing.T) { + t.Parallel() + + fs := NewMemMapFs() + const file = "/hello" + if err := fs.Mkdir(file, 0700); err != nil { + t.Fatal(err) + } + + info, err := fs.Stat(file) + if err != nil { + t.Fatal(err) + } + if info.Mode().String() != "drwx------" { + t.Fatal("mkdir failed to create a directory: mode =", info.Mode()) + } + + err = fs.Chmod(file, 0) + if err != nil { + t.Error("Failed to run chmod:", err) + } + + info, err = fs.Stat(file) + if err != nil { + t.Fatal(err) + } + if info.Mode().String() != "d---------" { + t.Error("chmod should not change file type. New mode =", info.Mode()) + } +} From 57ab25aed5652c5c9691ac2544958c488b7f0961 Mon Sep 17 00:00:00 2001 From: John Starich Date: Sat, 11 Jul 2020 20:42:35 -0500 Subject: [PATCH 2/3] Use more appropriate func name for unrestricted mode changes --- memmap.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/memmap.go b/memmap.go index 39b1e75d..6be0e9c2 100644 --- a/memmap.go +++ b/memmap.go @@ -141,7 +141,7 @@ func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error { m.registerWithParent(item) m.mu.Unlock() - return m.unrestrictedChmod(name, perm|os.ModeDir) + return m.setFileMode(name, perm|os.ModeDir) } func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error { @@ -238,7 +238,7 @@ func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, erro } } if chmod { - return file, m.unrestrictedChmod(name, perm) + return file, m.setFileMode(name, perm) } return file, nil } @@ -331,10 +331,10 @@ func (m *MemMapFs) Chmod(name string, mode os.FileMode) error { prevOtherBits := mem.GetFileInfo(f).Mode() & ^chmodBits mode = prevOtherBits | mode - return m.unrestrictedChmod(name, mode) + return m.setFileMode(name, mode) } -func (m *MemMapFs) unrestrictedChmod(name string, mode os.FileMode) error { +func (m *MemMapFs) setFileMode(name string, mode os.FileMode) error { name = normalizePath(name) m.mu.RLock() From d443df9ff3dfff432351d0938ee654c482291f6c Mon Sep 17 00:00:00 2001 From: John Starich Date: Sat, 11 Jul 2020 20:57:46 -0500 Subject: [PATCH 3/3] Fix test for Windows --- memmap_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/memmap_test.go b/memmap_test.go index 76a712db..371096ff 100644 --- a/memmap_test.go +++ b/memmap_test.go @@ -477,7 +477,7 @@ func TestMemFsChmod(t *testing.T) { t.Parallel() fs := NewMemMapFs() - const file = "/hello" + const file = "hello" if err := fs.Mkdir(file, 0700); err != nil { t.Fatal(err) }