Commit 733eed41 authored by catch's avatar catch

Issue #2172941 by vijaycs85, damiankloip: Endless looping on...

Issue #2172941 by vijaycs85, damiankloip: Endless looping on Config::castValue() for undefined config data type.
parent ef7dcd9f
......@@ -592,6 +592,9 @@ protected function getSchemaWrapper() {
*
* @return mixed
* The value cast to the type indicated in the schema.
*
* @throws \Drupal\Core\Config\UnsupportedDataTypeConfigException
* Exception on unsupported/undefined data type deducted.
*/
protected function castValue($key, $value) {
if ($value === NULL) {
......@@ -627,9 +630,12 @@ protected function castValue($key, $value) {
}
}
else {
// Any non-scalar value must be an array.
// Throw exception on any non-scalar or non-array value.
if (!is_array($value)) {
$value = (array) $value;
throw new UnsupportedDataTypeConfigException(String::format('Invalid data type for config element @name:@key', array(
'@name' => $this->getName(),
'@key' => $key,
)));
}
// Recurse into any nested keys.
foreach ($value as $nested_value_key => $nested_value) {
......
......@@ -7,7 +7,9 @@
namespace Drupal\Core\Config;
use Drupal\Component\Utility\String;
use Symfony\Component\Yaml\Dumper;
use Symfony\Component\Yaml\Exception\DumpException;
use Symfony\Component\Yaml\Parser;
/**
......@@ -105,11 +107,17 @@ public function readMultiple(array $names) {
/**
* Implements Drupal\Core\Config\StorageInterface::write().
*
* @throws Symfony\Component\Yaml\Exception\DumpException
* @throws \Drupal\Core\Config\UnsupportedDataTypeConfigException
* @throws \Drupal\Core\Config\StorageException
*/
public function write($name, array $data) {
$data = $this->encode($data);
try {
$data = $this->encode($data);
}
catch(DumpException $e) {
throw new UnsupportedDataTypeConfigException(String::format('Invalid data type for used in config: @name', array('@name' => $name)));
}
$target = $this->getFilePath($name);
$status = @file_put_contents($target, $data);
if ($status === FALSE) {
......
<?php
/**
* @file
* Contains \Drupal\Core\Config\UnsupportedDataTypeConfigException.
*/
namespace Drupal\Core\Config;
/**
* Exception thrown when a config data type is invalid.
*/
class UnsupportedDataTypeConfigException extends ConfigException {
}
......@@ -7,9 +7,11 @@
namespace Drupal\config\Tests;
use Drupal\Component\Utility\String;
use Drupal\Core\Config\ConfigNameException;
use Drupal\simpletest\DrupalUnitTestBase;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\UnsupportedDataTypeConfigException;
/**
* Tests CRUD operations on configuration objects.
......@@ -225,12 +227,31 @@ public function testDataTypes() {
$this->assertIdentical($config->get(), $data);
$this->assertIdentical($storage->read($name), $data);
// Test that setting an unsupported type for a config object with a schema
// fails.
try {
$config->set('stream', fopen(__FILE__, 'r'))->save();
$this->fail('No Exception thrown upon saving invalid data type.');
}
catch (\Exception $e) {
$this->pass(format_string('%class thrown upon saving invalid data type.', array(
catch (UnsupportedDataTypeConfigException $e) {
$this->pass(String::format('%class thrown upon saving invalid data type.', array(
'%class' => get_class($e),
)));
}
// Test that setting an unsupported type for a config object with no schema
// also fails.
$typed_config_manager = $this->container->get('config.typed');
$config_name = 'config_test.no_schema';
$config = $this->container->get('config.factory')->get($config_name);
$this->assertFalse($typed_config_manager->hasConfigSchema($config_name));
try {
$config->set('stream', fopen(__FILE__, 'r'))->save();
$this->fail('No Exception thrown upon saving invalid data type.');
}
catch (UnsupportedDataTypeConfigException $e) {
$this->pass(String::format('%class thrown upon saving invalid data type.', array(
'%class' => get_class($e),
)));
}
......
......@@ -131,3 +131,38 @@ config_test.schema_data_types:
type: sequence
sequence:
- type: boolean
config_test.types:
type: mapping
label: 'Configuration type'
mapping:
array:
type: sequence
label: 'Array'
sequence:
- type: string
label: 'Item'
boolean:
type: boolean
label: 'Boolean'
float:
type: float
label: 'Float'
exp:
type: float
label: 'Exponential'
hex:
type: integer
label: 'Hexadecimal'
int:
type: integer
label: 'Integer'
octal:
type: integer
label: 'Octal'
string:
type: string
label: 'String'
string_int:
type: string
label: 'String integer'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment