Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix LibGit2 tests on x86_64-linux-musl #45638

Merged
merged 2 commits into from
Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion base/secretbuffer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,17 @@ function SecretBuffer!(d::Vector{UInt8})
s
end

unsafe_SecretBuffer!(s::Cstring) = unsafe_SecretBuffer!(convert(Ptr{UInt8}, s), Int(ccall(:strlen, Csize_t, (Cstring,), s)))
function unsafe_SecretBuffer!(s::Cstring)
if s == C_NULL
throw(ArgumentError("cannot convert NULL to SecretBuffer"))
end
len = Int(ccall(:strlen, Csize_t, (Cstring,), s))
unsafe_SecretBuffer!(convert(Ptr{UInt8}, s), len)
end
function unsafe_SecretBuffer!(p::Ptr{UInt8}, len=1)
if p == C_NULL
throw(ArgumentError("cannot convert NULL to SecretBuffer"))
end
s = SecretBuffer(sizehint=len)
for i in 1:len
write(s, unsafe_load(p, i))
Expand Down
15 changes: 4 additions & 11 deletions base/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -257,19 +257,19 @@ graphical interface.
"""
function getpass end

if Sys.iswindows()
_getch() = UInt8(ccall(:jl_getch, Cint, ()))
function getpass(input::TTY, output::IO, prompt::AbstractString)
input === stdin || throw(ArgumentError("getpass only works for stdin"))
print(output, prompt, ": ")
flush(output)
s = SecretBuffer()
plen = 0
while true
c = UInt8(ccall(:_getch, Cint, ()))
if c == 0xff || c == UInt8('\n') || c == UInt8('\r')
c = _getch()
if c == 0xff || c == UInt8('\n') || c == UInt8('\r') || c == 0x04
break # EOF or return
elseif c == 0x00 || c == 0xe0
ccall(:_getch, Cint, ()) # ignore function/arrow keys
_getch() # ignore function/arrow keys
elseif c == UInt8('\b') && plen > 0
plen -= 1 # delete last character on backspace
elseif !iscntrl(Char(c)) && plen < 128
Expand All @@ -278,13 +278,6 @@ function getpass(input::TTY, output::IO, prompt::AbstractString)
end
return seekstart(s)
end
else
function getpass(input::TTY, output::IO, prompt::AbstractString)
(input === stdin && output === stdout) || throw(ArgumentError("getpass only works for stdin"))
msg = string(prompt, ": ")
unsafe_SecretBuffer!(ccall(:getpass, Cstring, (Cstring,), msg))
end
end

# allow new getpass methods to be defined if stdin has been
# redirected to some custom stream, e.g. in IJulia.
Expand Down
1 change: 1 addition & 0 deletions src/jl_exported_funcs.inc
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@
XX(jl_generic_function_def) \
XX(jl_gensym) \
XX(jl_getallocationgranularity) \
XX(jl_getch) \
XX(jl_getnameinfo) \
XX(jl_getpagesize) \
XX(jl_get_ARCH) \
Expand Down
1 change: 1 addition & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -2057,6 +2057,7 @@ extern JL_DLLEXPORT JL_STREAM *JL_STDERR;
JL_DLLEXPORT JL_STREAM *jl_stdout_stream(void);
JL_DLLEXPORT JL_STREAM *jl_stdin_stream(void);
JL_DLLEXPORT JL_STREAM *jl_stderr_stream(void);
JL_DLLEXPORT int jl_getch(void);

// showing and std streams
JL_DLLEXPORT void jl_flush_cstdio(void) JL_NOTSAFEPOINT;
Expand Down
28 changes: 28 additions & 0 deletions src/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#include <sys/mman.h>
#include <dlfcn.h>
#include <grp.h>

// For `struct termios`
#include <termios.h>
#endif

#ifndef _OS_WINDOWS_
Expand Down Expand Up @@ -514,6 +517,31 @@ JL_DLLEXPORT JL_STREAM *jl_stdin_stream(void) { return JL_STDIN; }
JL_DLLEXPORT JL_STREAM *jl_stdout_stream(void) { return JL_STDOUT; }
JL_DLLEXPORT JL_STREAM *jl_stderr_stream(void) { return JL_STDERR; }

// terminal workarounds
JL_DLLEXPORT int jl_getch(void) JL_NOTSAFEPOINT
{
#if defined(_OS_WINDOWS_)
// Windows has an actual `_getch()`, use that:
return _getch();
#else
// On all other platforms, we do the POSIX terminal manipulation dance
char c;
int r;
struct termios old_termios = {0};
struct termios new_termios = {0};
if (tcgetattr(0, &old_termios) != 0)
return -1;
new_termios = old_termios;
cfmakeraw(&new_termios);
if (tcsetattr(0, TCSADRAIN, &new_termios) != 0)
return -1;
r = read(0, &c, 1);
if (tcsetattr(0, TCSADRAIN, &old_termios) != 0)
return -1;
return r == 1 ? c : -1;
#endif
}

// -- processor native alignment information --

JL_DLLEXPORT void jl_native_alignment(uint_t *int8align, uint_t *int16align, uint_t *int32align,
Expand Down
7 changes: 7 additions & 0 deletions test/secretbuffer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,11 @@ using Test
@test hash(sb1, UInt(5)) === hash(sb2, UInt(5))
shred!(sb1); shred!(sb2)
end
@testset "NULL initialization" begin
null_ptr = Cstring(C_NULL)
@test_throws ArgumentError Base.unsafe_SecretBuffer!(null_ptr)
null_ptr = Ptr{UInt8}(C_NULL)
@test_throws ArgumentError Base.unsafe_SecretBuffer!(null_ptr)
@test_throws ArgumentError Base.unsafe_SecretBuffer!(null_ptr, 0)
end
end