From 332bc00a7c51372c2f7cc91fdb088c397dcde10e Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Thu, 18 Dec 2025 16:50:53 +0300 Subject: [PATCH 1/8] implement random_bytes function --- runtime-light/stdlib/math/random-functions.h | 32 ++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/runtime-light/stdlib/math/random-functions.h b/runtime-light/stdlib/math/random-functions.h index ba35d303e2..668f1739b3 100644 --- a/runtime-light/stdlib/math/random-functions.h +++ b/runtime-light/stdlib/math/random-functions.h @@ -13,8 +13,15 @@ #include #include #include +#include #include +#if defined(__APPLE__) +#include +#else +#include +#endif + #include "runtime-common/core/runtime-core.h" #include "runtime-common/stdlib/math/random-functions.h" #include "runtime-light/coroutine/task.h" @@ -83,6 +90,15 @@ inline int64_t lcg_modmult(int64_t a, int64_t b, int64_t c, int64_t m, int64_t s return res; } +inline int64_t secure_rand_buf(char* const buf, int64_t length) noexcept { +#if defined(__APPLE__) + arc4random_buf(static_cast(buf), static_cast(length)); + return 0; +#else + return getrandom(buf, static_cast(length), 0x0); +#endif +} + // Analogue of unix's `gettimeofday` // Returns seconds elapsed since Epoch, and milliseconds elapsed from the last second. inline std::pair system_seconds_and_micros() noexcept { @@ -126,6 +142,22 @@ inline double f$lcg_value() noexcept { return static_cast(z) * random_impl_::lcg_value_coef; } +inline Optional f$random_bytes(int64_t length) noexcept { + if (length < 1) [[unlikely]] { + kphp::log::warning("Argument #1 ($length) must be greater than 0"); + return false; + } + + string str{static_cast(length), false}; + + if (random_impl_::secure_rand_buf(str.buffer(), static_cast(length)) == -1) { + kphp::log::warning("Source of randomness cannot be found: {}", strerrordesc_np(errno)); + return false; + } + + return str; +} + inline kphp::coro::task f$uniqid(string prefix = string{}, bool more_entropy = false) noexcept { if (!more_entropy) { co_await f$usleep(1); From 0a0306e3cbe1f3ce2e55fdf26394e47eda13b5dd Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Thu, 18 Dec 2025 17:01:46 +0300 Subject: [PATCH 2/8] test --- builtin-functions/kphp-light/stdlib/math-functions.txt | 4 ++-- tests/phpt/dl/385_random_bytes.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builtin-functions/kphp-light/stdlib/math-functions.txt b/builtin-functions/kphp-light/stdlib/math-functions.txt index 6575523813..19226b9806 100644 --- a/builtin-functions/kphp-light/stdlib/math-functions.txt +++ b/builtin-functions/kphp-light/stdlib/math-functions.txt @@ -164,6 +164,8 @@ function levenshtein ($str1 ::: string, $str2 ::: string) ::: int; function lcg_value() ::: float; +function random_bytes($length ::: int) ::: string | false; + /** @kphp-extern-func-info interruptible */ function uniqid ($prefix ::: string = '', $more_entropy ::: bool = false) ::: string; @@ -187,5 +189,3 @@ define('PHP_ROUND_HALF_ODD', 123423146); /** @kphp-extern-func-info stub generation-required */ function random_int($l ::: int, $r ::: int) ::: int | false; -/** @kphp-extern-func-info stub generation-required */ -function random_bytes($length ::: int) ::: string | false; diff --git a/tests/phpt/dl/385_random_bytes.php b/tests/phpt/dl/385_random_bytes.php index 30c0cf3b42..4c5072e823 100644 --- a/tests/phpt/dl/385_random_bytes.php +++ b/tests/phpt/dl/385_random_bytes.php @@ -1,4 +1,4 @@ -@ok php8 k2_skip +@ok php8 Date: Thu, 18 Dec 2025 20:09:39 +0300 Subject: [PATCH 3/8] fix strerror --- runtime-light/stdlib/math/random-functions.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime-light/stdlib/math/random-functions.h b/runtime-light/stdlib/math/random-functions.h index 668f1739b3..8324a26b2f 100644 --- a/runtime-light/stdlib/math/random-functions.h +++ b/runtime-light/stdlib/math/random-functions.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -151,7 +152,9 @@ inline Optional f$random_bytes(int64_t length) noexcept { string str{static_cast(length), false}; if (random_impl_::secure_rand_buf(str.buffer(), static_cast(length)) == -1) { - kphp::log::warning("Source of randomness cannot be found: {}", strerrordesc_np(errno)); + locale_t c_locale{(kphp::memory::libc_alloc_guard{}, newlocale(LC_MESSAGES_MASK, "C", nullptr))}; + kphp::log::warning("Source of randomness cannot be found: {}", strerror_l(errno, c_locale)); + kphp::memory::libc_alloc_guard{}, freelocale(c_locale); return false; } From e94165287f7d99b2267488239f76ae51b94f84ad Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Fri, 19 Dec 2025 12:01:01 +0300 Subject: [PATCH 4/8] messages first letters --- runtime-light/stdlib/math/random-functions.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime-light/stdlib/math/random-functions.h b/runtime-light/stdlib/math/random-functions.h index 8324a26b2f..5de5297f23 100644 --- a/runtime-light/stdlib/math/random-functions.h +++ b/runtime-light/stdlib/math/random-functions.h @@ -145,7 +145,7 @@ inline double f$lcg_value() noexcept { inline Optional f$random_bytes(int64_t length) noexcept { if (length < 1) [[unlikely]] { - kphp::log::warning("Argument #1 ($length) must be greater than 0"); + kphp::log::warning("argument #1 ($length) must be greater than 0"); return false; } @@ -153,7 +153,7 @@ inline Optional f$random_bytes(int64_t length) noexcept { if (random_impl_::secure_rand_buf(str.buffer(), static_cast(length)) == -1) { locale_t c_locale{(kphp::memory::libc_alloc_guard{}, newlocale(LC_MESSAGES_MASK, "C", nullptr))}; - kphp::log::warning("Source of randomness cannot be found: {}", strerror_l(errno, c_locale)); + kphp::log::warning("source of randomness cannot be found: {}", strerror_l(errno, c_locale)); kphp::memory::libc_alloc_guard{}, freelocale(c_locale); return false; } From c6f84ea111d9682ebc998259533e238d03c4c5f8 Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Thu, 25 Dec 2025 13:46:02 +0300 Subject: [PATCH 5/8] use GRND_NONBLOCK --- runtime-light/stdlib/math/random-functions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime-light/stdlib/math/random-functions.h b/runtime-light/stdlib/math/random-functions.h index 5de5297f23..37fba41aae 100644 --- a/runtime-light/stdlib/math/random-functions.h +++ b/runtime-light/stdlib/math/random-functions.h @@ -96,7 +96,7 @@ inline int64_t secure_rand_buf(char* const buf, int64_t length) noexcept { arc4random_buf(static_cast(buf), static_cast(length)); return 0; #else - return getrandom(buf, static_cast(length), 0x0); + return getrandom(buf, static_cast(length), GRND_NONBLOCK); #endif } From ebcbeea7af35cb2195308b1234df1c9ccd9891db Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Thu, 25 Dec 2025 15:34:21 +0300 Subject: [PATCH 6/8] remove errno handling --- runtime-light/stdlib/math/random-functions.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/runtime-light/stdlib/math/random-functions.h b/runtime-light/stdlib/math/random-functions.h index 37fba41aae..9978bf8b81 100644 --- a/runtime-light/stdlib/math/random-functions.h +++ b/runtime-light/stdlib/math/random-functions.h @@ -11,10 +11,8 @@ #include #include #include -#include #include #include -#include #include #if defined(__APPLE__) @@ -152,9 +150,7 @@ inline Optional f$random_bytes(int64_t length) noexcept { string str{static_cast(length), false}; if (random_impl_::secure_rand_buf(str.buffer(), static_cast(length)) == -1) { - locale_t c_locale{(kphp::memory::libc_alloc_guard{}, newlocale(LC_MESSAGES_MASK, "C", nullptr))}; - kphp::log::warning("source of randomness cannot be found: {}", strerror_l(errno, c_locale)); - kphp::memory::libc_alloc_guard{}, freelocale(c_locale); + kphp::log::warning("source of randomness cannot be found"); return false; } From b2c44d8f78b39dc495654159429a31d9dda630f7 Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Thu, 25 Dec 2025 16:46:32 +0300 Subject: [PATCH 7/8] remove casts --- runtime-light/stdlib/math/random-functions.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime-light/stdlib/math/random-functions.h b/runtime-light/stdlib/math/random-functions.h index 9978bf8b81..4004b3c7de 100644 --- a/runtime-light/stdlib/math/random-functions.h +++ b/runtime-light/stdlib/math/random-functions.h @@ -89,12 +89,12 @@ inline int64_t lcg_modmult(int64_t a, int64_t b, int64_t c, int64_t m, int64_t s return res; } -inline int64_t secure_rand_buf(char* const buf, int64_t length) noexcept { +inline int64_t secure_rand_buf(void* const buf, size_t length) noexcept { #if defined(__APPLE__) - arc4random_buf(static_cast(buf), static_cast(length)); + arc4random_buf(buf, length); return 0; #else - return getrandom(buf, static_cast(length), GRND_NONBLOCK); + return getrandom(buf, length, GRND_NONBLOCK); #endif } From 589ba67b4e3716e25c507fe27baec7bd089a8e7f Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Thu, 25 Dec 2025 16:50:12 +0300 Subject: [PATCH 8/8] add static_cast --- runtime-light/stdlib/math/random-functions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime-light/stdlib/math/random-functions.h b/runtime-light/stdlib/math/random-functions.h index 4004b3c7de..50e95680c2 100644 --- a/runtime-light/stdlib/math/random-functions.h +++ b/runtime-light/stdlib/math/random-functions.h @@ -149,7 +149,7 @@ inline Optional f$random_bytes(int64_t length) noexcept { string str{static_cast(length), false}; - if (random_impl_::secure_rand_buf(str.buffer(), static_cast(length)) == -1) { + if (random_impl_::secure_rand_buf(static_cast(str.buffer()), static_cast(length)) == -1) { kphp::log::warning("source of randomness cannot be found"); return false; }