diff --git a/src/mindtouch.dream/dream/XUri.cs b/src/mindtouch.dream/dream/XUri.cs index cdb3877..924d8eb 100644 --- a/src/mindtouch.dream/dream/XUri.cs +++ b/src/mindtouch.dream/dream/XUri.cs @@ -976,6 +976,12 @@ public sealed class XUri : ISerializable { /// Input uri. public XUri(Uri uri) : this(uri.OriginalString) { } + /// + /// Create a new XUri from an existing XUri + /// + /// Input uri. + public XUri(XUri uri) : this(uri.Scheme, uri.User, uri.Password, uri.Host, uri.Port, uri.UsesDefaultPort, uri.Segments, uri.TrailingSlash, uri.Params, uri.Fragment, uri.UsesSegmentDoubleEncoding) { } + /// /// Create a new XUri from serialized form. /// diff --git a/src/tests/DreamMisc/XUri-Test.cs b/src/tests/DreamMisc/XUri-Test.cs index 2f56cbc..c3619d5 100644 --- a/src/tests/DreamMisc/XUri-Test.cs +++ b/src/tests/DreamMisc/XUri-Test.cs @@ -531,6 +531,23 @@ public class XUriTest { } } + [Test] + public void TestXUriFromUriConstruction2() { + string[] evilSegments = new string[] { + + // Escaped version of "Iñtërnâtiônàlizætiøn" (should look similar to "Internationalization" but with extended characteres) + "I\u00f1t\u00ebrn\u00e2ti\u00f4n\u00e0liz\u00e6ti\u00f8n", + "A%4b" + }; + foreach(string evil in evilSegments) { + XUri original = new XUri("http://" + evil); + XUri fromDecoded = new XUri(original.ToString()); + XUri uri1 = new XUri(original); + XUri uri2 = new XUri(fromDecoded); + // just making sure they actually parse + } + } + [Test] public void Decode_extended_chars1() { const string before = "F\u00F4\u00F6";