Ayende @ Rahien

Unnatural acts on source code

Is select (System.Uri) broken?

I can’t really figure out what is going on!

Take a look:

image

The value :

http://localhost:58080/indexes/categoriesByName?query=CategoryName%3ABeverages&start=0&pageSize=25

And the problem is that I can’t figure out why calling this once would fail, but calling it the second time would fail. That is leaving aside the fact this looks like a pretty good url to me.

Any ideas? This is perfectly reproducible on one project, but I can’t reproduce this on another project.

Updates:

  • This is System.Uri
  • The issue that it fails the first time, and works the second!
  • The exception is:
  • System.ArgumentNullException: Value cannot be null.
    Parameter name: str
       at System.Security.Permissions.FileIOPermission.HasIllegalCharacters(String[] str)
       at System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList)
       at System.Security.Permissions.FileIOPermission..ctor(FileIOPermissionAccess access, String path)
       at System.Uri.ParseConfigFile(String file, IdnScopeFromConfig& idnStateConfig, IriParsingFromConfig& iriParsingConfig)
       at System.Uri.GetConfig(UriIdnScope& idnScope, Boolean& iriParsing)
       at System.Uri.InitializeUriConfig()
       at System.Uri.InitializeUri(ParsingError err, UriKind uriKind, UriFormatException& e)
       at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
       at System.Uri..ctor(String uriString)
       at Raven.Scenarios.Scenario.GetUri_WorkaroundForStrangeBug(String uriString) in C:\Work\ravendb\Raven.Scenarios\Scenario.cs:line 155

  • This is a console application.

Okay, I can reproduce this now, here it how it got there:

public class Strange : MarshalByRefObject
{
    public void WTF()
    {
        Console.WriteLine(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
        new Uri("http://localhost:58080/indexes/categoriesByName?query=CategoryName%3ABeverages&start=0&pageSize=25");
    }
}

public class Program
{
    private static void Main()
    {
        var instanceAndUnwrap = (Strange) AppDomain.CreateDomain("test", null, new AppDomainSetup
        {
            ConfigurationFile = ""
        }).CreateInstanceAndUnwrap("ConsoleApplication5", "ConsoleApplication5.Strange");
        instanceAndUnwrap.WTF();
    }
}

That took some time to figure out.

The reason that I got this issue is that I am running this code as part of a unit test, and the xUnit seems to be running my system under the following conditions.

Comments

Matthijs ter Woord
03/04/2010 07:11 PM by
Matthijs ter Woord

Hi,

Any app.config settings involving system.net ?

Regards,

Matthijs ter Woord

Jan Willem B
03/04/2010 07:13 PM by
Jan Willem B

only thing I can think of is a race condition where uriString changes after the exception was already thrown.

Michael Stum
03/04/2010 07:13 PM by
Michael Stum
  • Is this really System.Uri, or possibly another class Uri in another namespace?

  • check the bytes of the uristring , is there maybe something that LOOKS like a :, /, & or = but really is some weird Unicode character?

  • What is the Exception?

  • Maybe use Reflector Pro, set a breakpoint on System.Uri.InitializeUri and check what exactly this does to your Uri?

Albert Weinert
03/04/2010 07:14 PM by
Albert Weinert

A : (%3A) is forbidden in an URI in ASP.NET up to 3.5.

In ASP.NET 4.0 you can allow it with some settings in web.config (forgot the name).

Ayende Rahien
03/04/2010 07:15 PM by
Ayende Rahien

Matthijs,

Nope.

And even if there was, why wouldn't it work on the second time around?

Ayende Rahien
03/04/2010 07:16 PM by
Ayende Rahien

timoconnell ,

Then why would it work the second time around?

And this is a console app

Diego Mijelshon
03/04/2010 07:16 PM by
Diego Mijelshon

Works here... but what's the exception?

Alex Simkin
03/04/2010 07:25 PM by
Alex Simkin

Yep. Works for me too. So, what's the exception?

Jan Willem B
03/04/2010 07:32 PM by
Jan Willem B

It has nothing to do with the Uri itself. With reflector you can see it tries to parse the app config file:

ParseConfigFile(Path.Combine(Path.Combine(runtimeDirectory, "Config"), "machine.config"), out config, out config3);

ParseConfigFile(appConfigFile, out config2, out config4);

So there seems to be an error in the config file, or in the path to the config file?

benek
03/04/2010 07:44 PM by
benek

I got only this error:

  • $exception {"Invalid URI: The Authority/Host could not be parsed."} System.Exception {System.UriFormatException}
Jacob
03/04/2010 07:55 PM by
Jacob

Jan's comment sparked an interesting hunt. Could it be that you have IRI (International Resource Identifier) turned on in the machine.config? In the help file for the Uri class, it mentions that doing so prompts the Uri class to check your config for whether or not to parse using IDN (Internationalized Domain Name) rules. If it is expecting to find the config element and isn't that could account for finding a null during the ParseConfigFile call reference by Jan.

Alex Simkin
03/04/2010 08:04 PM by
Alex Simkin

Now it is easy to explain why it works for the second time.

private static void InitializeUriConfig()

    { 

        if (!s_ConfigInitialized) { 

            lock(InitializeLock) {

                if (!s_ConfigInitialized) { 


                    // Set this first to avoid possible recursion

                    // if GetConfig's callees use Uri methods.

                    s_ConfigInitialized = true; 


                    GetConfig(ref s_IdnScope, ref s_IriParsing); 


                }

            } 

        }

    }

It only tries to parse config once.

timoconnell
03/04/2010 08:23 PM by
timoconnell

@Alex Simkin

Thanks for the follow up. You answered my question. Interesting that System.Uri dissambles to over 6000 lines!

timoconnell
03/04/2010 08:25 PM by
timoconnell

oops, disassembles ;)

Frank Quednau
03/04/2010 10:08 PM by
Frank Quednau

@timoconell

Wow...I just debugged into the class and it is extraordinarily huge! I never thought that making a Uri is that complicated...

Nick berardi
03/04/2010 10:30 PM by
Nick berardi

My bet is second one isn't making it past the compiler since the obj is never used. Also the error says you have an Illegal char in your config. Probably the new international section that specifies how to use Unicode in the URL. Check <idn section.

Tr&#226;̀n Hoàng Chương
03/05/2010 08:06 AM by
Trần Hoàng Chương

Hi,

If you blame for machine.config, you might be correct because I see that: when creating the instance of AppDomainSetup with not empty ConfigurationFile, the console is working well.

Harry Steinhilber
03/05/2010 12:48 PM by
Harry Steinhilber

@Nick

Actually the second call is actually being made. You can try assigning the instance to a var and printing it out, which works.

The issue, as Jan and Alex pointed out, is the lack of a config file for the AppDomain, but it is only checked once. Specifying any config file (even a non-existent one) will get rid of the error. But as xUnit is the one setting up the AppDomain in the original example, I don't think that is very useful information.

This does seem like a bug, though, since specifying a non-existent file can make the exception go away...

Comments have been closed on this topic.