public void ForbidUndefinedCharacters_RemovesUndefinedChars()
        {
            // Arrange
            // We only allow odd-numbered characters in this test so that
            // we can validate that we properly merged the two bitmaps together
            // rather than simply overwriting the target.
            var bitmap = AllowedCharsBitmap.CreateNew();

            for (int i = 1; i <= Char.MaxValue; i += 2)
            {
                bitmap.AllowCharacter((char)i);
            }

            // Act
            bitmap.ForbidUndefinedCharacters();

            // Assert
            for (int i = 0; i <= Char.MaxValue; i++)
            {
                if (i % 2 == 0)
                {
                    Assert.False(bitmap.IsCharacterAllowed((char)i)); // these chars were never allowed in the original description
                }
                else
                {
                    Assert.Equal(UnicodeHelpers.IsCharacterDefined((char)i), bitmap.IsCharacterAllowed((char)i));
                }
            }
        }
Example #2
0
        public void IsCharacterDefined()
        {
            // Arrange
            bool[]        definedChars = ReadListOfDefinedCharacters();
            List <string> errors       = new List <string>();

            // Act & assert
            for (int i = 0; i <= Char.MaxValue; i++)
            {
                bool expected = definedChars[i];
                bool actual   = UnicodeHelpers.IsCharacterDefined((char)i);
                if (expected != actual)
                {
                    errors.Add($"Character U+{i:X4}: expected = {expected}, actual = {actual}");
                }
            }

            if (errors.Count > 0)
            {
                Assert.True(false, String.Join(Environment.NewLine, errors));
            }
        }
        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);
            }
        }
Example #4
0
        public void JavaScriptStringEncode_AllRangesAllowed_StillEncodesForbiddenChars_Extended()
        {
            // Arrange
            JavaScriptStringEncoder encoder = new JavaScriptStringEncoder(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 = "\uFFFD"; // unpaired surrogate -> Unicode replacement char
                }
                else
                {
                    if (input == "\b")
                    {
                        expected = @"\b";
                    }
                    else if (input == "\t")
                    {
                        expected = @"\t";
                    }
                    else if (input == "\n")
                    {
                        expected = @"\n";
                    }
                    else if (input == "\f")
                    {
                        expected = @"\f";
                    }
                    else if (input == "\r")
                    {
                        expected = @"\r";
                    }
                    else if (input == "\\")
                    {
                        expected = @"\\";
                    }
                    else if (input == "/")
                    {
                        expected = @"\/";
                    }
                    else
                    {
                        bool mustEncode = false;
                        switch (i)
                        {
                        case '<':
                        case '>':
                        case '&':
                        case '\"':
                        case '\'':
                        case '+':
                            mustEncode = true;
                            break;
                        }

                        if (i <= 0x001F || (0x007F <= i && i <= 0x9F))
                        {
                            mustEncode = true; // control char
                        }
                        else if (!UnicodeHelpers.IsCharacterDefined((char)i))
                        {
                            mustEncode = true; // undefined (or otherwise disallowed) char
                        }

                        if (mustEncode)
                        {
                            expected = String.Format(CultureInfo.InvariantCulture, @"\u{0:X4}", i);
                        }
                        else
                        {
                            expected = input; // no encoding
                        }
                    }
                }

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

            // Act & assert - astral chars
            for (int i = 0x10000; i <= 0x10FFFF; i++)
            {
                string input    = Char.ConvertFromUtf32(i);
                string expected = String.Format(CultureInfo.InvariantCulture, @"\u{0:X4}\u{1:X4}", (uint)input[0], (uint)input[1]);
                string retVal   = encoder.JavaScriptStringEncode(input);
                Assert.Equal(expected, retVal);
            }
        }
        public void HtmlEncode_AllRangesAllowed_StillEncodesForbiddenChars_Extended()
        {
            // Arrange
            HtmlEncoder encoder = new HtmlEncoder(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 = "\uFFFD"; // unpaired surrogate -> Unicode replacement char
                }
                else
                {
                    if (input == "<")
                    {
                        expected = "&lt;";
                    }
                    else if (input == ">")
                    {
                        expected = "&gt;";
                    }
                    else if (input == "&")
                    {
                        expected = "&amp;";
                    }
                    else if (input == "\"")
                    {
                        expected = "&quot;";
                    }
                    else
                    {
                        bool mustEncode = false;
                        if (i == '\'' || i == '+')
                        {
                            mustEncode = true; // apostrophe, plus
                        }
                        else if (i <= 0x001F || (0x007F <= i && i <= 0x9F))
                        {
                            mustEncode = true; // control char
                        }
                        else if (!UnicodeHelpers.IsCharacterDefined((char)i))
                        {
                            mustEncode = true; // undefined (or otherwise disallowed) char
                        }

                        if (mustEncode)
                        {
                            expected = String.Format(CultureInfo.InvariantCulture, "&#x{0:X};", i);
                        }
                        else
                        {
                            expected = input; // no encoding
                        }
                    }
                }

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

            // Act & assert - astral chars
            for (int i = 0x10000; i <= 0x10FFFF; i++)
            {
                string input    = Char.ConvertFromUtf32(i);
                string expected = String.Format(CultureInfo.InvariantCulture, "&#x{0:X};", i);
                string retVal   = encoder.HtmlEncode(input);
                Assert.Equal(expected, retVal);
            }
        }