Skip to content

[Breaking change]: Combined Uri breaking changes for .NET 11 #55744

Description

@MihaZupan

Description

We've made a handful of minor breaking changes to Uri in .NET 11, I'm merging them as one issue since they're all rather niche.

PRs:

Version

.NET 11 GA

Previous behavior

  1. A Uri string without a delimiter between an IPv6 address and the path, such as "http://[::]extra", would be parsed the same if it had a delimiter "http://[::]/extra".
  2. The UriBuilder.Host setter allowed values such as "contoso.com/path", potentially altering other Uri components after the builder combined values together via ToString/Uri.
  3. Uri allowed parsing of IPv6 length prefixes, such as the "/64" in "http://[AB::/64]/path".
  4. Uri allowed an octal value in the last segment of an IPv4 address embedded in IPv6. E.g. "http://[::1.2.3.04]/" would be parsed while "http://[::1.2.03.4]/" would be rejected.
  5. There was an inconsistency between how new Uri("p%41th", UriKind.Relative) and Uri.TryCreate("p%41th", UriKind.Relative, out uri) behaved. The constructor would normalize the input to "pAth", while the TryCreate factory would leave it as-is.

New behavior

  1. Parsing will enforce that a delimiter is present after an IPv6 address. Parsing "http://[::]extra" now fails.
  2. The UriBuilder.Host setter now performs best-effort validation and rejects inputs that would alter other components. Setting the property to a value such as "contoso.com/path" or "user@host" now throws. Some other invalid inputs are now also caught early, such as some forms of invalid IPv6 addresses, e.g. "[127.0.0.1]". It is still possible that constructing the combined Uri will throw an exception for an invalid host even if the UriBuilder.Host property setter did not throw.
  3. If a IPv6 length prefix is present in the input, Uri parsing will now fail. The set of characters allowed in the zone ID (scope) is also more restricted.
  4. Octal values are now rejected in any position of an embedded IPv4 address. Parsing "http://[::1.2.3.04]/" will now fail.
  5. Normalization applied by new Uri(value, UriKind.Relative) and Uri.TryCreate(value, UriKind.Relative, out uri) is now the same. Processing "p%41th" through either will normalize the value to "pAth".

Type of breaking change

  • Binary incompatible: Existing binaries might encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
  • Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code might require source changes to compile successfully.
  • Behavioral change: Existing binaries might behave differently at run time.

Reason for change

Stricter adherence to the Uri spec and reducing parsing inconsistencies.

For more details about the design and security considerations of Uri and UriBuilder, review the following threat model documents:

Recommended action

It is unlikely that any changes should be made by your application code as a response to these changes.

If you are currently relying on setting multiple Uri components through the UriBuilder.Host setter, change the application logic to set individual components instead.

Feature area

Networking

Affected APIs

All Uri constructors / TryCreate factories + UriBuilder.Host.


Associated WorkItem - 628409

Metadata

Metadata

Assignees

Labels

📌 seQUESTeredIdentifies that an issue has been imported into Quest.breaking-changeIndicates a .NET Core breaking change

Type

No type

Projects

Status
🔖 Ready

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions