Framework: Blade parenthesis parsing issue

Created on 15 Oct 2016  路  14Comments  路  Source: laravel/framework

  • Laravel Version: 5.3.18
  • PHP Version: PHP 7.0.10
  • Database Driver & Version: MySQL Ver 14.14 Distrib 5.5.50

    Description:

When I use a single parenthesis in a string it will break the parsing. Which will trigger this error:
Parse error: syntax error, unexpected ':', expecting '('

Steps To Reproduce:

@if('(test' == '(test')
    {{ 'test' }}
@endif

All 14 comments

Yea, the result in the compiled view is

<?php if: ?>("(test" == "(test")
<?php echo e('test'); ?>

<?php endif; ?>

The top part of the statement gets broken
Should look like this :

<?php if("(test" == "(test"): ?>
<?php echo e('test'); ?>

<?php endif; ?>

https://github.com/laravel/framework/blob/5.3/src/Illuminate/View/Compilers/BladeCompiler.php#L320

Lets play around with the parsing and see if we can come up with something clever :)

https://github.com/laravel/framework/blob/5.3/src/Illuminate/View/Compilers/BladeCompiler.php#L334

The regex in the compileStatements method is made that it won't match brackets
[^()]+
This regex means "match 1 or more symbols that are not brackets".

I think it's done on purpose this way.
I could rewrite the regex but i don't know if they want to allow special symbols.
Technically you are using the special symbol in a string, so you should be able to do that but we have to get a word from the Laravel bourgeoisie.

Maybe a ugly workaround would be to take a look back and see if it's escaped

@if('\(test' == '\(test')
    {{ $test }}
@endif

this coul fix the issue but will not be good for the user experience

@iXshad0w I don't think that is a good way to do it.
Strings should work the same way in normal PHP, you shouldn't have to escape stuff that you normally don't.

I could rewrite the regex but i don't know if they want to allow special symbols.

It's not about allowing special characters I think, if you can build a new regex that would solve this issue then I think it'd be a nice fix.

@themsaid Super.

@themsaid i have a fix, do you want me to push it up on the 5.3 branch?

Yup, non-breaking changes go to 5.3

@themsaid Can't push, remote: Permission to laravel/framework.git denied to PetarDambovaliev.
fatal: unable to access 'https://github.com/laravel/framework.git/': The requested URL returned error: 403

Man you need to open a Pull Request :)

@themsaid https://github.com/laravel/framework/pull/15934
All checks passed, i hope it goes through :))

@themsaid Another way to solve this is add a method that will remove specified symbols from the string with PREG_OFFSET_CAPTURE. Add it in the callback and put them back after.
Seems kinda flawed logic though, doing something wrong and then fixing it.
This is quite a interesting one to solve, without making a lot of changes.

Well I think that might be a bit expensive in terms of performance, maybe it's better to use a regular <?php if(...) ?> in you blade file for this special case.

Was this page helpful?
0 / 5 - 0 ratings