Skip to content

Commit

Permalink
Fixes #45424 blade issue with "(" character
Browse files Browse the repository at this point in the history
  • Loading branch information
imanghafoori1 committed Jan 4, 2023
1 parent 7d72d45 commit 5015a74
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 6 deletions.
25 changes: 23 additions & 2 deletions src/Illuminate/View/Compilers/BladeCompiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ protected function compileExtensions($value)
*/
protected function compileStatements($template)
{
preg_match_all('/\B@(@?\w+(?:::\w+)?)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x', $template, $matches);
preg_match_all('/\B@(@?\w+(?:::\w+)?)([ \t]*)(\( ( [\S\s]*? ) \))?/x', $template, $matches);
for ($i = 0; isset($matches[0][$i]); $i++) {
$match = [
$matches[0][$i],
Expand All @@ -517,7 +517,7 @@ protected function compileStatements($template)
// Here we check to see if we have properly found the closing parenthesis by
// regex pattern or not, and will recursively continue on to the next ")"
// then check again until the tokenizer confirms we found the right one
while (isset($match[4]) && Str::endsWith($match[0], ')') && Arr::last(token_get_all('<?php '.$match[0])) !== ')') {
while (isset($match[4]) && Str::endsWith($match[0], ')') && ! $this->isProperMatch($match[0])) {
$rest = Str::before(Str::after($template, $match[0]), ')');
$match[0] = $match[0].$rest.')';
$match[3] = $match[3].$rest.')';
Expand Down Expand Up @@ -920,4 +920,25 @@ public function withoutComponentTags()
{
$this->compilesComponentTags = false;
}

protected function isProperMatch($match)
{
$tokens = token_get_all('<?php '.$match);

if (Arr::last($tokens) !== ')') {
return false;
}

$openings = 0;
$closings = 0;
foreach ($tokens as $token) {
if ($token == ')') {
$closings++;
} elseif ($token == '(') {
$openings++;
}
}

return $openings === $closings;
}
}
2 changes: 1 addition & 1 deletion tests/View/Blade/BladeIncludesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public function testEachsAreCompiled()
public function testIncludesAreCompiled()
{
$this->assertSame('<?php echo $__env->make(\'foo\', \Illuminate\Support\Arr::except(get_defined_vars(), [\'__data\', \'__path\']))->render(); ?>', $this->compiler->compileString('@include(\'foo\')'));
$this->assertSame('<?php echo $__env->make(\'foo\', [\'a\' => \'a\'], \Illuminate\Support\Arr::except(get_defined_vars(), [\'__data\', \'__path\']))->render(); ?>', $this->compiler->compileString('@include(\'foo\', [\'a\' => \'a\'])'));
$this->assertSame('<?php echo $__env->make(\'foo\', [\'((a)\' => \'((a)\'], \Illuminate\Support\Arr::except(get_defined_vars(), [\'__data\', \'__path\']))->render(); ?>', $this->compiler->compileString('@include(\'foo\', [\'((a)\' => \'((a)\'])'));
$this->assertSame('<?php echo $__env->make(name(foo), \Illuminate\Support\Arr::except(get_defined_vars(), [\'__data\', \'__path\']))->render(); ?>', $this->compiler->compileString('@include(name(foo))'));
}

Expand Down
12 changes: 12 additions & 0 deletions tests/View/Blade/BladePhpStatementsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ public function testVerbatimAndPhpStatementsDontGetMixedUp()

public function testStringWithParenthesisCanBeCompiled()
{
$string = "@php(\$data = ['single' => ':(('])";
$expected = "<?php (\$data = ['single' => ':((']); ?>";
$this->assertEquals($expected, $this->compiler->compileString($string));

$string = "@php(\$data = ['single' => (string)':(('])";
$expected = "<?php (\$data = ['single' => (string)':((']); ?>";
$this->assertEquals($expected, $this->compiler->compileString($string));

$string = "@php(\$data = ['single' => '(()(('])";
$expected = "<?php (\$data = ['single' => '(()((']); ?>";
$this->assertEquals($expected, $this->compiler->compileString($string));

$string = "@php(\$data = ['single' => ')'])";
$expected = "<?php (\$data = ['single' => ')']); ?>";

Expand Down
6 changes: 3 additions & 3 deletions tests/View/Blade/BladePushTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ public function testPushIsCompiled()

public function testPushOnceIsCompiled()
{
$string = '@pushOnce(\'foo))\', \'bar(())\')
$string = '@pushOnce(\'((foo\', \'bar\')
test
@endPushOnce';

$expected = '<?php if (! $__env->hasRenderedOnce(\'bar\')): $__env->markAsRenderedOnce(\'bar(())\');
$__env->startPush(\'foo))\'); ?>
$expected = '<?php if (! $__env->hasRenderedOnce(\'bar\')): $__env->markAsRenderedOnce(\'bar\');
$__env->startPush(\'((foo\'); ?>
test
<?php $__env->stopPush(); endif; ?>';

Expand Down

0 comments on commit 5015a74

Please sign in to comment.