Merge branch '3.4' into 4.0

* 3.4:
  Use the PCRE_DOLLAR_ENDONLY modifier in route regexes
  [Form] Make sure errors are a part of the label on bootstrap 4 - this is a requirement for WCAG2
  [Config] Only using filemtime to check file freshness
This commit is contained in:
Nicolas Grekas 2018-02-04 17:43:51 +01:00
commit 767b028439
28 changed files with 307 additions and 190 deletions

View File

@ -28,7 +28,6 @@ col-sm-2
{{- form_label(form) -}}
<div class="{{ block('form_group_class') }}">
{{- form_widget(form) -}}
{{- form_errors(form) -}}
</div>
{##}</div>
{%- endif -%}
@ -40,7 +39,6 @@ col-sm-2
{{- form_label(form) -}}
<div class="{{ block('form_group_class') }}">
{{- form_widget(form) -}}
{{- form_errors(form) -}}
</div>
</div>
{##}</fieldset>

View File

@ -39,7 +39,41 @@
{% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) -%}
{% set valid = true %}
{%- endif -%}
{{- parent() -}}
{%- if widget == 'single_text' -%}
{{- block('form_widget_simple') -}}
{%- else -%}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%}
<div {{ block('widget_container_attributes') }}>
<div class="table-responsive">
<table class="table {{ table_class|default('table-bordered table-condensed table-striped') }}">
<thead>
<tr>
{%- if with_years %}<th>{{ form_label(form.years) }}</th>{% endif -%}
{%- if with_months %}<th>{{ form_label(form.months) }}</th>{% endif -%}
{%- if with_weeks %}<th>{{ form_label(form.weeks) }}</th>{% endif -%}
{%- if with_days %}<th>{{ form_label(form.days) }}</th>{% endif -%}
{%- if with_hours %}<th>{{ form_label(form.hours) }}</th>{% endif -%}
{%- if with_minutes %}<th>{{ form_label(form.minutes) }}</th>{% endif -%}
{%- if with_seconds %}<th>{{ form_label(form.seconds) }}</th>{% endif -%}
</tr>
</thead>
<tbody>
<tr>
{%- if with_years %}<td>{{ form_widget(form.years) }}</td>{% endif -%}
{%- if with_months %}<td>{{ form_widget(form.months) }}</td>{% endif -%}
{%- if with_weeks %}<td>{{ form_widget(form.weeks) }}</td>{% endif -%}
{%- if with_days %}<td>{{ form_widget(form.days) }}</td>{% endif -%}
{%- if with_hours %}<td>{{ form_widget(form.hours) }}</td>{% endif -%}
{%- if with_minutes %}<td>{{ form_widget(form.minutes) }}</td>{% endif -%}
{%- if with_seconds %}<td>{{ form_widget(form.seconds) }}</td>{% endif -%}
</tr>
</tbody>
</table>
</div>
{%- if with_invert %}{{ form_widget(form.invert) }}{% endif -%}
</div>
{%- endif -%}
{%- endblock dateinterval_widget %}
{% block percent_widget -%}
@ -125,13 +159,28 @@
{# Labels #}
{% block form_label -%}
{%- if compound is defined and compound -%}
{%- set element = 'legend' -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-legend')|trim}) -%}
{%- else -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%}
{% if label is not same as(false) -%}
{%- if compound is defined and compound -%}
{%- set element = 'legend' -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-legend')|trim}) -%}
{%- else -%}
{%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%}
{%- endif -%}
{% if required -%}
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %}
{%- endif -%}
{% if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
<{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}{% block form_label_errors %}{{- form_errors(form) -}}{% endblock form_label_errors %}</{{ element|default('label') }}>
{%- endif -%}
{{- parent() -}}
{%- endblock form_label %}
{% block checkbox_radio_label -%}
@ -169,7 +218,6 @@
<{{ element|default('div') }} class="form-group">
{{- form_label(form) -}}
{{- form_widget(form) -}}
{{- form_errors(form) -}}
</{{ element|default('div') }}>
{%- endblock form_row %}

View File

@ -19,6 +19,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\CompiledRoute;
use Symfony\Component\Routing\RouteCollection;
class ObjectsProvider
@ -36,7 +37,7 @@ class ObjectsProvider
public static function getRoutes()
{
return array(
'route_1' => new Route(
'route_1' => new RouteStub(
'/hello/{name}',
array('name' => 'Joseph'),
array('name' => '[a-z]+'),
@ -45,7 +46,7 @@ class ObjectsProvider
array('http', 'https'),
array('get', 'head')
),
'route_2' => new Route(
'route_2' => new RouteStub(
'/name/add',
array(),
array(),
@ -187,3 +188,11 @@ class ExtendedCallableClass extends CallableClass
{
}
}
class RouteStub extends Route
{
public function compile()
{
return new CompiledRoute('', '#PATH_REGEX#', array(), array(), '#HOST_REGEX#');
}
}

View File

@ -1,11 +1,11 @@
{
"path": "\/hello\/{name}",
"pathRegex": "#^\/hello(?:\/(?P<name>[a-z]+))?$#s",
"pathRegex": "#PATH_REGEX#",
"host": "localhost",
"hostRegex": "#^localhost$#si",
"hostRegex": "#HOST_REGEX#",
"scheme": "http|https",
"method": "GET|HEAD",
"class": "Symfony\\Component\\Routing\\Route",
"class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\RouteStub",
"defaults": {
"name": "Joseph"
},

View File

@ -1,10 +1,10 @@
- Path: /hello/{name}
- Path Regex: #^/hello(?:/(?P<name>[a-z]+))?$#s
- Path Regex: #PATH_REGEX#
- Host: localhost
- Host Regex: #^localhost$#si
- Host Regex: #HOST_REGEX#
- Scheme: http|https
- Method: GET|HEAD
- Class: Symfony\Component\Routing\Route
- Class: Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub
- Defaults:
- `name`: Joseph
- Requirements:

View File

@ -1,17 +1,17 @@
+--------------+---------------------------------------------------------+
| Property | Value |
+--------------+---------------------------------------------------------+
| Route Name | |
| Path | /hello/{name} |
| Path Regex | #^/hello(?:/(?P<name>[a-z]+))?$#s |
| Host | localhost |
| Host Regex | #^localhost$#si |
| Scheme | http|https |
| Method | GET|HEAD |
| Requirements | name: [a-z]+ |
| Class | Symfony\Component\Routing\Route |
| Defaults | name: Joseph |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
| | opt1: val1 |
| | opt2: val2 |
+--------------+---------------------------------------------------------+
+--------------+-------------------------------------------------------------------+
| Property | Value |
+--------------+-------------------------------------------------------------------+
| Route Name | |
| Path | /hello/{name} |
| Path Regex | #PATH_REGEX# |
| Host | localhost |
| Host Regex | #HOST_REGEX# |
| Scheme | http|https |
| Method | GET|HEAD |
| Requirements | name: [a-z]+ |
| Class | Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub |
| Defaults | name: Joseph |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
| | opt1: val1 |
| | opt2: val2 |
+--------------+-------------------------------------------------------------------+

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<route class="Symfony\Component\Routing\Route">
<path regex="#^/hello(?:/(?P&lt;name&gt;[a-z]+))?$#s">/hello/{name}</path>
<host regex="#^localhost$#si">localhost</host>
<route class="Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub">
<path regex="#PATH_REGEX#">/hello/{name}</path>
<host regex="#HOST_REGEX#">localhost</host>
<scheme>http</scheme>
<scheme>https</scheme>
<method>GET</method>

View File

@ -1,11 +1,11 @@
{
"path": "\/name\/add",
"pathRegex": "#^\/name\/add$#s",
"pathRegex": "#PATH_REGEX#",
"host": "localhost",
"hostRegex": "#^localhost$#si",
"hostRegex": "#HOST_REGEX#",
"scheme": "http|https",
"method": "PUT|POST",
"class": "Symfony\\Component\\Routing\\Route",
"class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\RouteStub",
"defaults": [],
"requirements": "NO CUSTOM",
"options": {

View File

@ -1,10 +1,10 @@
- Path: /name/add
- Path Regex: #^/name/add$#s
- Path Regex: #PATH_REGEX#
- Host: localhost
- Host Regex: #^localhost$#si
- Host Regex: #HOST_REGEX#
- Scheme: http|https
- Method: PUT|POST
- Class: Symfony\Component\Routing\Route
- Class: Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub
- Defaults: NONE
- Requirements: NO CUSTOM
- Options:

View File

@ -1,17 +1,17 @@
+--------------+---------------------------------------------------------+
| Property | Value |
+--------------+---------------------------------------------------------+
| Route Name | |
| Path | /name/add |
| Path Regex | #^/name/add$#s |
| Host | localhost |
| Host Regex | #^localhost$#si |
| Scheme | http|https |
| Method | PUT|POST |
| Requirements | NO CUSTOM |
| Class | Symfony\Component\Routing\Route |
| Defaults | NONE |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
| | opt1: val1 |
| | opt2: val2 |
+--------------+---------------------------------------------------------+
+--------------+-------------------------------------------------------------------+
| Property | Value |
+--------------+-------------------------------------------------------------------+
| Route Name | |
| Path | /name/add |
| Path Regex | #PATH_REGEX# |
| Host | localhost |
| Host Regex | #HOST_REGEX# |
| Scheme | http|https |
| Method | PUT|POST |
| Requirements | NO CUSTOM |
| Class | Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub |
| Defaults | NONE |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
| | opt1: val1 |
| | opt2: val2 |
+--------------+-------------------------------------------------------------------+

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<route class="Symfony\Component\Routing\Route">
<path regex="#^/name/add$#s">/name/add</path>
<host regex="#^localhost$#si">localhost</host>
<route class="Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub">
<path regex="#PATH_REGEX#">/name/add</path>
<host regex="#HOST_REGEX#">localhost</host>
<scheme>http</scheme>
<scheme>https</scheme>
<method>PUT</method>

View File

@ -1,12 +1,12 @@
{
"route_1": {
"path": "\/hello\/{name}",
"pathRegex": "#^\/hello(?:\/(?P<name>[a-z]+))?$#s",
"pathRegex": "#PATH_REGEX#",
"host": "localhost",
"hostRegex": "#^localhost$#si",
"hostRegex": "#HOST_REGEX#",
"scheme": "http|https",
"method": "GET|HEAD",
"class": "Symfony\\Component\\Routing\\Route",
"class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\RouteStub",
"defaults": {
"name": "Joseph"
},
@ -21,12 +21,12 @@
},
"route_2": {
"path": "\/name\/add",
"pathRegex": "#^\/name\/add$#s",
"pathRegex": "#PATH_REGEX#",
"host": "localhost",
"hostRegex": "#^localhost$#si",
"hostRegex": "#HOST_REGEX#",
"scheme": "http|https",
"method": "PUT|POST",
"class": "Symfony\\Component\\Routing\\Route",
"class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\RouteStub",
"defaults": [],
"requirements": "NO CUSTOM",
"options": {

View File

@ -2,12 +2,12 @@ route_1
-------
- Path: /hello/{name}
- Path Regex: #^/hello(?:/(?P<name>[a-z]+))?$#s
- Path Regex: #PATH_REGEX#
- Host: localhost
- Host Regex: #^localhost$#si
- Host Regex: #HOST_REGEX#
- Scheme: http|https
- Method: GET|HEAD
- Class: Symfony\Component\Routing\Route
- Class: Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub
- Defaults:
- `name`: Joseph
- Requirements:
@ -22,12 +22,12 @@ route_2
-------
- Path: /name/add
- Path Regex: #^/name/add$#s
- Path Regex: #PATH_REGEX#
- Host: localhost
- Host Regex: #^localhost$#si
- Host Regex: #HOST_REGEX#
- Scheme: http|https
- Method: PUT|POST
- Class: Symfony\Component\Routing\Route
- Class: Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub
- Defaults: NONE
- Requirements: NO CUSTOM
- Options:

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<routes>
<route name="route_1" class="Symfony\Component\Routing\Route">
<path regex="#^/hello(?:/(?P&lt;name&gt;[a-z]+))?$#s">/hello/{name}</path>
<host regex="#^localhost$#si">localhost</host>
<route name="route_1" class="Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub">
<path regex="#PATH_REGEX#">/hello/{name}</path>
<host regex="#HOST_REGEX#">localhost</host>
<scheme>http</scheme>
<scheme>https</scheme>
<method>GET</method>
@ -19,9 +19,9 @@
<option key="opt2">val2</option>
</options>
</route>
<route name="route_2" class="Symfony\Component\Routing\Route">
<path regex="#^/name/add$#s">/name/add</path>
<host regex="#^localhost$#si">localhost</host>
<route name="route_2" class="Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub">
<path regex="#PATH_REGEX#">/name/add</path>
<host regex="#HOST_REGEX#">localhost</host>
<scheme>http</scheme>
<scheme>https</scheme>
<method>PUT</method>

View File

@ -60,7 +60,7 @@ class FileResource implements SelfCheckingResourceInterface, \Serializable
*/
public function isFresh($timestamp)
{
return file_exists($this->resource) && @filemtime($this->resource) <= $timestamp;
return false !== ($filemtime = @filemtime($this->resource)) && $filemtime <= $timestamp;
}
public function serialize()

View File

@ -40,11 +40,11 @@ class ReflectionClassResource implements SelfCheckingResourceInterface, \Seriali
}
foreach ($this->files as $file => $v) {
if (!file_exists($file)) {
if (false === $filemtime = @filemtime($file)) {
return false;
}
if (@filemtime($file) > $timestamp) {
if ($filemtime > $timestamp) {
return $this->hash === $this->computeHash();
}
}

View File

@ -11,6 +11,8 @@
namespace Symfony\Component\Form\Tests;
use Symfony\Component\Form\FormError;
/**
* Abstract class providing test cases for the Bootstrap 4 horizontal Twig form theme.
*
@ -18,6 +20,30 @@ namespace Symfony\Component\Form\Tests;
*/
abstract class AbstractBootstrap4HorizontalLayoutTest extends AbstractBootstrap4LayoutTest
{
public function testRow()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
$form->addError(new FormError('[trans]Error![/trans]'));
$view = $form->createView();
$html = $this->renderRow($view);
$this->assertMatchesXpath($html,
'/div
[
./label[@for="name"]
[
./div[
./ul
[./li[.="[trans]Error![/trans]"]]
[count(./li)=1]
]
]
/following-sibling::div[./input[@id="name"]]
]
'
);
}
public function testLabelOnForm()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType');

View File

@ -20,6 +20,30 @@ use Symfony\Component\Form\FormError;
*/
abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
{
public function testRow()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
$form->addError(new FormError('[trans]Error![/trans]'));
$view = $form->createView();
$html = $this->renderRow($view);
$this->assertMatchesXpath($html,
'/div
[
./label[@for="name"]
[
./div[
./ul
[./li[.="[trans]Error![/trans]"]]
[count(./li)=1]
]
]
/following-sibling::input[@id="name"]
]
'
);
}
public function testLabelOnForm()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType');

View File

@ -208,7 +208,7 @@ class RouteCompiler implements RouteCompilerInterface
for ($i = 0, $nbToken = count($tokens); $i < $nbToken; ++$i) {
$regexp .= self::computeRegexp($tokens, $i, $firstOptional);
}
$regexp = self::REGEX_DELIMITER.'^'.$regexp.'$'.self::REGEX_DELIMITER.'s'.($isHost ? 'i' : '');
$regexp = self::REGEX_DELIMITER.'^'.$regexp.'$'.self::REGEX_DELIMITER.'sD'.($isHost ? 'i' : '');
// enable Utf8 matching if really required
if ($needsUtf8) {

View File

@ -30,7 +30,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
if (0 === strpos($pathinfo, '/foo')) {
// foo
if (preg_match('#^/foo/(?P<bar>baz|symfony)$#s', $pathinfo, $matches)) {
if (preg_match('#^/foo/(?P<bar>baz|symfony)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo')), array ( 'def' => 'test',));
}
@ -43,7 +43,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
elseif (0 === strpos($pathinfo, '/bar')) {
// bar
if (preg_match('#^/bar/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/bar/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
if ('GET' !== $canonicalMethod) {
$allow[] = 'GET';
goto not_bar;
@ -54,7 +54,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
not_bar:
// barhead
if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
if ('GET' !== $canonicalMethod) {
$allow[] = 'GET';
goto not_barhead;
@ -86,12 +86,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
// baz4
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ());
}
// baz5
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
if ('POST' !== $canonicalMethod) {
$allow[] = 'POST';
goto not_baz5;
@ -102,7 +102,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
not_baz5:
// baz.baz6
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
if ('PUT' !== $canonicalMethod) {
$allow[] = 'PUT';
goto not_bazbaz6;
@ -115,7 +115,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
// quoter
if (preg_match('#^/(?P<quoter>[\']+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<quoter>[\']+)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'quoter')), array ());
}
@ -127,30 +127,30 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
if (0 === strpos($pathinfo, '/a')) {
if (0 === strpos($pathinfo, '/a/b\'b')) {
// foo1
if (preg_match('#^/a/b\'b/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo1')), array ());
}
// bar1
if (preg_match('#^/a/b\'b/(?P<bar>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<bar>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar1')), array ());
}
}
// overridden
if (preg_match('#^/a/(?P<var>.*)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/(?P<var>.*)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'overridden')), array ());
}
if (0 === strpos($pathinfo, '/a/b\'b')) {
// foo2
if (preg_match('#^/a/b\'b/(?P<foo1>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<foo1>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo2')), array ());
}
// bar2
if (preg_match('#^/a/b\'b/(?P<bar1>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<bar1>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar2')), array ());
}
@ -160,7 +160,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
elseif (0 === strpos($pathinfo, '/multi')) {
// helloWorld
if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P<who>[^/]++))?$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P<who>[^/]++))?$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'helloWorld')), array ( 'who' => 'World!',));
}
@ -177,12 +177,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
// foo3
if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo3')), array ());
}
// bar3
if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<bar>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<bar>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar3')), array ());
}
@ -193,7 +193,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
// foo4
if (preg_match('#^/aba/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/aba/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo4')), array ());
}
@ -201,7 +201,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
$host = $context->getHost();
if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) {
if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) {
// route1
if ('/route1' === $pathinfo) {
return array('_route' => 'route1');
@ -214,7 +214,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
if (preg_match('#^b\\.example\\.com$#si', $host, $hostMatches)) {
if (preg_match('#^b\\.example\\.com$#sDi', $host, $hostMatches)) {
// route3
if ('/c2/route3' === $pathinfo) {
return array('_route' => 'route3');
@ -222,7 +222,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) {
if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) {
// route4
if ('/route4' === $pathinfo) {
return array('_route' => 'route4');
@ -230,7 +230,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
if (preg_match('#^c\\.example\\.com$#si', $host, $hostMatches)) {
if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) {
// route5
if ('/route5' === $pathinfo) {
return array('_route' => 'route5');
@ -243,7 +243,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
return array('_route' => 'route6');
}
if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#si', $host, $hostMatches)) {
if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#sDi', $host, $hostMatches)) {
if (0 === strpos($pathinfo, '/route1')) {
// route11
if ('/route11' === $pathinfo) {
@ -256,12 +256,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
// route13
if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P<name>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route13')), array ());
}
// route14
if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P<name>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route14')), array ( 'var1' => 'val',));
}
@ -269,16 +269,16 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
if (preg_match('#^c\\.example\\.com$#si', $host, $hostMatches)) {
if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) {
// route15
if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P<name>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'route15')), array ());
}
}
// route16
if (0 === strpos($pathinfo, '/route16') && preg_match('#^/route16/(?P<name>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/route16') && preg_match('#^/route16/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'route16')), array ( 'var1' => 'val',));
}
@ -294,12 +294,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
if (0 === strpos($pathinfo, '/a/b')) {
// b
if (preg_match('#^/a/b/(?P<var>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'b')), array ());
}
// c
if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P<var>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'c')), array ());
}

View File

@ -30,7 +30,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
if (0 === strpos($pathinfo, '/foo')) {
// foo
if (preg_match('#^/foo/(?P<bar>baz|symfony)$#s', $pathinfo, $matches)) {
if (preg_match('#^/foo/(?P<bar>baz|symfony)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo')), array ( 'def' => 'test',));
}
@ -43,7 +43,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
elseif (0 === strpos($pathinfo, '/bar')) {
// bar
if (preg_match('#^/bar/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/bar/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
if ('GET' !== $canonicalMethod) {
$allow[] = 'GET';
goto not_bar;
@ -54,7 +54,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
not_bar:
// barhead
if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
if ('GET' !== $canonicalMethod) {
$allow[] = 'GET';
goto not_barhead;
@ -96,7 +96,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// baz4
if (preg_match('#^/test/(?P<foo>[^/]++)/?$#s', $pathinfo, $matches)) {
if (preg_match('#^/test/(?P<foo>[^/]++)/?$#sD', $pathinfo, $matches)) {
$ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ());
if ('/' === substr($pathinfo, -1)) {
// no-op
@ -111,7 +111,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
not_baz4:
// baz5
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
if ('POST' !== $canonicalMethod) {
$allow[] = 'POST';
goto not_baz5;
@ -122,7 +122,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
not_baz5:
// baz.baz6
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
if (preg_match('#^/test/(?P<foo>[^/]++)/$#sD', $pathinfo, $matches)) {
if ('PUT' !== $canonicalMethod) {
$allow[] = 'PUT';
goto not_bazbaz6;
@ -135,7 +135,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// quoter
if (preg_match('#^/(?P<quoter>[\']+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<quoter>[\']+)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'quoter')), array ());
}
@ -147,30 +147,30 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
if (0 === strpos($pathinfo, '/a')) {
if (0 === strpos($pathinfo, '/a/b\'b')) {
// foo1
if (preg_match('#^/a/b\'b/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo1')), array ());
}
// bar1
if (preg_match('#^/a/b\'b/(?P<bar>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<bar>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar1')), array ());
}
}
// overridden
if (preg_match('#^/a/(?P<var>.*)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/(?P<var>.*)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'overridden')), array ());
}
if (0 === strpos($pathinfo, '/a/b\'b')) {
// foo2
if (preg_match('#^/a/b\'b/(?P<foo1>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<foo1>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo2')), array ());
}
// bar2
if (preg_match('#^/a/b\'b/(?P<bar1>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<bar1>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar2')), array ());
}
@ -180,7 +180,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
elseif (0 === strpos($pathinfo, '/multi')) {
// helloWorld
if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P<who>[^/]++))?$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P<who>[^/]++))?$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'helloWorld')), array ( 'who' => 'World!',));
}
@ -207,12 +207,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// foo3
if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo3')), array ());
}
// bar3
if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<bar>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P<bar>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar3')), array ());
}
@ -223,7 +223,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// foo4
if (preg_match('#^/aba/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/aba/(?P<foo>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo4')), array ());
}
@ -231,7 +231,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
$host = $context->getHost();
if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) {
if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) {
// route1
if ('/route1' === $pathinfo) {
return array('_route' => 'route1');
@ -244,7 +244,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
if (preg_match('#^b\\.example\\.com$#si', $host, $hostMatches)) {
if (preg_match('#^b\\.example\\.com$#sDi', $host, $hostMatches)) {
// route3
if ('/c2/route3' === $pathinfo) {
return array('_route' => 'route3');
@ -252,7 +252,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) {
if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) {
// route4
if ('/route4' === $pathinfo) {
return array('_route' => 'route4');
@ -260,7 +260,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
if (preg_match('#^c\\.example\\.com$#si', $host, $hostMatches)) {
if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) {
// route5
if ('/route5' === $pathinfo) {
return array('_route' => 'route5');
@ -273,7 +273,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
return array('_route' => 'route6');
}
if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#si', $host, $hostMatches)) {
if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#sDi', $host, $hostMatches)) {
if (0 === strpos($pathinfo, '/route1')) {
// route11
if ('/route11' === $pathinfo) {
@ -286,12 +286,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// route13
if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P<name>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route13')), array ());
}
// route14
if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P<name>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route14')), array ( 'var1' => 'val',));
}
@ -299,16 +299,16 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
if (preg_match('#^c\\.example\\.com$#si', $host, $hostMatches)) {
if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) {
// route15
if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P<name>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'route15')), array ());
}
}
// route16
if (0 === strpos($pathinfo, '/route16') && preg_match('#^/route16/(?P<name>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/route16') && preg_match('#^/route16/(?P<name>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'route16')), array ( 'var1' => 'val',));
}
@ -324,12 +324,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
if (0 === strpos($pathinfo, '/a/b')) {
// b
if (preg_match('#^/a/b/(?P<var>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'b')), array ());
}
// c
if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P<var>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'c')), array ());
}

View File

@ -35,7 +35,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
// dynamic
if (preg_match('#^/rootprefix/(?P<var>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/rootprefix/(?P<var>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'dynamic')), array ());
}

View File

@ -47,7 +47,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// a_wildcard
if (preg_match('#^/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'a_wildcard')), array ());
}
@ -100,7 +100,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// nested_wildcard
if (0 === strpos($pathinfo, '/nested') && preg_match('#^/nested/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/nested') && preg_match('#^/nested/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'nested_wildcard')), array ());
}

View File

@ -71,12 +71,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
elseif (0 === strpos($pathinfo, '/trailing/regex')) {
// regex_trailing_slash_no_methods
if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P<param>[^/]++)/$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ());
}
// regex_trailing_slash_GET_method
if (0 === strpos($pathinfo, '/trailing/regex/get-method') && preg_match('#^/trailing/regex/get\\-method/(?P<param>[^/]++)/$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/trailing/regex/get-method') && preg_match('#^/trailing/regex/get\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
if ('GET' !== $canonicalMethod) {
$allow[] = 'GET';
goto not_regex_trailing_slash_GET_method;
@ -87,7 +87,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
not_regex_trailing_slash_GET_method:
// regex_trailing_slash_HEAD_method
if (0 === strpos($pathinfo, '/trailing/regex/head-method') && preg_match('#^/trailing/regex/head\\-method/(?P<param>[^/]++)/$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/trailing/regex/head-method') && preg_match('#^/trailing/regex/head\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
if ('HEAD' !== $requestMethod) {
$allow[] = 'HEAD';
goto not_regex_trailing_slash_HEAD_method;
@ -98,7 +98,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
not_regex_trailing_slash_HEAD_method:
// regex_trailing_slash_POST_method
if (0 === strpos($pathinfo, '/trailing/regex/post-method') && preg_match('#^/trailing/regex/post\\-method/(?P<param>[^/]++)/$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/trailing/regex/post-method') && preg_match('#^/trailing/regex/post\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
if ('POST' !== $canonicalMethod) {
$allow[] = 'POST';
goto not_regex_trailing_slash_POST_method;
@ -153,12 +153,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
elseif (0 === strpos($pathinfo, '/not-trailing/regex')) {
// regex_not_trailing_slash_no_methods
if (0 === strpos($pathinfo, '/not-trailing/regex/no-methods') && preg_match('#^/not\\-trailing/regex/no\\-methods/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/not-trailing/regex/no-methods') && preg_match('#^/not\\-trailing/regex/no\\-methods/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_no_methods')), array ());
}
// regex_not_trailing_slash_GET_method
if (0 === strpos($pathinfo, '/not-trailing/regex/get-method') && preg_match('#^/not\\-trailing/regex/get\\-method/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/not-trailing/regex/get-method') && preg_match('#^/not\\-trailing/regex/get\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
if ('GET' !== $canonicalMethod) {
$allow[] = 'GET';
goto not_regex_not_trailing_slash_GET_method;
@ -169,7 +169,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
not_regex_not_trailing_slash_GET_method:
// regex_not_trailing_slash_HEAD_method
if (0 === strpos($pathinfo, '/not-trailing/regex/head-method') && preg_match('#^/not\\-trailing/regex/head\\-method/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/not-trailing/regex/head-method') && preg_match('#^/not\\-trailing/regex/head\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
if ('HEAD' !== $requestMethod) {
$allow[] = 'HEAD';
goto not_regex_not_trailing_slash_HEAD_method;
@ -180,7 +180,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
not_regex_not_trailing_slash_HEAD_method:
// regex_not_trailing_slash_POST_method
if (0 === strpos($pathinfo, '/not-trailing/regex/post-method') && preg_match('#^/not\\-trailing/regex/post\\-method/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/not-trailing/regex/post-method') && preg_match('#^/not\\-trailing/regex/post\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
if ('POST' !== $canonicalMethod) {
$allow[] = 'POST';
goto not_regex_not_trailing_slash_POST_method;

View File

@ -99,7 +99,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
elseif (0 === strpos($pathinfo, '/trailing/regex')) {
// regex_trailing_slash_no_methods
if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P<param>[^/]++)/?$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P<param>[^/]++)/?$#sD', $pathinfo, $matches)) {
$ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ());
if ('/' === substr($pathinfo, -1)) {
// no-op
@ -114,7 +114,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
not_regex_trailing_slash_no_methods:
// regex_trailing_slash_GET_method
if (0 === strpos($pathinfo, '/trailing/regex/get-method') && preg_match('#^/trailing/regex/get\\-method/(?P<param>[^/]++)/?$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/trailing/regex/get-method') && preg_match('#^/trailing/regex/get\\-method/(?P<param>[^/]++)/?$#sD', $pathinfo, $matches)) {
if ('GET' !== $canonicalMethod) {
$allow[] = 'GET';
goto not_regex_trailing_slash_GET_method;
@ -134,7 +134,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
not_regex_trailing_slash_GET_method:
// regex_trailing_slash_HEAD_method
if (0 === strpos($pathinfo, '/trailing/regex/head-method') && preg_match('#^/trailing/regex/head\\-method/(?P<param>[^/]++)/?$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/trailing/regex/head-method') && preg_match('#^/trailing/regex/head\\-method/(?P<param>[^/]++)/?$#sD', $pathinfo, $matches)) {
if ('HEAD' !== $requestMethod) {
$allow[] = 'HEAD';
goto not_regex_trailing_slash_HEAD_method;
@ -154,7 +154,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
not_regex_trailing_slash_HEAD_method:
// regex_trailing_slash_POST_method
if (0 === strpos($pathinfo, '/trailing/regex/post-method') && preg_match('#^/trailing/regex/post\\-method/(?P<param>[^/]++)/$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/trailing/regex/post-method') && preg_match('#^/trailing/regex/post\\-method/(?P<param>[^/]++)/$#sD', $pathinfo, $matches)) {
if ('POST' !== $canonicalMethod) {
$allow[] = 'POST';
goto not_regex_trailing_slash_POST_method;
@ -209,12 +209,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
elseif (0 === strpos($pathinfo, '/not-trailing/regex')) {
// regex_not_trailing_slash_no_methods
if (0 === strpos($pathinfo, '/not-trailing/regex/no-methods') && preg_match('#^/not\\-trailing/regex/no\\-methods/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/not-trailing/regex/no-methods') && preg_match('#^/not\\-trailing/regex/no\\-methods/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_not_trailing_slash_no_methods')), array ());
}
// regex_not_trailing_slash_GET_method
if (0 === strpos($pathinfo, '/not-trailing/regex/get-method') && preg_match('#^/not\\-trailing/regex/get\\-method/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/not-trailing/regex/get-method') && preg_match('#^/not\\-trailing/regex/get\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
if ('GET' !== $canonicalMethod) {
$allow[] = 'GET';
goto not_regex_not_trailing_slash_GET_method;
@ -225,7 +225,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
not_regex_not_trailing_slash_GET_method:
// regex_not_trailing_slash_HEAD_method
if (0 === strpos($pathinfo, '/not-trailing/regex/head-method') && preg_match('#^/not\\-trailing/regex/head\\-method/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/not-trailing/regex/head-method') && preg_match('#^/not\\-trailing/regex/head\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
if ('HEAD' !== $requestMethod) {
$allow[] = 'HEAD';
goto not_regex_not_trailing_slash_HEAD_method;
@ -236,7 +236,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
not_regex_not_trailing_slash_HEAD_method:
// regex_not_trailing_slash_POST_method
if (0 === strpos($pathinfo, '/not-trailing/regex/post-method') && preg_match('#^/not\\-trailing/regex/post\\-method/(?P<param>[^/]++)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/not-trailing/regex/post-method') && preg_match('#^/not\\-trailing/regex/post\\-method/(?P<param>[^/]++)$#sD', $pathinfo, $matches)) {
if ('POST' !== $canonicalMethod) {
$allow[] = 'POST';
goto not_regex_not_trailing_slash_POST_method;

View File

@ -162,6 +162,18 @@ class UrlMatcherTest extends TestCase
$this->assertEquals(array('_route' => '$péß^a|'), $matcher->match('/bar'));
}
/**
* @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
*/
public function testTrailingEncodedNewlineIsNotOverlooked()
{
$collection = new RouteCollection();
$collection->add('foo', new Route('/foo'));
$matcher = $this->getUrlMatcher($collection);
$matcher->match('/foo%0a');
}
public function testMatchNonAlpha()
{
$collection = new RouteCollection();

View File

@ -38,7 +38,7 @@ class RouteCompilerTest extends TestCase
array(
'Static route',
array('/foo'),
'/foo', '#^/foo$#s', array(), array(
'/foo', '#^/foo$#sD', array(), array(
array('text', '/foo'),
),
),
@ -46,7 +46,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with a variable',
array('/foo/{bar}'),
'/foo', '#^/foo/(?P<bar>[^/]++)$#s', array('bar'), array(
'/foo', '#^/foo/(?P<bar>[^/]++)$#sD', array('bar'), array(
array('variable', '/', '[^/]++', 'bar'),
array('text', '/foo'),
),
@ -55,7 +55,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with a variable that has a default value',
array('/foo/{bar}', array('bar' => 'bar')),
'/foo', '#^/foo(?:/(?P<bar>[^/]++))?$#s', array('bar'), array(
'/foo', '#^/foo(?:/(?P<bar>[^/]++))?$#sD', array('bar'), array(
array('variable', '/', '[^/]++', 'bar'),
array('text', '/foo'),
),
@ -64,7 +64,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with several variables',
array('/foo/{bar}/{foobar}'),
'/foo', '#^/foo/(?P<bar>[^/]++)/(?P<foobar>[^/]++)$#s', array('bar', 'foobar'), array(
'/foo', '#^/foo/(?P<bar>[^/]++)/(?P<foobar>[^/]++)$#sD', array('bar', 'foobar'), array(
array('variable', '/', '[^/]++', 'foobar'),
array('variable', '/', '[^/]++', 'bar'),
array('text', '/foo'),
@ -74,7 +74,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with several variables that have default values',
array('/foo/{bar}/{foobar}', array('bar' => 'bar', 'foobar' => '')),
'/foo', '#^/foo(?:/(?P<bar>[^/]++)(?:/(?P<foobar>[^/]++))?)?$#s', array('bar', 'foobar'), array(
'/foo', '#^/foo(?:/(?P<bar>[^/]++)(?:/(?P<foobar>[^/]++))?)?$#sD', array('bar', 'foobar'), array(
array('variable', '/', '[^/]++', 'foobar'),
array('variable', '/', '[^/]++', 'bar'),
array('text', '/foo'),
@ -84,7 +84,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with several variables but some of them have no default values',
array('/foo/{bar}/{foobar}', array('bar' => 'bar')),
'/foo', '#^/foo/(?P<bar>[^/]++)/(?P<foobar>[^/]++)$#s', array('bar', 'foobar'), array(
'/foo', '#^/foo/(?P<bar>[^/]++)/(?P<foobar>[^/]++)$#sD', array('bar', 'foobar'), array(
array('variable', '/', '[^/]++', 'foobar'),
array('variable', '/', '[^/]++', 'bar'),
array('text', '/foo'),
@ -94,7 +94,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with an optional variable as the first segment',
array('/{bar}', array('bar' => 'bar')),
'', '#^/(?P<bar>[^/]++)?$#s', array('bar'), array(
'', '#^/(?P<bar>[^/]++)?$#sD', array('bar'), array(
array('variable', '/', '[^/]++', 'bar'),
),
),
@ -102,7 +102,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with a requirement of 0',
array('/{bar}', array('bar' => null), array('bar' => '0')),
'', '#^/(?P<bar>0)?$#s', array('bar'), array(
'', '#^/(?P<bar>0)?$#sD', array('bar'), array(
array('variable', '/', '0', 'bar'),
),
),
@ -110,7 +110,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with an optional variable as the first segment with requirements',
array('/{bar}', array('bar' => 'bar'), array('bar' => '(foo|bar)')),
'', '#^/(?P<bar>(foo|bar))?$#s', array('bar'), array(
'', '#^/(?P<bar>(foo|bar))?$#sD', array('bar'), array(
array('variable', '/', '(foo|bar)', 'bar'),
),
),
@ -118,7 +118,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with only optional variables',
array('/{foo}/{bar}', array('foo' => 'foo', 'bar' => 'bar')),
'', '#^/(?P<foo>[^/]++)?(?:/(?P<bar>[^/]++))?$#s', array('foo', 'bar'), array(
'', '#^/(?P<foo>[^/]++)?(?:/(?P<bar>[^/]++))?$#sD', array('foo', 'bar'), array(
array('variable', '/', '[^/]++', 'bar'),
array('variable', '/', '[^/]++', 'foo'),
),
@ -127,7 +127,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with a variable in last position',
array('/foo-{bar}'),
'/foo-', '#^/foo\-(?P<bar>[^/]++)$#s', array('bar'), array(
'/foo-', '#^/foo\-(?P<bar>[^/]++)$#sD', array('bar'), array(
array('variable', '-', '[^/]++', 'bar'),
array('text', '/foo'),
),
@ -136,7 +136,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with nested placeholders',
array('/{static{var}static}'),
'/{static', '#^/\{static(?P<var>[^/]+)static\}$#s', array('var'), array(
'/{static', '#^/\{static(?P<var>[^/]+)static\}$#sD', array('var'), array(
array('text', 'static}'),
array('variable', '', '[^/]+', 'var'),
array('text', '/{static'),
@ -146,7 +146,7 @@ class RouteCompilerTest extends TestCase
array(
'Route without separator between variables',
array('/{w}{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => '(y|Y)')),
'', '#^/(?P<w>[^/\.]+)(?P<x>[^/\.]+)(?P<y>(y|Y))(?:(?P<z>[^/\.]++)(?:\.(?P<_format>[^/]++))?)?$#s', array('w', 'x', 'y', 'z', '_format'), array(
'', '#^/(?P<w>[^/\.]+)(?P<x>[^/\.]+)(?P<y>(y|Y))(?:(?P<z>[^/\.]++)(?:\.(?P<_format>[^/]++))?)?$#sD', array('w', 'x', 'y', 'z', '_format'), array(
array('variable', '.', '[^/]++', '_format'),
array('variable', '', '[^/\.]++', 'z'),
array('variable', '', '(y|Y)', 'y'),
@ -158,7 +158,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with a format',
array('/foo/{bar}.{_format}'),
'/foo', '#^/foo/(?P<bar>[^/\.]++)\.(?P<_format>[^/]++)$#s', array('bar', '_format'), array(
'/foo', '#^/foo/(?P<bar>[^/\.]++)\.(?P<_format>[^/]++)$#sD', array('bar', '_format'), array(
array('variable', '.', '[^/]++', '_format'),
array('variable', '/', '[^/\.]++', 'bar'),
array('text', '/foo'),
@ -168,7 +168,7 @@ class RouteCompilerTest extends TestCase
array(
'Static non UTF-8 route',
array("/fo\xE9"),
"/fo\xE9", "#^/fo\xE9$#s", array(), array(
"/fo\xE9", "#^/fo\xE9$#sD", array(), array(
array('text', "/fo\xE9"),
),
),
@ -176,7 +176,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with an explicit UTF-8 requirement',
array('/{bar}', array('bar' => null), array('bar' => '.'), array('utf8' => true)),
'', '#^/(?P<bar>.)?$#su', array('bar'), array(
'', '#^/(?P<bar>.)?$#sDu', array('bar'), array(
array('variable', '/', '.', 'bar', true),
),
),
@ -205,7 +205,7 @@ class RouteCompilerTest extends TestCase
array(
'Static UTF-8 route',
array('/foé'),
'/foé', '#^/foé$#su', array(), array(
'/foé', '#^/foé$#sDu', array(), array(
array('text', '/foé'),
),
'patterns',
@ -214,7 +214,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with an implicit UTF-8 requirement',
array('/{bar}', array('bar' => null), array('bar' => 'é')),
'', '#^/(?P<bar>é)?$#su', array('bar'), array(
'', '#^/(?P<bar>é)?$#sDu', array('bar'), array(
array('variable', '/', 'é', 'bar', true),
),
'requirements',
@ -223,7 +223,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with a UTF-8 class requirement',
array('/{bar}', array('bar' => null), array('bar' => '\pM')),
'', '#^/(?P<bar>\pM)?$#su', array('bar'), array(
'', '#^/(?P<bar>\pM)?$#sDu', array('bar'), array(
array('variable', '/', '\pM', 'bar', true),
),
'requirements',
@ -232,7 +232,7 @@ class RouteCompilerTest extends TestCase
array(
'Route with a UTF-8 separator',
array('/foo/{bar}§{_format}', array(), array(), array('compiler_class' => Utf8RouteCompiler::class)),
'/foo', '#^/foo/(?P<bar>[^/§]++)§(?P<_format>[^/]++)$#su', array('bar', '_format'), array(
'/foo', '#^/foo/(?P<bar>[^/§]++)§(?P<_format>[^/]++)$#sDu', array('bar', '_format'), array(
array('variable', '§', '[^/]++', '_format', true),
array('variable', '/', '[^/§]++', 'bar', true),
array('text', '/foo'),
@ -326,21 +326,21 @@ class RouteCompilerTest extends TestCase
array(
'Route with host pattern',
array('/hello', array(), array(), array(), 'www.example.com'),
'/hello', '#^/hello$#s', array(), array(), array(
'/hello', '#^/hello$#sD', array(), array(), array(
array('text', '/hello'),
),
'#^www\.example\.com$#si', array(), array(
'#^www\.example\.com$#sDi', array(), array(
array('text', 'www.example.com'),
),
),
array(
'Route with host pattern and some variables',
array('/hello/{name}', array(), array(), array(), 'www.example.{tld}'),
'/hello', '#^/hello/(?P<name>[^/]++)$#s', array('tld', 'name'), array('name'), array(
'/hello', '#^/hello/(?P<name>[^/]++)$#sD', array('tld', 'name'), array('name'), array(
array('variable', '/', '[^/]++', 'name'),
array('text', '/hello'),
),
'#^www\.example\.(?P<tld>[^\.]++)$#si', array('tld'), array(
'#^www\.example\.(?P<tld>[^\.]++)$#sDi', array('tld'), array(
array('variable', '.', '[^\.]++', 'tld'),
array('text', 'www.example'),
),
@ -348,10 +348,10 @@ class RouteCompilerTest extends TestCase
array(
'Route with variable at beginning of host',
array('/hello', array(), array(), array(), '{locale}.example.{tld}'),
'/hello', '#^/hello$#s', array('locale', 'tld'), array(), array(
'/hello', '#^/hello$#sD', array('locale', 'tld'), array(), array(
array('text', '/hello'),
),
'#^(?P<locale>[^\.]++)\.example\.(?P<tld>[^\.]++)$#si', array('locale', 'tld'), array(
'#^(?P<locale>[^\.]++)\.example\.(?P<tld>[^\.]++)$#sDi', array('locale', 'tld'), array(
array('variable', '.', '[^\.]++', 'tld'),
array('text', '.example'),
array('variable', '', '[^\.]++', 'locale'),
@ -360,10 +360,10 @@ class RouteCompilerTest extends TestCase
array(
'Route with host variables that has a default value',
array('/hello', array('locale' => 'a', 'tld' => 'b'), array(), array(), '{locale}.example.{tld}'),
'/hello', '#^/hello$#s', array('locale', 'tld'), array(), array(
'/hello', '#^/hello$#sD', array('locale', 'tld'), array(), array(
array('text', '/hello'),
),
'#^(?P<locale>[^\.]++)\.example\.(?P<tld>[^\.]++)$#si', array('locale', 'tld'), array(
'#^(?P<locale>[^\.]++)\.example\.(?P<tld>[^\.]++)$#sDi', array('locale', 'tld'), array(
array('variable', '.', '[^\.]++', 'tld'),
array('text', '.example'),
array('variable', '', '[^\.]++', 'locale'),

View File

@ -245,7 +245,7 @@ class RouteTest extends TestCase
*/
public function testSerializedRepresentationKeepsWorking()
{
$serialized = 'C:31:"Symfony\Component\Routing\Route":934:{a:8:{s:4:"path";s:13:"/prefix/{foo}";s:4:"host";s:20:"{locale}.example.net";s:8:"defaults";a:1:{s:3:"foo";s:7:"default";}s:12:"requirements";a:1:{s:3:"foo";s:3:"\d+";}s:7:"options";a:1:{s:14:"compiler_class";s:39:"Symfony\Component\Routing\RouteCompiler";}s:7:"schemes";a:0:{}s:7:"methods";a:0:{}s:8:"compiled";C:39:"Symfony\Component\Routing\CompiledRoute":569:{a:8:{s:4:"vars";a:2:{i:0;s:6:"locale";i:1;s:3:"foo";}s:11:"path_prefix";s:7:"/prefix";s:10:"path_regex";s:30:"#^/prefix(?:/(?P<foo>\d+))?$#s";s:11:"path_tokens";a:2:{i:0;a:4:{i:0;s:8:"variable";i:1;s:1:"/";i:2;s:3:"\d+";i:3;s:3:"foo";}i:1;a:2:{i:0;s:4:"text";i:1;s:7:"/prefix";}}s:9:"path_vars";a:1:{i:0;s:3:"foo";}s:10:"host_regex";s:39:"#^(?P<locale>[^\.]++)\.example\.net$#si";s:11:"host_tokens";a:2:{i:0;a:2:{i:0;s:4:"text";i:1;s:12:".example.net";}i:1;a:4:{i:0;s:8:"variable";i:1;s:0:"";i:2;s:7:"[^\.]++";i:3;s:6:"locale";}}s:9:"host_vars";a:1:{i:0;s:6:"locale";}}}}}';
$serialized = 'C:31:"Symfony\Component\Routing\Route":936:{a:8:{s:4:"path";s:13:"/prefix/{foo}";s:4:"host";s:20:"{locale}.example.net";s:8:"defaults";a:1:{s:3:"foo";s:7:"default";}s:12:"requirements";a:1:{s:3:"foo";s:3:"\d+";}s:7:"options";a:1:{s:14:"compiler_class";s:39:"Symfony\Component\Routing\RouteCompiler";}s:7:"schemes";a:0:{}s:7:"methods";a:0:{}s:8:"compiled";C:39:"Symfony\Component\Routing\CompiledRoute":571:{a:8:{s:4:"vars";a:2:{i:0;s:6:"locale";i:1;s:3:"foo";}s:11:"path_prefix";s:7:"/prefix";s:10:"path_regex";s:31:"#^/prefix(?:/(?P<foo>\d+))?$#sD";s:11:"path_tokens";a:2:{i:0;a:4:{i:0;s:8:"variable";i:1;s:1:"/";i:2;s:3:"\d+";i:3;s:3:"foo";}i:1;a:2:{i:0;s:4:"text";i:1;s:7:"/prefix";}}s:9:"path_vars";a:1:{i:0;s:3:"foo";}s:10:"host_regex";s:40:"#^(?P<locale>[^\.]++)\.example\.net$#sDi";s:11:"host_tokens";a:2:{i:0;a:2:{i:0;s:4:"text";i:1;s:12:".example.net";}i:1;a:4:{i:0;s:8:"variable";i:1;s:0:"";i:2;s:7:"[^\.]++";i:3;s:6:"locale";}}s:9:"host_vars";a:1:{i:0;s:6:"locale";}}}}}';
$unserialized = unserialize($serialized);
$route = new Route('/prefix/{foo}', array('foo' => 'default'), array('foo' => '\d+'));