Fix issue 329 (#333)
* Used ENT_DISALLOWED when escaping a string. * Added workaround for environments where ENT_DISALLOWED is not defined
This commit is contained in:
parent
4cb30bc36d
commit
ef4a32eb5e
@ -14,6 +14,31 @@ class ODS implements EscaperInterface
|
||||
{
|
||||
use Singleton;
|
||||
|
||||
/** @var string Regex pattern to detect control characters that need to be escaped */
|
||||
protected $escapableControlCharactersPattern;
|
||||
|
||||
/**
|
||||
* Initializes the singleton instance
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
$this->escapableControlCharactersPattern = $this->getEscapableControlCharactersPattern();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Regex pattern containing all escapable control characters
|
||||
*/
|
||||
protected function getEscapableControlCharactersPattern()
|
||||
{
|
||||
// control characters values are from 0 to 1F (hex values) in the ASCII table
|
||||
// some characters should not be escaped though: "\t", "\r" and "\n".
|
||||
return '[\x00-\x08' .
|
||||
// skipping "\t" (0x9) and "\n" (0xA)
|
||||
'\x0B-\x0C' .
|
||||
// skipping "\r" (0xD)
|
||||
'\x0E-\x1F]';
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the given string to make it compatible with XLSX
|
||||
*
|
||||
@ -22,7 +47,17 @@ class ODS implements EscaperInterface
|
||||
*/
|
||||
public function escape($string)
|
||||
{
|
||||
return htmlspecialchars($string, ENT_QUOTES);
|
||||
if (defined('ENT_DISALLOWED')) {
|
||||
// 'ENT_DISALLOWED' ensures that invalid characters in the given document type are replaced.
|
||||
// Otherwise characters like a vertical tab "\v" will make the XML document unreadable by the XML processor
|
||||
// @link https://github.com/box/spout/issues/329
|
||||
return htmlspecialchars($string, ENT_QUOTES | ENT_DISALLOWED);
|
||||
} else {
|
||||
// We are on hhvm or any other engine that does not support ENT_DISALLOWED
|
||||
$escapedString = htmlspecialchars($string, ENT_QUOTES);
|
||||
$replacedString = preg_replace('/'.$this->escapableControlCharactersPattern.'/', '<27>', $escapedString);
|
||||
return $replacedString;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
42
tests/Spout/Common/Escaper/ODSTest.php
Normal file
42
tests/Spout/Common/Escaper/ODSTest.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Box\Spout\Common\Escaper;
|
||||
|
||||
/**
|
||||
* Class ODSTest
|
||||
*
|
||||
* @package Box\Spout\Common\Escaper
|
||||
*/
|
||||
class ODSTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function dataProviderForTestEscape()
|
||||
{
|
||||
return [
|
||||
['test', 'test'],
|
||||
['carl\'s "pokemon"', 'carl's "pokemon"'],
|
||||
["\n", "\n"],
|
||||
["\r", "\r"],
|
||||
["\t", "\t"],
|
||||
["\v", "<EFBFBD>"],
|
||||
["\f", "<EFBFBD>"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProviderForTestEscape
|
||||
*
|
||||
* @param string $stringToEscape
|
||||
* @param string $expectedEscapedString
|
||||
* @return void
|
||||
*/
|
||||
public function testEscape($stringToEscape, $expectedEscapedString)
|
||||
{
|
||||
$escaper = \Box\Spout\Common\Escaper\ODS::getInstance();
|
||||
$escapedString = $escaper->escape($stringToEscape);
|
||||
|
||||
$this->assertEquals($expectedEscapedString, $escapedString, 'Incorrect escaped string');
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user