Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nullsafe operator breaks route cache #38903

Closed
pelomedusa opened this issue Sep 22, 2021 · 3 comments
Closed

Nullsafe operator breaks route cache #38903

pelomedusa opened this issue Sep 22, 2021 · 3 comments
Assignees
Labels

Comments

@pelomedusa
Copy link
Contributor

  • Laravel Version: 8.61.0
  • PHP Version: 8.0.10
  • Database Driver & Version: /

Description:

Using the nullsafe operator in a route file will break the route cache.

Steps To Reproduce:

Issue is reproduced here:
https://github.com/pelomedusa/laravel-8-nullsafe-operator-bug

Reproduce by following these steps:

  • Create a new laravel app
 laravel new myapp
 cd myapp
  • Edit the routes/web.php file with a nullsafe operator, ie:
Route::get('/', function () {
  $example = null;
  $bug = $example?->test;
  return view('welcome');
});
  • Generate a route cache and serve:
php artisan route:cache
php artisan serve
[2021-09-22 08:18:30] local.ERROR: syntax error, unexpected fully qualified name "\test", expecting identifier or variable or "{" or "$" {"exception":"[object] (ParseError(code: 0): syntax error, unexpected fully qualified name \"\\test\", expecting identifier or variable or \"{\" or \"$\" at closure://function () {
\t$example = null;
\t$bug = $example?->\\test;
    return \\view('welcome');
}:4)
[stacktrace]
#0 [internal function]: Opis\\Closure\\SerializableClosure->unserialize()
#1 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Routing/RouteSignatureParameters.php(22): unserialize()
#2 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Routing/Route.php(513): Illuminate\\Routing\\RouteSignatureParameters::fromAction()
#3 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Routing/ImplicitRouteBinding.php(25): Illuminate\\Routing\\Route->signatureParameters()
#4 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Routing/Router.php(833): Illuminate\\Routing\\ImplicitRouteBinding::resolveForRoute()
#5 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\\Routing\\Router->substituteImplicitBindings()
#6 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle()
#7 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#8 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle()
#9 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#10 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()
#11 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#12 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()
#13 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Session\\Middleware\\StartSession->handle()
#14 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#15 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()
#16 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#17 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()
#18 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#19 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Routing/Router.php(697): Illuminate\\Pipeline\\Pipeline->then()
#20 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Routing/Router.php(672): Illuminate\\Routing\\Router->runRouteWithinStack()
#21 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Routing/Router.php(636): Illuminate\\Routing\\Router->runRoute()
#22 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Routing/Router.php(625): Illuminate\\Routing\\Router->dispatchToRoute()
#23 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(166): Illuminate\\Routing\\Router->dispatch()
#24 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#25 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#26 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#27 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle()
#28 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#29 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#30 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#31 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#32 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle()
#33 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#34 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#35 /tmp/laravel-test/bugtest/vendor/fruitcake/laravel-cors/src/HandleCors.php(38): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#36 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fruitcake\\Cors\\HandleCors->handle()
#37 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#38 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Http\\Middleware\\TrustProxies->handle()
#39 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#40 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(141): Illuminate\\Pipeline\\Pipeline->then()
#41 /tmp/laravel-test/bugtest/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(110): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#42 /tmp/laravel-test/bugtest/public/index.php(52): Illuminate\\Foundation\\Http\\Kernel->handle()
#43 /tmp/laravel-test/bugtest/server.php(21): require_once('...')
#44 {main}
"} 
@derekmd
Copy link
Contributor

derekmd commented Sep 22, 2021

Next Laravel release will be switching the "opis/closure" package with a new fork laravel/serializable-closure (#38801).

The "opis/closure" package's test suite has one unit test for ReflectionClosure converting a nullsafe function to a string (https://github.com/opis/closure/blob/e7254e8f2a524ae05b1e0bcb1207ac0267385eaa/tests/ReflectionClosure6Test.php#L58-L64) but I don't see a full integration test on SerializableClosure to unserialize and actually run a nullsafe'd closure. Both packages may need a fix: https://github.com/opis/closure/issues

@nunomaduro
Copy link
Member

nunomaduro commented Sep 29, 2021

Fixed. If you are using the latest version of the framework, please run composer update laravel/serializable-closure.

@driesvints
Copy link
Member

We released v1.0.1 of serializable closure which should fix this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants