1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 08:12:21 +01:00
Commit Graph

129 Commits

Author SHA1 Message Date
Arnaud Le Blanc
d1048a0869 Add zend_random_bytes(), zend_random_bytes_insecure() functions (#14054)
Co-authored-by: Tim Düsterhus <tim@bastelstu.be>
2024-06-12 17:27:01 +02:00
Peter Kokot
5d3fab9334 Sync #if/ifdef/defined (#14520)
These are either undefined or defined (to value 1):
- __DragonFly__
- __FreeBSD__
- HAS_MCAST_EXT
- HAVE_GETCWD
- HAVE_GETWD
- HAVE_GLIBC_ICONV
- HAVE_JIT
- HAVE_LCHOWN
- HAVE_NL_LANGINFO
- HAVE_RL_CALLBACK_READ_CHAR
- HAVE_RL_ON_NEW_LINE
- HAVE_SQL_EXTENDED_FETCH
- HAVE_UTIME

Follow up of GH-5526 (-Wundef)
2024-06-11 22:47:05 +02:00
Jorg Adam Sowa
45714e2cb8 random: Remove redundant assignments in php_random_rangeX() (#14536)
Co-authored-by: Tim Düsterhus <tim@bastelstu.be>
2024-06-11 21:36:02 +02:00
Peter Kokot
a82d86479c Replace WIN32 conditions with _WIN32 or PHP_WIN32 (#14462)
* Replace WIN32 conditions with _WIN32 or PHP_WIN32

WIN32 is defined by the SDK and not defined all the time on Windows by
compilers or the environment. _WIN32 is defined as 1 when the
compilation target is 32-bit ARM, 64-bit ARM, x86, or x64. Otherwise,
undefined.

This syncs these usages one step further.

Upstream libgd has replaced WIN32 with _WIN32 via
c60d9fe577

PHP_WIN32 is added to ext/sockets/sockets.stub.php as done in other
*.stub.php files at this point.

* Use PHP_WIN32 in ext/random

* Use PHP_WIN32 in ext/sockets

* Use _WIN32 in xxhash.h as done upstream

See https://github.com/Cyan4973/xxHash/pull/931

* Update end comment with PHP_WIN32
2024-06-10 21:59:41 +02:00
Peter Kokot
84a0da1574 Sync #if/ifdef/defined (#14508)
This syncs CPP macro conditions:
- _WIN32
- _WIN64
- HAVE_ALLOCA_H
- HAVE_ALPHASORT
- HAVE_ARPA_INET_H
- HAVE_CONFIG_H
- HAVE_DIRENT_H
- HAVE_DLFCN_H
- HAVE_GETTIMEOFDAY
- HAVE_LIBDL
- HAVE_POLL_H
- HAVE_PWD_H
- HAVE_SCANDIR
- HAVE_SYS_FILE_H
- HAVE_SYS_PARAM_H
- HAVE_SYS_SOCKET_H
- HAVE_SYS_TIME_H
- HAVE_SYS_TYPES_H
- HAVE_SYS_WAIT_H
- HAVE_UNISTD_H
- PHP_WIN32
- ZEND_WIN32

These are either undefined or defined to 1 in Autotools and Windows.

Follow up of GH-5526 (-Wundef).
2024-06-09 14:23:41 +02:00
Gina Peter Banyard
8c16076dc3 ext/random: Fix signess issues 2024-06-08 17:15:01 +01:00
Peter Kokot
da86eec3db Sync #if/ifdef/defined (#14371)
These are either undefined or defined to value 1 in Autotools and
Windows:
- HAVE_COMMONCRYPTO_COMMONRANDOM_H
- HAVE_EXIF
- HAVE_FOPENCOOKIE
- HAVE_IF_NAMETOINDEX
- HAVE_LIBICONV
- HAVE_SOCKETS
- HAVE_STRUCT_STAT_ST_RDEV
- HAVE_STRUCT_TM_TM_GMTOFF
- HAVE_STRUCT_TM_TM_ZONE

Follow up of GH-5526 (-Wundef)
2024-06-07 23:45:17 +02:00
Arnaud Le Blanc
44c199ce6b random: Make php_random_bytes() useable early during engine startup (#14291)
php_random_bytes() can now be used before RANDOM_G() is initialized
2024-05-30 17:24:34 +02:00
Tim Düsterhus
8cf8751533 random: Remove internal aliases for the global Mt19937 functionality (#14314)
* random: Remove `php_rand()`

This effectively is just a slim wrapper around `(zend_long)php_mt_rand()`. It
is not compatible between 32-bit and 64-bit builds of PHP, due to the use of
`zend_long`, which may result in negative integersbeing returned on 32-bit
platforms, whereas 64-bit platforms will be compatible with `php_mt_rand()`. An
example would be the `0` seed, which emits 2357136044 on 64-bit platforms and
-1937831252 on 32-bit platforms.

Users of `php_rand()` should ideally migrate to one of the more modern engines,
with extension-specific state. If drop-in compatibility is desired, they can
just cast the result of `php_mt_rand()`. But providing it out of the box does
not provide a value-add and is potentially dangerous.

* random: Remove `php_srand()`

With `php_rand()` gone, preserving its companion `php_srand()` is just
confusing. The same recommendations apply: Migrate to a modern engine if
possible and just call `php_mt_srand()` with an appropriately casted input.

* random: Remove `PHP_RAND_MAX` and `RAND_MAX`

These are the companions to `php_rand()`, which was removed in a previous
commit.

Generally speaking the maximum returnable value is not particularly useful
anyways. Attempting it to create a random float by dividing the returned
integer by the maximum value would result in a bias if the maximum value would
be larger than 2**53 and even for that case, the various `range()` helpers
allow to easily retrieve a uniformly distributed integer from a suitable range.

* UPGRADING.INTERNALS
2024-05-27 08:12:13 +02:00
Tim Düsterhus
6c59c29942 random: Add missing PHPAPI to php_random_generate_fallback_seed() in random.c
The declaration in the header had it.
2024-05-23 23:12:29 +02:00
Tim Düsterhus
d5cc7e9109 random: Add PHPAPI to all php_random_algo definitions (#14088)
The php_random.h header already defines them as `PHPAPI` and they actually are
part of the public API.

Co-authored-by: Arnaud Le Blanc <arnaud.lb@gmail.com>
2024-04-30 21:01:13 +02:00
Ørjan Malde
ff76cb738b rudimentary midipix port (#13896) 2024-04-18 08:19:44 +02:00
Tim Düsterhus
7c851042cb random: Add clarifying comments to the implementation of CombinedLCG
The implementation is needlessly obfuscated. It's not immediately clear that
MODMULT is a simple modular multiplication, despite its name. Specifically it's
not clear which of the parameters is the second factor.

Furthermore the stated period is off-by-one: A value of `0` is part of its own
chain, thus it may not be included in the period of the underlying generators.
2024-04-06 17:46:28 +02:00
Tim Düsterhus
6fb20cd9de random: Simplify implementation of php_random_generate_fallback_seed() (#13761)
As all the input bits and pieces are mixed with SHA-1, cross-architecture
compatibility is not required and we can just mix in whatever they may look
like in memory, instead of going through the `write_*()` helpers that were
created for a previous in-development version that first filled a buffer that
was then hashed (allowing for easy inspection of the input data, but making it
harder to safely add values without checking for buffer overflows all the
time).

This change should also fix a build error on macOS ZTS: The thread ID is an
opaque type and not guaranteed to be arithmetic as per IEEE Std 1003.1-2017.
And indeed macOS defines it as a pointer to a structure, failing due to the
implicit pointer to integer conversion.
2024-03-20 09:41:01 +01:00
Tim Düsterhus
807524d61c random: Use CSPRNG for CombinedLCG seeding (#13748)
Now that the CombinedLCG is no longer used within GENERATE_SEED(), we can
safely use the CSPRNG with a php_random_generate_fallback_seed() fallback to
seed the CombinedLCG.
2024-03-19 20:13:44 +01:00
Tim Düsterhus
81744d6cf7 random: Improve the output quality of RANDOM_SEED() (#13730)
* random: Improve the output quality of RANDOM_SEED()

Previously 4 consecutive calls to `RANDOM_SEED()` each for 4 different CLI
requests resulted in:

    $ sapi/cli/php test.php
    2c13e9fde9caa
    2c13e9fd1d6b0
    2c13e9fd4de34
    2c13e9fd1610e
    $ sapi/cli/php test.php
    2c1436764fe07
    2c14367621770
    2c143676c0bf6
    2c143676e02f5
    $ sapi/cli/php test.php
    2c144995a0626
    2c14499590fe2
    2c144995c65db
    2c14499536833
    $ sapi/cli/php test.php
    2c145cb30860b
    2c145cb3ec027
    2c145cb33b4ca
    2c145cb38ff63

Now they result in:

    $ sapi/cli/php test.php
    6796973ace1b5f3d
    1913daf5c158cb4b
    255dbf24237bc8c9
    7c3ba22e60f35196
    $ sapi/cli/php test.php
    afb7cc9ba9819cd2
    3e01a71b91ad020c
    6b718364d3ef108
    bdcd17beeb4b31d2
    $ sapi/cli/php test.php
    53d36eb9b83f8788
    4381c85e816187aa
    2e9b32ee9898e71e
    31d15c946842bddb
    $ sapi/cli/php test.php
    2037a3cba88114b4
    ba0b0d93a9bb43aa
    e13d82d2421269e2
    191de474f3292240

* tree-wide: Replace GENERATE_SEED() by php_random_generate_fallback_seed()

* random: Fix NTS build

* random: Fix Windows build
2024-03-18 16:08:23 +01:00
Tim Düsterhus
bf0abd1629 random: Initialize the mode field when seeding in php_random_default_status() (#13608)
This is a follow-up fix for GH-13579. The issue was detected in the nightly
MSAN build.
2024-03-06 18:57:17 +01:00
Tim Düsterhus
3d4cb1da3e random: Convert RANDOM_SEED() from a macro to a function (#13575)
* random: Convert `RANDOM_SEED()` from a macro to a function

* random: Fix GENERATE_SEED()'s prototype
2024-03-04 19:51:17 +01:00
Tim Düsterhus
06569bbd04 random: Clean Up the Mt19937 state struct (#13577)
* random: Make Mt19937's `mode` field an enum

* random: Reorder the `php_random_status_state_mt19937` struct

Empirical testing did not show any differences in performance, but it makes
sense to me to put the `count` field (which is accessed for every invocation of
Mt19937) at the beginning of the struct, keeping it near the values from the
state array that are returned first, resulting in only a single cache line load
if only a small amount of numbers are requested.

It naturally follows to also put the `mode` field there and move the
humongous state array to the end.

* random: Remove the `MT_N` constant

`MT_N` is an awfully generic name that bleeds into every file including
`php_random.h`. As it's an implementation detail, remove it entirely to keep
`php_random.h` clean.

To prevent the state struct from diverging from the implementation, the size of
the state vector is statically verified. Furthermore there are phpt tests
verifying the Mt19937 output across a reload, revealing when the state vector
is reloaded too early or too late.
2024-03-04 19:51:01 +01:00
Tim Düsterhus
650a8fb098 random: Embed the Mt19937 and CombinedLCG state within the module globals (#13579)
These are always dynamically allocated in GINIT, thus always take up memory. By
embedding them here we can avoid the dynamic allocation and additional pointer
indirection accessing them.

The test script:

    <?php
    for ($i = 0; $i < 9999999; $i++) mt_rand(1, 100);

Appears to run slightly faster with this change applied: Before this change it
always ran in just over 3 seconds, after this change I was also seeing times
below 3 seconds. Howver results are too close and too jittery to state this
performance improvement as a fact.
2024-03-04 17:51:40 +01:00
Tim Düsterhus
54079babf8 Merge branch 'PHP-8.3'
* PHP-8.3:
  random: Fix unknown `mt_srand()` compatibility for unknown modes (#13544)
  Merge branch 'PHP-8.2' into PHP-8.3
  Removed `REPORT_EXIT_STATUS=no` in libmysql tests
  Revert "Fix GH-13519: PGSQL_CONNECT_FORCE_RENEW with persistent connections." (#13546)
2024-02-29 18:15:09 +01:00
Tim Düsterhus
e6c0b09e88 Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  random: Fix unknown `mt_srand()` compatibility for unknown modes (#13544)
  Removed `REPORT_EXIT_STATUS=no` in libmysql tests
  Revert "Fix GH-13519: PGSQL_CONNECT_FORCE_RENEW with persistent connections." (#13546)
2024-02-29 18:10:39 +01:00
Tim Düsterhus
e059498c04 random: Fix unknown mt_srand() compatibility for unknown modes (#13544)
PHP 8.1 and below interpreted unknown modes as `MT_RAND_MT19937`, but PHP 8.2+
interprets them as `MT_RAND_PHP`.

Align the behavior with PHP 8.1 and below, because folks should be steered
towards the standard mode.
2024-02-29 18:05:59 +01:00
Tim Düsterhus
99e7cf074b random: Clean up seeding API (#13540)
* random: Expose xoshiro256**'s seeding functions

* random: Expose pcgoneseq128xslrr64's seeding functions

* random: Expose Mt19937's seeding functions

* random: Expose CombinedLCG's seeding functions

* random: Call php_random_mt19937_seed32 to seed the global Mt19937

This avoids the function pointer indirection and improves type safety.

* random: NULL the generic seeding function

Different engines work quite differently, it is not useful to attempt to seed
them in a generic way using a 64 bit integer. As an example Mt19937 completely
ignores the upper 32 bits.

* random: Remove the `seed` member from `php_random_algo`

See the explanation in the previous commit for the reasoning. This member is
unused since the previous commit and was not consistently available even before
that (specifically for the Secure engine).

* UPGRADING.INTERNALS

* random: Remove useless cast in `php_mt_srand()`
2024-02-29 08:03:35 +01:00
Tim Düsterhus
dce6ed3199 random: Adjust status to state (#13521)
* random: Rename `status` local to `state`

* random: Rename `php_random_algo_with_state`'s `status` member to `state`
2024-02-26 20:38:45 +01:00
Tim Düsterhus
79133df156 random: Pass algorithm and state together as php_random_algo_with_state (#13350)
* random: Remove `php_random_status`

Since 162e1dce98, the `php_random_status` struct
contains just a single `void*`, resulting in needless indirection when
accessing the engine state and thus decreasing readability because of the
additional non-meaningful `->state` references / the local helper variables.

There is also a small, but measurable performance benefit:

    <?php
    $e = new Random\Engine\Xoshiro256StarStar(0);
    $r = new Random\Randomizer($e);

    for ($i = 0; $i < 15; $i++)
    	var_dump(strlen($r->getBytes(100000000)));

goes from roughly 3.85s down to 3.60s.

The names of the `status` variables have not yet been touched to keep the diff
small. They will be renamed to the more appropriate `state` in a follow-up
cleanup commit.

* Introduce `php_random_algo_with_state`
2024-02-25 20:48:58 +01:00
Máté Kocsis
f2e199e878 Implement "support doc comments for internal classes and functions" (#13266)
Fixes #13130
2024-02-25 08:41:31 +01:00
Máté Kocsis
10957e498c Do not generate frameless info items when func info generation is disabled
While here, I fixed newlines around arginfo and function entry generation. Previously, newlines were repeated.
2024-02-18 11:39:00 +01:00
Tim Düsterhus
ce2d26363f random: Reuse the seed128/seed256 helpers when seeding using the CSPRNG (#13311)
Instead of writing to the engine's state struct directly, use the helpers for
consistency.
2024-02-05 17:00:33 +01:00
Tim Düsterhus
7ed21e66fa random: Do not hardcode the target type when invoking the CSPRNG (#13308)
Instead derive the number of bytes to retrieve from the variable that is being
filled.
2024-02-02 20:10:19 +01:00
Tim Düsterhus
97b3b4552d random: Move CSPRNG API into php_random_csprng.h (#13290)
This allows consumers of just the CSPRNG to include a much smaller header. It
also allows to verify at a glance whether a source file might use non-secure
randomness.

This commit includes the new header wherever the CSPRNG is used, possibly
replacing the inclusion of php_random.h if nothing else is used, but also
includes it in the main php_random.h header for compatibility.

Somewhat related to 45f8cfaf10,
2b30f18708, and
b14dd85dca.
2024-02-01 19:09:35 +01:00
Tim Düsterhus
f39357b07b random: Call int-seeding functions directly
As the `__construct()` implementation is engine-specific anyway, we know what
engine were dealing with and can just call the seeding function directly
instead of going through a function pointer.

This likely improves construction performance a little, but I did not measure.
2024-01-31 08:49:17 +01:00
Tim Düsterhus
304c9c3db1 random: Add explicitly named seed64() helper for xoshiro256** 2024-01-31 08:49:17 +01:00
Tim Düsterhus
79f648ace2 random: Narrow the parameter types of seed128/seed256
These internal-only functions accepted a `php_random_status`, just to extract
the internal state from the `state` pointer. Make them take the state struct
directly to improve type safety.
2024-01-31 08:49:17 +01:00
Tim Düsterhus
45f8cfaf10 random: Split the uint128 implementation into its own header (#13132)
The implementation of `php_random_uint128_*` exists specifically for
pcgoneseq128xslrr66 and takes up a third of php_random.h. Split it into its own
header to keep php_random.h focused on the functionality directly related to
randomness.
2024-01-17 16:07:45 +01:00
Tim Düsterhus
0b7587feae Merge branch 'PHP-8.3'
* PHP-8.3:
  random/standard: Adjust #13138 for PHP 8.3
  random/standard: Correctly handle broken engines in php_array_pick_keys (#13138)
2024-01-14 13:07:18 +01:00
Tim Düsterhus
00ea756c93 random/standard: Adjust #13138 for PHP 8.3 2024-01-14 13:05:44 +01:00
Tim Düsterhus
f2f070a897 Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  random/standard: Correctly handle broken engines in php_array_pick_keys (#13138)
2024-01-14 13:03:33 +01:00
Tim Düsterhus
97c6da1dec random/standard: Correctly handle broken engines in php_array_pick_keys (#13138) 2024-01-14 13:01:29 +01:00
Tim Düsterhus
db68565d03 random: Dynamically calculate the state size when seeding with CSPRNG
Instead of hardcoding struct names, or even sizes, we can just determine the
actual size of the target structure using sizeof().
2024-01-11 08:54:18 +01:00
Tim Düsterhus
62aa8fa375 random: Reduce variable scope in Random\Engine\PcgOneseq128XslRr64::__construct()
This is for consistency with xoshiro256**'s constructor.
2024-01-11 08:54:18 +01:00
Tim Düsterhus
162e1dce98 random: Optimize data flow for the generate function of native engines (#13043)
Instead of returning the generated `uint64_t` and providing the size (i.e. the
number of bytes of the generated value) out-of-band via the
`last_generated_size` member of the `php_random_status` struct, the `generate`
function is now expected to return a new `php_random_result` struct containing
both the `size` and the `result`.

This has two benefits, one for the developer:

It's no longer possible to forget setting `last_generated_size` to the correct
value, because it now happens at the time of returning from the function.

and the other benefit is for performance:

The `php_random_result` struct will be returned as a register pair, thus the
`size` will be directly available without reloading it from main memory.

Checking a simplified version of `php_random_range64()` on Compiler Explorer
(“Godbolt”) with clang 17 shows a single change in the resulting assembly
showcasing the improvement (https://godbolt.org/z/G4WjdYxqx):

    - add     rbp, qword ptr [r14]
    + add     rbp, rdx

Empirical testing confirms a measurable performance increase for the
`Randomizer::getBytes()` method:

    <?php
    $e = new Random\Engine\Xoshiro256StarStar(0);
    $r = new Random\Randomizer($e);

    var_dump(strlen($r->getBytes(100000000)));

goes from 250ms (before the change) to 220ms (after the change). While
generating 100 MB of random data certainly is not the most common use case, it
confirms the theoretical improvement in practice.
2024-01-09 19:04:29 +01:00
Tim Düsterhus
6b1d0606d0 Merge branch 'PHP-8.3'
* PHP-8.3:
  random: Add additional test for Randomizer::getFloat() (#12436)
2023-10-14 18:38:43 +02:00
Tim Düsterhus
ac0b9bff97 random: Add additional test for Randomizer::getFloat() (#12436) 2023-10-14 18:38:11 +02:00
Tim Düsterhus
82c2143ddb Merge branch 'PHP-8.3'
* PHP-8.3:
  random: Fix γ-section implementation for Randomizer::getFloat() (#12402)
2023-10-13 18:04:40 +02:00
Tim Düsterhus
582b724c35 random: Fix γ-section implementation for Randomizer::getFloat() (#12402)
The reference implementation of the "Drawing Random Floating-Point Numbers from
an Interval" paper contains two mistakes that will result in erroneous values
being returned under certain circumstances:

- For large values of `g` the multiplication of `k * g` might overflow to
  infinity.
- The value of `ceilint()` might exceed 2^53, possibly leading to a rounding
  error when promoting `k` to double within the multiplication of `k * g`.

This commit updates the implementation based on Prof. Goualard suggestions
after reaching out to him. It will correctly handle inputs larger than 2^-1020
in absolute values. This limitation will be documented and those inputs
possibly be rejected in a follow-up commit depending on performance concerns.
2023-10-13 17:55:14 +02:00
Tim Düsterhus
3bc63a37a3 random: Remove RAND_RANGE_BADSCALING (#12374)
This macro is no longer used within php-src since
60ace13f9c, it invokes undefined behavior
depending on the input and the corresponding MT_RAND_PHP mode was deprecated in
PHP 8.3.

Thus remove this macro. Any remaining non-php-src user should just inline it
into their code, but should ideally migrate to a non-biased scaler. In any case
the undefined behavior of the original implementation should be accounted for.
2023-10-07 13:19:54 +01:00
divinity76
ab30f27ce3 random: Perform fewer iterations if SKIP_SLOW_TESTS is set (#12279)
Co-authored-by: Tim Düsterhus <tim@bastelstu.be>
2023-09-23 14:48:33 +02:00
Tim Düsterhus
61251093ab Deprecate MT_RAND_PHP (#11560)
see https://wiki.php.net/rfc/deprecations_php_8_3#mt_rand_php
2023-07-07 12:16:48 +02:00
Máté Kocsis
3906bccc00 Add support for typed class constants in stubs 2023-07-01 11:50:04 +02:00