Merge branch '2.8' into 3.1

* 2.8:
  [DependencyInjection] Add missing PHPDoc type
  Correct a typo in the ReflectionExtractor's description
  [HttpFoundation] JSONP callback validation
  [Console] Improved the explanation of the hasOption() method
  Uniformize exception vars according to our CS
  add missing use statement
  bug #18042 [Security] $attributes can be anything, but RoleVoter assumes strings
This commit is contained in:
Fabien Potencier 2016-10-05 18:44:51 -07:00
commit d9dfed2976
9 changed files with 43 additions and 12 deletions

View File

@ -13,6 +13,7 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
class AddConstraintValidatorsPass implements CompilerPassInterface class AddConstraintValidatorsPass implements CompilerPassInterface
{ {

View File

@ -281,6 +281,9 @@ class InputDefinition
/** /**
* Returns true if an InputOption object exists by name. * Returns true if an InputOption object exists by name.
* *
* This method can't be used to check if the user included the option when
* executing the command (use getOption() instead).
*
* @param string $name The InputOption name * @param string $name The InputOption name
* *
* @return bool true if the InputOption object exists, false otherwise * @return bool true if the InputOption object exists, false otherwise

View File

@ -664,7 +664,7 @@ class Definition
/** /**
* Sets autowired. * Sets autowired.
* *
* @param $autowired * @param bool $autowired
* *
* @return Definition The current instance * @return Definition The current instance
*/ */

View File

@ -81,11 +81,19 @@ class JsonResponse extends Response
public function setCallback($callback = null) public function setCallback($callback = null)
{ {
if (null !== $callback) { if (null !== $callback) {
// taken from http://www.geekality.net/2011/08/03/valid-javascript-identifier/ // partially token from http://www.geekality.net/2011/08/03/valid-javascript-identifier/
$pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*+$/u'; // partially token from https://github.com/willdurand/JsonpCallbackValidator
// JsonpCallbackValidator is released under the MIT License. See https://github.com/willdurand/JsonpCallbackValidator/blob/v1.1.0/LICENSE for details.
// (c) William Durand <william.durand1@gmail.com>
$pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*(?:\[(?:"(?:\\\.|[^"\\\])*"|\'(?:\\\.|[^\'\\\])*\'|\d+)\])*?$/u';
$reserved = array(
'break', 'do', 'instanceof', 'typeof', 'case', 'else', 'new', 'var', 'catch', 'finally', 'return', 'void', 'continue', 'for', 'switch', 'while',
'debugger', 'function', 'this', 'with', 'default', 'if', 'throw', 'delete', 'in', 'try', 'class', 'enum', 'extends', 'super', 'const', 'export',
'import', 'implements', 'let', 'private', 'public', 'yield', 'interface', 'package', 'protected', 'static', 'null', 'true', 'false',
);
$parts = explode('.', $callback); $parts = explode('.', $callback);
foreach ($parts as $part) { foreach ($parts as $part) {
if (!preg_match($pattern, $part)) { if (!preg_match($pattern, $part) || in_array($part, $reserved, true)) {
throw new \InvalidArgumentException('The callback name is not valid.'); throw new \InvalidArgumentException('The callback name is not valid.');
} }
} }

View File

@ -225,6 +225,14 @@ class JsonResponseTest extends \PHPUnit_Framework_TestCase
JsonResponse::create($serializable); JsonResponse::create($serializable);
} }
public function testSetComplexCallback()
{
$response = JsonResponse::fromJsonString('{foo: "bar"}');
$response->setCallback('ಠ_ಠ["foo"].bar[0]');
$this->assertEquals('/**/ಠ_ಠ["foo"].bar[0]({foo: "bar"});', $response->getContent());
}
} }
if (interface_exists('JsonSerializable')) { if (interface_exists('JsonSerializable')) {

View File

@ -230,7 +230,7 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property
// Use a ReflectionProperty instead of $class to get the parent class if applicable // Use a ReflectionProperty instead of $class to get the parent class if applicable
try { try {
$reflectionProperty = new \ReflectionProperty($class, $property); $reflectionProperty = new \ReflectionProperty($class, $property);
} catch (\ReflectionException $reflectionException) { } catch (\ReflectionException $e) {
return; return;
} }
@ -263,7 +263,7 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property
) { ) {
break; break;
} }
} catch (\ReflectionException $reflectionException) { } catch (\ReflectionException $e) {
// Try the next prefix if the method doesn't exist // Try the next prefix if the method doesn't exist
} }
} }

View File

@ -17,7 +17,7 @@ use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
use Symfony\Component\PropertyInfo\Type; use Symfony\Component\PropertyInfo\Type;
/** /**
* Extracts PHP informations using the reflection API. * Extracts data using the reflection API.
* *
* @author Kévin Dunglas <dunglas@gmail.com> * @author Kévin Dunglas <dunglas@gmail.com>
*/ */
@ -51,7 +51,7 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
{ {
try { try {
$reflectionClass = new \ReflectionClass($class); $reflectionClass = new \ReflectionClass($class);
} catch (\ReflectionException $reflectionException) { } catch (\ReflectionException $e) {
return; return;
} }
@ -261,7 +261,7 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
$reflectionProperty = new \ReflectionProperty($class, $property); $reflectionProperty = new \ReflectionProperty($class, $property);
return $reflectionProperty->isPublic(); return $reflectionProperty->isPublic();
} catch (\ReflectionException $reflectionExcetion) { } catch (\ReflectionException $e) {
// Return false if the property doesn't exist // Return false if the property doesn't exist
} }
@ -290,7 +290,7 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
if (0 === $reflectionMethod->getNumberOfRequiredParameters()) { if (0 === $reflectionMethod->getNumberOfRequiredParameters()) {
return array($reflectionMethod, $prefix); return array($reflectionMethod, $prefix);
} }
} catch (\ReflectionException $reflectionException) { } catch (\ReflectionException $e) {
// Return null if the property doesn't exist // Return null if the property doesn't exist
} }
} }
@ -319,7 +319,7 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
if ($reflectionMethod->getNumberOfParameters() >= 1) { if ($reflectionMethod->getNumberOfParameters() >= 1) {
return array($reflectionMethod, $prefix); return array($reflectionMethod, $prefix);
} }
} catch (\ReflectionException $reflectionException) { } catch (\ReflectionException $e) {
// Try the next prefix if the method doesn't exist // Try the next prefix if the method doesn't exist
} }
} }

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Security\Core\Authorization\Voter; namespace Symfony\Component\Security\Core\Authorization\Voter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Role\RoleInterface;
/** /**
* RoleVoter votes if any attribute starts with a given prefix. * RoleVoter votes if any attribute starts with a given prefix.
@ -41,7 +42,11 @@ class RoleVoter implements VoterInterface
$roles = $this->extractRoles($token); $roles = $this->extractRoles($token);
foreach ($attributes as $attribute) { foreach ($attributes as $attribute) {
if (0 !== strpos($attribute, $this->prefix)) { if ($attribute instanceof RoleInterface) {
$attribute = $attribute->getRole();
}
if (!is_string($attribute) || 0 !== strpos($attribute, $this->prefix)) {
continue; continue;
} }

View File

@ -36,6 +36,12 @@ class RoleVoterTest extends \PHPUnit_Framework_TestCase
array(array('ROLE_FOO'), array('ROLE_FOO'), VoterInterface::ACCESS_GRANTED), array(array('ROLE_FOO'), array('ROLE_FOO'), VoterInterface::ACCESS_GRANTED),
array(array('ROLE_FOO'), array('FOO', 'ROLE_FOO'), VoterInterface::ACCESS_GRANTED), array(array('ROLE_FOO'), array('FOO', 'ROLE_FOO'), VoterInterface::ACCESS_GRANTED),
array(array('ROLE_BAR', 'ROLE_FOO'), array('ROLE_FOO'), VoterInterface::ACCESS_GRANTED), array(array('ROLE_BAR', 'ROLE_FOO'), array('ROLE_FOO'), VoterInterface::ACCESS_GRANTED),
// Test mixed Types
array(array(), array(array()), VoterInterface::ACCESS_ABSTAIN),
array(array(), array(new \stdClass()), VoterInterface::ACCESS_ABSTAIN),
array(array('ROLE_BAR'), array(new Role('ROLE_BAR')), VoterInterface::ACCESS_GRANTED),
array(array('ROLE_BAR'), array(new Role('ROLE_FOO')), VoterInterface::ACCESS_DENIED),
); );
} }