icingaweb2/test/php/library/Icinga/File/Ini/IniParserTest.php

239 lines
8.2 KiB
PHP
Raw Normal View History

<?php
/* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */
namespace Tests\Icinga\Config;
use Icinga\File\Ini\IniWriter;
use Icinga\Test\BaseTestCase;
use Icinga\Application\Config;
use Icinga\File\Ini\IniParser;
class IniParserTest extends BaseTestCase
{
protected $tempFile;
public function setUp(): void
{
parent::setUp();
$this->tempFile = tempnam(sys_get_temp_dir(), 'icinga-ini-parser-test');
}
public function tearDown(): void
{
parent::tearDown();
unlink($this->tempFile);
}
public function testSectionNameEscaping()
{
$config = <<<'EOD'
[title with \"quote]
[title with \;semicolon]
[title with \\backslash]
EOD;
$doc = IniParser::parseIni($config);
$this->assertTrue(
$doc->hasSection('title with "quote'),
'IniParser::parseIni does not recognize escaped quotes in section names'
);
$this->assertTrue(
$doc->hasSection('title with ;semicolon'),
'IniParser::parseIni does not recognize escaped semicolons in section names'
);
$this->assertTrue(
$doc->hasSection('title with \\backslash'),
'IniParser::parseIni does not recognize escaped backslashes in section names'
);
(new IniWriter(Config::fromArray([
'title with "quote' => [],
'title with ;semicolon' => [],
'title with \\backslash' => []
]), $this->tempFile))->write();
$configObject = IniParser::parseIniFile($this->tempFile);
$this->assertTrue(
$configObject->hasSection('title with "quote'),
'IniParser::parseIniFile does not recognize escaped quotes in section names'
);
$this->assertTrue(
$configObject->hasSection('title with ;semicolon'),
'IniParser::parseIniFile does not recognize escaped semicolons in section names'
);
$this->assertTrue(
$configObject->hasSection('title with \\backslash'),
'IniParser::parseIniFile does not recognize escaped backslashes in section names'
);
}
public function testDirectiveValueEscaping()
{
$config = <<<'EOD'
[section]
key1 = "key with escaped \"quote"
key2 = "key with escaped backslash \\"
key3 = "key with escaped backslash followed by quote \\\""
EOD;
$doc = IniParser::parseIni($config);
$this->assertEquals(
'key with escaped "quote',
$doc->getSection('section')->getDirective('key1')->getValue(),
'IniParser::parseIni does not recognize escaped quotes in values'
);
$this->assertEquals(
'key with escaped backslash \\',
$doc->getSection('section')->getDirective('key2')->getValue(),
'IniParser::parseIni does not recognize escaped backslashes in values'
);
$this->assertEquals(
'key with escaped backslash followed by quote \\"',
$doc->getSection('section')->getDirective('key3')->getValue(),
'IniParser::parseIni does not recognize escaped backslashes followed by quotes in values'
);
(new IniWriter(Config::fromArray([
'section' => [
'key1' => 'key with escaped "quote',
'key2' => 'key with escaped backslash \\',
'key3' => 'key with escaped backslash followed by quote \\"'
]
]), $this->tempFile))->write();
$configObject = IniParser::parseIniFile($this->tempFile);
$this->assertEquals(
'key with escaped "quote',
$configObject->getSection('section')->get('key1'),
'IniParser::parseIniFile does not recognize escaped quotes in values'
);
$this->assertEquals(
'key with escaped backslash \\',
$configObject->getSection('section')->get('key2'),
'IniParser::parseIniFile does not recognize escaped backslashes in values'
);
$this->assertEquals(
'key with escaped backslash followed by quote \\"',
$configObject->getSection('section')->get('key3'),
'IniParser::parseIniFile does not recognize escaped backslashes followed by quotes in values'
);
}
2015-08-10 14:49:27 +02:00
public function testMultilineValues()
{
$config = <<<'EOD'
[section]
key1 = "with some
newline in the value"
EOD;
$doc = IniParser::parseIni($config);
$this->assertEquals(
2,
count(explode("\n", $doc->getSection('section')->getDirective('key1')->getValue())),
2019-03-04 12:16:55 +01:00
'IniParser::parseIni does not recognize multi-line values'
);
(new IniWriter(Config::fromArray([
'section' => [
'key1' => "with some\nnewline in the value"
]
]), $this->tempFile))->write();
$doc = IniParser::parseIniFile($this->tempFile);
$this->assertEquals(
2,
count(explode("\n", $doc->getSection('section')->get('key1'))),
'IniParser::parseIniFile does not recognize multi-line values'
);
}
public function testEnvironmentVariableResolutionDoesNotWork()
{
(new IniWriter(Config::fromArray([
'section' => [
'key1' => '${PATH}_${APACHE_RUN_DIR}',
'key2' => '${APACHE_RUN_USER}'
]
]), $this->tempFile))->write();
$configObject = IniParser::parseIniFile($this->tempFile);
$this->assertEquals(
'${PATH}_${APACHE_RUN_DIR}',
$configObject->getSection('section')->get('key1'),
'IniParser::parseIniFile does resolve environment variables'
);
$this->assertEquals(
'${APACHE_RUN_USER}',
$configObject->getSection('section')->get('key2'),
'IniParser::parseIniFile does resolve environment variables'
2015-08-10 14:49:27 +02:00
);
}
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'
);*/
}
}