• Alex Brainman's avatar
    os: make readConsole handle its input and output correctly · 1af769da
    Alex Brainman authored
    This CL introduces first test for readConsole. And new test
    discovered couple of problems with readConsole.
    
    Console characters consist of multiple bytes each, but byte blocks
    returned by syscall.ReadFile have no character boundaries. Some
    multi-byte characters might start at the end of one block, and end
    at the start of next block. readConsole feeds these blocks to
    syscall.MultiByteToWideChar to convert them into utf16, but if some
    multi-byte characters have no ending or starting bytes, the
    syscall.MultiByteToWideChar might get confused. Current version of
    syscall.MultiByteToWideChar call will make
    syscall.MultiByteToWideChar ignore all these not complete
    multi-byte characters.
    
    The CL solves this issue by changing processing from "randomly
    sized block of bytes at a time" to "one multi-byte character at a
    time". New readConsole code calls syscall.ReadFile to get 1 byte
    first. Then it feeds this byte to syscall.MultiByteToWideChar.
    The new syscall.MultiByteToWideChar call uses MB_ERR_INVALID_CHARS
    flag to make syscall.MultiByteToWideChar return error if input is
    not complete character. If syscall.MultiByteToWideChar returns
    correspondent error, we read another byte and pass 2 byte buffer
    into syscall.MultiByteToWideChar, and so on until success.
    
    Old readConsole code would also sometimes return no data if user
    buffer was smaller then uint16 size, which would confuse callers
    that supply 1 byte buffer. This CL fixes that problem too.
    
    Fixes #17097
    
    Change-Id: I88136cdf6a7bf3aed5fbb9ad2c759b6c0304ce30
    Reviewed-on: https://go-review.googlesource.com/29493
    Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: default avatarRuss Cox <rsc@golang.org>
    1af769da
file_windows.go 14.7 KB