Problem/Motivation

Symfony 4 only supports routes with UTF-8 characters if they have the utf8 option set to TRUE.

Proposed resolution

Set the utf8 option in our RouteCompiler class and ensure routes are using this compiler class.

Remaining tasks

User interface changes

None

API changes

None

Data model changes

None

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

alexpott created an issue. See original summary.

alexpott’s picture

Status: Active » Needs review
FileSize
4.42 KB
Berdir’s picture

Well, nothing prevents you from entering a path like that in views or page manager for example?

Makes me wonder if that is even really relevant for us, I assume this might be related to how their default router lookup now works, for our database-based lookup, does it really matter?

alexpott’s picture

Issue summary: View changes

Updated issue summary with #3. I thought of views when I was thinking but I got distracted by the fact views can't have utf8 in their IDs but that is totally irrelevant.

martin107’s picture

Priority: Normal » Major

Makes me wonder if that is even really relevant for us,

This is coming into sharp relief...

When Investigatory patches bump the symfony version all the way up to eleven .... er I mean 4

Then testbot starts spitting out all the errors which show that this patch is much needed.

see
#2976394: Allow Symfony 4.4 to be installed in Drupal 8

Over there in relation to the comment in #11B

https://www.drupal.org/project/drupal/issues/2976394#comment-12636129

From what I see the current patch is a natural solution to the errors listed in the corresponding test run [ see below ].

https://www.drupal.org/pift-ci-job/978873

In response to #3 above ... I think we are going to have to find a general solution to views/page managers etc.

This patch is far from complete...

As usual I will help out where I can.

TLDR;

I stupidly created a duplicate issue ... before I could shut that down Catch moved that issue to major.
#2976649: Make auto handling of utf8 routes deprecated I agree and so I am upgrading this issue.

martin107’s picture

Looking at views question, here is an example which applies broadly. and just echoes #4.

entity.view.edit_form:
path: '/admin/structure/views/view/{view}'

the variable {view} is derived from the machine name .. so limited to lowercase[a-z] and underscore.

@Bedir

Can you expand on the page manager comment in #3?
Or just point me at an example of what is on your mind.

I am still trying to decide if we are sitting on a upgrade headache... or not.

martin107’s picture

FileSize
4.49 KB

Reroll.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

martin107’s picture

FileSize
4.47 KB

reroll.

Mile23’s picture

Status: Needs review » Reviewed & tested by the community

LGTM. I tried reverting the RoutingFixtures files and ran a few tests that ended up failing on deprecation errors. Then I reverted system_test.routing.yml to the same result.

The last submitted patch, 7: 2961688-7.patch, failed testing. View results

longwave’s picture

Status: Reviewed & tested by the community » Needs work

Work out how this affects our database looks and paths entered by users in the Views UI.

This patch doesn't take this into account. If I remove the @ from the trigger_error() line in RouteCompiler::compilePattern() and then create a Views page with a custom path that uses UTF-8 characters, the deprecation warning is logged in watchdog. Looks like this might need to be detected and handled in our RouteBuilder class?

tstoeckler’s picture

Re #12 wouldn't it be sufficient for \Drupal\views\Plugin\views\display\PathPluginBase::getRoute() to conditionally specify the utf-8 option as part of the generated route?

longwave’s picture

I guess the question is, do we need to fix this for Views only, or are there enough places that users can enter custom paths elsewhere that we need to provide a more generic solution? I didn't test custom URL aliases for nodes, for example.

Berdir’s picture

Thanks for pointing out views, I wanted to do that as well but didn't get to it yet ;)

Aliases aren't routes, they are resolved before that.

AFAIK views is currently the only place in core where users can define the actual routes. But there's also Page manager and possibly more things like that in Contrib.

alexpott’s picture

Status: Needs work » Needs review
FileSize
2.9 KB
3 KB

@longwave++ was just about to write something along the same lines.

Here's a patch that sets the UTF-8 option for all routes.

alexpott’s picture

Also we don't support non-UTF8 routes.

I tried adding


    // Non UTF-8 route.
    $route = new Route("/place/fo\xE9");
    $route->setMethods(['GET', 'HEAD']);
    $collection->add('route_f', $route);

to \Drupal\Tests\Core\Routing\RoutingFixtures::complexRouteCollection() and got Drupal\Core\Database\DatabaseExceptionWrapper : SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xE9' for column 'path'

So maybe we could just always set the UTF-8 option and not do if (preg_match('//u', $route->getPath())) {

alexpott’s picture

Also it is not just views... a module could have

happy.emoji:
  path: '/😁'
  defaults:
    _controller: '\Drupal\happy\Controller:onSmiley'
    _title: '✌'
  requirements:
    _access: 'TRUE'

In it's routing.yml file.

Status: Needs review » Needs work

The last submitted patch, 16: 2961688-2-13.patch, failed testing. View results

alexpott’s picture

Status: Needs work » Needs review
FileSize
798 bytes
3.78 KB

Funky so routes generated by the rebuild don't have the correct compiler class.

Status: Needs review » Needs work

The last submitted patch, 20: 2961688-2-20.patch, failed testing. View results

alexpott’s picture

Status: Needs work » Needs review
FileSize
4.76 KB
7.7 KB

So let's use RouteCompiler::class everywhere so it is standardised. Also need to fix the test.

alexpott’s picture

Issue summary: View changes
+++ b/core/lib/Drupal/Core/Routing/RouteCompiler.php
@@ -31,7 +31,11 @@ class RouteCompiler extends SymfonyRouteCompiler implements RouteCompilerInterfa
+    // Symfony 4 requires that all UTF-8 route patterns have the "utf8" option
+    // set.
+    if (preg_match('//u', $route->getPath())) {
+      $route->setOption('utf8', TRUE);
+    }

So as far as I can see the last to resolve here is whether or not the if has any point because I can't see how we support non-utf8 routes. See #17

longwave’s picture

Status: Needs review » Needs work

I don't see how we can support non-UTF8 routes either. MatcherDumper always wants to write the entire route collection to the database, no exceptions, and if the database only supports UTF8 then logically the route path can only be UTF8 as well.

I guess there are extreme edge cases where someone either changes the database character set or replaces the route dumper service with some other backend - but I don't think we should consider supporting this as they could always override the route compiler class as well if they need to.

NW to always set the UTF8 option.

Berdir’s picture

If I understand this correctly, then this is about https://symfony.com/blog/new-in-symfony-3-2-unicode-routing-support. So before Symfony 3.2, *they* didn't support utf8 at all.

But that's never been true for us anyway with our database-based matcher, we always supported it and as pointed out, we in fact can not "not support" it. The whole thing seems a bit unfortunate in how it's implemented, because we call that compilePattern() method in some but very few cases (building the routes calls it from \Drupal\Core\EventSubscriber\SpecialAttributesRouteSubscriber::alterRoutes()*, and at runtime \Drupal\Core\Routing\UrlGenerator::getInternalPathFromRoute() calls compile(), the only call to that that I see in my default installation is from bigpipe.

And then it only uses that flag to set the u modifier on route regexp, which we AFAIK never use anyway. I guess most of what compilePatterns() does is not relevant for us? So we just need to get rid of the deprecation messages and always setting it is fine.

* Pretty sure several things that are being checked in there haven't existed in a very long time, e..g _content.

alexpott’s picture

Status: Needs work » Needs review
FileSize
795 bytes
7.75 KB

Patches addresses #23. Thanks for the reviews @Berdir and @longwave.

longwave’s picture

Status: Needs review » Reviewed & tested by the community

#26 looks good.

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/lib/Drupal/Core/Routing/RouteBuilder.php
@@ -168,6 +168,8 @@ public function rebuild() {
+        $route_info['options']['compiler_class'] = RouteCompiler::class;

should we do this only if a value doesn't exist? i.e.

$route['options'] += [
 'compiler_class' => ...
];

what if a contrib/client project wants to use their own snowflake compiler?

alexpott’s picture

@larowlan that's not possible. Err... no I'm wrong. Here's a test for doing just that. Nice catch!

Hopefully there are not too many snowflake compilers out there though.

larowlan’s picture

+1 thanks

jibran’s picture

Do we need/link a change notice?

alexpott’s picture

@jibran nothing is changing. We already do not support non-UTF8 routes - see comments above.

jibran’s picture

Status: Needs review » Reviewed & tested by the community

ok

larowlan’s picture

Adding review credits

larowlan’s picture

Status: Reviewed & tested by the community » Fixed

Committed 729b440 and pushed to 8.7.x. Thanks!

  • larowlan committed 729b440 on 8.7.x
    Issue #2961688 by alexpott, martin107, longwave, Berdir, larowlan: Fix "...
Mile23’s picture

Status: Fixed » Closed (fixed)

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