Problem/Motivation

When visiting an uninstalled site and running PHP 7, PHP 7 catches a invalid shift.

ArithmeticError: Bit shift by negative number in Drupal\Core\Routing\RouteProvider->getCandidateOutlines()

Technically a fatal error but this already does a fatal error a couple lines later in getRoutesByPath() when it tries to query a non-existent table so not going to bump the priority.

The problem is that, without config, the frontpage resolves to an empty string which gets resolved to a length "-1." When
we shift by $length on line 282 we shift by a negative number and we get the fatal.

Proposed resolution

IRC discussion with Dawehner decided that its probably best to fix the frontpage resolution to always resolve _something_ and then also fix the outline code to not fatal.

Remaining tasks

Resolve what the fallback frontpage should be when not installed.
Resolve what getCandidate

User interface changes

API changes

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

neclimdul created an issue. See original summary.

neclimdul’s picture

Patch to show the error.

Status: Needs review » Needs work

The last submitted patch, 2: 2616498-2.patch, failed testing.

neclimdul’s picture

The 5.x fail actually holds a clue. This was wrong all along but not the shift, the bug is in the optimized mask generations. Lets look at the code:

    // The highest possible mask is a 1 bit for every part of the path. We will
    // check every value down from there to generate a possible outline.
    if ($number_parts == 1) {
      $masks = array(1);
    }
    elseif ($number_parts <= 3) {
      // Optimization - don't query the state system for short paths. This also
      // insulates against the state entry for masks going missing for common
      // user-facing paths since we generate all values without checking state.
      $masks = range($end, 1);
    }
    elseif ($number_parts <= 0) {
      // No path can match, short-circuit the process.
      $masks = array();
    }
    else {
      // Get the actual patterns that exist out of state.
      $masks = (array) $this->state->get('routing.menu_masks.' . $this->tableName, array());
    }

We're focused on the 2nd and 3rd cases. The first case matches everything less then 2nd matches everything <= 3 and the second matches everything <= 0. Obviously the 3rd if never gets matched but its important that it does. It exists because when $end <= 0 assumptions fall apart and and the safe guards in mask loop that happens next fail.

Because the optimized version of the mask generation doesn't exist in 7, its not affected and this is only a 8.x problem.

neclimdul’s picture

Status: Needs work » Needs review
dawehner’s picture

Should we still fix the potential bug in the FronPathProcessor?

neclimdul’s picture

FileSize
5.71 KB
3.79 KB

Status: Needs review » Needs work

The last submitted patch, 7: 2616498-7.patch, failed testing.

neclimdul’s picture

Forgot the comment sorry. So the idea here is we want to make sure we only return routeable paths. So thinking about what an empty config return means, we have 2 possibilities.

  1. Best case, someone hand entered an invalid value and the site works but the frontpage is broken.
  2. Worst case, the config is broken and any URL will fail.

So, I think the options are to hard code a fallback or throw an exception. Since broken config is going to cause the site to be broken anywhere else, I went with throwing the exception in this patch. Lets see what the rest of the test suite thinks about it.

The last submitted patch, 7: 2616498-7.patch, failed testing.

dawehner’s picture

+++ b/core/lib/Drupal/Core/PathProcessor/PathProcessorFront.php
@@ -41,6 +42,9 @@ public function __construct(ConfigFactoryInterface $config) {
       $path = $this->config->get('system.site')->get('page.front');
+      if (empty($path)) {
+        throw new NotFoundHttpException();
+      }

We should add a line of documentation why we do things here.

neclimdul’s picture

Status: Needs work » Needs review
FileSize
1.28 KB
5.86 KB

Apparently the failure was @group missing. The failure return code broke something in drupalci and something something so the message was lost but Mixologic committed a fix and people shouldn't see it in the future.

Added some docs and fixed the test.

Mixologic’s picture

added a retest in #7 to see if the commit, did, indeed fix it. We should now see something else.

The last submitted patch, 7: 2616498-7.patch, failed testing.

Mixologic’s picture

Once again, this time with more feeling.

The last submitted patch, 7: 2616498-7.patch, failed testing.

Mixologic’s picture

Git push --tags makes the tag actually there.

The last submitted patch, 7: 2616498-7.patch, failed testing.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Great, thank you!

Crell’s picture

+1 from me, thanks!

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.1.x and cherry-picked to 8.0.x. Thanks!

  • catch committed d9a92c3 on 8.1.x
    Issue #2616498 by neclimdul, dawehner, Mixologic: Drupal\Core\Routing\...

  • catch committed fee06d2 on
    Issue #2616498 by neclimdul, dawehner, Mixologic: Drupal\Core\Routing\...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.