Skip to content

Commit e37e8ef

Browse files
committed
Fixed paquettg#187 and added tests
1 parent 1a1c3eb commit e37e8ef

File tree

4 files changed

+59
-8
lines changed

4 files changed

+59
-8
lines changed

src/PHPHtmlParser/Content.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace PHPHtmlParser;
66

7+
use PHPHtmlParser\Exceptions\ContentLengthException;
78
use PHPHtmlParser\Exceptions\LogicalException;
89

910
/**
@@ -74,14 +75,27 @@ public function char(?int $char = null): string
7475
* Moves the current position forward.
7576
*
7677
* @chainable
78+
* @throws ContentLengthException
7779
*/
7880
public function fastForward(int $count): Content
7981
{
82+
if (!$this->canFastForward()) {
83+
// trying to go over the content length, throw exception
84+
throw new ContentLengthException('Attempt to fastForward pass the length of the content.');
85+
}
8086
$this->pos += $count;
8187

8288
return $this;
8389
}
8490

91+
/**
92+
* Checks if we can move the position forward.
93+
*/
94+
public function canFastForward(): bool
95+
{
96+
return \strlen($this->content) > $this->pos;
97+
}
98+
8599
/**
86100
* Moves the current position backward.
87101
*
@@ -197,14 +211,15 @@ public function copyByToken(string $token, bool $char = false, bool $escape = fa
197211
/**
198212
* Skip a given set of characters.
199213
*
200-
* @return Content|string
214+
* @throws LogicalException
201215
*/
202-
public function skip(string $string, bool $copy = false)
216+
public function skip(string $string, bool $copy = false): string
203217
{
204218
$len = \strspn($this->content, $string, $this->pos);
205-
206-
// make it chainable if they don't want a copy
207-
$return = $this;
219+
if ($len === false) {
220+
throw new LogicalException('Strspn returned false with position ' . $this->pos . '.');
221+
}
222+
$return = '';
208223
if ($copy) {
209224
$return = \substr($this->content, $this->pos, $len);
210225
if ($return === false) {

src/PHPHtmlParser/Dom.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PHPHtmlParser\Dom\TextNode;
1313
use PHPHtmlParser\Exceptions\ChildNotFoundException;
1414
use PHPHtmlParser\Exceptions\CircularException;
15+
use PHPHtmlParser\Exceptions\ContentLengthException;
1516
use PHPHtmlParser\Exceptions\CurlException;
1617
use PHPHtmlParser\Exceptions\LogicalException;
1718
use PHPHtmlParser\Exceptions\NotLoadedException;
@@ -646,7 +647,13 @@ private function parseTag(): array
646647
}
647648

648649
// check if this is a closing tag
649-
if ($this->content->fastForward(1)->char() == '/') {
650+
try {
651+
$this->content->fastForward(1);
652+
} catch (ContentLengthException $exception) {
653+
// we are at the end of the file
654+
return $return;
655+
}
656+
if ($this->content->char() == '/') {
650657
// end tag
651658
$tag = $this->content->fastForward(1)
652659
->copyByToken('slash', true);
@@ -683,7 +690,12 @@ private function parseTag(): array
683690
) {
684691
$space = $this->content->skipByToken('blank', true);
685692
if (empty($space)) {
686-
$this->content->fastForward(1);
693+
try {
694+
$this->content->fastForward(1);
695+
} catch (ContentLengthException $exception) {
696+
// reached the end of the content
697+
break;
698+
}
687699
continue;
688700
}
689701

@@ -764,7 +776,9 @@ private function parseTag(): array
764776
}
765777
}
766778

767-
$this->content->fastForward(1);
779+
if ($this->content->canFastForward()) {
780+
$this->content->fastForward(1);
781+
}
768782

769783
$return['status'] = true;
770784
$return['node'] = $node;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPHtmlParser\Exceptions;
6+
7+
use Exception;
8+
9+
/**
10+
* Class EmptyCollectionException.
11+
*/
12+
final class ContentLengthException extends Exception
13+
{
14+
}

tests/DomTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,4 +649,12 @@ public function testCompatibleWithWordPressShortcode()
649649
$this->assertEquals(' [wprs_alert type="success" content="this is a short code" /] ', $node->innerHtml);
650650

651651
}
652+
653+
public function testBrokenHtml()
654+
{
655+
$dom = new Dom();
656+
$dom->loadStr('<the thing broke itV');
657+
658+
$this->assertEquals('<the thing broke itv></the>', $dom->outerHtml);
659+
}
652660
}

0 commit comments

Comments
 (0)