Skip to content

Commit 217ed95

Browse files
committed
path/filepath: detect Windows CONIN$ and CONOUT$ paths in IsLocal
CreateFile creates a handle to the console input or screen buffer when opening a file named CONIN$ or CONOUT$: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#consoles Detect these paths as non-local. For #56219. Change-Id: Ib09e76a110d6ec09aef8038074b9bcbae09d00d7 Reviewed-on: https://go-review.googlesource.com/c/go/+/451657 Run-TryBot: Damien Neil <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Bryan Mills <[email protected]>
1 parent 38b9ff6 commit 217ed95

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

src/path/filepath/path_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ var winislocaltests = []IsLocalTest{
174174
{`C:`, false},
175175
{`C:\a`, false},
176176
{`..\a`, false},
177+
{`CONIN$`, false},
178+
{`conin$`, false},
179+
{`CONOUT$`, false},
180+
{`conout$`, false},
181+
{`dollar$`, true}, // not a special file name
177182
}
178183

179184
var plan9islocaltests = []IsLocalTest{

src/path/filepath/path_windows.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func toUpper(c byte) byte {
2020
return c
2121
}
2222

23-
// isReservedName reports if name is a Windows reserved device name.
23+
// isReservedName reports if name is a Windows reserved device name or a console handle.
2424
// It does not detect names with an extension, which are also reserved on some Windows versions.
2525
//
2626
// For details, search for PRN in
@@ -34,6 +34,17 @@ func isReservedName(name string) bool {
3434
return len(name) == 4 && '1' <= name[3] && name[3] <= '9'
3535
}
3636
}
37+
// Passing CONIN$ or CONOUT$ to CreateFile opens a console handle.
38+
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#consoles
39+
//
40+
// While CONIN$ and CONOUT$ aren't documented as being files,
41+
// they behave the same as CON. For example, ./CONIN$ also opens the console input.
42+
if len(name) == 6 && name[5] == '$' && strings.EqualFold(name, "CONIN$") {
43+
return true
44+
}
45+
if len(name) == 7 && name[6] == '$' && strings.EqualFold(name, "CONOUT$") {
46+
return true
47+
}
3748
return false
3849
}
3950

0 commit comments

Comments
 (0)