Changes to the default arguments for `htmlspecialchars()` and `html_entity_decode()` requires setting of the argument value explicitly to prevent changes in behaviour. (#2176)

Specifically, the default for these two functions has been changed from `ENT_COMPAT` to `ENT_QUOTES | ENT_SUBSTITUTE`

This PR configures the argument used for those functions in Settings, and then explicitly applies it everywhere they are used in the codebase.
This commit is contained in:
Mark Baker 2021-06-21 12:56:03 +02:00 committed by GitHub
parent d200c5363f
commit 5769885802
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 18 deletions

View File

@ -1,20 +1,35 @@
<?php <?php
use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Settings;
require __DIR__ . '/../Header.php'; require __DIR__ . '/../Header.php';
?> ?>
<form action="45_Quadratic_equation_solver.php" method="POST"> <form action="45_Quadratic_equation_solver.php" method="POST">
Enter the coefficients for the Ax<sup>2</sup> + Bx + C = 0 Enter the coefficients for the Ax<sup>2</sup> + Bx + C = 0
<table border="0" cellpadding="0" cellspacing="0"> <table border="0" cellpadding="0" cellspacing="0">
<tr><td><b>A&nbsp;</b></td> <tr>
<td><input name="A" type="text" size="8" value="<?php echo (isset($_POST['A'])) ? htmlentities($_POST['A']) : ''; ?>"></td> <td>
<b>A&nbsp;</b>
</td>
<td>
<input name="A" type="text" size="8" value="<?php echo (isset($_POST['A'])) ? htmlentities($_POST['A'], Settings::htmlEntityFlags()) : ''; ?>">
</td>
</tr> </tr>
<tr><td><b>B&nbsp;</b></td> <tr>
<td><input name="B" type="text" size="8" value="<?php echo (isset($_POST['B'])) ? htmlentities($_POST['B']) : ''; ?>"></td> <td>
<b>B&nbsp;</b>
</td>
<td>
<input name="B" type="text" size="8" value="<?php echo (isset($_POST['B'])) ? htmlentities($_POST['B'], Settings::htmlEntityFlags()) : ''; ?>">
</td>
</tr> </tr>
<tr><td><b>C&nbsp;</b></td> <tr>
<td><input name="C" type="text" size="8" value="<?php echo (isset($_POST['C'])) ? htmlentities($_POST['C']) : ''; ?>"></td> <td><b>C&nbsp;</b>
</td>
<td>
<input name="C" type="text" size="8" value="<?php echo (isset($_POST['C'])) ? htmlentities($_POST['C'], Settings::htmlEntityFlags()) : ''; ?>">
</td>
</tr> </tr>
</table> </table>
<input name="submit" type="submit" value="calculate"><br /> <input name="submit" type="submit" value="calculate"><br />

View File

@ -99,6 +99,11 @@ class Settings
return self::$chartRenderer; return self::$chartRenderer;
} }
public static function htmlEntityFlags(): int
{
return \ENT_COMPAT;
}
/** /**
* Set default options for libxml loader. * Set default options for libxml loader.
* *

View File

@ -2,6 +2,8 @@
namespace PhpOffice\PhpSpreadsheet\Shared; namespace PhpOffice\PhpSpreadsheet\Shared;
use PhpOffice\PhpSpreadsheet\Settings;
class XMLWriter extends \XMLWriter class XMLWriter extends \XMLWriter
{ {
public static $debugEnabled = false; public static $debugEnabled = false;
@ -87,6 +89,6 @@ class XMLWriter extends \XMLWriter
$text = implode("\n", $text); $text = implode("\n", $text);
} }
return $this->writeRaw(htmlspecialchars($text ?? '')); return $this->writeRaw(htmlspecialchars($text ?? '', Settings::htmlEntityFlags()));
} }
} }

View File

@ -9,6 +9,7 @@ use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Chart\Chart; use PhpOffice\PhpSpreadsheet\Chart\Chart;
use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\RichText\RichText;
use PhpOffice\PhpSpreadsheet\RichText\Run; use PhpOffice\PhpSpreadsheet\RichText\Run;
use PhpOffice\PhpSpreadsheet\Settings;
use PhpOffice\PhpSpreadsheet\Shared\Drawing as SharedDrawing; use PhpOffice\PhpSpreadsheet\Shared\Drawing as SharedDrawing;
use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Shared\Font as SharedFont; use PhpOffice\PhpSpreadsheet\Shared\Font as SharedFont;
@ -350,7 +351,9 @@ class Html extends BaseWriter
private static function generateMeta($val, $desc) private static function generateMeta($val, $desc)
{ {
return $val ? (' <meta name="' . $desc . '" content="' . htmlspecialchars($val) . '" />' . PHP_EOL) : ''; return $val
? (' <meta name="' . $desc . '" content="' . htmlspecialchars($val, Settings::htmlEntityFlags()) . '" />' . PHP_EOL)
: '';
} }
/** /**
@ -369,7 +372,7 @@ class Html extends BaseWriter
$html .= ' <head>' . PHP_EOL; $html .= ' <head>' . PHP_EOL;
$html .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' . PHP_EOL; $html .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' . PHP_EOL;
$html .= ' <meta name="generator" content="PhpSpreadsheet, https://github.com/PHPOffice/PhpSpreadsheet" />' . PHP_EOL; $html .= ' <meta name="generator" content="PhpSpreadsheet, https://github.com/PHPOffice/PhpSpreadsheet" />' . PHP_EOL;
$html .= ' <title>' . htmlspecialchars($properties->getTitle()) . '</title>' . PHP_EOL; $html .= ' <title>' . htmlspecialchars($properties->getTitle(), Settings::htmlEntityFlags()) . '</title>' . PHP_EOL;
$html .= self::generateMeta($properties->getCreator(), 'author'); $html .= self::generateMeta($properties->getCreator(), 'author');
$html .= self::generateMeta($properties->getTitle(), 'title'); $html .= self::generateMeta($properties->getTitle(), 'title');
$html .= self::generateMeta($properties->getDescription(), 'description'); $html .= self::generateMeta($properties->getDescription(), 'description');
@ -672,7 +675,7 @@ class Html extends BaseWriter
$filename = preg_replace('@^[.]([^/])@', '$1', $filename); $filename = preg_replace('@^[.]([^/])@', '$1', $filename);
// Convert UTF8 data to PCDATA // Convert UTF8 data to PCDATA
$filename = htmlspecialchars($filename); $filename = htmlspecialchars($filename, Settings::htmlEntityFlags());
$html .= PHP_EOL; $html .= PHP_EOL;
$imageData = self::winFileToUrl($filename); $imageData = self::winFileToUrl($filename);
@ -1301,7 +1304,7 @@ class Html extends BaseWriter
// Convert UTF8 data to PCDATA // Convert UTF8 data to PCDATA
$cellText = $element->getText(); $cellText = $element->getText();
$cellData .= htmlspecialchars($cellText); $cellData .= htmlspecialchars($cellText, Settings::htmlEntityFlags());
$cellData .= $cellEnd; $cellData .= $cellEnd;
@ -1309,7 +1312,7 @@ class Html extends BaseWriter
} else { } else {
// Convert UTF8 data to PCDATA // Convert UTF8 data to PCDATA
$cellText = $element->getText(); $cellText = $element->getText();
$cellData .= htmlspecialchars($cellText); $cellData .= htmlspecialchars($cellText, Settings::htmlEntityFlags());
} }
} }
} }
@ -1326,7 +1329,7 @@ class Html extends BaseWriter
[$this, 'formatColor'] [$this, 'formatColor']
); );
if ($cellData === $origData) { if ($cellData === $origData) {
$cellData = htmlspecialchars($cellData ?? ''); $cellData = htmlspecialchars($cellData ?? '', Settings::htmlEntityFlags());
} }
if ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSuperscript()) { if ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSuperscript()) {
$cellData = '<sup>' . $cellData . '</sup>'; $cellData = '<sup>' . $cellData . '</sup>';
@ -1491,7 +1494,7 @@ class Html extends BaseWriter
// Hyperlink? // Hyperlink?
if ($pSheet->hyperlinkExists($coordinate) && !$pSheet->getHyperlink($coordinate)->isInternal()) { if ($pSheet->hyperlinkExists($coordinate) && !$pSheet->getHyperlink($coordinate)->isInternal()) {
$cellData = '<a href="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getUrl()) . '" title="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getTooltip()) . '">' . $cellData . '</a>'; $cellData = '<a href="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getUrl(), Settings::htmlEntityFlags()) . '" title="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getTooltip(), Settings::htmlEntityFlags()) . '">' . $cellData . '</a>';
} }
// Should the cell be written or is it swallowed by a rowspan or colspan? // Should the cell be written or is it swallowed by a rowspan or colspan?
@ -1671,7 +1674,7 @@ class Html extends BaseWriter
} }
// convert to PCDATA // convert to PCDATA
$value = htmlspecialchars($pValue); $value = htmlspecialchars($pValue, Settings::htmlEntityFlags());
// color span tag // color span tag
if ($color !== null) { if ($color !== null) {

View File

@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\RichText\RichText;
use PhpOffice\PhpSpreadsheet\Settings;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
use PhpOffice\PhpSpreadsheet\Style\Conditional; use PhpOffice\PhpSpreadsheet\Style\Conditional;
@ -1172,7 +1173,10 @@ class Worksheet extends WriterPart
{ {
$objWriter->writeAttribute('t', $mappedType); $objWriter->writeAttribute('t', $mappedType);
if (!$cellValue instanceof RichText) { if (!$cellValue instanceof RichText) {
$objWriter->writeElement('t', StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue))); $objWriter->writeElement(
't',
StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue, Settings::htmlEntityFlags()))
);
} elseif ($cellValue instanceof RichText) { } elseif ($cellValue instanceof RichText) {
$objWriter->startElement('is'); $objWriter->startElement('is');
$this->getParentWriter()->getWriterPartstringtable()->writeRichText($objWriter, $cellValue); $this->getParentWriter()->getWriterPartstringtable()->writeRichText($objWriter, $cellValue);

View File

@ -3,6 +3,7 @@
namespace PhpOffice\PhpSpreadsheetTests\Writer\Html; namespace PhpOffice\PhpSpreadsheetTests\Writer\Html;
use DOMDocument; use DOMDocument;
use PhpOffice\PhpSpreadsheet\Settings;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Html; use PhpOffice\PhpSpreadsheet\Writer\Html;
@ -175,7 +176,7 @@ class HtmlNumberFormatTest extends Functional\AbstractFunctional
$rows = $tbod[0]->getElementsByTagName('tr'); $rows = $tbod[0]->getElementsByTagName('tr');
$tds = $rows[0]->getElementsByTagName('td'); $tds = $rows[0]->getElementsByTagName('td');
$nbsp = html_entity_decode('&nbsp;'); $nbsp = html_entity_decode('&nbsp;', Settings::htmlEntityFlags());
self::assertEquals($expectedResult, str_replace($nbsp, ' ', $tds[0]->textContent)); self::assertEquals($expectedResult, str_replace($nbsp, ' ', $tds[0]->textContent));
$this->writeAndReload($spreadsheet, 'Html'); $this->writeAndReload($spreadsheet, 'Html');
@ -211,7 +212,7 @@ class HtmlNumberFormatTest extends Functional\AbstractFunctional
$rows = $tbod[0]->getElementsByTagName('tr'); $rows = $tbod[0]->getElementsByTagName('tr');
$tds = $rows[0]->getElementsByTagName('td'); $tds = $rows[0]->getElementsByTagName('td');
$nbsp = html_entity_decode('&nbsp;'); $nbsp = html_entity_decode('&nbsp;', Settings::htmlEntityFlags());
self::assertEquals($expectedResult, str_replace($nbsp, ' ', $tds[0]->textContent)); self::assertEquals($expectedResult, str_replace($nbsp, ' ', $tds[0]->textContent));
$this->writeAndReload($spreadsheet, 'Html'); $this->writeAndReload($spreadsheet, 'Html');