diff options
Diffstat (limited to 'libphobos/src')
-rw-r--r-- | libphobos/src/MERGE | 2 | ||||
-rw-r--r-- | libphobos/src/Makefile.am | 20 | ||||
-rw-r--r-- | libphobos/src/Makefile.in | 23 | ||||
-rw-r--r-- | libphobos/src/std/file.d | 4 | ||||
-rw-r--r-- | libphobos/src/std/format/write.d | 11 | ||||
-rw-r--r-- | libphobos/src/std/internal/windows/bcrypt.d | 65 | ||||
-rw-r--r-- | libphobos/src/std/random.d | 84 |
7 files changed, 159 insertions, 50 deletions
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 3dfe008..a28116a 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -60034b56e2a036a66fa78cbc0ec0290956423684 +40ffbb3641495b02815891ee004d4c6e173b1089 The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/Makefile.am b/libphobos/src/Makefile.am index 94e28f3..a84fc4d 100644 --- a/libphobos/src/Makefile.am +++ b/libphobos/src/Makefile.am @@ -26,7 +26,8 @@ D_EXTRA_DFLAGS=-fpreview=dip1000 -fpreview=dtorfields -fpreview=fieldwise \ # D flags for compilation AM_DFLAGS= \ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \ - $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(SECTION_FLAGS) $(CET_FLAGS) + $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(SECTION_FLAGS) $(CET_FLAGS) \ + $(OS_DFLAGS) # Flags for other kinds of sources AM_CFLAGS=$(CET_FLAGS) @@ -144,14 +145,15 @@ PHOBOS_DSOURCES = etc/c/curl.d etc/c/odbc/odbc32.d etc/c/odbc/odbc64.d \ std/internal/unicode_comp.d std/internal/unicode_decomp.d \ std/internal/unicode_grapheme.d std/internal/unicode_norm.d \ std/internal/unicode_tables.d std/internal/windows/advapi32.d \ - std/json.d std/logger/core.d std/logger/filelogger.d \ - std/logger/multilogger.d std/logger/nulllogger.d std/logger/package.d \ - std/math/algebraic.d std/math/constants.d std/math/exponential.d \ - std/math/hardware.d std/math/operations.d std/math/package.d \ - std/math/remainder.d std/math/rounding.d std/math/traits.d \ - std/math/trigonometry.d std/mathspecial.d std/meta.d std/mmfile.d \ - std/net/curl.d std/net/isemail.d std/numeric.d std/outbuffer.d \ - std/package.d std/parallelism.d std/path.d std/process.d std/random.d \ + std/internal/windows/bcrypt.d std/json.d std/logger/core.d \ + std/logger/filelogger.d std/logger/multilogger.d \ + std/logger/nulllogger.d std/logger/package.d std/math/algebraic.d \ + std/math/constants.d std/math/exponential.d std/math/hardware.d \ + std/math/operations.d std/math/package.d std/math/remainder.d \ + std/math/rounding.d std/math/traits.d std/math/trigonometry.d \ + std/mathspecial.d std/meta.d std/mmfile.d std/net/curl.d \ + std/net/isemail.d std/numeric.d std/outbuffer.d std/package.d \ + std/parallelism.d std/path.d std/process.d std/random.d \ std/range/interfaces.d std/range/package.d std/range/primitives.d \ std/regex/internal/backtracking.d std/regex/internal/generator.d \ std/regex/internal/ir.d std/regex/internal/kickstart.d \ diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in index d052aa8..64cc9c3 100644 --- a/libphobos/src/Makefile.in +++ b/libphobos/src/Makefile.in @@ -252,6 +252,7 @@ am__dirstamp = $(am__leading_dot)dirstamp @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/unicode_norm.lo \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/unicode_tables.lo \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/windows/advapi32.lo \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/windows/bcrypt.lo \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/json.lo std/logger/core.lo \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/logger/filelogger.lo \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/logger/multilogger.lo \ @@ -410,6 +411,7 @@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ +OS_DFLAGS = @OS_DFLAGS@ OS_LINK_SPEC = @OS_LINK_SPEC@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ @@ -518,7 +520,8 @@ D_EXTRA_DFLAGS = -fpreview=dip1000 -fpreview=dtorfields -fpreview=fieldwise \ # D flags for compilation AM_DFLAGS = \ $(phobos_lt_pic_flag) $(phobos_compiler_shared_flag) \ - $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(SECTION_FLAGS) $(CET_FLAGS) + $(WARN_DFLAGS) $(CHECKING_DFLAGS) $(SECTION_FLAGS) $(CET_FLAGS) \ + $(OS_DFLAGS) # Flags for other kinds of sources @@ -612,14 +615,15 @@ libgphobos_la_LINK = $(LIBTOOL) --tag=D $(libgphobos_la_LIBTOOLFLAGS) \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/unicode_comp.d std/internal/unicode_decomp.d \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/unicode_grapheme.d std/internal/unicode_norm.d \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/unicode_tables.d std/internal/windows/advapi32.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/json.d std/logger/core.d std/logger/filelogger.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/logger/multilogger.d std/logger/nulllogger.d std/logger/package.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/math/algebraic.d std/math/constants.d std/math/exponential.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/math/hardware.d std/math/operations.d std/math/package.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/math/remainder.d std/math/rounding.d std/math/traits.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/math/trigonometry.d std/mathspecial.d std/meta.d std/mmfile.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/net/curl.d std/net/isemail.d std/numeric.d std/outbuffer.d \ -@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/package.d std/parallelism.d std/path.d std/process.d std/random.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/internal/windows/bcrypt.d std/json.d std/logger/core.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/logger/filelogger.d std/logger/multilogger.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/logger/nulllogger.d std/logger/package.d std/math/algebraic.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/math/constants.d std/math/exponential.d std/math/hardware.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/math/operations.d std/math/package.d std/math/remainder.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/math/rounding.d std/math/traits.d std/math/trigonometry.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/mathspecial.d std/meta.d std/mmfile.d std/net/curl.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/net/isemail.d std/numeric.d std/outbuffer.d std/package.d \ +@ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/parallelism.d std/path.d std/process.d std/random.d \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/range/interfaces.d std/range/package.d std/range/primitives.d \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/backtracking.d std/regex/internal/generator.d \ @ENABLE_LIBDRUNTIME_ONLY_FALSE@ std/regex/internal/ir.d std/regex/internal/kickstart.d \ @@ -901,6 +905,7 @@ std/internal/windows/$(am__dirstamp): @: > std/internal/windows/$(am__dirstamp) std/internal/windows/advapi32.lo: \ std/internal/windows/$(am__dirstamp) +std/internal/windows/bcrypt.lo: std/internal/windows/$(am__dirstamp) std/json.lo: std/$(am__dirstamp) std/logger/$(am__dirstamp): @$(MKDIR_P) std/logger diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d index c3466ac..0b8da50 100644 --- a/libphobos/src/std/file.d +++ b/libphobos/src/std/file.d @@ -983,10 +983,10 @@ private void renameImpl(scope const(char)[] f, scope const(char)[] t, import std.conv : to, text; if (!f) - f = to!(typeof(f))(fromz[0 .. wcslen(fromz)]); + f = fromz ? to!(typeof(f))(fromz[0 .. wcslen(fromz)]) : "(null)"; if (!t) - t = to!(typeof(t))(toz[0 .. wcslen(toz)]); + t = toz ? to!(typeof(t))(toz[0 .. wcslen(toz)]) : "(null)"; enforce(false, new FileException( diff --git a/libphobos/src/std/format/write.d b/libphobos/src/std/format/write.d index d704c14..68a96d4 100644 --- a/libphobos/src/std/format/write.d +++ b/libphobos/src/std/format/write.d @@ -534,6 +534,8 @@ uint formattedWrite(Writer, Char, Args...)(auto ref Writer w, const scope Char[] // Are we already done with formats? Then just dump each parameter in turn uint currentArg = 0; + bool lastWasConsumeAll; + while (spec.writeUpToNextSpec(w)) { if (currentArg == Args.length && !spec.indexStart) @@ -649,7 +651,10 @@ uint formattedWrite(Writer, Char, Args...)(auto ref Writer w, const scope Char[] } default: if (spec.indexEnd == spec.indexEnd.max) + { + lastWasConsumeAll = true; break; + } else if (spec.indexEnd == spec.indexStart) throw new FormatException( text("Positional specifier %", spec.indexStart, '$', spec.spec, @@ -660,7 +665,8 @@ uint formattedWrite(Writer, Char, Args...)(auto ref Writer w, const scope Char[] " index exceeds ", Args.length)); } } - return currentArg; + + return lastWasConsumeAll ? Args.length : currentArg; } /// @@ -1212,7 +1218,8 @@ if (isSomeString!(typeof(fmt))) import std.array : appender; auto w = appender!(char[])(); - formattedWrite(w, "%1:$d", 1, 2, 3); + uint count = formattedWrite(w, "%1:$d", 1, 2, 3); + assert(count == 3); assert(w.data == "123"); } diff --git a/libphobos/src/std/internal/windows/bcrypt.d b/libphobos/src/std/internal/windows/bcrypt.d new file mode 100644 index 0000000..239dcd5 --- /dev/null +++ b/libphobos/src/std/internal/windows/bcrypt.d @@ -0,0 +1,65 @@ +module std.internal.windows.bcrypt; + +version (Windows): + +import core.sys.windows.bcrypt : BCryptGenRandom, BCRYPT_USE_SYSTEM_PREFERRED_RNG; +import core.sys.windows.windef : HMODULE, PUCHAR, ULONG; +import core.sys.windows.ntdef : NT_SUCCESS; + +pragma(lib, "Bcrypt.lib"); + +package(std) bool bcryptGenRandom(T)(out T result) @trusted +{ + loadBcrypt(); + + const gotRandom = ptrBCryptGenRandom( + null, + cast(PUCHAR) &result, + ULONG(T.sizeof), + BCRYPT_USE_SYSTEM_PREFERRED_RNG, + ); + + return NT_SUCCESS(gotRandom); +} + +private +{ + HMODULE hBcrypt = null; + typeof(BCryptGenRandom)* ptrBCryptGenRandom; +} + +private void loadBcrypt() @nogc nothrow +{ + import core.sys.windows.winbase : GetProcAddress, LoadLibraryA; + + if (!hBcrypt) + { + hBcrypt = LoadLibraryA("Bcrypt.dll"); + if (!hBcrypt) + assert(false, `LoadLibraryA("Bcrypt.dll") failed.`); // `@nogc` + + ptrBCryptGenRandom = cast(typeof(ptrBCryptGenRandom)) GetProcAddress(hBcrypt , "BCryptGenRandom"); + if (!ptrBCryptGenRandom) + assert(false, `GetProcAddress(hBcrypt , "BCryptGenRandom") failed.`); // `@nogc` + } +} + +// Will free `Bcrypt.dll`. +private void freeBcrypt() @nogc nothrow +{ + import core.sys.windows.winbase : FreeLibrary; + + if (hBcrypt) + { + if (!FreeLibrary(hBcrypt)) + assert(false, `FreeLibrary("Bcrypt.dll") failed.`); // `@nogc` + + hBcrypt = null; + ptrBCryptGenRandom = null; + } +} + +static ~this() +{ + freeBcrypt(); +} diff --git a/libphobos/src/std/random.d b/libphobos/src/std/random.d index fb4e546..edb8902c 100644 --- a/libphobos/src/std/random.d +++ b/libphobos/src/std/random.d @@ -1774,41 +1774,71 @@ else version (linux) { - // `getrandom()` was introduced in Linux 3.17. + version (linux_legacy_emulate_getrandom) + { + /+ + Emulates `getrandom()` for backwards compatibility + with outdated kernels and legacy libc versions. + + `getrandom()` was added to the GNU C Library in v2.25. + +/ + pragma(msg, "`getrandom()` emulation for legacy Linux targets is enabled."); + + /+ + On modern kernels (5.6+), `/dev/random` would behave more similar + to `getrandom()`. + However, this emulator was specifically written for systems older + than that. Hence, `/dev/urandom` is the CSPRNG of choice. + + <https://web.archive.org/web/20200914181930/https://www.2uo.de/myths-about-urandom/> + +/ + private static immutable _pathLinuxSystemCSPRNG = "/dev/urandom"; + + import core.sys.posix.sys.types : ssize_t; + + /+ + Linux `getrandom()` emulation built upon `/dev/urandom`. + The fourth parameter (`uint flags`) is happily ignored. + +/ + private ssize_t getrandom( + void* buf, + size_t buflen, + uint, + ) @system nothrow @nogc + { + import core.stdc.stdio : fclose, fopen, fread; - // Shim for missing bindings in druntime - version (none) - import core.sys.linux.sys.random : getrandom; + auto blockDev = fopen(_pathLinuxSystemCSPRNG.ptr, "r"); + if (blockDev is null) + assert(false, "System CSPRNG unavailable: `fopen(\"" ~ _pathLinuxSystemCSPRNG ~ "\")` failed."); + scope (exit) fclose(blockDev); + + const bytesRead = fread(buf, 1, buflen, blockDev); + return bytesRead; + } + } else { - import core.sys.posix.sys.types : ssize_t; - extern extern(C) ssize_t getrandom( - void* buf, - size_t buflen, - uint flags, - ) @system nothrow @nogc; + // `getrandom()` was introduced in Linux 3.17. + + // Shim for missing bindings in druntime + version (none) + import core.sys.linux.sys.random : getrandom; + else + { + import core.sys.posix.sys.types : ssize_t; + private extern extern(C) ssize_t getrandom( + void* buf, + size_t buflen, + uint flags, + ) @system nothrow @nogc; + } } } version (Windows) { - pragma(lib, "Bcrypt.lib"); - - private bool bcryptGenRandom(T)(out T result) @trusted - { - import core.sys.windows.windef : PUCHAR, ULONG; - import core.sys.windows.ntdef : NT_SUCCESS; - import core.sys.windows.bcrypt : BCryptGenRandom, BCRYPT_USE_SYSTEM_PREFERRED_RNG; - - const gotRandom = BCryptGenRandom( - null, - cast(PUCHAR) &result, - ULONG(T.sizeof), - BCRYPT_USE_SYSTEM_PREFERRED_RNG, - ); - - return NT_SUCCESS(gotRandom); - } + import std.internal.windows.bcrypt : bcryptGenRandom; } /** |