From 892bd13d900680c30e3a9ab5bc37ae43593078eb Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Wed, 17 Apr 2019 10:23:10 +0200 Subject: [PATCH] Merge pull request #3751 from Icinga/fix/php-does-not-strip-trailing-whitespace-3733 Fix php ini parser does not strip trailing whitespace (cherry picked from commit f027bc50e8e13d2cf048b2a5758dbce664be6171) Signed-off-by: Johannes Meyer --- library/Icinga/File/Ini/IniParser.php | 3 +- .../library/Icinga/File/Ini/IniParserTest.php | 65 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/library/Icinga/File/Ini/IniParser.php b/library/Icinga/File/Ini/IniParser.php index 6be0dec15..5ec03a2e9 100644 --- a/library/Icinga/File/Ini/IniParser.php +++ b/library/Icinga/File/Ini/IniParser.php @@ -304,6 +304,7 @@ class IniParser $str = str_replace('\"', '"', $str); $str = str_replace('\\\\', '\\', $str); - return $str; + // This replacement is a work-around for PHP bug #76965. Fixed with versions 7.1.24, 7.2.12 and 7.3.0. + return preg_replace('~^([\'"])(.*?)\1\s+$~', '$2', $str); } } diff --git a/test/php/library/Icinga/File/Ini/IniParserTest.php b/test/php/library/Icinga/File/Ini/IniParserTest.php index 7de2e1abe..5a1d7df90 100644 --- a/test/php/library/Icinga/File/Ini/IniParserTest.php +++ b/test/php/library/Icinga/File/Ini/IniParserTest.php @@ -170,4 +170,69 @@ EOD; 'IniParser::parseIniFile does resolve environment variables' ); } + + public function testPhpBug76965() + { + $config = <<<'EOD' +[section] +a = "foobar" +b = "foo"bar "" +c = "foobar" ; comment +d =' foo ' +e =foo +f = foo +g = ""foo" "; Edge case, see below for more details +EOD; + + $parsedConfig = parse_ini_string($config, true, INI_SCANNER_RAW)['section']; + if ($parsedConfig['a'] === 'foobar') { + $this->markTestSkipped('This version of PHP is not affected by bug #76965'); + } + + $this->assertEquals('"foobar" ', $parsedConfig['a'], 'PHP version affected but bug #76965 not in effect?'); + $this->assertEquals('"foo"bar "" ', $parsedConfig['b'], 'PHP version affected but bug #76965 not in effect?'); + $this->assertEquals('"foobar" ', $parsedConfig['c'], 'PHP version affected but bug #76965 not in effect?'); + $this->assertEquals("' foo ' ", $parsedConfig['d'], 'PHP version affected but bug #76965 not in effect?'); + + file_put_contents($this->tempFile, $config); + $configObject = IniParser::parseIniFile($this->tempFile); + + $this->assertEquals( + 'foobar', + $configObject->get('section', 'a'), + 'Workaround for PHP bug #76965 missing' + ); + $this->assertEquals( + 'foo"bar "', + $configObject->get('section', 'b'), + 'Workaround for PHP bug #76965 missing' + ); + $this->assertEquals( + 'foobar', + $configObject->get('section', 'c'), + 'Workaround for PHP bug #76965 missing' + ); + $this->assertEquals( + ' foo ', + $configObject->get('section', 'd'), + 'Workaround for PHP bug #76965 missing' + ); + $this->assertEquals( + 'foo', + $configObject->get('section', 'e'), + 'Workaround for PHP bug #76965 missing' + ); + $this->assertEquals( + 'foo', + $configObject->get('section', 'f'), + 'Workaround for PHP bug #76965 missing' + ); + // This is an edge case which will fail with the current work-around implementation. + // Though, it's considered a really rare case and as such deliberately ignored. + /*$this->assertEquals( + '"foo" ', + $configObject->get('section', 'g'), + 'Workaround for PHP bug #76965 too greedy' + );*/ + } }