Skip to content

Commit

Permalink
PHP7 consistent ordering for splitHttpAcceptHeader
Browse files Browse the repository at this point in the history
In PHP7 sorting order is changed, splitHttpAcceptHeader was
relying on unspecified behaviour of arsort(). Sorting order
is now made explicit.
  • Loading branch information
mdeheij committed Sep 6, 2016
1 parent c2da6e3 commit 865bb94
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 26 deletions.
11 changes: 11 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
language: php
php:
- 7.0
- 5.6
- hhvm

before_script:
- composer install --dev

script:
- vendor/bin/phpunit
43 changes: 40 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,48 @@
{
"name": "symfony/symfony1",
"name": "symfony/symfony1",
"description": "Symfony is a complete framework designed to optimize the development of web applications by way of several key features. For starters, it separates a web application's business rules, server logic, and presentation views. It contains numerous tools and classes aimed at shortening the development time of a complex web application. Additionally, it automates common tasks so that the developer can focus entirely on the specifics of an application. The end result of these advantages means there is no need to reinvent the wheel every time a new web application is built!",
"authors": [
"authors": [
{
"name": "Fabien Potencier",
"email": "[email protected]"
}
],
"license": "MIT"
"license": "MIT",
"require-dev": {
"phpunit/phpunit": "^5.5"
},
"autoload-dev": {
"classmap": [
"lib/action",
"lib/addon",
"lib/autoload",
"lib/cache",
"lib/command",
"lib/config",
"lib/controller",
"lib/database",
"lib/debug",
"lib/event",
"lib/exception",
"lib/filter",
"lib/form",
"lib/generator",
"lib/helper",
"lib/i18n",
"lib/log",
"lib/plugin",
"lib/request",
"lib/response",
"lib/routing",
"lib/storage",
"lib/task",
"lib/user",
"lib/util",
"lib/validator",
"lib/vendor",
"lib/view",
"lib/widget",
"lib/yaml"
]
}
}
63 changes: 40 additions & 23 deletions lib/request/sfWebRequest.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -927,34 +927,51 @@ public function setRelativeUrlRoot($value)
$this->relativeUrlRoot = $value;
}

/**
* Splits an HTTP header for the current web request.
*
* @param string $header Header to split
*/
public function splitHttpAcceptHeader($header)
/**
* Splits an HTTP header for the current web request.
*
* @param string $header Header to split
*/
public function splitHttpAcceptHeader($header)
{
$i = 0;
$values = array();
foreach (array_filter(explode(',', $header)) as $value)
{
$values = array();
foreach (array_filter(explode(',', $header)) as $value)
// Cut off any q-value that might come after a semi-colon
if ($pos = strpos($value, ';'))
{
// Cut off any q-value that might come after a semi-colon
if ($pos = strpos($value, ';'))
{
$q = (float) trim(substr($value, $pos + 3));
$value = trim(substr($value, 0, $pos));
}
else
{
$q = 1;
}

$values[$value] = $q;
$q = (float) trim(substr($value, $pos + 3));
$value = trim(substr($value, 0, $pos));
}
else
{
$q = 1;
}

arsort($values);

return array_keys($values);
$values[$value] = array($q, $i++);
}
/**
* Implement reverse stable sort instead of arsort
*/
uasort($values, function ($a, $b) {
if ($a[0] == $b[0]) {
// Can not be same since we used $i++
if ($a[1] < $b[1]) {
return 1;
} else {
return -1;
}
} elseif ($a[0] < $b[0]) {
return 1;
} else {
return -1;
}
});

return array_keys($values);
}


/**
* Returns the array that contains all request information ($_SERVER or $_ENV).
Expand Down
17 changes: 17 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors = "true"
bootstrap = "vendor/autoload.php"
backupGlobals = "false"
backupStaticAttributes = "false">

<testsuites>
<testsuite name="Symfony1 test" >
<directory>./test/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./lib</directory>
</whitelist>
</filter>
</phpunit>
74 changes: 74 additions & 0 deletions test/lib/request/sfWebRequestTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
use PHPUnit\Framework\TestCase;

require_once(__DIR__ . '/../../../lib/request/sfWebRequest.class.php');

class sfWebRequestTest extends TestCase
{

/**
* @var sfWebRequest
*/
private $request;

protected function setUp()
{
$event_dispatcher = new sfEventDispatcher();
$this->request = new sfWebRequest($event_dispatcher);
}

/**
* @dataProvider splitHttpAcceptHeaderProvider
* @covers sfWebRequest::splitHttpAcceptHeader
*/
public function testSplitHttpAcceptHeader($header, $expected)
{
self::assertSame($expected, $this->request->splitHttpAcceptHeader($header));
}

public function splitHttpAcceptHeaderProvider()
{
return [
[
"text/javascript, text/html, application/xml, text/xml, */*",
[
' */*',
' text/xml',
' application/xml',
' text/html',
'text/javascript',
]
],
[
"text/javascript, text/html;q=2.9, application/xml, text/xml, */*",
[
'text/html',
' */*',
' text/xml',
' application/xml',
'text/javascript',
]
],
[
"text/javascript;q=1.0, text/html;q=2.9, application/xml, text/xml, */*",
[
'text/html',
' */*',
' text/xml',
' application/xml',
'text/javascript',
]
],
[
"text/javascript;q=1.0, text/html;q=1.0, application/xml, text/xml, */*",
[
' */*',
' text/xml',
' application/xml',
'text/html',
'text/javascript',
]
]
];
}
}

0 comments on commit 865bb94

Please sign in to comment.