Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing Issues with Escaping HTML Entities #36

Merged
merged 1 commit into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions tests/webfiori/test/ui/HTMLNodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,6 @@ public function testGetComment01() {
$node->setText('Hello World!');
$this->assertEquals('Hello World!',$node->getText());
$this->assertEquals('<!--Hello World!-->',$node->getComment());
$this->assertEquals('Hello World!',$node->getOriginalText());
}
/**
* @test
Expand All @@ -1066,10 +1065,8 @@ public function testGetComment02() {
$this->assertEquals('<!---->',$node->getComment());
$node->setText('A Comment <div> with </div> html.');
$this->assertEquals('A Comment <div> with </div> html.',$node->getText());
$this->assertEquals('A Comment <div> with </div> html.',$node->getOriginalText());
$node->setText('<!--A Comment');
$this->assertEquals(' --A Comment',$node->getText());
$this->assertEquals('<!--A Comment',$node->getOriginalText());
$this->assertEquals('<!-- --A Comment-->',$node->getComment());
$node->setText('<!--A Comment X -->');
$this->assertEquals(' --A Comment X -- ',$node->getText());
Expand Down Expand Up @@ -1170,13 +1167,10 @@ public function testGetText01() {
$this->assertEquals('',$node->getText());
$node->setText('Hello World!');
$this->assertEquals('Hello World!',$node->getText());
$this->assertEquals('Hello World!',$node->getOriginalText());
$node->setText('X < 6 and Y > 100');
$this->assertEquals('X &lt; 6 and Y &gt; 100',$node->getText());
$this->assertEquals('X < 6 and Y > 100',$node->getOriginalText());
$node->setText('X < 6 and Y > 100',false);
$this->assertEquals('X < 6 and Y > 100',$node->getText());
$this->assertEquals('X < 6 and Y > 100',$node->getOriginalText());
}
/**
* @test
Expand Down Expand Up @@ -2480,9 +2474,9 @@ public function testToHTML10() {
$html = new HTMLNode();
$html->addChild($txtNode);
$this->assertEquals('<div>&lt;a&gt;Link&lt;/a&gt;</div>',$html.'');
$txtNode->setUseOriginal(true);
$txtNode->setEscapeEntities(false);
$this->assertEquals('<div><a>Link</a></div>',$html.'');
$txtNode->setUseOriginal(false);
$txtNode->setEscapeEntities(true);
$this->assertEquals('<div>&lt;a&gt;Link&lt;/a&gt;</div>',$html.'');
}
/**
Expand Down
89 changes: 42 additions & 47 deletions webfiori/ui/HTMLNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class HTMLNode implements Countable, Iterator {
*
*/
private $isVoid;
private $isEsc;
/**
* The name of the tag (such as 'div')
* @var string
Expand All @@ -173,12 +174,6 @@ class HTMLNode implements Countable, Iterator {
private $nodesStack;
private $null;

/**
* The original text of a text node.
* @var string
*
*/
private $originalText;
/**
* The parent node of the instance.
* @var HTMLNode
Expand Down Expand Up @@ -245,11 +240,15 @@ public function __construct(string $name = 'div', array $attrs = []) {
$this->text = '';
$this->useOriginalTxt = false;
$this->attributes = [];
$this->isEsc = true;

$nameUpper = strtoupper(trim($name));

if ($nameUpper == self::TEXT_NODE || $nameUpper == self::COMMENT_NODE) {
$this->name = $nameUpper;
if ($nameUpper == self::COMMENT_NODE) {
$this->isEsc = false;
}
$this->setIsVoidNode(true);
} else {
$this->name = trim($name);
Expand Down Expand Up @@ -330,7 +329,7 @@ public function addChild($node, $attrsOrChain = [], bool $chainOnParent = false)
$lastChild = $this->getLastChild();

if ($lastChild !== null && $lastChild->getNodeName() == '#TEXT') {
$lastChild->setText($lastChild->getText().$toAdd->getText(), $toAdd->getOriginalText() != $toAdd->getText());
$lastChild->setText($lastChild->getText().$toAdd->getText());
} else {
$toAdd->setParentHelper($this);
$this->childrenList->add($toAdd);
Expand Down Expand Up @@ -1063,14 +1062,17 @@ public function getNodeName() : string {
return $this->name;
}
/**
* Returns the original text which was set in the body of the node.
* Sets the value of the property which is used to check if the text
* on the body of the node will be escaped or not if it has HTML entities.
*
* This only applies to text nodes and comment nodes.
* This only applies to text node.
*
* @return string The original text without any modifications.
* @param bool $esc
*/
public function getOriginalText() {
return $this->originalText;
public function setEscapeEntities(bool $esc) {
if ($this->isTextNode()) {
$this->isEsc = $esc;
}
}
/**
* Returns the parent node.
Expand Down Expand Up @@ -1131,7 +1133,11 @@ public function getTabIndex() {
*/
public function getText() : string {
if ($this->isComment() || $this->isTextNode()) {
return $this->text;
if ($this->isEntityEscaped()) {
return htmlentities($this->text, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
} else {
return $this->text;
}
}

return '';
Expand Down Expand Up @@ -1340,6 +1346,17 @@ public function insert(HTMLNode $el, int $position) : HTMLNode {
public function isComment() : bool {
return $this->getNodeName() == self::COMMENT_NODE;
}
/**
* Checks if HTML entities will be escaped or not.
*
* This method is applicable only if node type is text.
*
* @return bool The method will return true if they will be escaped. False
* otherwise.
*/
public function isEntityEscaped() : bool {
return $this->isEsc;
}
/**
* Returns the value of the property $isFormatted.
*
Expand Down Expand Up @@ -1404,6 +1421,8 @@ public function isUseForwardSlash() : bool {
*
* @return bool True if original text will be used in the body of the
* text node. False if not. Default is false.
*
* @deprecated since version 2.5.4
*
*/
public function isUseOriginalText() : bool {
Expand Down Expand Up @@ -1956,7 +1975,9 @@ public function setNodeName(string $name) : bool {

if (($this->isTextNode() && $uName == self::COMMENT_NODE) || ($this->isComment() && $uName == self::TEXT_NODE)) {
$this->name = $uName;

if ($uName == self::COMMENT_NODE) {
$this->isEsc = false;
}
return true;
} else {
return false;
Expand Down Expand Up @@ -2074,12 +2095,13 @@ public function setTabIndex(int $val) : HTMLNode {
*/
public function setText(string $text, bool $escHtmlEntities = true) : HTMLNode {
if ($this->isTextNode() || $this->isComment()) {
$this->originalText = $text;




if ($this->isComment()) {
$text = str_replace('<!--', ' --', str_replace('-->', '-- ', $text));
} else if ($escHtmlEntities === true) {
$text = htmlentities($text, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
} else {
$this->setEscapeEntities($escHtmlEntities);
}
$this->text = $text;
}
Expand Down Expand Up @@ -2115,25 +2137,6 @@ public function setTitle(string $val) : HTMLNode {
public function setUseForwardSlash(bool $hasForward) {
self::$UseForwardSlash = $hasForward;
}
/**
* Sets the value of the property $useOriginalTxt.
*
* The property is used when parsing text nodes. If it is set to true,
* the text that will be in the body of the node will be the exact text
* which was set using the method HTMLNode::setText() (The value which will be
* returned by the method HTMLNode::getOriginalText()). If it is set to
* false, then the text which is in the body of the node will be the
* value which is returned by the method HTMLNode::getText().
*
* @param bool $boolean True or false.
*
*
*/
public function setUseOriginal(bool $boolean) {
if ($this->isTextNode()) {
$this->useOriginalTxt = $boolean === true;
}
}
/**
* Sets the value of the attribute 'dir' of the node.
*
Expand Down Expand Up @@ -2532,11 +2535,7 @@ private function popNodeAsCode(array $FO) {
private function pushNode(HTMLNode $node) {
if ($node->isTextNode()) {
if (!self::isFormatted()) {
if ($node->isUseOriginalText()) {
$this->htmlString .= $node->getOriginalText();
} else {
$this->htmlString .= $node->getText();
}
$this->htmlString .= $node->getText();
} else {
$parent = $node->getParent();

Expand Down Expand Up @@ -2595,11 +2594,7 @@ private function pushNode(HTMLNode $node) {
*/
private function pushNodeAsCode(HTMLNode $node, array $FO) {
if ($node->isTextNode()) {
if ($node->isUseOriginalText()) {
$this->codeString .= $this->getTab().$node->getOriginalText().$this->nl;
} else {
$this->codeString .= $this->getTab().$node->getText().$this->nl;
}
$this->codeString .= $this->getTab().$node->getText().$this->nl;
} else if ($node->isComment()) {
if ($FO['with-colors'] === true) {
$this->codeString .= $this->getTab().'<span style="color:'.$FO['colors']['comment-color'].'">&lt!--'.$node->getText().'--&gt;</span>'.$this->nl;
Expand Down
31 changes: 23 additions & 8 deletions webfiori/ui/HTMLTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,16 @@
*
* @param array $attributes An array that contains the attributes and
* their values.
*
* @return HTMLTable the method will return the same instance at which the
* method is called on.
*/
public function setColAttributes(int $colNum, array $attributes) {
public function setColAttributes(int $colNum, array $attributes) : HTMLTable {

Check warning on line 244 in webfiori/ui/HTMLTable.php

View check run for this annotation

Codecov / codecov/patch

webfiori/ui/HTMLTable.php#L244

Added line #L244 was not covered by tests
for ($x = 0 ; $x < $this->rows() ; $x++) {
$this->getCell($x, $colNum)->setAttributes($attributes);
}

return $this;

Check warning on line 249 in webfiori/ui/HTMLTable.php

View check run for this annotation

Codecov / codecov/patch

webfiori/ui/HTMLTable.php#L249

Added line #L249 was not covered by tests
}
/**
* Sets the attributes of cells in one specific row.
Expand All @@ -253,13 +258,18 @@
*
* @param array $attributes An array that contains the attributes and
* their values.
*
* @return HTMLTable the method will return the same instance at which the
* method is called on.
*/
public function setRowAttributes(int $rowNum, array $attributes) {
public function setRowAttributes(int $rowNum, array $attributes) : HTMLTable {

Check warning on line 265 in webfiori/ui/HTMLTable.php

View check run for this annotation

Codecov / codecov/patch

webfiori/ui/HTMLTable.php#L265

Added line #L265 was not covered by tests
$row = $this->getRow($rowNum);

foreach ($row->children() as $cell) {
$cell->setAttributes($attributes);
}

return $this;

Check warning on line 272 in webfiori/ui/HTMLTable.php

View check run for this annotation

Codecov / codecov/patch

webfiori/ui/HTMLTable.php#L272

Added line #L272 was not covered by tests
}
/**
* Sets the value of a specific cell in the table.
Expand All @@ -273,21 +283,26 @@
*
* @throws InvalidArgumentException If row index or column index is invalid.
*
* @return HTMLTable the method will return the same instance at which the
* method is called on.
*
* @since 1.0
*/
public function setValue(int $rowIndex, int $colIndex, $value) {
public function setValue(int $rowIndex, int $colIndex, $value) : HTMLTable {
if ($rowIndex < $this->rows() && $rowIndex >= 0) {
if ($colIndex < $this->cols() && $colIndex >= 0) {
$cell = $this->getChild($rowIndex)->getChild($colIndex);
$cell->removeAllChildNodes();

if ($value instanceof HTMLNode) {
$cell->addChild($value);
} else {
$cell->text($value);
if ($value !== null) {
if ($value instanceof HTMLNode) {
$cell->addChild($value);
} else {
$cell->text($value);
}
}

return;
return $this;
}
throw new InvalidArgumentException("Column index must be less than ".$this->cols().' and greater than -1.');
}
Expand Down