Skip to content

Commit

Permalink
Merge pull request #45638 from JuliaLang/sf/fix_musl_libgit2
Browse files Browse the repository at this point in the history
Fix LibGit2 tests on `x86_64-linux-musl`
  • Loading branch information
staticfloat authored Jun 20, 2022
2 parents 7a1e404 + 22042be commit 782458c
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 12 deletions.
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

0 comments on commit 782458c

Please sign in to comment.