Fix sheet name escaping (fixes #576)

This commit is contained in:
Tim Hunt 2018-07-03 16:41:43 +01:00
parent 799ad93d23
commit 22821d718f
6 changed files with 14 additions and 13 deletions

View File

@ -22,17 +22,17 @@ class ODS implements EscaperInterface
*/ */
public function escape($string) public function escape($string)
{ {
// @NOTE: ODS files are basically XML, so we need to escape <, > and &.
// Mostly values are saved in element contents, but a few things (e.g. worksheet names)
// are stored in attributes, so we also need to escape " and ', hence ENT_QUOTES.
if (defined('ENT_DISALLOWED')) { if (defined('ENT_DISALLOWED')) {
// 'ENT_DISALLOWED' ensures that invalid characters in the given document type are replaced. // 'ENT_DISALLOWED' ensures that invalid characters in the given document type are replaced.
// Otherwise control characters like a vertical tab "\v" will make the XML document unreadable by the XML processor // Otherwise control characters like a vertical tab "\v" will make the XML document unreadable by the XML processor
// @link https://github.com/box/spout/issues/329 // @link https://github.com/box/spout/issues/329
$replacedString = htmlspecialchars($string, ENT_NOQUOTES | ENT_DISALLOWED, 'UTF-8'); $replacedString = htmlspecialchars($string, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8');
} else { } else {
// We are on hhvm or any other engine that does not support ENT_DISALLOWED. // We are on hhvm or any other engine that does not support ENT_DISALLOWED.
// $escapedString = htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
// @NOTE: Using ENT_NOQUOTES as only XML entities ('<', '>', '&') need to be encoded.
// Single and double quotes can be left as is.
$escapedString = htmlspecialchars($string, ENT_NOQUOTES, 'UTF-8');
// control characters values are from 0 to 1F (hex values) in the ASCII table // 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". // some characters should not be escaped though: "\t", "\r" and "\n".

View File

@ -42,9 +42,10 @@ class XLSX implements EscaperInterface
public function escape($string) public function escape($string)
{ {
$escapedString = $this->escapeControlCharacters($string); $escapedString = $this->escapeControlCharacters($string);
// @NOTE: Using ENT_NOQUOTES as only XML entities ('<', '>', '&') need to be encoded. // @NOTE: Excel files are basically XML, so we need to escape <, > and &.
// Single and double quotes can be left as is. // Mostly values are saved in element contents, but a few things (e.g. worksheet names)
$escapedString = htmlspecialchars($escapedString, ENT_NOQUOTES, 'UTF-8'); // are stored in attributes, so we also need to escape " and ', hence ENT_QUOTES.
$escapedString = htmlspecialchars($escapedString, ENT_QUOTES, 'UTF-8');
return $escapedString; return $escapedString;
} }

View File

@ -16,7 +16,7 @@ class ODSTest extends \PHPUnit_Framework_TestCase
{ {
return [ return [
['test', 'test'], ['test', 'test'],
['carl\'s "pokemon"', 'carl\'s "pokemon"'], ['carl\'s "pokemon"', 'carl&#039;s &quot;pokemon&quot;'],
["\n", "\n"], ["\n", "\n"],
["\r", "\r"], ["\r", "\r"],
["\t", "\t"], ["\t", "\t"],

View File

@ -16,7 +16,7 @@ class XLSXTest extends \PHPUnit_Framework_TestCase
{ {
return [ return [
['test', 'test'], ['test', 'test'],
['adam\'s "car"', 'adam\'s "car"'], ['adam\'s "car"', 'adam&#039;s &quot;car&quot;'],
["\n", "\n"], ["\n", "\n"],
["\r", "\r"], ["\r", "\r"],
["\t", "\t"], ["\t", "\t"],
@ -25,7 +25,7 @@ class XLSXTest extends \PHPUnit_Framework_TestCase
['_x0000_', '_x005F_x0000_'], ['_x0000_', '_x005F_x0000_'],
[chr(21), '_x0015_'], [chr(21), '_x0015_'],
['control '.chr(21).' character', 'control _x0015_ character'], ['control '.chr(21).' character', 'control _x0015_ character'],
['control\'s '.chr(21).' "character"', 'control\'s _x0015_ "character"'], ['control\'s '.chr(21).' "character"', 'control&#039;s _x0015_ &quot;character&quot;'],
]; ];
} }

View File

@ -421,7 +421,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase
$this->writeToODSFile($dataRows, $fileName); $this->writeToODSFile($dataRows, $fileName);
$this->assertValueWasWritten($fileName, 'I\'m in "great" mood', 'Quotes should not be escaped'); $this->assertValueWasWritten($fileName, 'I&#039;m in &quot;great&quot; mood', 'Quotes should be escaped');
$this->assertValueWasWritten($fileName, 'This &lt;must&gt; be escaped &amp; tested', '<, > and & should be escaped'); $this->assertValueWasWritten($fileName, 'This &lt;must&gt; be escaped &amp; tested', '<, > and & should be escaped');
} }

View File

@ -473,7 +473,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase
$this->writeToXLSXFile($dataRows, $fileName); $this->writeToXLSXFile($dataRows, $fileName);
$this->assertInlineDataWasWrittenToSheet($fileName, 1, 'I\'m in "great" mood', 'Quotes should not be escaped'); $this->assertInlineDataWasWrittenToSheet($fileName, 1, 'I&#039;m in &quot;great&quot; mood', 'Quotes should be escaped');
$this->assertInlineDataWasWrittenToSheet($fileName, 1, 'This &lt;must&gt; be escaped &amp; tested', '<, > and & should be escaped'); $this->assertInlineDataWasWrittenToSheet($fileName, 1, 'This &lt;must&gt; be escaped &amp; tested', '<, > and & should be escaped');
} }