Edit report at https://bugs.php.net/bug.php?id=65626&edit=1
ID: 65626
Comment by: cmbecker69 at gmx dot de
Reported by: cmbecker69 at gmx dot de
Summary: uniqid(null, false) should guarantee unique
identifier
Status: Feedback
Type: Bug
Package: Unknown/Other Function
Operating System: WIN32
PHP Version: 5.4.19
Block user comment: N
Private report: N
New Comment:
helly wrote:
| To ensure this we use usleep() internally to either force a
| thread (windows) or process (*nix) switch.
From what I can tell, usleep() is not called on Windows.[1]
ab wrote:
| For instance, on win8 a snippet "while(uniqid(null, false)
| != uniqid(null, false));" loops forever with 5.4 even if
| it doesn't have to.
However, the documentation[2] states:
| Gets a prefixed unique identifier based on the current time
| in microseconds.
IMHO, a unique identifier should be unique.
I have not changed the status, because I had not re-opened the
ticket nor had I reported it as bug, but rather as a feature
request.
[1] <http://lxr.php.net/xref/PHP_TRUNK/ext/standard/uniqid.c#61>
[2] <http://php.net/manual/en/function.uniqid.php>
Previous Comments:
------------------------------------------------------------------------
[2014-02-08 22:03:49] ab@php.net
Hi,
I'm not sure why you reopen this ticket :) If you read the helly's comment in bug #37106,
it's pretty matching. uniqid() isn't in any way expected to be predictable on different
platforms.
Btw. never tried to compile it under cygwin. Also see the history, that part was introduced in 2002.
Were cygwin builds ever been seriously supported?
So where you see a bug here? Nevertheless, the uniqid function is documented as not being secure.
usleep() can be used from the userspace and the value is highly variable depending on the platform
and hardware.
Thanks.
------------------------------------------------------------------------
[2014-02-08 21:09:12] yohgaki@php.net
#if HAVE_USLEEP && !defined(PHP_WIN32)
!defined(PHP_WIN32) seems legacy check to me as PHP's usleep() only checks HAVE_USLEEP.
#if defined(__CYGWIN__)
Why Cygwin requires more entropy? I guess the #if check is for assuring uniqueness of uniqid(). Is
this needed still?
I think we need Windows experts.
------------------------------------------------------------------------
[2014-02-08 20:51:12] yohgaki@php.net
It seems uniqid() has protection under UNIXes.
#if HAVE_USLEEP && !defined(PHP_WIN32)
if (!more_entropy) {
#if defined(__CYGWIN__)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must use 'more entropy'
under CYGWIN");
RETURN_FALSE;
#else
usleep(1);
#endif
}
#endif
Why is this disabled for windows?
------------------------------------------------------------------------
[2014-02-08 20:30:04] ab@php.net
I think helly's comment is pretty much matching. Also, an integral part of that function relies
on the microtime API, but those implementation is platform dependent. For instance, on win8 a
snippet "while(uniqid(null, false) != uniqid(null, false));" loops forever with 5.4 even
if it doesn't have to. Otherwise you can use usleep() in userspace to ensure some better
result.
------------------------------------------------------------------------
[2013-09-05 22:46:43] cmbecker69 at gmx dot de
Description:
------------
From looking at the sources[1], it occurs to me that
uniqid(null, false) doesn't *guarantee* to return a
unique identifier on WIN32, because usleep(3) is skipped.
As usleep() is implemented as PHP userland function since
PHP 5.0.0[2], it seems to be reasonable and possible to add
the equivalent to usleep(3) there.
As far as I can tell, this won't introduce any BC issues, so
the change might be done for PHP 5.4.x.
Please note that this is related to #37106[3], but helly's
comment doesn't seem to fit to the current sources.
[1] <http://lxr.php.net/xref/PHP_5_4/ext/standard/uniqid.c#61>
[2] <http://lxr.php.net/xref/PHP_5_4/win32/time.c#96>
[3] <https://bugs.php.net/bug.php?id=37106>
Test script:
---------------
var_dump(uniqid(null, false) != uniqid(null, false));
Expected result:
----------------
bool(true)
Actual result:
--------------
bool(false) // at least sometimes on a fast machine ;)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=65626&edit=1