Skip to content

Fix for Redirect URLs that do not contain a backslash (fixes 22308)#22315

Closed
justin-nevitech wants to merge 1 commit intoumbraco:mainfrom
justin-nevitech:22308-Redirect-URL-Issue
Closed

Fix for Redirect URLs that do not contain a backslash (fixes 22308)#22315
justin-nevitech wants to merge 1 commit intoumbraco:mainfrom
justin-nevitech:22308-Redirect-URL-Issue

Conversation

@justin-nevitech
Copy link
Copy Markdown
Contributor

Prerequisites

I have added steps to test this contribution in the description below

If there's an existing issue for this PR then this fixes: #22308

Description

The Redirect URL Management page crashes if the umbracoRedirectUrl table contains a malformed row where the Url value does not contain a / character.

The root cause is in NewDefaultUrlProvider.GetUrlFromRoute, which assumes the route is always in the format {contentId}/{path}.

When IndexOf('/') returns -1 (no / present), the code proceeds to call Substring with a negative index, throwing an ArgumentOutOfRangeException. This propagates and crashes the entire Redirect URL Management page during serialization rather than gracefully handling the invalid row.

Fix

The existing route processing logic has been wrapped in a if (pos >= 0) guard, returning null when no / is found in the route:

var pos = route.IndexOf('/', StringComparison.Ordinal);

if (pos >= 0)
{
    // existing path/domain resolution logic
    ...
    return UrlInfo.FromUri(url, Alias, culture);
}

return null;

This ensures that malformed routes without a / are safely handled without throwing an exception.

How to reproduce

The malformed URL is believed to be the result of a migration (the issue was originally reported on a v13 to v17 upgrade), however I was unable to reproduce the malformed data through normal site usage. To test this fix, the Url value of a row in the umbracoRedirectUrl table can be manually set to a value containing no / character (e.g. 1226#). The exact scenario that originally caused the malformed data to be written is unknown.

Steps to test

  1. Directly update a row in the umbracoRedirectUrl table, setting Url to a value with no / (e.g. UPDATE umbracoRedirectUrl SET Url = '1226#' WHERE Id = )
  2. Navigate to the Redirect URL Management dashboard in the Umbraco backoffice
  3. Without the fix, the page crashes with an ArgumentOutOfRangeException
  4. With the fix applied, the page loads successfully, skipping the malformed row

Copilot AI review requested due to automatic review settings March 31, 2026 16:36
@github-actions
Copy link
Copy Markdown

Hi there @justin-nevitech, thank you for this contribution! 👍

While we wait for one of the Core Collaborators team to have a look at your work, we wanted to let you know about that we have a checklist for some of the things we will consider during review:

  • It's clear what problem this is solving, there's a connected issue or a description of what the changes do and how to test them
  • The automated tests all pass (see "Checks" tab on this PR)
  • The level of security for this contribution is the same or improved
  • The level of performance for this contribution is the same or improved
  • Avoids creating breaking changes; note that behavioral changes might also be perceived as breaking
  • If this is a new feature, Umbraco HQ provided guidance on the implementation beforehand
  • 💡 The contribution looks original and the contributor is presumably allowed to share it

Don't worry if you got something wrong. We like to think of a pull request as the start of a conversation, we're happy to provide guidance on improving your contribution.

If you realize that you might want to make some changes then you can do that by adding new commits to the branch you created for this work and pushing new commits. They should then automatically show up as updates to this pull request.

Thanks, from your friendly Umbraco GitHub bot 🤖 🙂

@umbracocommunity
Copy link
Copy Markdown

This pull request has been mentioned on Umbraco community forum. There might be relevant details there:

https://forum.umbraco.com/t/redirect-url-management-crashes-when-umbracoredirecturl-url-contains-no-character/7781/3

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a crash in Umbraco’s URL resolution when legacy redirect routes are malformed (missing a / separator), preventing the Redirect URL Management page from failing during serialization.

Changes:

  • Adds a pos >= 0 guard around route parsing in GetUrlFromRoute to avoid negative slicing/substring behavior.
  • Returns null for malformed legacy routes that don’t contain a /, skipping invalid rows instead of throwing.

Comment on lines 220 to +224
// extract domainUri and path
// route is /<path> or <domainRootId>/<path>
var pos = route.IndexOf('/', StringComparison.Ordinal);
var path = pos == 0 ? route : route[pos..];
DomainAndUri? domainUri = pos == 0
? null
: DomainUtilities.DomainForNode(
_domainCache,
_siteDomainMapper,
int.Parse(route[..pos], CultureInfo.InvariantCulture),
current,
culture);

var defaultCulture = _languageService.GetDefaultIsoCodeAsync().GetAwaiter().GetResult();
if (domainUri is not null ||
string.IsNullOrEmpty(culture) ||
culture.Equals(defaultCulture, StringComparison.InvariantCultureIgnoreCase))

if (pos >= 0)
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR title mentions a missing backslash, but the code (and the PR description/issue) are handling a missing forward slash ('/'). Consider updating the title to match the actual delimiter to avoid confusion when searching/referencing this fix later.

Copilot uses AI. Check for mistakes.
Comment on lines +224 to +229
if (pos >= 0)
{
Uri url = AssembleUrl(domainUri, path, current, mode);
return UrlInfo.FromUri(url, Alias, culture);
var path = pos == 0 ? route : route[pos..];
DomainAndUri? domainUri = pos == 0
? null
: DomainUtilities.DomainForNode(
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This guard fixes GetUrlFromRoute for malformed routes without '/'. However, the same assumption (IndexOf('/') then slicing with route[pos..]) still exists in GetOtherUrls (see around NewDefaultUrlProvider.cs:131-137) and will still throw for the same malformed data. Consider applying the same pos>=0 check there too (or reusing GetUrlFromRoute) so malformed legacy routes can't crash other URL resolution paths.

Copilot uses AI. Check for mistakes.
@AndyButland
Copy link
Copy Markdown
Contributor

We have a PR raised for this issue already @justin-nevitech - see #22309

I left some feedback on that one, but I think the same would apply to your suggested approach too.

@justin-nevitech
Copy link
Copy Markdown
Contributor Author

Hi @AndyButland

Ok, I didn't realise there was already a PR as it wasn't linked to the issue. I will leave this then as it looks like @VargyasMoniLajos has responded to your suggestions.

@AndyButland
Copy link
Copy Markdown
Contributor

Yes, he's just updated so best now we progress that version. Thanks for the contribution though (normally a PR will link to an issue, so it's a bit more obvious if something is already underway).

@AndyButland AndyButland closed this Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Redirect URL Management crashes on malformed redirect route

4 participants