Skip to content

Commit 79a00e9

Browse files
committed
only check forbidden content outside @unblaze
1 parent fa87721 commit 79a00e9

File tree

6 files changed

+105
-1
lines changed

6 files changed

+105
-1
lines changed

src/Folder/Folder.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ public function fold(Node $node): Node
135135

136136
protected function validateFoldableComponent(string $source, string $componentPath): void
137137
{
138+
// Strip out @unblaze blocks before validation since they can contain dynamic content
139+
$sourceWithoutUnblaze = $this->stripUnblazeBlocks($source);
140+
138141
$problematicPatterns = [
139142
'@once' => 'forOnce',
140143
'\\$errors' => 'forErrors',
@@ -147,12 +150,18 @@ protected function validateFoldableComponent(string $source, string $componentPa
147150
];
148151

149152
foreach ($problematicPatterns as $pattern => $factoryMethod) {
150-
if (preg_match('/' . $pattern . '/', $source)) {
153+
if (preg_match('/' . $pattern . '/', $sourceWithoutUnblaze)) {
151154
throw InvalidBlazeFoldUsageException::{$factoryMethod}($componentPath);
152155
}
153156
}
154157
}
155158

159+
protected function stripUnblazeBlocks(string $source): string
160+
{
161+
// Remove content between @unblaze and @endunblaze (including the directives themselves)
162+
return preg_replace('/@unblaze.*?@endunblaze/s', '', $source);
163+
}
164+
156165
protected function buildRuntimeDataArray(array $attributeNameToOriginal, string $rawAttributes): string
157166
{
158167
$pairs = [];

tests/UnblazeTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,63 @@
219219
expect($renders[2])->toContain('Dynamic value: three');
220220
});
221221
});
222+
223+
describe('unblaze validation', function () {
224+
beforeEach(function () {
225+
app('blade.compiler')->anonymousComponentNamespace('', 'x');
226+
app('blade.compiler')->anonymousComponentPath(__DIR__ . '/fixtures/components');
227+
});
228+
229+
it('allows $errors inside @unblaze blocks', function () {
230+
$input = '<x-with-errors-inside-unblaze />';
231+
232+
// Should not throw an exception
233+
$compiled = app('blaze')->compile($input);
234+
235+
expect($compiled)->toContain('form-input');
236+
expect($compiled)->toContain('$errors');
237+
});
238+
239+
it('throws exception for $errors outside @unblaze blocks', function () {
240+
expect(fn() => app('blaze')->compile('<x-with-errors-outside-unblaze />'))
241+
->toThrow(\Livewire\Blaze\Exceptions\InvalidBlazeFoldUsageException::class);
242+
});
243+
244+
it('allows @csrf inside @unblaze blocks', function () {
245+
$input = '<x-with-csrf-inside-unblaze />';
246+
247+
// Should not throw an exception
248+
$compiled = app('blaze')->compile($input);
249+
250+
expect($compiled)->toContain('form-wrapper');
251+
});
252+
253+
it('allows request() inside @unblaze blocks', function () {
254+
$input = '<x-with-request-inside-unblaze />';
255+
256+
// Should not throw an exception
257+
$compiled = app('blaze')->compile($input);
258+
259+
expect($compiled)->toContain('<nav>');
260+
expect($compiled)->toContain('request()');
261+
});
262+
263+
it('still validates problematic patterns in static parts of component', function () {
264+
// Create a component with $errors in static part and @unblaze
265+
$componentPath = __DIR__ . '/fixtures/components/mixed-errors.blade.php';
266+
file_put_contents($componentPath, '@blaze
267+
<div>
268+
<p>{{ $errors->count() }}</p>
269+
@unblaze
270+
<span>{{ $errors->first() }}</span>
271+
@endunblaze
272+
</div>');
273+
274+
try {
275+
expect(fn() => app('blaze')->compile('<x-mixed-errors />'))
276+
->toThrow(\Livewire\Blaze\Exceptions\InvalidBlazeFoldUsageException::class);
277+
} finally {
278+
unlink($componentPath);
279+
}
280+
});
281+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@blaze
2+
<div class="form-wrapper">
3+
<h2>Form</h2>
4+
@unblaze
5+
<form method="POST">
6+
@csrf
7+
<button>Submit</button>
8+
</form>
9+
@endunblaze
10+
</div>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@blaze
2+
<div class="form-input">
3+
<label>Email</label>
4+
<input type="email" name="email">
5+
@unblaze
6+
@if($errors->has('email'))
7+
<span class="error">{{ $errors->first('email') }}</span>
8+
@endif
9+
@endunblaze
10+
</div>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@blaze
2+
<div class="form-input">
3+
<label>Email</label>
4+
<input type="email" name="email">
5+
@if($errors->has('email'))
6+
<span class="error">{{ $errors->first('email') }}</span>
7+
@endif
8+
</div>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@blaze
2+
<nav>
3+
<a href="/home">Home</a>
4+
@unblaze
5+
<a href="/about" class="{{ request()->is('about') ? 'active' : '' }}">About</a>
6+
@endunblaze
7+
</nav>

0 commit comments

Comments
 (0)