php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71334 Cannot access array keys while uksort()
Submitted: 2016-01-11 11:03 UTC Modified: 2016-02-22 12:55 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:0 (0.0%)
From: alex dot schneider at sevenval dot com Assigned: laruence (profile)
Status: Closed Package: Arrays related
PHP Version: 7.0.2 OS: Linux Mint 17.3
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: alex dot schneider at sevenval dot com
New email:
PHP Version: OS:

 

 [2016-01-11 11:03 UTC] alex dot schneider at sevenval dot com
Description:
------------
Cannot access array keys while uksort().

Sorry for my English...

Test script:
---------------
<?php

class myClass
{
	private $a = [
		'foo-test' => [1],
		'-' => [2],
		'bar-test' => [3]
	];

	private function _mySort($x, $y)
	{
		if (!isset($this->a[$x])) {
			throw new Exception('Missing X: "' . $x . '"');
		}

		if (!isset($this->a[$y])) {
			throw new Exception('Missing Y: "' . $y . '"');
		}

		return $x < $y;
	}

	public function __construct()
	{
		uksort($this->a, [$this, '_mySort']);
	}
}

new myClass();

Expected result:
----------------
No Exceptions

Actual result:
--------------
Exception:

PHP Fatal error:  Uncaught Exception: Missing Y: "bar-test" in ...

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-01-12 15:37 UTC] nikic@php.net
-Assigned To: +Assigned To: laruence
 [2016-01-12 15:37 UTC] nikic@php.net
The problem is that we're doing the sort in-place, so any access to the array during the sort will see it in an inconsistent state. I don't see any way to solve this problem without requiring the array to always be duplicated before sorts with user-defined callbacks.

Here's a patch to implement this: https://github.com/nikic/php-src/commit/703fed650319f9e2d78e2dc2cafb422e558c5841 It also removes the array modification check, as it's no longer relevant after this change.

@laruence: You worked on the sorting functionality, do you see a way to fix this in any other way?
 [2016-01-12 16:36 UTC] nikic@php.net
It looks like ArrayObject relies on sorting functions not to duplicate the array for the rc=1 case, so this will need some more work :(
 [2016-01-13 06:36 UTC] laruence@php.net
hmm, we could also adjust arHash after swap, but it must not be a simple patch..

thanks
 [2016-01-13 16:15 UTC] jsgoupil at gmail dot com
I have the same problem, I am able to access the values, but the sorting is not correct.

<?php
function cmp($a, $b)
{
    $x = $GLOBALS['x'];
    
    $v1 = $x[$a];
    $v2 = $x[$b];
    if ($v1 < $v2) {
        return -1;
    } elseif ($v1 > $v2) {
        return 1;
    } else {
        // Would then sort by key, irrelevant here.
    }
}

$x = array(1 => 1, 2 => 3, 3 => 2);
uksort($x, 'cmp');
var_dump($x);

// PHP5
array(3) { [1]=> int(1) [3]=> int(2) [2]=> int(3) }

// PHP7
array(3) { [3]=> int(2) [2]=> int(3) [1]=> int(1) }


Let me know if you want me to open another bug instead.
 [2016-02-22 12:55 UTC] nikic@php.net
New patch that resolves the ArrayObject issue: https://github.com/nikic/php-src/commit/73e6c257abc9ad5a5aef6b91a2238e941b2045d5
 [2016-03-30 20:50 UTC] nikic@php.net
Automatic comment on behalf of nikic
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b1e854f7762b2e0648ddc240835cb446ee4d20a7
Log: Fix bug #71334
 [2016-03-30 20:50 UTC] nikic@php.net
-Status: Assigned +Status: Closed
 [2016-07-20 11:32 UTC] davey@php.net
Automatic comment on behalf of nikic
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b1e854f7762b2e0648ddc240835cb446ee4d20a7
Log: Fix bug #71334
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 12:01:29 2024 UTC