Skip to content

Commit 215671f

Browse files
authored
feat(view): prevent invalid closing tags (#1195)
1 parent 25adb82 commit 215671f

File tree

5 files changed

+31
-2
lines changed

5 files changed

+31
-2
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Tempest\View\Exceptions;
4+
5+
use Exception;
6+
7+
final class InvalidClosingTag extends Exception
8+
{
9+
public function __construct(string $openTag, string $closingTag)
10+
{
11+
parent::__construct("Invalid closing tag `{$closingTag}` for opening tag `{$openTag}`");
12+
}
13+
}

packages/view/src/Parser/Token.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Tempest\View\Parser;
44

5+
use Tempest\View\Exceptions\InvalidClosingTag;
6+
57
use function Tempest\Support\str;
68

79
final class Token
@@ -79,6 +81,10 @@ public function setEndingToken(Token $endingToken): void
7981

8082
public function setClosingToken(Token $closingToken): void
8183
{
84+
if ($closingToken->tag && $this->tag !== $closingToken->tag) {
85+
throw new InvalidClosingTag($this->tag, $closingToken->tag);
86+
}
87+
8288
$this->closingToken = $closingToken;
8389
}
8490

packages/view/tests/Fixtures/html/4.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ <h1 id="top" class="mt-2 font-bold text-4xl text-(--ui-text-highlighted) lg:scro
108108
</li>
109109
<li :foreach="$chapter['children'] as $url => $title">
110110
<a :href="$url" :data-on-this-page="$title" class="pl-4 group relative text-sm flex items-center focus-visible:outline-(--ui-primary) py-1 text-(--ui-text-dimmed) hover:text-(--ui-text) data-[active]:text-(--ui-primary) transition-colors">
111-
{{ \Tempest\Support\Str\strip_tags($title) }}</span>
111+
<span>{{ \Tempest\Support\Str\strip_tags($title) }}</span>
112112
</a>
113113
</li>
114114
</x-template>

packages/view/tests/TempestViewParserTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Generator;
66
use PHPUnit\Framework\Attributes\DataProvider;
77
use PHPUnit\Framework\TestCase;
8+
use Tempest\View\Exceptions\InvalidClosingTag;
89
use Tempest\View\Parser\TempestViewLexer;
910
use Tempest\View\Parser\TempestViewParser;
1011
use Tempest\View\Parser\Token;
@@ -66,6 +67,15 @@ public function test_self_closing_tags_with_attributes(): void
6667
HTML, $ast->compile());
6768
}
6869

70+
public function test_invalid_closing_tag(): void
71+
{
72+
$tokens = new TempestViewLexer('<a></span></a>')->lex();
73+
74+
$this->expectException(InvalidClosingTag::class);
75+
76+
new TempestViewParser($tokens)->parse();
77+
}
78+
6979
public function test_doctype(): void
7080
{
7181
$tokens = new TokenCollection([

tests/Integration/View/ViewComponentDiscoveryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public function test_auto_registration_with_x_component(): void
5353
$discovery->apply();
5454

5555
$html = $this->render(<<<'HTML'
56-
<x-auto-registered-with-declaration></x-auto-registered-with-x-component>
56+
<x-auto-registered-with-declaration></x-auto-registered-with-declaration>
5757
HTML);
5858

5959
$this->assertSame('<span>Hello World</span>', $html);

0 commit comments

Comments
 (0)