diff --git a/src/Spout/Common/Escaper/ODS.php b/src/Spout/Common/Escaper/ODS.php index 9de665b..219d3f6 100644 --- a/src/Spout/Common/Escaper/ODS.php +++ b/src/Spout/Common/Escaper/ODS.php @@ -22,17 +22,17 @@ class ODS implements EscaperInterface */ 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')) { // '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 // @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 { // We are on hhvm or any other engine that does not support ENT_DISALLOWED. - // - // @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'); + $escapedString = htmlspecialchars($string, ENT_QUOTES, 'UTF-8'); // 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". diff --git a/src/Spout/Common/Escaper/XLSX.php b/src/Spout/Common/Escaper/XLSX.php index 12b44d7..240b571 100644 --- a/src/Spout/Common/Escaper/XLSX.php +++ b/src/Spout/Common/Escaper/XLSX.php @@ -42,9 +42,10 @@ class XLSX implements EscaperInterface public function escape($string) { $escapedString = $this->escapeControlCharacters($string); - // @NOTE: Using ENT_NOQUOTES as only XML entities ('<', '>', '&') need to be encoded. - // Single and double quotes can be left as is. - $escapedString = htmlspecialchars($escapedString, ENT_NOQUOTES, 'UTF-8'); + // @NOTE: Excel 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. + $escapedString = htmlspecialchars($escapedString, ENT_QUOTES, 'UTF-8'); return $escapedString; } diff --git a/tests/Spout/Common/Escaper/ODSTest.php b/tests/Spout/Common/Escaper/ODSTest.php index 77b4913..fb5c960 100644 --- a/tests/Spout/Common/Escaper/ODSTest.php +++ b/tests/Spout/Common/Escaper/ODSTest.php @@ -16,7 +16,7 @@ class ODSTest extends \PHPUnit_Framework_TestCase { return [ ['test', 'test'], - ['carl\'s "pokemon"', 'carl\'s "pokemon"'], + ['carl\'s "pokemon"', 'carl's "pokemon"'], ["\n", "\n"], ["\r", "\r"], ["\t", "\t"], diff --git a/tests/Spout/Common/Escaper/XLSXTest.php b/tests/Spout/Common/Escaper/XLSXTest.php index 0f2098f..55f7615 100644 --- a/tests/Spout/Common/Escaper/XLSXTest.php +++ b/tests/Spout/Common/Escaper/XLSXTest.php @@ -16,7 +16,7 @@ class XLSXTest extends \PHPUnit_Framework_TestCase { return [ ['test', 'test'], - ['adam\'s "car"', 'adam\'s "car"'], + ['adam\'s "car"', 'adam's "car"'], ["\n", "\n"], ["\r", "\r"], ["\t", "\t"], @@ -25,7 +25,7 @@ class XLSXTest extends \PHPUnit_Framework_TestCase ['_x0000_', '_x005F_x0000_'], [chr(21), '_x0015_'], ['control '.chr(21).' character', 'control _x0015_ character'], - ['control\'s '.chr(21).' "character"', 'control\'s _x0015_ "character"'], + ['control\'s '.chr(21).' "character"', 'control's _x0015_ "character"'], ]; } diff --git a/tests/Spout/Writer/ODS/WriterTest.php b/tests/Spout/Writer/ODS/WriterTest.php index 836e679..172f8bd 100644 --- a/tests/Spout/Writer/ODS/WriterTest.php +++ b/tests/Spout/Writer/ODS/WriterTest.php @@ -421,7 +421,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase $this->writeToODSFile($dataRows, $fileName); - $this->assertValueWasWritten($fileName, 'I\'m in "great" mood', 'Quotes should not be escaped'); + $this->assertValueWasWritten($fileName, 'I'm in "great" mood', 'Quotes should be escaped'); $this->assertValueWasWritten($fileName, 'This <must> be escaped & tested', '<, > and & should be escaped'); } diff --git a/tests/Spout/Writer/XLSX/WriterTest.php b/tests/Spout/Writer/XLSX/WriterTest.php index c7f4f96..e1b8a54 100644 --- a/tests/Spout/Writer/XLSX/WriterTest.php +++ b/tests/Spout/Writer/XLSX/WriterTest.php @@ -473,7 +473,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase $this->writeToXLSXFile($dataRows, $fileName); - $this->assertInlineDataWasWrittenToSheet($fileName, 1, 'I\'m in "great" mood', 'Quotes should not be escaped'); + $this->assertInlineDataWasWrittenToSheet($fileName, 1, 'I'm in "great" mood', 'Quotes should be escaped'); $this->assertInlineDataWasWrittenToSheet($fileName, 1, 'This <must> be escaped & tested', '<, > and & should be escaped'); }