Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Uri.TryCreate throws NRE when url contains Turkish character?

I have encountered an interesting situation where I get NRE from Uri.TryCreate method when it's supposed to return false.

You can reproduce the issue like below:

Uri url;
if (Uri.TryCreate("http:Ç", UriKind.RelativeOrAbsolute, out url))
{
    Console.WriteLine("success");
}

I guess it's failing during the parse, but when I try "http:A" for example, it returns true and parses it as relative url. Even if fails on parse it should just return false as I understand, what could be the problem here? This seems like a bug in the implementation cause documentation doesn't mention about any exception on this method.

The error occurs in .NET 4.6.1 but not 4.0

like image 664
Selman Genç Avatar asked Jun 17 '16 12:06

Selman Genç


People also ask

What is UriKind absolute?

UriKind.Absolute: Absolute URIs are Complete url, which start with protocol name Example: new Uri("http://www.testdomain.com/index.html ", UriKind.Absolute)

What is Uri TryCreate?

TryCreate(Uri, Uri, Uri) Creates a new Uri using the specified base and relative Uri instances. TryCreate(String, UriKind, Uri) Creates a new Uri using the specified String instance and a UriKind.


1 Answers

This is a bug in the .NET framework. You can open a ticket on MicrosoftConnect.

The exception will be raised in this method

void Systen.Uri.CreateUriInfo(System.Uri.Flags cF)

on line 2290 (inspect the reference source) executing following statement:

// This is NOT an ImplicitFile uri
idx = (ushort)m_Syntax.SchemeName.Length;

At this time, the m_Syntax object will be null, because during parsing, it will be discarded.

Method

void InitializeUri(ParsingError err, UriKind uriKind, out UriFormatException e)

line 121:

if (m_Syntax.IsSimple)
{
    if ((err = PrivateParseMinimal()) != ParsingError.None)
    {
        if (uriKind != UriKind.Absolute && err <= ParsingError.LastRelativeUriOkErrIndex)
        {
            // RFC 3986 Section 5.4.2 - http:(relativeUri) may be considered a valid relative Uri.
            m_Syntax = null; // convert to relative uri
            e = null;
            m_Flags &= Flags.UserEscaped; // the only flag that makes sense for a relative uri
         }
         // ...
     }
    // ...
 }

The PrivateParseMinimal() method returns ParsingError.BadAuthority and uriKind == UriKind.RelativeOrAbsolute by your specification.

The PrivateParseMinimal() method looks for any of the following character sequences: "//", "\", "/\", "/". And since there are no such sequences in your input string, a ParsingError.BadAuthority code will be returned.

like image 159
dymanoid Avatar answered Oct 05 '22 04:10

dymanoid