Bug #103844
closedURL generation broken
0%
Description
The last security update changed how URLs are generated and broke some URLs.
We have URLs, which use the PersistedPatternMapper. This mapper would generate a URL with the given parameter, even if the generate-Method could not find the object. This is now prevented with the fix for #103400
Example Routing-Configuration (simplified)¶
Dealer:
type: Extbase
extension: Example
plugin: dealer
defaultController: 'Dealer::index'
routes:
-
routePath: '/dealer/{dealer}'
_controller: 'Dealer::show'
_arguments:
dealer: dealer
requirements:
dealer: '(.*-)?[0-9]+'
aspects:
dealer:
type: PersistedPatternMapper
tableName: tx_example_domain_model_dealer
routeFieldPattern: '^(?P<uid>\d+)$'
routeFieldResult: '{uid}'
The generated URLs look like this: www.example.com/dealer/123
We have an API endpoint, which generates links for 6000 dealers. If we would generate those links using the TYPO3 API, we would have multiple SQL Queries for each dealer. To solve this issue, we only generate a "fake" URL and replace the Path-Part:
$baseLink = $this->getTSFE()->cObj->typoLink_URL([
'parameter' => 't3://page?uid=' . $dealerPage,
'additionalParams' => GeneralUtility::implodeArrayForUrl('', [
'tx_vierwdbosch_dealer' => [
'action' => 'show',
'dealer' => '0',
],
]),
]);
This will generate a URL www.example.com/dealer/123
Now we can generate all URLs with a simple string-replace:
foreach ($dealers as $dealer) {
$dealer['link'] = str_replace('/0', '/' . $dealer['uid'], $baseLink);
}
This does not work anymore, because the initial URL will not be correctly generated. The dealer with ID 0 does not exist and the URL will look like this:
www.example.com?tx_example_dealer%5Baction%5D=show&tx_example_dealer%5Bdealer%5D=0&cHash=0875exxxxxx
Generating the URLs for all 6000 dealers takes 7 Seconds. Using one fake link and replacing the slug with string replace takes 70ms.
Another use-case was generating a link with a slug when we only had the slug and not the object.
We had an API change and many URLs changed, because the underlying DB was changed. We know that the OLD slugs should be mapped to new URLs. We have a catchallAction for this.
defaultController: 'SelfService::index'
routes:
-
routePath: '/asset/{asset}'
_controller: 'Asset::show'
_arguments:
asset: asset
-
routePath: '/{matchAny}'
_controller: 'SelfService::catchall'
_arguments:
matchAny: path
requirements:
asset: 'asset-.*'
matchAny: '.*'
public function catchallAction(string $path): ResponseInterface {
if (preg_match('/-e(\d+)$/', $path, $matches)) {
$asset = 'asset-' . str_pad($matches[1], 5, '0', STR_PAD_LEFT);
$this->redirect('show', 'Asset', null, ['asset' => $asset], null, null, 301);
}
...
}
URLs in the form of /random-prefix-e123
are redirected to /asset/asset-00123
This does not work anymore, because the URL for the redirect is not generated correctly anymore.
I think to fix this issue, we would need to load and validate the asset in the catchall action to get the correct object and use this in the URL generation.
It's possible that this is as intended, but this is still a large breaking change for us and prevents us from installing the security update :(