Merge branch '2.8' into 3.3

* 2.8:
  Username and password in basic auth are allowed to contain '.'
  Remove obsolete PHPDoc from UriSigner
  [Serializer] ObjectNormalizer: throw if PropertyAccess isn't installed
  [PropertyInfo] Add support for the iterable type
  pdo session fix
  Fixed unsetting from loosely equal keys OrderedHashMap
  [Debug] Fix same vendor detection in class loader
  Updated the source text and translation
  reject remember-me token if user check fails
This commit is contained in:
Fabien Potencier 2017-10-18 08:00:09 -07:00
commit f51d4d4c8f
13 changed files with 53 additions and 21 deletions

View File

@ -204,18 +204,11 @@ class DebugClassLoader
self::$deprecated[$name] = preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]);
} else {
// Don't trigger deprecations for classes in the same vendor
if (2 > $len = 1 + (strpos($name, '\\', 1 + strpos($name, '\\')) ?: strpos($name, '_'))) {
if (2 > $len = 1 + (strpos($name, '\\') ?: strpos($name, '_'))) {
$len = 0;
$ns = '';
} else {
switch ($ns = substr($name, 0, $len)) {
case 'Symfony\Bridge\\':
case 'Symfony\Bundle\\':
case 'Symfony\Component\\':
$ns = 'Symfony\\';
$len = strlen($ns);
break;
}
$ns = substr($name, 0, $len);
}
if (!$parent || strncmp($ns, $parent, $len)) {

View File

@ -11,8 +11,8 @@
<target>Den uppladdade filen var för stor. Försök ladda upp en mindre fil.</target>
</trans-unit>
<trans-unit id="30">
<source>The CSRF token is invalid.</source>
<target>CSRF-symbolen är inte giltig.</target>
<source>The CSRF token is invalid. Please try to resubmit the form.</source>
<target>CSRF-elementet är inte giltigt. Försök att skicka formuläret igen.</target>
</trans-unit>
</body>
</file>

View File

@ -56,6 +56,15 @@ class OrderedHashMapTest extends TestCase
$this->assertSame(array(0 => 1, 'foo' => 2, 1 => 3), iterator_to_array($map));
}
public function testInsertLooselyEqualKeys()
{
$map = new OrderedHashMap();
$map['1 as a string'] = '1 as a string';
$map[1] = 1;
$this->assertSame(array('1 as a string' => '1 as a string', 1 => 1), iterator_to_array($map));
}
/**
* Updates should not change the position of an element, otherwise we could
* turn foreach loops into endless loops if they change the current
@ -111,6 +120,17 @@ class OrderedHashMapTest extends TestCase
$this->assertSame(array('second' => 2), iterator_to_array($map));
}
public function testUnsetFromLooselyEqualKeysHashMap()
{
$map = new OrderedHashMap();
$map['1 as a string'] = '1 as a string';
$map[1] = 1;
unset($map[1]);
$this->assertSame(array('1 as a string' => '1 as a string'), iterator_to_array($map));
}
public function testUnsetNonExistingSucceeds()
{
$map = new OrderedHashMap();

View File

@ -133,7 +133,7 @@ class OrderedHashMap implements \ArrayAccess, \IteratorAggregate, \Countable
: 1 + (int) max($this->orderedKeys);
}
$this->orderedKeys[] = $key;
$this->orderedKeys[] = (string) $key;
}
$this->elements[$key] = $value;
@ -144,7 +144,7 @@ class OrderedHashMap implements \ArrayAccess, \IteratorAggregate, \Countable
*/
public function offsetUnset($key)
{
if (false !== ($position = array_search($key, $this->orderedKeys))) {
if (false !== ($position = array_search((string) $key, $this->orderedKeys))) {
array_splice($this->orderedKeys, $position, 1);
unset($this->elements[$key]);

View File

@ -118,7 +118,13 @@ class OrderedHashMapIterator implements \Iterator
*/
public function key()
{
return $this->key;
if (null === $this->key) {
return null;
}
$array = array($this->key => null);
return key($array);
}
/**

View File

@ -387,7 +387,7 @@ class PdoSessionHandler implements \SessionHandlerInterface
$this->gcCalled = false;
// delete the session records that have expired
$sql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol < :time";
$sql = "DELETE FROM $this->table WHERE $this->lifetimeCol < :time - $this->timeCol";
$stmt = $this->pdo->prepare($sql);
$stmt->bindValue(':time', time(), \PDO::PARAM_INT);

View File

@ -58,10 +58,6 @@ class UriSigner
/**
* Checks that a URI contains the correct hash.
*
* The query string parameter must be the last one
* (as it is generated that way by the sign() method, it should
* never be a problem).
*
* @param string $uri A signed URI
*
* @return bool True if the URI is signed correctly, false otherwise

View File

@ -37,6 +37,12 @@ class TypeTest extends TestCase
$this->assertEquals(Type::BUILTIN_TYPE_STRING, $collectionValueType->getBuiltinType());
}
public function testIterable()
{
$type = new Type('iterable');
$this->assertSame('iterable', $type->getBuiltinType());
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage "foo" is not a valid PHP type.

View File

@ -29,6 +29,7 @@ class Type
const BUILTIN_TYPE_ARRAY = 'array';
const BUILTIN_TYPE_NULL = 'null';
const BUILTIN_TYPE_CALLABLE = 'callable';
const BUILTIN_TYPE_ITERABLE = 'iterable';
/**
* List of PHP builtin types.
@ -45,6 +46,7 @@ class Type
self::BUILTIN_TYPE_ARRAY,
self::BUILTIN_TYPE_CALLABLE,
self::BUILTIN_TYPE_NULL,
self::BUILTIN_TYPE_ITERABLE,
);
/**
@ -104,7 +106,7 @@ class Type
/**
* Gets built-in type.
*
* Can be bool, int, float, string, array, object, resource, null or callback.
* Can be bool, int, float, string, array, object, resource, null, callback or iterable.
*
* @return string
*/

View File

@ -49,6 +49,7 @@ class RememberMeAuthenticationProvider implements AuthenticationProviderInterfac
$user = $token->getUser();
$this->userChecker->checkPreAuth($user);
$this->userChecker->checkPostAuth($user);
$authenticatedToken = new RememberMeToken($user, $this->providerKey, $this->secret);
$authenticatedToken->setAttributes($token->getAttributes());

View File

@ -15,6 +15,7 @@ use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
use Symfony\Component\Serializer\Exception\RuntimeException;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
@ -32,6 +33,10 @@ class ObjectNormalizer extends AbstractObjectNormalizer
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null)
{
if (!class_exists('Symfony\Component\PropertyAccess\PropertyAccess')) {
throw new RuntimeException('The ObjectNormalizer class requires the "PropertyAccess" component. Install "symfony/property-access" to use it.');
}
parent::__construct($classMetadataFactory, $nameConverter, $propertyTypeExtractor);
$this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor();

View File

@ -22,7 +22,7 @@ class UrlValidator extends ConstraintValidator
{
const PATTERN = '~^
(%s):// # protocol
(([\pL\pN-]+:)?([\pL\pN-]+)@)? # basic auth
(([\.\pL\pN-]+:)?([\.\pL\pN-]+)@)? # basic auth
(
([\pL\pN\pS-\.])+(\.?([\pL\pN]|xn\-\-[\pL\pN-]+)+\.?) # a domain name
| # or

View File

@ -116,6 +116,9 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
array('http://xn--d1abbgf6aiiy.xn--p1ai/'),
array('http://☎.com/'),
array('http://username:password@symfony.com'),
array('http://user.name:password@symfony.com'),
array('http://username:pass.word@symfony.com'),
array('http://user.name:pass.word@symfony.com'),
array('http://user-name@symfony.com'),
array('http://symfony.com?'),
array('http://symfony.com?query=1'),