Problem/Motivation

If you visit /index.php.php path, the PHP warning occurs and a log record is created:

Notice: Undefined offset: 1 in template_preprocess_html() (line 1343 of core/includes/theme.inc).
template_preprocess_html(Array, 'html', Array) (Line: 287)
Drupal\Core\Theme\ThemeManager->render('html', Array) (Line: 431)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 200)
Drupal\Core\Render\Renderer->render(Array) (Line: 147)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 573)

Steps to reproduce

1) First case: Visit your.site/index.php. or your.site/index.php.php

2) Second case:

  1. Clean Drupal installation
  2. Go to admin/structure/block, edit any (for example: Search) block that appears on the frontpage
  3. Go to pages tab and set /user/* and click "Show for the listed pages"
  4. Go to your.site/index.php.php
  5. There is an exception: InvalidArgumentException: Source path .php has to start with a slash. in Drupal\Core\Path\AliasManager->getAliasByPath() (line 229 of core/lib/Drupal/Core/Path/AliasManager.php).

Proposed resolution

1) Adjust Drupal\system\Plugin\Condition\RequestPath to request a path with a slash.
2) Fix template_preprocess_html() so it doesn't show a warning if there is an extra dot when resolving route path.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

The function CurrentPathStack::getPath() now returns the path with leading slashes. This change was made because paths with leading slashes are almost always correct in Drupal.

Issue fork drupal-3167426

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mbovan created an issue. See original summary.

mbovan’s picture

Status: Active » Needs review
StatusFileSize
new500 bytes

This conditionally sets the route path if the first item of the system path is available.

mbovan’s picture

Title: Undefined offset PHP warning when visting /index.php.php path » PHP warning on undefined offset when visiting /index.php.php
Version: 8.9.x-dev » 9.0.x-dev
mbovan’s picture

Title: PHP warning on undefined offset when visiting /index.php.php » Exception and warnings when accessing the site with invalid through /index.php.php
Issue summary: View changes

Updated the issue title and description to cover #3043779.18.

mbovan’s picture

Title: Exception and warnings when accessing the site with invalid through /index.php.php » Exception and warning when accessing the site through /index.php.php
mbovan’s picture

Updates:

  • Fix for the second case from the issue summary.
  • Tests for the first case.
  • Tests for the second case.

The last submitted patch, 6: 3167426-6-php-warning-TEST-ONLY.patch, failed testing. View results

The last submitted patch, 6: 3167426-6-TEST-ONLY.patch, failed testing. View results

berdir’s picture

+++ b/core/includes/theme.inc
@@ -1317,7 +1317,7 @@ function template_preprocess_html(&$variables) {
   else {
     $system_path = \Drupal::service('path.current')->getPath();
-    $variables['root_path'] = explode('/', $system_path)[1];
+    $variables['root_path'] = explode('/', $system_path)[1] ?? FALSE;

Both cases use path.current, could we enforce within that that it always returns a leading /?

This is touching an existing point about the incorrect documentation on \Drupal\Core\Path\CurrentPathStack::getPath(), I thought we had an issue but can't find it right now, which says it is without leading / but that's clearly wrong and code expects it to be otherwise.

\Symfony\Component\HttpFoundation\Request::getPathInfo() documents that there is a case when it returns an empty string, although I'm a bit confused about that.

berdir’s picture

Status: Needs review » Needs work
+++ b/core/modules/block/tests/src/Functional/BlockTest.php
@@ -66,6 +66,34 @@ public function testBlockVisibility() {
+    $edit = [
+      'id' => strtolower($this->randomMachineName(8)),
+      'region' => 'sidebar_first',
+      'settings[label]' => $title,
+      'settings[label_display]' => TRUE,
+    ];
+    $this->drupalGet('admin/structure/block/add/' . $block_name . '/' . $default_theme);
+
+    $edit['visibility[request_path][pages]'] = '/user/*';
+    $this->drupalPostForm(NULL, $edit, t('Save block'));

why the split of the extra $edit addition and manually requesting the path first, can't we just put it all in the initial $edit definition and add the path to drupalPostForm() so it requests it first internally?

mbovan’s picture

Status: Needs review » Needs work

The last submitted patch, 11: 3167426-11.patch, failed testing. View results

mbovan’s picture

Status: Needs work » Needs review
StatusFileSize
new4.35 KB
new3.05 KB

There are more places where this needs to be fixed to address the original problem...

To catch all the places, this would need to be fixed in Symfony\Component\HttpFoundation\Request::preparePathInfo IMHO.

larowlan’s picture

Issue tags: +Bug Smash Initiative
+++ b/core/lib/Drupal/Core/Routing/RequestContext.php
@@ -64,4 +64,24 @@ public function setCompleteBaseUrl($complete_base_url) {
+    return $path[0] !== '/' && $path !== '/' ? '/' . $path : $path;

could we use ltrim here and then just add back?

mbovan’s picture

StatusFileSize
new4.32 KB
new548 bytes

#14 That reads eaiser, thanks!

berdir’s picture

+++ b/core/lib/Drupal/Core/Path/CurrentPathStack.php
@@ -73,9 +74,11 @@ public function setPath($path, Request $request = NULL) {
   }
 
+
+

nitpick: extra spaces here.

Wondering if we want to merge the old issue about the documentation into this, it got stuck in 2018 and kind of makes sense to fix the documentation as we are fixing bugs the implementation?

mbovan’s picture

Title: Exception and warning when accessing the site through /index.php.php » CurrentPathStack::getPath should always return a path with leading slashes
StatusFileSize
new4.53 KB
new1.39 KB

Removed the extra spaces and fixed docs based on #2430805: Fix CurrentPathStack::getPath() documentation that says it has no leading / (and make it easier to actually get that?).

Since the fix is going into direction of fixing Drupal\Core\Path\CurrentPathStack::getPath, I improved the issue title as well.

berdir’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me. We can decide what to do with the other issue when this is committed? Possibly fine to close as duplicate although there's another change in those patches that I'm not sure still makes sense or not.

catch’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs release note, +Needs change record
+++ b/core/lib/Drupal/Core/Routing/RequestContext.php
@@ -64,4 +64,24 @@ public function setCompleteBaseUrl($complete_base_url) {
+
+  /**
+   * Prepends a slash to the given path.
+   *
+   * @param string $path
+   *   The original path.
+   *
+   * @return string
+   *   The path with a leading slash.
+   */
+  public static function prependSlash($path) {
+    return '/' . ltrim($path, '/');
+  }

I think we should have a change record for this, and a small release note - seems like there's a small chance that contrib or custom code could be relying on the buggy behaviour (which I think the 500 error in core overrides).

adamps’s picture

Issue summary: View changes
Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs release note, -Needs change record

Done change record and release note snippet.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 17: 3167426-17.patch, failed testing. View results

Version: 9.0.x-dev » 9.1.x-dev

Drupal 9.0.10 was released on December 3, 2020 and is the final full bugfix release for the Drupal 9.0.x series. Drupal 9.0.x will not receive any further development aside from security fixes. Sites should update to Drupal 9.1.0 to continue receiving regular bugfixes.

Drupal-9-only bug reports should be targeted for the 9.1.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.2.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

berdir’s picture

Version: 9.1.x-dev » 9.2.x-dev
Component: theme system » request processing system
Status: Needs work » Needs review
StatusFileSize
new4.55 KB
new1.5 KB

Looks like this was set back to need work due to a random fail?

Rebased on 9.2.x, also noticed that we were using a bunch of deprecated methods in the test and updated that.

acbramley’s picture

StatusFileSize
new4.54 KB
new505 bytes

Looks like new checks for spelling were added since #17

Status: Needs review » Needs work

The last submitted patch, 24: 3167426-24.patch, failed testing. View results

acbramley’s picture

Status: Needs work » Needs review

Fail was a rando

guilhermevp’s picture

StatusFileSize
new18.58 KB
new43 KB

Followed step 2 and was able to successfully reproduce the error. After applying the patch, could verify that accessing index.php.php don't returns error anymore.

RTBC +1

adamps’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me thanks for the new patches

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 24: 3167426-24.patch, failed testing. View results

benjifisher’s picture

Please do not ask the testbot to try again until #3207086: [HEAD BROKEN] Consistent failure in MonthDatePluginTest is fixed.

alexpott’s picture

Status: Needs work » Reviewed & tested by the community
alexpott’s picture

Version: 9.2.x-dev » 9.1.x-dev
Priority: Normal » Major
Status: Reviewed & tested by the community » Patch (to be ported)

Committed 3b40d8c and pushed to 9.2.x. Thanks!

Before publishing the CR I'm going to ping catch about this going in 9.1.x and maybe even 8.9.x since this bug is causing pages to be 200 when they should be a 404 - which makes this a major.

acbramley’s picture

Thanks @alexpott, it looks like that commit link is 404ing, maybe a forgotten push?

alexpott’s picture

Version: 9.1.x-dev » 9.2.x-dev
Status: Patch (to be ported) » Needs work

Woke up thinking that I'd committed this prematurely so not going to push.

  1. +++ b/core/lib/Drupal/Core/Path/CurrentPathStack.php
    @@ -46,14 +47,14 @@ public function __construct(RequestStack $request_stack) {
    -      $this->paths[$request] = $request->getPathInfo();
    +      $this->paths[$request] = RequestContext::prependSlash($request->getPathInfo());
    
    +++ b/core/lib/Drupal/Core/Routing/RequestContext.php
    @@ -64,4 +64,24 @@ public function setCompleteBaseUrl($complete_base_url) {
    +  /**
    +   * {@inheritdoc}
    +   */
    +  public function setPathInfo($path_info) {
    +    return parent::setPathInfo(static::prependSlash($path_info));
    +  }
    

    This changes deserve there own tests - unit or kernel somewhere.

  2. +++ b/core/modules/block/tests/src/Functional/BlockTest.php
    @@ -68,6 +68,33 @@ public function testBlockVisibility() {
    +    // Test the page by requesting invalid paths.
    +    $this->drupalGet('index.php.');
    +    $this->assertSession()->statusCodeEquals(404);
    +    $this->drupalGet('index.php.php');
    +    $this->assertSession()->statusCodeEquals(404);
    

    I think this test only needs one of these requests. The other should be in \Drupal\Tests\system\Functional\System\IndexPhpTest because the 404 is not really part of the block visibility stuff and if we refactored this test in the future because of changes to how block visibility work then we might remove this important coverage.

alexpott’s picture

I also woke up wondering if this is a Symfony bug. I think if we reported this to Symfony they would point us to https://github.com/symfony/recipes-contrib/blob/master/symfony/apache-pa... and say that Drupal shouldn't serve duplicated content on / and /index.php but I think regardless \Symfony\Component\HttpFoundation\Request::preparePathInfo() should always return a leading slash. I've opened https://github.com/symfony/symfony/pull/40750 to fix this upstream.

mohit_aghera’s picture

Assigned: Unassigned » mohit_aghera
mohit_aghera’s picture

Status: Needs work » Needs review
Issue tags: +DrupalFest2021
StatusFileSize
new5.44 KB

- Refactoring the tests as suggested in #34
- Added new test cases to validate prependSlash method.

mohit_aghera’s picture

StatusFileSize
new2.21 KB

- Uploading interdiff for the above patch.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

ranjith_kumar_k_u’s picture

StatusFileSize
new5.44 KB

Rerolled #37 for 9.5

adamps’s picture

Status: Needs review » Reviewed & tested by the community

The requested comments have been made so back to RTBC

alexpott’s picture

Status: Reviewed & tested by the community » Postponed

As per #35 I think the correct place to fix this is upstream - see https://github.com/symfony/symfony/pull/40750 - I'll push on that again and see if I can get it moving.

Going to postpone this one depending on the outcome.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

berdir’s picture

StatusFileSize
new5.48 KB
new543 bytes

Re #44: fair, I do think we could get a workaround in core while we push for upstream, but up to you. Just a reroll for now to update this for D10. Patch still applied but is not compatible with Symfony 6.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

damienmckenna’s picture

We ran into this bug on a site when someone loaded an oddly formatted URL. In fairness it was a bot trying to find an attack vector on the site, but it still shouldn't have caused an error when it should have been displaying a 404 error page.

joelpittet’s picture

Patch in #46 totally puts a dent in this for us, we got around 600+ logs directly related to this. Thanks @Berdir.

Thanks @alexpott for taking this upstream as well though it looks like it might have stalled?

georob’s picture

StatusFileSize
new5.5 KB

Rerolled the patch from #46 for 10.3. Applies successfully. Successfully addresses the test criteria still.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

alexpott’s picture

Status: Postponed » Closed (outdated)

This finally got fixed in Symfony - in a security issue no less! https://github.com/symfony/symfony/security/advisories/GHSA-3rg7-wf37-54rm and 10.6 has the fixed version of Symfony.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.