Skip to content

Commit 20ae6f6

Browse files
committed
Improve regex parsing of quoted strings
1 parent ad0ec12 commit 20ae6f6

File tree

2 files changed

+16
-30
lines changed

2 files changed

+16
-30
lines changed

src/View/StringTemplate.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class StringTemplate extends StringTemplateBase
1616
protected function extractNamed(string &$formatted): array
1717
{
1818
$supportedIdentifiers = ['swap'];
19-
$pattern = '/\s*(\w+(?:-\w+)*):(\w+(?:-\w+)*)=(["\'])(.*?)\3\s*/';
19+
$pattern = '/\s*\b(\w+(?:-\w+)*):(\w+(?:-\w+)*)\b=(["\'])(.*?)\3\s*/';
2020
$attributes = [];
2121

2222
$formatted = (string)preg_replace_callback(
@@ -55,7 +55,7 @@ public function format(string $name, array $data): string
5555
if (preg_match('/<(\w+)([^>]*)>/', $formatted, $matches)) {
5656
$attributesString = $matches[2];
5757
preg_match_all(
58-
'/([a-zA-Z@][a-zA-Z0-9\-.:]*(?::\w+(?:-\w+)*)?)=(["\'])([^"\']*)\2/',
58+
'/([a-zA-Z@][a-zA-Z0-9\-.:@]*)=(["\'])(.*?)\2+/',
5959
$attributesString,
6060
$attrMatches,
6161
PREG_SET_ORDER,

tests/TestCase/View/StringTemplateTest.php

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -114,24 +114,7 @@ public function testWithFormHelperSwap(): void
114114
);
115115
}
116116

117-
public function testUnsupportedIdentifierIgnored(): void
118-
{
119-
$formatted = $this->templater->format('input', [
120-
'type' => 'input',
121-
'name' => 'test',
122-
'attrs' => $this->templater->formatAttributes([
123-
'class' => 'default-class',
124-
'class:unsupported' => 'should-be-ignored',
125-
]),
126-
]);
127-
128-
$this->assertSame(
129-
'<input class="bg-red-800 p-2 text-white rounded-sm default-class" type="input" name="test" class:unsupported="should-be-ignored">',
130-
$formatted,
131-
);
132-
}
133-
134-
public function testMixedSupportedAndUnsupportedIdentifiers(): void
117+
public function testIdentifierFiltering(): void
135118
{
136119
$formatted = $this->templater->format('input', [
137120
'type' => 'input',
@@ -140,30 +123,33 @@ public function testMixedSupportedAndUnsupportedIdentifiers(): void
140123
'class' => 'default-class',
141124
'class:swap' => 'swapped-class',
142125
'data-value:unsupported' => 'should-remain',
143-
'id:unknown' => 'should-stay',
126+
'x-model.fill' => 'someValue',
127+
'@click.prevent' => 'submit()',
144128
]),
145129
]);
146130

147131
$this->assertSame(
148-
'<input class="swapped-class" type="input" name="test" data-value:unsupported="should-remain" id:unknown="should-stay">',
132+
'<input class="swapped-class" type="input" name="test" data-value:unsupported="should-remain" x-model.fill="someValue" @click.prevent="submit()">',
149133
$formatted,
150134
);
151135
}
152136

153-
public function testAttributesWithDotsPreserved(): void
137+
public function testAttributesWithEncodedQuotes(): void
154138
{
155-
$formatted = $this->templater->format('input', [
156-
'type' => 'input',
157-
'name' => 'test',
139+
$this->templater = new StringTemplate([
140+
'div' => '<div class="fieldset"{{attrs}}>{{content}}</div>',
141+
]);
142+
143+
$formatted = $this->templater->format('div', [
144+
'content' => 'test content',
158145
'attrs' => $this->templater->formatAttributes([
159-
'x-model.fill' => 'someValue',
160-
'x-on:click' => 'handleClick()',
161-
'@click.prevent' => 'submit()',
146+
'x-show' => '["basic","digest"].includes(auth_type)',
147+
'class:swap' => 'new-class',
162148
]),
163149
]);
164150

165151
$this->assertSame(
166-
'<input class="bg-red-800 p-2 text-white rounded-sm" type="input" name="test" x-model.fill="someValue" x-on:click="handleClick()" @click.prevent="submit()">',
152+
'<div class="new-class" x-show="[&quot;basic&quot;,&quot;digest&quot;].includes(auth_type)">test content</div>',
167153
$formatted,
168154
);
169155
}

0 commit comments

Comments
 (0)