diff --git a/src/Symfony/Component/BrowserKit/Client.php b/src/Symfony/Component/BrowserKit/Client.php
index c57b9e37a1..8664f31ab0 100644
--- a/src/Symfony/Component/BrowserKit/Client.php
+++ b/src/Symfony/Component/BrowserKit/Client.php
@@ -266,7 +266,7 @@ abstract class Client
$response = $this->filterResponse($this->response);
- $this->cookieJar->updateFromResponse($response);
+ $this->cookieJar->updateFromResponse($response, $uri);
$this->redirect = $response->getHeader('Location');
diff --git a/src/Symfony/Component/BrowserKit/Cookie.php b/src/Symfony/Component/BrowserKit/Cookie.php
index b4c3385934..1e2c64ce63 100644
--- a/src/Symfony/Component/BrowserKit/Cookie.php
+++ b/src/Symfony/Component/BrowserKit/Cookie.php
@@ -95,7 +95,7 @@ class Cookie
$cookie .= '; domain='.$this->domain;
}
- if ('/' !== $this->path) {
+ if ($this->path) {
$cookie .= '; path='.$this->path;
}
@@ -147,10 +147,9 @@ class Cookie
if ((false === $urlParts = parse_url($url)) || !isset($urlParts['host']) || !isset($urlParts['path'])) {
throw new \InvalidArgumentException(sprintf('The URL "%s" is not valid.', $url));
}
- $parts = array_merge($urlParts, $parts);
- $values['domain'] = $parts['host'];
- $values['path'] = substr($parts['path'], 0, strrpos($parts['path'], '/'));
+ $values['domain'] = $urlParts['host'];
+ $values['path'] = substr($urlParts['path'], 0, strrpos($urlParts['path'], '/'));
}
foreach ($parts as $part) {
diff --git a/src/Symfony/Component/BrowserKit/Tests/ClientTest.php b/src/Symfony/Component/BrowserKit/Tests/ClientTest.php
index 32a3889a4b..1bf9e5c844 100644
--- a/src/Symfony/Component/BrowserKit/Tests/ClientTest.php
+++ b/src/Symfony/Component/BrowserKit/Tests/ClientTest.php
@@ -205,6 +205,15 @@ class ClientTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('foo' => 'bar'), $client->getCookieJar()->allValues('http://www.example.com/foo/foobar'), '->request() updates the CookieJar');
}
+ public function testRequestSecureCookies()
+ {
+ $client = new TestClient();
+ $client->setNextResponse(new Response('foo', 200, array('Set-Cookie' => 'foo=bar; path=/; secure')));
+ $client->request('GET', 'https://www.example.com/foo/foobar');
+
+ $this->assertTrue($client->getCookieJar()->get('foo', '/', 'www.example.com')->isSecure());
+ }
+
public function testClick()
{
if (!class_exists('Symfony\Component\DomCrawler\Crawler')) {
diff --git a/src/Symfony/Component/BrowserKit/Tests/CookieTest.php b/src/Symfony/Component/BrowserKit/Tests/CookieTest.php
index be53eea417..606b2e2e91 100644
--- a/src/Symfony/Component/BrowserKit/Tests/CookieTest.php
+++ b/src/Symfony/Component/BrowserKit/Tests/CookieTest.php
@@ -26,14 +26,14 @@ class CookieTest extends \PHPUnit_Framework_TestCase
public function getTestsForToFromString()
{
return array(
- array('foo=bar'),
+ array('foo=bar; path=/'),
array('foo=bar; path=/foo'),
- array('foo=bar; domain=google.com'),
- array('foo=bar; domain=example.com; secure', 'https://example.com/'),
- array('foo=bar; httponly'),
+ array('foo=bar; domain=google.com; path=/'),
+ array('foo=bar; domain=example.com; path=/; secure', 'https://example.com/'),
+ array('foo=bar; path=/; httponly'),
array('foo=bar; domain=google.com; path=/foo; secure; httponly', 'https://google.com/'),
- array('foo=bar=baz'),
- array('foo=bar%3Dbaz'),
+ array('foo=bar=baz; path=/'),
+ array('foo=bar%3Dbaz; path=/'),
);
}
@@ -67,17 +67,17 @@ class CookieTest extends \PHPUnit_Framework_TestCase
public function testFromStringWithCapitalization()
{
- $this->assertEquals('Foo=Bar', (string) Cookie::fromString('Foo=Bar'));
- $this->assertEquals('foo=bar; expires=Fri, 31 Dec 2010 23:59:59 GMT', (string) Cookie::fromString('foo=bar; Expires=Fri, 31 Dec 2010 23:59:59 GMT'));
- $this->assertEquals('foo=bar; domain=www.example.org; httponly', (string) Cookie::fromString('foo=bar; DOMAIN=www.example.org; HttpOnly'));
+ $this->assertEquals('Foo=Bar; path=/', (string) Cookie::fromString('Foo=Bar'));
+ $this->assertEquals('foo=bar; expires=Fri, 31 Dec 2010 23:59:59 GMT; path=/', (string) Cookie::fromString('foo=bar; Expires=Fri, 31 Dec 2010 23:59:59 GMT'));
+ $this->assertEquals('foo=bar; domain=www.example.org; path=/; httponly', (string) Cookie::fromString('foo=bar; DOMAIN=www.example.org; HttpOnly'));
}
public function testFromStringWithUrl()
{
- $this->assertEquals('foo=bar; domain=www.example.com', (string) Cookie::FromString('foo=bar', 'http://www.example.com/'));
+ $this->assertEquals('foo=bar; domain=www.example.com; path=/', (string) Cookie::FromString('foo=bar', 'http://www.example.com/'));
$this->assertEquals('foo=bar; domain=www.example.com; path=/foo', (string) Cookie::FromString('foo=bar', 'http://www.example.com/foo/bar'));
- $this->assertEquals('foo=bar; domain=www.example.com', (string) Cookie::FromString('foo=bar; path=/', 'http://www.example.com/foo/bar'));
- $this->assertEquals('foo=bar; domain=www.myotherexample.com', (string) Cookie::FromString('foo=bar; domain=www.myotherexample.com', 'http://www.example.com/'));
+ $this->assertEquals('foo=bar; domain=www.example.com; path=/', (string) Cookie::FromString('foo=bar; path=/', 'http://www.example.com/foo/bar'));
+ $this->assertEquals('foo=bar; domain=www.myotherexample.com; path=/', (string) Cookie::FromString('foo=bar; domain=www.myotherexample.com', 'http://www.example.com/'));
}
public function testFromStringThrowsAnExceptionIfCookieIsNotValid()
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php
index e24b5b0202..03528fefa9 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php
@@ -56,11 +56,13 @@ class CheckCircularReferencesPass implements CompilerPassInterface
private function checkOutEdges(array $edges)
{
foreach ($edges as $edge) {
- $node = $edge->getDestNode();
- $this->currentPath[] = $id = $node->getId();
+ $node = $edge->getDestNode();
+ $id = $node->getId();
+ $searchKey = array_search($id, $this->currentPath);
+ $this->currentPath[] = $id;
- if ($this->currentId === $id) {
- throw new ServiceCircularReferenceException($this->currentId, $this->currentPath);
+ if (false !== $searchKey) {
+ throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey));
}
$this->checkOutEdges($node->getOutEdges());
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php
index 25f816b834..085bc519b7 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php
@@ -24,7 +24,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
class CheckCircularReferencesPassTest extends \PHPUnit_Framework_TestCase
{
/**
- * @expectedException \RuntimeException
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
*/
public function testProcess()
{
@@ -36,7 +36,7 @@ class CheckCircularReferencesPassTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException \RuntimeException
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
*/
public function testProcessWithAliases()
{
@@ -49,7 +49,7 @@ class CheckCircularReferencesPassTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException \RuntimeException
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
*/
public function testProcessDetectsIndirectCircularReference()
{
@@ -61,6 +61,19 @@ class CheckCircularReferencesPassTest extends \PHPUnit_Framework_TestCase
$this->process($container);
}
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
+ */
+ public function testDeepCircularReference()
+ {
+ $container = new ContainerBuilder();
+ $container->register('a')->addArgument(new Reference('b'));
+ $container->register('b')->addArgument(new Reference('c'));
+ $container->register('c')->addArgument(new Reference('b'));
+
+ $this->process($container);
+ }
+
public function testProcessIgnoresMethodCalls()
{
$container = new ContainerBuilder();
diff --git a/src/Symfony/Component/HttpFoundation/Cookie.php b/src/Symfony/Component/HttpFoundation/Cookie.php
index fdc33e3679..68fe853b2f 100644
--- a/src/Symfony/Component/HttpFoundation/Cookie.php
+++ b/src/Symfony/Component/HttpFoundation/Cookie.php
@@ -93,11 +93,11 @@ class Cookie
}
}
- if ('/' !== $this->path) {
+ if ($this->path) {
$str .= '; path='.$this->path;
}
- if (null !== $this->getDomain()) {
+ if ($this->getDomain()) {
$str .= '; domain='.$this->getDomain();
}
diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php
index 448a501321..7d8ace2181 100644
--- a/src/Symfony/Component/HttpFoundation/Request.php
+++ b/src/Symfony/Component/HttpFoundation/Request.php
@@ -1489,11 +1489,14 @@ class Request
{
$requestUri = '';
- if ($this->headers->has('X_ORIGINAL_URL') && false !== stripos(PHP_OS, 'WIN')) {
+ if ($this->headers->has('X_ORIGINAL_URL')) {
// IIS with Microsoft Rewrite Module
$requestUri = $this->headers->get('X_ORIGINAL_URL');
$this->headers->remove('X_ORIGINAL_URL');
- } elseif ($this->headers->has('X_REWRITE_URL') && false !== stripos(PHP_OS, 'WIN')) {
+ $this->server->remove('HTTP_X_ORIGINAL_URL');
+ $this->server->remove('UNENCODED_URL');
+ $this->server->remove('IIS_WasUrlRewritten');
+ } elseif ($this->headers->has('X_REWRITE_URL')) {
// IIS with ISAPI_Rewrite
$requestUri = $this->headers->get('X_REWRITE_URL');
$this->headers->remove('X_REWRITE_URL');
diff --git a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php
index 721cc3cd9e..2a3e808909 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php
@@ -134,11 +134,12 @@ class CookieTest extends \PHPUnit_Framework_TestCase
public function testToString()
{
$cookie = new Cookie('foo', 'bar', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
-
- $this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; domain=.myfoodomain.com; secure; httponly', $cookie->__toString(), '->__toString() returns string representation of the cookie');
+ $this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure; httponly', $cookie->__toString(), '->__toString() returns string representation of the cookie');
$cookie = new Cookie('foo', null, 1, '/admin/', '.myfoodomain.com');
-
$this->assertEquals('foo=deleted; expires=' . gmdate("D, d-M-Y H:i:s T", time()-31536001) . '; path=/admin/; domain=.myfoodomain.com; httponly', $cookie->__toString(), '->__toString() returns string representation of a cleared cookie if value is NULL');
+
+ $cookie = new Cookie('foo', 'bar', 0, '/', '');
+ $this->assertEquals('foo=bar; path=/; httponly', $cookie->__toString());
}
}
diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
index a1b548fd22..fee7ea0062 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
@@ -1391,6 +1391,95 @@ class RequestTest extends \PHPUnit_Framework_TestCase
// reset
Request::setTrustedProxies(array());
}
+
+ /**
+ * @dataProvider iisRequestUriProvider
+ */
+ public function testIISRequestUri($headers, $server, $expectedRequestUri)
+ {
+ $request = new Request();
+ $request->headers->replace($headers);
+ $request->server->replace($server);
+
+ $this->assertEquals($expectedRequestUri, $request->getRequestUri(), '->getRequestUri() is correct');
+
+ $subRequestUri = '/bar/foo';
+ $subRequest = $request::create($subRequestUri, 'get', array(), array(), array(), $request->server->all());
+ $this->assertEquals($subRequestUri, $subRequest->getRequestUri(), '->getRequestUri() is correct in sub request');
+ }
+
+ public function iisRequestUriProvider()
+ {
+ return array(
+ array(
+ array(
+ 'X_ORIGINAL_URL' => '/foo/bar',
+ ),
+ array(),
+ '/foo/bar'
+ ),
+ array(
+ array(
+ 'X_REWRITE_URL' => '/foo/bar',
+ ),
+ array(),
+ '/foo/bar'
+ ),
+ array(
+ array(),
+ array(
+ 'IIS_WasUrlRewritten' => '1',
+ 'UNENCODED_URL' => '/foo/bar'
+ ),
+ '/foo/bar'
+ ),
+ array(
+ array(
+ 'X_ORIGINAL_URL' => '/foo/bar',
+ ),
+ array(
+ 'HTTP_X_ORIGINAL_URL' => '/foo/bar'
+ ),
+ '/foo/bar'
+ ),
+ array(
+ array(
+ 'X_ORIGINAL_URL' => '/foo/bar',
+ ),
+ array(
+ 'IIS_WasUrlRewritten' => '1',
+ 'UNENCODED_URL' => '/foo/bar'
+ ),
+ '/foo/bar'
+ ),
+ array(
+ array(
+ 'X_ORIGINAL_URL' => '/foo/bar',
+ ),
+ array(
+ 'HTTP_X_ORIGINAL_URL' => '/foo/bar',
+ 'IIS_WasUrlRewritten' => '1',
+ 'UNENCODED_URL' => '/foo/bar'
+ ),
+ '/foo/bar'
+ ),
+ array(
+ array(),
+ array(
+ 'ORIG_PATH_INFO' => '/foo/bar',
+ ),
+ '/foo/bar'
+ ),
+ array(
+ array(),
+ array(
+ 'ORIG_PATH_INFO' => '/foo/bar',
+ 'QUERY_STRING' => 'foo=bar',
+ ),
+ '/foo/bar?foo=bar'
+ )
+ );
+ }
}
class RequestContentProxy extends Request
diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php
index c3dd9a27fc..1cb327860d 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php
@@ -114,11 +114,11 @@ class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
$bag = new ResponseHeaderBag(array());
$bag->setCookie(new Cookie('foo', 'bar'));
- $this->assertContains("Set-Cookie: foo=bar; httponly", explode("\r\n", $bag->__toString()));
+ $this->assertContains("Set-Cookie: foo=bar; path=/; httponly", explode("\r\n", $bag->__toString()));
$bag->clearCookie('foo');
- $this->assertContains("Set-Cookie: foo=deleted; expires=".gmdate("D, d-M-Y H:i:s T", time() - 31536001)."; httponly", explode("\r\n", $bag->__toString()));
+ $this->assertContains("Set-Cookie: foo=deleted; expires=".gmdate("D, d-M-Y H:i:s T", time() - 31536001)."; path=/; httponly", explode("\r\n", $bag->__toString()));
}
public function testReplace()
@@ -158,7 +158,7 @@ class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
$this->assertContains("Set-Cookie: foo=bar; path=/path/foo; domain=foo.bar; httponly", $headers);
$this->assertContains("Set-Cookie: foo=bar; path=/path/foo; domain=foo.bar; httponly", $headers);
$this->assertContains("Set-Cookie: foo=bar; path=/path/bar; domain=bar.foo; httponly", $headers);
- $this->assertContains("Set-Cookie: foo=bar; httponly", $headers);
+ $this->assertContains("Set-Cookie: foo=bar; path=/; httponly", $headers);
$cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
$this->assertTrue(isset($cookies['foo.bar']['/path/foo']['foo']));
diff --git a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
index 5e9850d819..0cafc043ac 100644
--- a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
+++ b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
@@ -40,7 +40,7 @@ class XliffFileLoader implements LoaderInterface
throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
}
- $xml = $this->parseFile($resource);
+ list($xml, $encoding) = $this->parseFile($resource);
$xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2');
$catalogue = new MessageCatalogue($locale);
@@ -52,7 +52,21 @@ class XliffFileLoader implements LoaderInterface
}
$source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source;
- $catalogue->set((string) $source, (string) $translation->target, $domain);
+ $target = (string) $translation->target;
+
+ // If the xlf file has another encoding specified, try to convert it because
+ // simple_xml will always return utf-8 encoded values
+ if ('UTF-8' !== $encoding && !empty($encoding)) {
+ if (function_exists('mb_convert_encoding')) {
+ $target = mb_convert_encoding($target, $encoding, 'UTF-8');
+ } elseif (function_exists('iconv')) {
+ $target = iconv('UTF-8', $encoding, $target);
+ } else {
+ throw new \RuntimeException('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
+ }
+ }
+
+ $catalogue->set((string) $source, $target, $domain);
}
$catalogue->addResource(new FileResource($resource));
@@ -117,7 +131,7 @@ class XliffFileLoader implements LoaderInterface
libxml_use_internal_errors($internalErrors);
- return simplexml_import_dom($dom);
+ return array(simplexml_import_dom($dom), strtoupper($dom->encoding));
}
/**
diff --git a/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php b/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php
index c7fbab2d9c..f68fd5852f 100644
--- a/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php
+++ b/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php
@@ -50,6 +50,19 @@ class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($catalogue->has('extra', 'domain1'));
}
+ public function testEncoding()
+ {
+ if (!function_exists('iconv') && !function_exists('mb_convert_encoding')) {
+ $this->markTestSkipped('The iconv and mbstring extensions are not available.');
+ }
+
+ $loader = $this->createLoader();
+ $catalogue = $loader->load(__DIR__.'/../fixtures/encoding.xlf', 'en', 'domain1');
+
+ $this->assertEquals(utf8_decode('föö'), $catalogue->get('bar', 'domain1'));
+ $this->assertEquals(utf8_decode('bär'), $catalogue->get('foo', 'domain1'));
+ }
+
/**
* @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
*/
diff --git a/src/Symfony/Component/Translation/Tests/fixtures/encoding.xlf b/src/Symfony/Component/Translation/Tests/fixtures/encoding.xlf
new file mode 100644
index 0000000000..6be901bd75
--- /dev/null
+++ b/src/Symfony/Component/Translation/Tests/fixtures/encoding.xlf
@@ -0,0 +1,15 @@
+
+
+
+
+
+ foo
+ bär
+
+
+ bar
+ föö
+
+
+
+