From 77d0c0ab9c465356b4228beef26b0dbca97af56a Mon Sep 17 00:00:00 2001 From: Aditya Kumar Singh Date: Sun, 18 Jan 2026 01:00:51 +0530 Subject: [PATCH 1/2] Fix YAML dump incorrectly handling zero values In PHP, empty(0) and empty("0") return true, which caused the YAML dumper to incorrectly treat zero values as empty. This resulted in: - Arrays containing 0 being serialized without the zero value - Scalar zero values being omitted from YAML output Changes: - dump(): Replace 'if ($array)' with explicit null/empty checks to properly handle arrays that may contain zero values - _yamlize(): Replace 'empty($value)' with 'count($value) === 0' to only treat actually empty arrays as empty, not zero values Added test cases: - testDumpIntegerZero: Verify integer 0 is correctly dumped - testDumpStringZero: Verify string '0' is correctly dumped - testDumpAssociativeZero: Verify zero values in associative arrays - testDumpMixedWithZero: Verify mixed arrays containing zero Fixes wp-cli/wp-cli#6188 --- src/Spyc.php | 8 ++++++-- tests/DumpTest.php | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/Spyc.php b/src/Spyc.php index fd2c38c..18682a9 100644 --- a/src/Spyc.php +++ b/src/Spyc.php @@ -211,7 +211,9 @@ public function dump($array,$indent = false,$wordwrap = false, $no_opening_dashe if (!$no_opening_dashes) $string = "---\n"; // Start at the base of the array and move through it. - if ($array) { + // Note: We use !== null check to properly handle arrays containing zero values + // since `if ($array)` would incorrectly skip processing for falsey values like 0. + if ($array !== null && $array !== '' && (!is_array($array) || count($array) > 0)) { $array = (array)$array; $previous_key = -1; foreach ($array as $key => $value) { @@ -234,7 +236,9 @@ public function dump($array,$indent = false,$wordwrap = false, $no_opening_dashe private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0, $source_array = null) { if(is_object($value)) $value = (array)$value; if (is_array($value)) { - if (empty ($value)) + // Note: We use explicit count check instead of empty() because empty(0) and empty("0") + // return true in PHP, which would incorrectly treat zero values as empty arrays. + if (count($value) === 0) return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array); // It has children. What to do? // Make it the right kind of item diff --git a/tests/DumpTest.php b/tests/DumpTest.php index ac7774f..febbb71 100644 --- a/tests/DumpTest.php +++ b/tests/DumpTest.php @@ -193,4 +193,43 @@ public function testPerCentAndDoubleQuote() { $this->assertEquals ($awaiting, $dump); } + /** + * Test that integer zero values are correctly dumped. + * This is a regression test for the issue where empty(0) returns true in PHP, + * causing zero values to be incorrectly treated as empty. + */ + public function testDumpIntegerZero() { + $dump = Spyc::YAMLDump(array(0)); + $awaiting = "---\n- 0\n"; + $this->assertEquals($awaiting, $dump); + } + + /** + * Test that string zero values are correctly dumped. + * This is a regression test for the issue where empty("0") returns true in PHP. + */ + public function testDumpStringZero() { + $dump = Spyc::YAMLDump(array('0')); + $awaiting = "---\n- \"0\"\n"; + $this->assertEquals($awaiting, $dump); + } + + /** + * Test that associative arrays with zero values are correctly dumped. + */ + public function testDumpAssociativeZero() { + $dump = Spyc::YAMLDump(array('key' => 0)); + $awaiting = "---\nkey: 0\n"; + $this->assertEquals($awaiting, $dump); + } + + /** + * Test that mixed arrays containing zero values are correctly dumped. + */ + public function testDumpMixedWithZero() { + $dump = Spyc::YAMLDump(array(1, 0, 2)); + $awaiting = "---\n- 1\n- 0\n- 2\n"; + $this->assertEquals($awaiting, $dump); + } + } From 03948eb81e7cf88c6e7a4fdb3ed41e19b0463fc0 Mon Sep 17 00:00:00 2001 From: Aditya Kumar Singh Date: Wed, 21 Jan 2026 11:17:45 +0530 Subject: [PATCH 2/2] Address review feedback: improve code comments for clarity - dump() method: Updated comment to clarify the fix handles both: - Scalar zero values passed directly (dump(0) or dump("0")) - Arrays containing zero values (dump([0])) - _yamlize() method: Updated comment to clarify this is a stylistic consistency change, since at this point is already verified to be an array (not a scalar zero) --- src/Spyc.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Spyc.php b/src/Spyc.php index 18682a9..e66a5f3 100644 --- a/src/Spyc.php +++ b/src/Spyc.php @@ -211,8 +211,10 @@ public function dump($array,$indent = false,$wordwrap = false, $no_opening_dashe if (!$no_opening_dashes) $string = "---\n"; // Start at the base of the array and move through it. - // Note: We use !== null check to properly handle arrays containing zero values - // since `if ($array)` would incorrectly skip processing for falsey values like 0. + // Note: We use explicit checks instead of `if ($array)` to properly handle: + // - Scalar zero values passed directly (e.g., dump(0) or dump("0")) + // - Arrays containing zero values (e.g., dump([0])) + // PHP treats 0 and "0" as falsey, so a simple `if ($array)` would skip processing. if ($array !== null && $array !== '' && (!is_array($array) || count($array) > 0)) { $array = (array)$array; $previous_key = -1; @@ -236,8 +238,10 @@ public function dump($array,$indent = false,$wordwrap = false, $no_opening_dashe private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0, $source_array = null) { if(is_object($value)) $value = (array)$value; if (is_array($value)) { - // Note: We use explicit count check instead of empty() because empty(0) and empty("0") - // return true in PHP, which would incorrectly treat zero values as empty arrays. + // Note: We use count($value) === 0 instead of empty($value) for stylistic consistency + // with the fix in dump(). While functionally equivalent here (since $value is already + // verified to be an array), this makes the intent explicit and avoids any confusion + // with PHP's empty() behavior on zero values. if (count($value) === 0) return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array); // It has children. What to do?