Skip to content

Commit 5cf5a6f

Browse files
iwdgoalexbrainman
authored andcommitted
os: return an error when the argument of Mkdir on Windows is os.DevNull
Test added. Fixes #24556 Change-Id: I4d1cd4513142edeea1a983fbfde46c2fccecab2a Reviewed-on: https://go-review.googlesource.com/c/go/+/186139 Run-TryBot: Alex Brainman <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Alex Brainman <[email protected]>
1 parent cb325fe commit 5cf5a6f

File tree

3 files changed

+39
-20
lines changed

3 files changed

+39
-20
lines changed

src/os/file.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,9 @@ func (f *File) WriteString(s string) (n int, err error) {
228228
// bits (before umask).
229229
// If there is an error, it will be of type *PathError.
230230
func Mkdir(name string, perm FileMode) error {
231+
if runtime.GOOS == "windows" && isWindowsNulName(name) {
232+
return &PathError{"mkdir", name, syscall.ENOTDIR}
233+
}
231234
e := syscall.Mkdir(fixLongPath(name), syscallMode(perm))
232235

233236
if e != nil {
@@ -560,3 +563,21 @@ func (f *File) SyscallConn() (syscall.RawConn, error) {
560563
}
561564
return newRawConn(f)
562565
}
566+
567+
// isWindowsNulName reports whether name is os.DevNull ('NUL') on Windows.
568+
// True is returned if name is 'NUL' whatever the case.
569+
func isWindowsNulName(name string) bool {
570+
if len(name) != 3 {
571+
return false
572+
}
573+
if name[0] != 'n' && name[0] != 'N' {
574+
return false
575+
}
576+
if name[1] != 'u' && name[1] != 'U' {
577+
return false
578+
}
579+
if name[2] != 'l' && name[2] != 'L' {
580+
return false
581+
}
582+
return true
583+
}

src/os/os_windows_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,3 +1168,19 @@ func TestWindowsReadlink(t *testing.T) {
11681168
mklink(t, "relfilelink", "file")
11691169
testReadlink(t, "relfilelink", "file")
11701170
}
1171+
1172+
// os.Mkdir(os.DevNull) fails.
1173+
func TestMkdirDevNull(t *testing.T) {
1174+
err := os.Mkdir(os.DevNull, 777)
1175+
oserr, ok := err.(*os.PathError)
1176+
if !ok {
1177+
t.Fatalf("error (%T) is not *os.PathError", err)
1178+
}
1179+
errno, ok := oserr.Err.(syscall.Errno)
1180+
if !ok {
1181+
t.Fatalf("error (%T) is not syscall.Errno", oserr)
1182+
}
1183+
if errno != syscall.ENOTDIR {
1184+
t.Fatalf("error %d is not syscall.ENOTDIR", errno)
1185+
}
1186+
}

src/os/stat_windows.go

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,6 @@ import (
1010
"unsafe"
1111
)
1212

13-
// isNulName reports whether name is NUL file name.
14-
// For example, it returns true for both "NUL" and "nul".
15-
func isNulName(name string) bool {
16-
if len(name) != 3 {
17-
return false
18-
}
19-
if name[0] != 'n' && name[0] != 'N' {
20-
return false
21-
}
22-
if name[1] != 'u' && name[1] != 'U' {
23-
return false
24-
}
25-
if name[2] != 'l' && name[2] != 'L' {
26-
return false
27-
}
28-
return true
29-
}
30-
3113
// Stat returns the FileInfo structure describing file.
3214
// If there is an error, it will be of type *PathError.
3315
func (file *File) Stat() (FileInfo, error) {
@@ -39,7 +21,7 @@ func (file *File) Stat() (FileInfo, error) {
3921
// I don't know any better way to do that for directory
4022
return Stat(file.dirinfo.path)
4123
}
42-
if isNulName(file.name) {
24+
if isWindowsNulName(file.name) {
4325
return &devNullStat, nil
4426
}
4527

@@ -65,7 +47,7 @@ func stat(funcname, name string, createFileAttrs uint32) (FileInfo, error) {
6547
if len(name) == 0 {
6648
return nil, &PathError{funcname, name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
6749
}
68-
if isNulName(name) {
50+
if isWindowsNulName(name) {
6951
return &devNullStat, nil
7052
}
7153
namep, err := syscall.UTF16PtrFromString(fixLongPath(name))

0 commit comments

Comments
 (0)