From 1c017c0e81e9682a6f42d39be9fb126462411ac2 Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Mon, 15 Apr 2024 22:48:29 +0100 Subject: [PATCH] Issue #3427174 by longwave, quietone, dineshkumarbollu, mondrake, alexpott: Throw exception when calling NestedArray::setValue() when parents reference a non-array value instead of causing a PHP error --- core/.phpstan-baseline.php | 6 ------ core/lib/Drupal/Component/Utility/NestedArray.php | 7 +++++-- .../Drupal/Tests/Component/Utility/NestedArrayTest.php | 4 ++++ core/tests/Drupal/Tests/Core/Config/ConfigTest.php | 3 ++- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php index 9f651bdc7b81..9dec751955e7 100644 --- a/core/.phpstan-baseline.php +++ b/core/.phpstan-baseline.php @@ -2146,12 +2146,6 @@ 'count' => 1, 'path' => __DIR__ . '/tests/Drupal/Tests/Composer/ComposerTest.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Call to deprecated method expectError\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\: -https\\://github\\.com/sebastianbergmann/phpunit/issues/5062$#', - 'count' => 1, - 'path' => __DIR__ . '/tests/Drupal/Tests/Core/Config/ConfigTest.php', -]; $ignoreErrors[] = [ 'message' => '#^Trying to mock an undefined method getRevisionId\\(\\) on class Drupal\\\\Tests\\\\Core\\\\Entity\\\\UrlTestEntity\\.$#', 'count' => 1, diff --git a/core/lib/Drupal/Component/Utility/NestedArray.php b/core/lib/Drupal/Component/Utility/NestedArray.php index c9feb599d1b4..354d58183201 100644 --- a/core/lib/Drupal/Component/Utility/NestedArray.php +++ b/core/lib/Drupal/Component/Utility/NestedArray.php @@ -138,7 +138,7 @@ public static function &getValue(array &$array, array $parents, &$key_exists = N * @param bool $force * (optional) If TRUE, the value is forced into the structure even if it * requires the deletion of an already existing non-array parent value. If - * FALSE, PHP throws an error if trying to add into a value that is not an + * FALSE, throws an exception if trying to add into a value that is not an * array. Defaults to FALSE. * * @see NestedArray::unsetValue() @@ -149,7 +149,10 @@ public static function setValue(array &$array, array $parents, $value, $force = foreach ($parents as $parent) { // PHP auto-creates container arrays and NULL entries without error if $ref // is NULL, but throws an error if $ref is set, but not an array. - if ($force && isset($ref) && !is_array($ref)) { + if (isset($ref) && !is_array($ref)) { + if (!$force) { + throw new \LogicException('Cannot create key "' . $parent . '" on non-array value.'); + } $ref = []; } $ref = &$ref[$parent]; diff --git a/core/tests/Drupal/Tests/Component/Utility/NestedArrayTest.php b/core/tests/Drupal/Tests/Component/Utility/NestedArrayTest.php index f1d4436a5cfc..a48d5bab73f8 100644 --- a/core/tests/Drupal/Tests/Component/Utility/NestedArrayTest.php +++ b/core/tests/Drupal/Tests/Component/Utility/NestedArrayTest.php @@ -87,6 +87,10 @@ public function testSetValue() { NestedArray::setValue($this->form, $this->parents, $new_value); $this->assertSame('New value', $this->form['details']['element']['#value'], 'Changed nested element value found.'); $this->assertTrue($this->form['details']['element']['#required'], 'New nested element value found.'); + + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot create key "child" on non-array value.'); + NestedArray::setValue($this->form, ['details', 'element', '#value', 'child'], $new_value); } /** diff --git a/core/tests/Drupal/Tests/Core/Config/ConfigTest.php b/core/tests/Drupal/Tests/Core/Config/ConfigTest.php index 29032f8f54db..4ba8a31f727c 100644 --- a/core/tests/Drupal/Tests/Core/Config/ConfigTest.php +++ b/core/tests/Drupal/Tests/Core/Config/ConfigTest.php @@ -276,7 +276,8 @@ public function testSetIllegalOffsetValue() { $this->config->set('testData', 1); // Attempt to treat the single value as a nested item. - $this->expectError(); + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot create key "illegalOffset" on non-array value.'); $this->config->set('testData.illegalOffset', 1); } -- GitLab