PHP-CS-Fixer: Problem with custom attribute

Bug report

PHP 8.0.2 (cli) (built: Feb  4 2021 18:10:29) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.2, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.2, Copyright (c), by Zend Technologies
PHP CS Fixer 2.18.2 Remote Void by Fabien Potencier and Dariusz Ruminski
Runtime: PHP 8.0.2
php vendor/bin/php-cs-fixer fix src/Controller/Security/Abo/ConfirmAboController.php --verbose

Code:

<?php

declare(strict_types=1);

namespace App\Controller\Security\Abo;

use App\Entity\Abo;
use App\Entity\User;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
use Symfony\Component\Routing\Annotation\Route;

#[Route('/abo/confirm/{aboSecret}', name: 'foo')]
final class ConfirmAboController
{
    public function __invoke(Abo $abo, Request $request, #[CurrentUser] ?User $user = null): Response
    {
return new Response('hi');
    }
}

leads to:

Files that were not fixed due to errors reported during fixing:
   1) /Users/oskar.stark/dev/cockpit/src/Controller/Security/Abo/ConfirmAboController.php
error sending signal urgent I/O condition os: process already finished
exit status 64

Changing to:

-    public function __invoke(Abo $abo, Request $request, #[CurrentUser] ?User $user = null): Response
+    public function __invoke(Abo $abo, Request $request, #[CurrentUser] ?User $user): Response

ends up in a non ending process and my macbook starts to explode ๐Ÿค”

Changing to:

-    public function __invoke(Abo $abo, Request $request, #[CurrentUser] ?User $user): Response
+    public function __invoke(Abo $abo, Request $request, #[CurrentUser] User $user): Response

Cs-fixer can fix and lint it, but my code is not working anymore ๐Ÿ˜„

cc @localheinz @derrabus

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 21 (21 by maintainers)

Commits related to this issue

Most upvoted comments

Failing test (and soon hopefully a fix): https://github.com/FriendsOfPHP/PHP-CS-Fixer/pull/5665

@OskarStark, @derrabus, @jrmajor Iโ€™ve made a fix โ˜๐Ÿผ - do not hesitate and drop a review there, please.

@keradus @derrabus

Iโ€™ve managed to reproduce this bug with the following code:

<?php

function test(#[Attribute] ?User $user) {}

The problem is in TernaryToElvisOperatorFixer. Nullable type hint is treated as a part of a ternary operator.

https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/9bf2760ce9d2218cc127cb4106e9ddfedca4eb3a/src/Fixer/Operator/TernaryToElvisOperatorFixer.php#L126-L134

$beforeOperator == ['start' => 6, 'end' => 8], which is #[Attribute].

Then inside getAfterOperator() it falls into an infinite loop, because getNextMeaningfulToken() returns the first token after returning the last one:

https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/9bf2760ce9d2218cc127cb4106e9ddfedca4eb3a/src/Fixer/Operator/TernaryToElvisOperatorFixer.php#L210-L219

Unfortunately, I donโ€™t know how to fix this, but I hope this will help you.

You mean without the attribute? ๐Ÿค”

The workaround would be to remove the attribute and change the type hint to UserInterface. Anyhow, CS Fixer should not explode when using that attribute. ๐Ÿ˜‰