From 321c312d8246dec6889f5fe334b6193c320baf0e Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 18 Oct 2016 12:34:19 -0400 Subject: [PATCH] os: reject Rename("old", "new") where new is a directory Unix rejects this when new is a non-empty directory. Other systems reject this when new is a directory, empty or not. Make Unix reject empty directory too. Fixes #14527. Change-Id: Ice24b8065264c91c22cba24aa73e142386c29c87 Reviewed-on: https://go-review.googlesource.com/31358 Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/os/file_unix.go | 4 ++++ src/os/os_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/os/file_unix.go b/src/os/file_unix.go index 83a814348f..0d0167f9e3 100644 --- a/src/os/file_unix.go +++ b/src/os/file_unix.go @@ -12,6 +12,10 @@ import ( ) func rename(oldname, newname string) error { + fi, err := Lstat(newname) + if err == nil && fi.IsDir() { + return &LinkError{"rename", oldname, newname, syscall.EEXIST} + } e := syscall.Rename(oldname, newname) if e != nil { return &LinkError{"rename", oldname, newname, e} diff --git a/src/os/os_test.go b/src/os/os_test.go index 0c4042a4bf..44a578418f 100644 --- a/src/os/os_test.go +++ b/src/os/os_test.go @@ -828,6 +828,37 @@ func TestRenameFailed(t *testing.T) { } } +func TestRenameToDirFailed(t *testing.T) { + defer chtmpdir(t)() + from, to := "renamefrom", "renameto" + + Remove(from) + Remove(to) + Mkdir(from, 0777) + Mkdir(to, 0777) + + err := Rename(from, to) + switch err := err.(type) { + case *LinkError: + if err.Op != "rename" { + t.Errorf("rename %q, %q: err.Op: want %q, got %q", from, to, "rename", err.Op) + } + if err.Old != from { + t.Errorf("rename %q, %q: err.Old: want %q, got %q", from, to, from, err.Old) + } + if err.New != to { + t.Errorf("rename %q, %q: err.New: want %q, got %q", from, to, to, err.New) + } + case nil: + t.Errorf("rename %q, %q: expected error, got nil", from, to) + + // cleanup whatever was placed in "renameto" + Remove(to) + default: + t.Errorf("rename %q, %q: expected %T, got %T %v", from, to, new(LinkError), err, err) + } +} + func exec(t *testing.T, dir, cmd string, args []string, expect string) { r, w, err := Pipe() if err != nil { -- 2.48.1