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;
|
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
|
* Escapes the given string to make it compatible with XLSX
|
||||||
*
|
*
|
||||||
@ -22,7 +47,17 @@ class ODS implements EscaperInterface
|
|||||||
*/
|
*/
|
||||||
public function escape($string)
|
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