Skip to content

[HttpFoundation] Ensure path info has a leading slash #40750

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

Open
wants to merge 4 commits into
base: 7.4
Choose a base branch
from

Conversation

alexpott
Copy link
Contributor

@alexpott alexpott commented Apr 9, 2021

Q A
Branch? 4.4
Bug fix? yes
New feature? no
Deprecations? no
Tickets Fix #...
License MIT
Doc PR symfony/symfony-docs#...

On a Drupal 8/9 site if you make a request for /index.php.php then this will cause PHP notices. The default .htaccess rule shipped with Drupal does not redirect from /index.php to / if it did that the path would be /.php and it would correctly 404. However changing the Drupal .htaccess rule to behave like https://github.com/symfony/recipes-contrib/blob/master/symfony/apache-pack/1.0/public/.htaccess suggests is fraught and would probably not fix existing sites.

Already in \Symfony\Component\HttpFoundation\Request::preparePathInfo() we ensure that it starts with a leading slash if \Symfony\Component\HttpFoundation\Request::getBaseUrlReal() returns NULL and I think we should do the same if strip the base url from the request URI.

See https://www.drupal.org/project/drupal/issues/3167426 for more information on the bugs this is causing in Drupal.

'SCRIPT_NAME' => '/index.php',
'PHP_SELF' => '/index.php',
]);
$this->assertEquals('http://test.com/index.php/.php', $request->getUri());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that case looks wrong to me though, as that would be a different Uri that the input

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What should the uri be though? If you make a request to index.php/something or /something in this situation you'd want the path info to be /something. And it is. I think this is a special edge case because of the way htaccess rules work for Drupal (and probably a number of other projects). The relevant parts of our rule is:

  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^ index.php [L]

I think we should treat a request to index.phpSOMETHING as a request to SOMETHING - regardless of whether SOMETHING starts with a /... which means we need to duplicate the logic of when there is no base path...

This is just above the code I've added.

        if ('' !== $requestUri && '/' !== $requestUri[0]) {
            $requestUri = '/'.$requestUri;
        }

        if (null === ($baseUrl = $this->getBaseUrl())) {
            return $requestUri;
        }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For index.php/something, It totally agree. But this is not what this test is covering.

@Nyholm
Copy link
Member

Nyholm commented Apr 9, 2021

How would I be able to detect the difference between the following URLs:

https://example.com/
https://example.com

?

@alexpott
Copy link
Contributor Author

alexpott commented Apr 9, 2021

How would I be able to detect the difference between the following URLs:

https://example.com/
https://example.com

?

This is unaffected as far as I can see. Here's the preceding code which is going to deal with this case...

        if ('' !== $requestUri && '/' !== $requestUri[0]) {
            $requestUri = '/'.$requestUri;
        }

        if (null === ($baseUrl = $this->getBaseUrl())) {
            return $requestUri;
        }

        $pathInfo = substr($requestUri, \strlen($baseUrl));
        if (false === $pathInfo || '' === $pathInfo) {
            // If substr() returns false then PATH_INFO is set to an empty string
            return '/';
        }

@xabbuh
Copy link
Member

xabbuh commented Apr 9, 2021

Would this fix #37995?

@alexpott
Copy link
Contributor Author

alexpott commented Apr 9, 2021

@xabbuh I was wondering that too but I think the question you asked in #37995 (comment) is key there. I'm not sure how you end up with "SCRIPT_NAME" => "index.php", and not "SCRIPT_NAME" => "/index.php",

@jderusse jderusse added this to the 5.x milestone Apr 10, 2021
@carsonbot carsonbot changed the title Ensure path info has a leading slash [HttpFoundation] Ensure path info has a leading slash Apr 10, 2021
@fabpot fabpot modified the milestones: 5.4, 6.1 Nov 29, 2021
@fabpot fabpot modified the milestones: 6.1, 6.2 May 20, 2022
@alexpott
Copy link
Contributor Author

alexpott commented Oct 4, 2022

@stof what do I need to do to get this one fixed?

@nicolas-grekas nicolas-grekas modified the milestones: 6.2, 6.3 Nov 5, 2022
@nicolas-grekas nicolas-grekas modified the milestones: 6.3, 6.4 May 23, 2023
@nicolas-grekas nicolas-grekas modified the milestones: 6.4, 7.1 Nov 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants