1
0
mirror of https://github.com/golang/go synced 2024-11-18 14:54:40 -07:00

os: use GetConsoleCP() instead of GetACP()

It is possible (and common) for Windows systems to use a different codepage
for console applications from that used on normal windowed application
(called ANSI codepage); for instance, most of the western Europe uses
CP850 for console (for backward compatibility with MS-DOS), while
windowed applications use a different codepage depending on the country
(eg: CP1252 aka Latin-1). The usage being changed with this commit is
specifically related to decoding input coming from the console, so the
previous usage of the ANSI codepage was wrong.

Also fixes an issue that previous did convert bytes as NFD. Go is
designed to handle single Unicode code point. This fix change behaivor
to NFC.

Fixes #16857.

Change-Id: I4f41ae83ece47321b6e9a79a2087ecbb8ac066dd
Reviewed-on: https://go-review.googlesource.com/27575
Reviewed-by: Hiroshi Ioka <hirochachacha@gmail.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
Yasuhiro Matsumoto 2016-08-24 10:34:16 +09:00 committed by Alex Brainman
parent 16f81b617e
commit b851ded09a
3 changed files with 13 additions and 3 deletions

View File

@ -138,4 +138,5 @@ func Rename(oldpath, newpath string) error {
} }
//sys GetACP() (acp uint32) = kernel32.GetACP //sys GetACP() (acp uint32) = kernel32.GetACP
//sys GetConsoleCP() (ccp uint32) = kernel32.GetConsoleCP
//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar //sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar

View File

@ -43,6 +43,7 @@ var (
procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW")
procMoveFileExW = modkernel32.NewProc("MoveFileExW") procMoveFileExW = modkernel32.NewProc("MoveFileExW")
procGetACP = modkernel32.NewProc("GetACP") procGetACP = modkernel32.NewProc("GetACP")
procGetConsoleCP = modkernel32.NewProc("GetConsoleCP")
procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar") procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar")
) )
@ -84,6 +85,12 @@ func GetACP() (acp uint32) {
return return
} }
func GetConsoleCP() (ccp uint32) {
r0, _, _ := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0)
ccp = uint32(r0)
return
}
func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) { func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) {
r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar))
nwrite = int32(r0) nwrite = int32(r0)

View File

@ -217,14 +217,16 @@ func (f *File) readConsole(b []byte) (n int, err error) {
if len(b) > 0 { if len(b) > 0 {
pmb = &mbytes[0] pmb = &mbytes[0]
} }
acp := windows.GetACP() ccp := windows.GetConsoleCP()
nwc, err := windows.MultiByteToWideChar(acp, 2, pmb, int32(nmb), nil, 0) // Convert from 8-bit console encoding to UTF16.
// MultiByteToWideChar defaults to Unicode NFC form, which is the expected one.
nwc, err := windows.MultiByteToWideChar(ccp, 0, pmb, int32(nmb), nil, 0)
if err != nil { if err != nil {
return 0, err return 0, err
} }
wchars := make([]uint16, nwc) wchars := make([]uint16, nwc)
pwc := &wchars[0] pwc := &wchars[0]
nwc, err = windows.MultiByteToWideChar(acp, 2, pmb, int32(nmb), pwc, nwc) nwc, err = windows.MultiByteToWideChar(ccp, 0, pmb, int32(nmb), pwc, nwc)
if err != nil { if err != nil {
return 0, err return 0, err
} }