Skip to content

Commit

Permalink
feature #22527 [DI] Throw useful exception on bad XML argument tags (…
Browse files Browse the repository at this point in the history
…nicolas-grekas)

This PR was merged into the 3.3-dev branch.

Discussion
----------

[DI] Throw useful exception on bad XML argument tags

| Q             | A
| ------------- | ---
| Branch?       | 3.3
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #22525
| License       | MIT
| Doc PR        | -

I still think that the feature request in #22525 would make things better.
But at least, let's make thing fail loudly, instead of silently today, with the associated usual wtfs :)

Commits
-------

91828ec [DI] Throw useful exception on bad XML argument tags
  • Loading branch information
fabpot committed Apr 29, 2017
2 parents 35608f5 + 91828ec commit 8872833
Showing 1 changed file with 21 additions and 10 deletions.
31 changes: 21 additions & 10 deletions src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
Expand Up @@ -50,7 +50,7 @@ public function load($resource, $type = null)
$this->parseImports($xml, $path);

// parameters
$this->parseParameters($xml);
$this->parseParameters($xml, $path);

// extensions
$this->loadFromExtensions($xml);
Expand Down Expand Up @@ -83,11 +83,12 @@ public function supports($resource, $type = null)
* Parses parameters.
*
* @param \DOMDocument $xml
* @param string $file
*/
private function parseParameters(\DOMDocument $xml)
private function parseParameters(\DOMDocument $xml, $file)
{
if ($parameters = $this->getChildren($xml->documentElement, 'parameters')) {
$this->container->getParameterBag()->add($this->getArgumentsAsPhp($parameters[0], 'parameter'));
$this->container->getParameterBag()->add($this->getArgumentsAsPhp($parameters[0], 'parameter', $file));
}
}

Expand Down Expand Up @@ -278,8 +279,8 @@ private function parseDefinition(\DOMElement $service, $file, array $defaults =
$definition->setDeprecated(true, $deprecated[0]->nodeValue ?: null);
}

$definition->setArguments($this->getArgumentsAsPhp($service, 'argument', false, $definition instanceof ChildDefinition));
$definition->setProperties($this->getArgumentsAsPhp($service, 'property'));
$definition->setArguments($this->getArgumentsAsPhp($service, 'argument', $file, false, $definition instanceof ChildDefinition));
$definition->setProperties($this->getArgumentsAsPhp($service, 'property', $file));

if ($factories = $this->getChildren($service, 'factory')) {
$factory = $factories[0];
Expand Down Expand Up @@ -312,7 +313,7 @@ private function parseDefinition(\DOMElement $service, $file, array $defaults =
}

foreach ($this->getChildren($service, 'call') as $call) {
$definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument'));
$definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument', $file));
}

$tags = $this->getChildren($service, 'tag');
Expand Down Expand Up @@ -446,11 +447,12 @@ private function processAnonymousServices(\DOMDocument $xml, $file)
*
* @param \DOMElement $node
* @param string $name
* @param string $file
* @param bool $lowercase
*
* @return mixed
*/
private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true, $isChildDefinition = false)
private function getArgumentsAsPhp(\DOMElement $node, $name, $file, $lowercase = true, $isChildDefinition = false)
{
$arguments = array();
foreach ($this->getChildren($node, $name) as $arg) {
Expand Down Expand Up @@ -486,6 +488,9 @@ private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true,

switch ($arg->getAttribute('type')) {
case 'service':
if (!$arg->getAttribute('id')) {
throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="service" has no or empty "id" attribute in "%s".', $name, $file));
}
if ($arg->hasAttribute('strict')) {
@trigger_error(sprintf('The "strict" attribute used when referencing the "%s" service is deprecated since version 3.3 and will be removed in 4.0.', $arg->getAttribute('id')), E_USER_DEPRECATED);
}
Expand All @@ -496,17 +501,23 @@ private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true,
$arguments[$key] = new Expression($arg->nodeValue);
break;
case 'closure-proxy':
if (!$arg->getAttribute('id')) {
throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="closure-proxy" has no or empty "id" attribute in "%s".', $name, $file));
}
if (!$arg->getAttribute('method')) {
throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="closure-proxy" has no or empty "method" attribute in "%s".', $name, $file));
}
$arguments[$key] = new ClosureProxyArgument($arg->getAttribute('id'), $arg->getAttribute('method'), $invalidBehavior);
break;
case 'collection':
$arguments[$key] = $this->getArgumentsAsPhp($arg, $name, false);
$arguments[$key] = $this->getArgumentsAsPhp($arg, $name, $file, false);
break;
case 'iterator':
$arg = $this->getArgumentsAsPhp($arg, $name, false);
$arg = $this->getArgumentsAsPhp($arg, $name, $file, false);
try {
$arguments[$key] = new IteratorArgument($arg);
} catch (InvalidArgumentException $e) {
throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="iterator" only accepts collections of type="service" references.', $name));
throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="iterator" only accepts collections of type="service" references in "%s".', $name, $file));
}
break;
case 'string':
Expand Down

0 comments on commit 8872833

Please sign in to comment.