Skip to content

[DI] Added safeguards against invalid config in the YamlFileLoader #11374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 10, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ public function load($file, $type = null)

// parameters
if (isset($content['parameters'])) {
if (!is_array($content['parameters'])) {
throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $file));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the text be The "parameters" key should be an array in %s.?

Because parameters does not need to contain an array, but just be one? Even the code above says so.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, the key is not an array. The key is a string

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I actually missed the key part. Still early in the morning. 😉

}

foreach ($content['parameters'] as $key => $value) {
$this->container->setParameter($key, $this->resolveServices($value));
}
Expand Down Expand Up @@ -92,7 +96,15 @@ private function parseImports($content, $file)
return;
}

if (!is_array($content['imports'])) {
throw new InvalidArgumentException(sprintf('The "imports" key should contain an array in %s. Check your YAML syntax.', $file));
}

foreach ($content['imports'] as $import) {
if (!is_array($import)) {
throw new InvalidArgumentException(sprintf('The values in the "imports" key should be arrays in %s. Check your YAML syntax.', $file));
}

$this->setCurrentDir(dirname($file));
$this->import($import['resource'], null, isset($import['ignore_errors']) ? (bool) $import['ignore_errors'] : false, $file);
}
Expand All @@ -110,6 +122,10 @@ private function parseDefinitions($content, $file)
return;
}

if (!is_array($content['services'])) {
throw new InvalidArgumentException(sprintf('The "services" key should contain an array in %s. Check your YAML syntax.', $file));
}

foreach ($content['services'] as $id => $service) {
$this->parseDefinition($id, $service, $file);
}
Expand All @@ -130,7 +146,13 @@ private function parseDefinition($id, $service, $file)
$this->container->setAlias($id, substr($service, 1));

return;
} elseif (isset($service['alias'])) {
}

if (!is_array($service)) {
throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but %s found for service "%s" in %s. Check your YAML syntax.', gettype($service), $id, $file));
}

if (isset($service['alias'])) {
$public = !array_key_exists('public', $service) || (bool) $service['public'];
$this->container->setAlias($id, new Alias($service['alias'], $public));

Expand Down Expand Up @@ -204,6 +226,10 @@ private function parseDefinition($id, $service, $file)
}

if (isset($service['calls'])) {
if (!is_array($service['calls'])) {
throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
}

foreach ($service['calls'] as $call) {
$args = isset($call[1]) ? $this->resolveServices($call[1]) : array();
$definition->addMethodCall($call[0], $args);
Expand All @@ -212,20 +238,24 @@ private function parseDefinition($id, $service, $file)

if (isset($service['tags'])) {
if (!is_array($service['tags'])) {
throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s.', $id, $file));
throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
}

foreach ($service['tags'] as $tag) {
if (!is_array($tag)) {
throw new InvalidArgumentException(sprintf('A "tags" entry must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
}

if (!isset($tag['name'])) {
throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in %s.', $id, $file));
}

$name = $tag['name'];
unset($tag['name']);

foreach ($tag as $attribute => $value) {
foreach ($tag as $value) {
if (!is_scalar($value)) {
throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s" in %s.', $id, $name, $file));
throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s" in %s. Check your YAML syntax.', $id, $name, $file));
}
}

Expand Down Expand Up @@ -279,7 +309,7 @@ private function validate($content, $file)
}

if (!is_array($content)) {
throw new InvalidArgumentException(sprintf('The service file "%s" is not valid.', $file));
throw new InvalidArgumentException(sprintf('The service file "%s" is not valid. It should contain an array. Check your YAML syntax.', $file));
}

foreach (array_keys($content) as $namespace) {
Expand All @@ -305,9 +335,9 @@ private function validate($content, $file)
/**
* Resolves services.
*
* @param string $value
* @param string|array $value
*
* @return Reference
* @return array|string|Reference
*/
private function resolveServices($value)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
services:
method_call1:
class: FooClass
calls: foo
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
imports:
- foo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
imports:
foo:bar
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
parameters:
foo:bar
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
services:
foo: bar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
services: foo
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
services:
foo_service:
class: FooClass
tags:
# tag is not an array
- foo
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\Config\Loader\Loader;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
Expand Down Expand Up @@ -80,6 +79,29 @@ public function testLoadFile()
}
}

/**
* @dataProvider provideInvalidFiles
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
*/
public function testLoadInvalidFile($file)
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));

$loader->load($file.'.yml');
}

public function provideInvalidFiles()
{
return array(
array('bad_parameters'),
array('bad_imports'),
array('bad_import'),
array('bad_services'),
array('bad_service'),
array('bad_calls'),
);
}

public function testLoadParameters()
{
$container = new ContainerBuilder();
Expand Down Expand Up @@ -179,7 +201,7 @@ public function testSupports()
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
}

public function testNonArrayTagThrowsException()
public function testNonArrayTagsThrowsException()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
try {
Expand All @@ -191,6 +213,16 @@ public function testNonArrayTagThrowsException()
}
}

/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
* @expectedExceptionMessage A "tags" entry must be an array for service
*/
public function testNonArrayTagThrowsException()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('badtag4.yml');
}

public function testTagWithoutNameThrowsException()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy