php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80723 Different sockets compare as equal (regression in 8.0)
Submitted: 2021-02-08 02:44 UTC Modified: 2021-02-16 11:36 UTC
From: bugs-a17 at moonlit-rail dot com Assigned: nikic (profile)
Status: Closed Package: Sockets related
PHP Version: 8.0.2 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: bugs-a17 at moonlit-rail dot com
New email:
PHP Version: OS:

 

 [2021-02-08 02:44 UTC] bugs-a17 at moonlit-rail dot com
Description:
------------
In PHP 8.0, two different sockets compare as equal.
This is a regression versus PHP 7.x.

I use PHP for writing internet servers, and upgrading to 8.0 sees most of them failing.  Simple constructs such as, $socknum = array_search($sock, $sockets)
no longer function as they intuitively ought to.

As an aside, it used to be convenient to do, $array[(int)$socket] = $socket;
But in 8.0, (int) $socket bombs, and var_export($socket, true) returns the same value regardless of what's in the socket.

Test script:
---------------
#!/usr/bin/php
<?php

$socket_1 = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$socket_2 = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$vector   = array(1 => $socket_1,
                  2 => $socket_2);
$IDX_1    = array_search($socket_1, $vector);
$IDX_2    = array_search($socket_2, $vector);
$V        = substr(PHP_VERSION, 0, 3);

echo "In PHP {$V}:\n".
     "\tSocket 1 was found at array index {$IDX_1}, and\n".
     "\tSocket 2 was found at array index {$IDX_2}.\n";

socket_close($socket_1);
socket_close($socket_2);
?>

Expected result:
----------------
~$ /tmp/socket-compare-test.php 
In PHP 7.3:
        Socket 1 was found at array index 1, and
        Socket 2 was found at array index 2.


Actual result:
--------------
~$ /tmp/socket-compare-test.php 
In PHP 8.0:
        Socket 1 was found at array index 1, and
        Socket 2 was found at array index 1.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-02-08 02:57 UTC] danack@php.net
That probably needs to be investigated, but you may be able to use WeakMaps as a better holder for things like this: https://wiki.php.net/rfc/weak_maps

which might need to be documented...
 [2021-02-08 06:24 UTC] bugs-a17 at moonlit-rail dot com
Thanks for the note about the weak-maps, looks quite useful for many of my use cases.

One workaround for this bug is to use === rather than == in the comparison.

As the sockets now create a Socket class, and each instance appears empty, that might explain why <empty> == <empty> returns true; clearly, the Socket object returned by create_socket() should be populated with socket information (or at least a pointer to a resource) to permit the comparison to have something to work with.
 [2021-02-16 11:26 UTC] nikic@php.net
-Assigned To: +Assigned To: nikic
 [2021-02-16 11:34 UTC] nikic@php.net
Automatic comment on behalf of nikita.ppv@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=cb9785add1bc8031531c2870c267e6a72efae6af
Log: Fixed bug #80723
 [2021-02-16 11:34 UTC] nikic@php.net
-Status: Assigned +Status: Closed
 [2021-02-16 11:36 UTC] nikic@php.net
The replacement for (int)$socket is spl_object_id($socket). Though we might want to add an overload for sockets in particular, as we did for curl handles.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Nov 26 04:01:31 2024 UTC