public void Ctor_WithNoParameters_DefaultsToBasicLatin()
        {
            // Arrange
            UrlEncoder encoder = new UrlEncoder();

            // Act & assert
            Assert.Equal("a", encoder.UrlEncode("a"));
            Assert.Equal("%C3%A9", encoder.UrlEncode("\u00E9" /* LATIN SMALL LETTER E WITH ACUTE */));
            Assert.Equal("%E2%98%81", encoder.UrlEncode("\u2601" /* CLOUD */));
        }
        public void Ctor_WithUnicodeRanges()
        {
            // Arrange
            UrlEncoder encoder = new UrlEncoder(UnicodeRanges.Latin1Supplement, UnicodeRanges.MiscellaneousSymbols);

            // Act & assert
            Assert.Equal("%61", encoder.UrlEncode("a"));
            Assert.Equal("\u00E9", encoder.UrlEncode("\u00E9" /* LATIN SMALL LETTER E WITH ACUTE */));
            Assert.Equal("\u2601", encoder.UrlEncode("\u2601" /* CLOUD */));
        }
        public void GetUrlEncoder_ServiceProviderHasEncoder_ReturnsRegisteredInstance()
        {
            // Arrange
            var expectedEncoder = new UrlEncoder();
            var serviceProvider = new TestServiceProvider() { Service = expectedEncoder };

            // Act
            var retVal = serviceProvider.GetUrlEncoder();

            // Assert
            Assert.Same(expectedEncoder, retVal);
        }
        public void UrlEncode_PositiveTestCase()
        {
            // Arrange
            IUrlEncoder encoder = new UrlEncoder(UnicodeRanges.All);
            StringWriter writer = new StringWriter();

            // Act
            encoder.UrlEncode("Hello+there!", writer);

            // Assert
            Assert.Equal("Hello%2Bthere!", writer.ToString());
        }
Beispiel #5
0
        public void GetUrlEncoder_ServiceProviderHasEncoder_ReturnsRegisteredInstance()
        {
            // Arrange
            var expectedEncoder = new UrlEncoder();
            var serviceProvider = new TestServiceProvider()
            {
                Service = expectedEncoder
            };

            // Act
            var retVal = serviceProvider.GetUrlEncoder();

            // Assert
            Assert.Same(expectedEncoder, retVal);
        }
        public void UrlEncode_BadSurrogates_ReturnsUnicodeReplacementChar()
        {
            // Arrange
            UrlEncoder encoder = new UrlEncoder(UnicodeRanges.All); // allow all codepoints

            // "a<unpaired leading>b<unpaired trailing>c<trailing before leading>d<unpaired trailing><valid>e<high at end of string>"
            const string input    = "a\uD800b\uDFFFc\uDFFF\uD800d\uDFFF\uD800\uDFFFe\uD800";
            const string expected = "a%EF%BF%BDb%EF%BF%BDc%EF%BF%BD%EF%BF%BDd%EF%BF%BD%F0%90%8F%BFe%EF%BF%BD"; // 'D800' 'DFFF' was preserved since it's valid

            // Act
            string retVal = encoder.UrlEncode(input);

            // Assert
            Assert.Equal(expected, retVal);
        }
        public void Ctor_WithCodePointFilter()
        {
            // Arrange
            var filter = new CodePointFilter().AllowChars("ab").AllowChars('\0', '&', '\uFFFF', 'd');
            UrlEncoder encoder = new UrlEncoder(filter);

            // Act & assert
            Assert.Equal("a", encoder.UrlEncode("a"));
            Assert.Equal("b", encoder.UrlEncode("b"));
            Assert.Equal("%63", encoder.UrlEncode("c"));
            Assert.Equal("d", encoder.UrlEncode("d"));
            Assert.Equal("%00", encoder.UrlEncode("\0")); // we still always encode control chars
            Assert.Equal("%26", encoder.UrlEncode("&")); // we still always encode HTML-special chars
            Assert.Equal("%EF%BF%BF", encoder.UrlEncode("\uFFFF")); // we still always encode non-chars and other forbidden chars
        }
        public void Default_EquivalentToBasicLatin()
        {
            // Arrange
            UrlEncoder controlEncoder = new UrlEncoder(UnicodeRanges.BasicLatin);
            UrlEncoder testEncoder    = UrlEncoder.Default;

            // Act & assert
            for (int i = 0; i <= Char.MaxValue; i++)
            {
                if (!IsSurrogateCodePoint(i))
                {
                    string input = new String((char)i, 1);
                    Assert.Equal(controlEncoder.UrlEncode(input), testEncoder.UrlEncode(input));
                }
            }
        }
        public void Default_EquivalentToBasicLatin()
        {
            // Arrange
            UrlEncoder controlEncoder = new UrlEncoder(UnicodeRanges.BasicLatin);
            UrlEncoder testEncoder = UrlEncoder.Default;

            // Act & assert
            for (int i = 0; i <= Char.MaxValue; i++)
            {
                if (!IsSurrogateCodePoint(i))
                {
                    string input = new String((char)i, 1);
                    Assert.Equal(controlEncoder.UrlEncode(input), testEncoder.UrlEncode(input));
                }
            }
        }
        public void Ctor_WithTextEncoderSettings()
        {
            // Arrange
            var filter = new TextEncoderSettings();

            filter.AllowCharacters('a', 'b');
            filter.AllowCharacters('\0', '&', '\uFFFF', 'd');
            UrlEncoder encoder = new UrlEncoder(filter);

            // Act & assert
            Assert.Equal("a", encoder.UrlEncode("a"));
            Assert.Equal("b", encoder.UrlEncode("b"));
            Assert.Equal("%63", encoder.UrlEncode("c"));
            Assert.Equal("d", encoder.UrlEncode("d"));
            Assert.Equal("%00", encoder.UrlEncode("\0"));           // we still always encode control chars
            Assert.Equal("%26", encoder.UrlEncode("&"));            // we still always encode HTML-special chars
            Assert.Equal("%EF%BF%BF", encoder.UrlEncode("\uFFFF")); // we still always encode non-chars and other forbidden chars
        }
        public void UrlEncode_DoesNotOutputHtmlSensitiveCharacters()
        {
            // Per the design document, we provide additional defense-in-depth
            // by never emitting HTML-sensitive characters unescaped.

            // Arrange
            UrlEncoder  urlEncoder  = new UrlEncoder(UnicodeRanges.All);
            HtmlEncoder htmlEncoder = new HtmlEncoder(UnicodeRanges.All);

            // Act & assert
            for (int i = 0; i <= 0x10FFFF; i++)
            {
                if (IsSurrogateCodePoint(i))
                {
                    continue; // surrogates don't matter here
                }

                string urlEncoded      = urlEncoder.UrlEncode(Char.ConvertFromUtf32(i));
                string thenHtmlEncoded = htmlEncoder.HtmlEncode(urlEncoded);
                Assert.Equal(urlEncoded, thenHtmlEncoded); // should have contained no HTML-sensitive characters
            }
        }
        public void UrlEncode_AllRangesAllowed_StillEncodesForbiddenChars()
        {
            // Arrange
            UrlEncoder encoder = new UrlEncoder(UnicodeRanges.All);

            // Act & assert - BMP chars
            for (int i = 0; i <= 0xFFFF; i++)
            {
                string input = new String((char)i, 1);
                string expected;
                if (IsSurrogateCodePoint(i))
                {
                    expected = "%EF%BF%BD"; // unpaired surrogate -> Unicode replacement char
                }
                else
                {
                    bool mustEncode = true;

                    // RFC 3987, Sec. 2.2 gives the list of allowed chars
                    // (We allow 'ipchar' except for "'", "&", "+", "%", and "="
                    if (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z') || ('0' <= i && i <= '9'))
                    {
                        mustEncode = false; // ALPHA / DIGIT
                    }
                    else if ((0x00A0 <= i && i <= 0xD7FF) | (0xF900 <= i && i <= 0xFDCF) | (0xFDF0 <= i && i <= 0xFFEF))
                    {
                        mustEncode = !UnicodeHelpers.IsCharacterDefined((char)i); // 'ucschar'
                    }
                    else
                    {
                        switch (i)
                        {
                            // iunreserved
                            case '-':
                            case '.':
                            case '_':
                            case '~':

                            // isegment-nz-nc
                            case '@':

                            // sub-delims
                            case '!':
                            case '$':
                            case '(':
                            case ')':
                            case '*':
                            case ',':
                            case ';':
                                mustEncode = false;
                                break;
                        }
                    }

                    if (mustEncode)
                    {
                        expected = GetKnownGoodPercentEncodedValue(i);
                    }
                    else
                    {
                        expected = input; // no encoding
                    }
                }

                string retVal = encoder.UrlEncode(input);
                Assert.Equal(expected, retVal);
            }

            // Act & assert - astral chars
            for (int i = 0x10000; i <= 0x10FFFF; i++)
            {
                string input = Char.ConvertFromUtf32(i);
                string expected = GetKnownGoodPercentEncodedValue(i);
                string retVal = encoder.UrlEncode(input);
                Assert.Equal(expected, retVal);
            }
        }
        public void UrlEncode_AllRangesAllowed_StillEncodesForbiddenChars()
        {
            // Arrange
            UrlEncoder encoder = new UrlEncoder(UnicodeRanges.All);

            // Act & assert - BMP chars
            for (int i = 0; i <= 0xFFFF; i++)
            {
                string input = new String((char)i, 1);
                string expected;
                if (IsSurrogateCodePoint(i))
                {
                    expected = "%EF%BF%BD"; // unpaired surrogate -> Unicode replacement char
                }
                else
                {
                    bool mustEncode = true;

                    // RFC 3987, Sec. 2.2 gives the list of allowed chars
                    // (We allow 'ipchar' except for "'", "&", "+", "%", and "="
                    if (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z') || ('0' <= i && i <= '9'))
                    {
                        mustEncode = false; // ALPHA / DIGIT
                    }
                    else if ((0x00A0 <= i && i <= 0xD7FF) | (0xF900 <= i && i <= 0xFDCF) | (0xFDF0 <= i && i <= 0xFFEF))
                    {
                        mustEncode = !UnicodeHelpers.IsCharacterDefined((char)i); // 'ucschar'
                    }
                    else
                    {
                        switch (i)
                        {
                        // iunreserved
                        case '-':
                        case '.':
                        case '_':
                        case '~':

                        // isegment-nz-nc
                        case '@':

                        // sub-delims
                        case '!':
                        case '$':
                        case '(':
                        case ')':
                        case '*':
                        case ',':
                        case ';':
                            mustEncode = false;
                            break;
                        }
                    }

                    if (mustEncode)
                    {
                        expected = GetKnownGoodPercentEncodedValue(i);
                    }
                    else
                    {
                        expected = input; // no encoding
                    }
                }

                string retVal = encoder.UrlEncode(input);
                Assert.Equal(expected, retVal);
            }

            // Act & assert - astral chars
            for (int i = 0x10000; i <= 0x10FFFF; i++)
            {
                string input    = Char.ConvertFromUtf32(i);
                string expected = GetKnownGoodPercentEncodedValue(i);
                string retVal   = encoder.UrlEncode(input);
                Assert.Equal(expected, retVal);
            }
        }
Beispiel #14
0
        //        public static string ExternalUrlEncode(string url)
        //        {
        //            // Don't do the redirect anymore.  We were doing it to track external link clicks.
        //            //return ConfigurationManager.AppSettings["SiteUrl"] + "Redirect/" + url;
        //            return "http://" + url;
        //        }
        public static string UrlEncode(string url)
        {
            string newUrl;

            // Change front slashes with spaces to spaces.
            newUrl = url.Replace(@" / ", " ");

            // Change spaces into hyphens.
            newUrl = newUrl.Replace(" ", "-");

            // Change double quotes to blanks.
            newUrl = newUrl.Replace(@"""", "");

            // Change single quotes to blanks.
            newUrl = newUrl.Replace(@"'", "");

            // Change commas to blanks
            newUrl = newUrl.Replace(@",", "");

            // Change front slashes to blanks.
            newUrl = newUrl.Replace(@"/", "");

            // Change parentheses to blanks.
            newUrl = newUrl.Replace(@"(", "");
            newUrl = newUrl.Replace(@")", "");

            // Change percent signs to blanks.
            newUrl = newUrl.Replace(@"%", "");

            // Change ampersands to blanks.
            newUrl = newUrl.Replace(@"&", "");

            // Change question marksersands to blanks.
            newUrl = newUrl.Replace(@"&", "");

            // Change periods to blanks.
            newUrl = newUrl.Replace(@".", "");

            // Change ’ to blanks
            newUrl = newUrl.Replace(@"’", "");

            // Change ä to a
            newUrl = newUrl.Replace(@"ä", "a");

            // Change é to e
            newUrl = newUrl.Replace(@"é", "e");

            // Change è to e
            newUrl = newUrl.Replace(@"è", "e");

            // Change í to i
            newUrl = newUrl.Replace(@"í", "i");

            // Change ñ to n
            newUrl = newUrl.Replace(@"ñ", "n");

            // Change ó to o
            newUrl = newUrl.Replace(@"ó", "o");

            // Change ö to o
            newUrl = newUrl.Replace(@"ö", "o");

            // Change ú to u
            newUrl = newUrl.Replace(@"ú", "u");

            // Then UrlEncode the rest with the .NET method.
            newUrl = new UrlEncoder().UrlEncode(newUrl);

            // Lowercase
            newUrl = newUrl.ToLower();

            return newUrl;
        }
        public void UrlEncode_EmptyStringInput_ReturnsEmptyString()
        {
            // Arrange
            UrlEncoder encoder = new UrlEncoder();

            // Act & assert
            Assert.Equal("", encoder.UrlEncode(""));
        }
Beispiel #16
0
 [MethodImpl(MethodImplOptions.NoInlining)] // the JITter can attempt to inline the caller itself without worrying about us
 private static UrlEncoder CreateDefaultEncoderSlow()
 {
     var onDemandEncoder = new UrlEncoder();
     return Interlocked.CompareExchange(ref _defaultEncoder, onDemandEncoder, null) ?? onDemandEncoder;
 }
        public void UrlEncode_InputDoesNotRequireEncoding_ReturnsOriginalStringInstance()
        {
            // Arrange
            UrlEncoder encoder = new UrlEncoder();
            string input = "Hello,there!";

            // Act & assert
            Assert.Same(input, encoder.UrlEncode(input));
        }
        public void UrlEncode_NullInput_ReturnsNull()
        {
            // Arrange
            UrlEncoder encoder = new UrlEncoder();

            // Act & assert
            Assert.Null(encoder.UrlEncode(null));
        }
        public void UrlEncode_DoesNotOutputHtmlSensitiveCharacters()
        {
            // Per the design document, we provide additional defense-in-depth
            // by never emitting HTML-sensitive characters unescaped.

            // Arrange
            UrlEncoder urlEncoder = new UrlEncoder(UnicodeRanges.All);
            HtmlEncoder htmlEncoder = new HtmlEncoder(UnicodeRanges.All);

            // Act & assert
            for (int i = 0; i <= 0x10FFFF; i++)
            {
                if (IsSurrogateCodePoint(i))
                {
                    continue; // surrogates don't matter here
                }

                string urlEncoded = urlEncoder.UrlEncode(Char.ConvertFromUtf32(i));
                string thenHtmlEncoded = htmlEncoder.HtmlEncode(urlEncoded);
                Assert.Equal(urlEncoded, thenHtmlEncoded); // should have contained no HTML-sensitive characters
            }
        }
        public void UrlEncode_StringSubstring()
        {
            // Arrange
            UrlEncoder encoder = new UrlEncoder();
            var output = new StringWriter();

            // Act
            encoder.UrlEncode("Hello+world!", 3, 5, output);

            // Assert
            Assert.Equal("lo%2Bwo", output.ToString());
        }
Beispiel #21
0
        [MethodImpl(MethodImplOptions.NoInlining)] // the JITter can attempt to inline the caller itself without worrying about us
        private static UrlEncoder CreateDefaultEncoderSlow()
        {
            var onDemandEncoder = new UrlEncoder();

            return(Interlocked.CompareExchange(ref _defaultEncoder, onDemandEncoder, null) ?? onDemandEncoder);
        }
        public void UrlEncode_BadSurrogates_ReturnsUnicodeReplacementChar()
        {
            // Arrange
            UrlEncoder encoder = new UrlEncoder(UnicodeRanges.All); // allow all codepoints

            // "a<unpaired leading>b<unpaired trailing>c<trailing before leading>d<unpaired trailing><valid>e<high at end of string>"
            const string input = "a\uD800b\uDFFFc\uDFFF\uD800d\uDFFF\uD800\uDFFFe\uD800";
            const string expected = "a%EF%BF%BDb%EF%BF%BDc%EF%BF%BD%EF%BF%BDd%EF%BF%BD%F0%90%8F%BFe%EF%BF%BD"; // 'D800' 'DFFF' was preserved since it's valid

            // Act
            string retVal = encoder.UrlEncode(input);

            // Assert
            Assert.Equal(expected, retVal);
        }