FakerPHP / Faker

Faker is a PHP library that generates fake data for you
https://fakerphp.github.io
Other
3.47k stars 330 forks source link

only set a new random seed if _the last_ Generator gets destruct'ed #871

Open themasch opened 3 months ago

themasch commented 3 months ago

What is the reason for this PR?

In cases where multiple Generator instances might be created, a gc cycle collection run can trigger at any time, potentially removing "old" Generator instances, which then calls __destruct and thus seed, which reset the global mt_rand seed, impacting everyone else.

If another, still live instance of Generator gets used after that, its output is no longer deterministic, since a new random seed was set.

Author's checklist

Summary of changes

I added a new static class property to Faker\Generator which counts the number of currently existing Generator instances: It gets incremented in construct, and decremented in destruct. Only if this counter reaches 0 does __destruct also call seed to restore the system to a "properly random" state.

Using a global counter is, imho, quite ugly, but since Generator::seed already modifies global state anyway I think its like fighting fire with fire. Other than that, I think its a quite minimal change that does not impact any other use of Faker. Cases that "properly" only ever use exactly one instance of the Generator will not see any difference in behaviour.

It's not a perfect solution by any means. But I think it is a reasonable one.

Review checklist

stale[bot] commented 2 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 1 week if no further activity occurs. Thank you for your contributions.