예제 #1
0
        /// <summary>
        /// Emits a valid XML local-name (i.e. encodes invalid chars including ':')
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="value"></param>
        /// <remarks>
        /// Explicitly escaping ':' to maintain compatibility with XML Namespaces.
        /// From XML 1.0, 5th ed. http://www.w3.org/TR/xml/#sec-common-syn
        ///		Name			= NameStartChar (NameChar)*
        ///		NameStartChar	= ":"
        ///						| [A-Z]
        ///						| "_"
        ///						| [a-z]
        ///						| [#xC0-#xD6]
        ///						| [#xD8-#xF6]
        ///						| [#xF8-#x2FF]
        ///						| [#x370-#x37D]
        ///						| [#x37F-#x1FFF]
        ///						| [#x200C-#x200D]
        ///						| [#x2070-#x218F]
        ///						| [#x2C00-#x2FEF]
        ///						| [#x3001-#xD7FF]
        ///						| [#xF900-#xFDCF]
        ///						| [#xFDF0-#xFFFD]
        ///						| [#x10000-#xEFFFF]
        ///		NameChar		= NameStartChar
        ///						| "-"
        ///						| "."
        ///						| [0-9]
        ///						| #xB7
        ///						| [#x0300-#x036F]
        ///						| [#x203F-#x2040]
        /// </remarks>
        private void WriteLocalName(TextWriter writer, string value)
        {
            int start  = 0,
                length = value.Length;

            for (int i = start; i < length; i++)
            {
                char ch = value[i];

                if ((ch >= 'a' && ch <= 'z') ||
                    (ch >= 'A' && ch <= 'Z') ||
                    (ch == '_') ||
                    (ch >= '\u00C0' && ch <= '\u00D6') ||
                    (ch >= '\u00D8' && ch <= '\u00F6') ||
                    (ch >= '\u00F8' && ch <= '\u02FF') ||
                    (ch >= '\u0370' && ch <= '\u037D') ||
                    (ch >= '\u037F' && ch <= '\u1FFF') ||
                    (ch >= '\u200C' && ch <= '\u200D') ||
                    (ch >= '\u2070' && ch <= '\u218F') ||
                    (ch >= '\u2C00' && ch <= '\u2FEF') ||
                    (ch >= '\u3001' && ch <= '\uD7FF') ||
                    (ch >= '\uF900' && ch <= '\uFDCF') ||
                    (ch >= '\uFDF0' && ch <= '\uFFFD'))
                {
                    // purposefully leaving out ':' to implement namespace prefixes
                    // and cannot represent [#x10000-#xEFFFF] as single char so this will incorrectly escape
                    continue;
                }

                if ((i > 0) &&
                    ((ch >= '0' && ch <= '9') ||
                     (ch == '-') ||
                     (ch == '.') ||
                     (ch == '\u00B7') ||
                     (ch >= '\u0300' && ch <= '\u036F') ||
                     (ch >= '\u203F' && ch <= '\u2040')))
                {
                    // these chars are only valid after initial char
                    continue;
                }

                if (i > start)
                {
                    // copy any leading unescaped chunk
                    writer.Write(value.Substring(start, i - start));
                }
                start = i + 1;

                // use XmlSerializer-hex-style encoding of UTF-16
                writer.Write("_x");
                writer.Write(CharUtility.ConvertToUtf32(value, i).ToString("X4"));
                writer.Write("_");
            }

            if (length > start)
            {
                // copy any trailing unescaped chunk
                writer.Write(value.Substring(start, length - start));
            }
        }
예제 #2
0
        private static void HtmlAttributeEncode(TextWriter writer, string value, bool encodeNonAscii, bool canonicalForm)
        {
            if (String.IsNullOrEmpty(value))
            {
                return;
            }

            int start  = 0,
                length = value.Length;

            for (int i = start; i < length; i++)
            {
                char ch = value[i];

                string entity;
                switch (ch)
                {
                case '<':
                {
                    entity = "&lt;";
                    break;
                }

                case '>':
                {
                    if (canonicalForm)
                    {
                        // http://www.w3.org/TR/xml-c14n#ProcessingModel
                        continue;
                    }

                    entity = "&gt;";
                    break;
                }

                case '&':
                {
                    entity = "&amp;";
                    break;
                }

                case '"':
                {
                    entity = "&quot;";
                    break;
                }

                case '\'':
                {
                    if (!canonicalForm)
                    {
                        continue;
                    }

                    // http://www.w3.org/TR/xml-c14n#ProcessingModel
                    entity = "&apos;";
                    break;
                }

                default:
                {
                    if ((ch < ' ') ||
                        (encodeNonAscii && (ch >= 0x7F)) ||
                        ((ch >= 0x7F) && (ch <= 0x84)) ||
                        ((ch >= 0x86) && (ch <= 0x9F)) ||
                        ((ch >= 0xFDD0) && (ch <= 0xFDEF)))
                    {
                        // encode all control chars: http://www.w3.org/TR/xml/#charsets
                        int utf16 = CharUtility.ConvertToUtf32(value, i);
                        entity = String.Concat("&#x", utf16.ToString("X", CultureInfo.InvariantCulture), ';');
                        break;
                    }
                    continue;
                }
                }

                if (i > start)
                {
                    // copy any leading unescaped chunk
                    writer.Write(value.Substring(start, i - start));
                }
                start = i + 1;

                // use XML named entity
                writer.Write(entity);
            }

            if (length > start)
            {
                // copy any trailing unescaped chunk
                writer.Write(value.Substring(start, length - start));
            }
        }
예제 #3
0
        private static void HtmlEncode(TextWriter writer, string value, bool encodeNonAscii, bool canonicalForm)
        {
            int start  = 0,
                length = value.Length;

            for (int i = start; i < length; i++)
            {
                char ch = value[i];

                string entity;
                switch (ch)
                {
                case '<':
                {
                    entity = "&lt;";
                    break;
                }

                case '>':
                {
                    entity = "&gt;";
                    break;
                }

                case '&':
                {
                    entity = "&amp;";
                    break;
                }

                case '\r':
                {
                    if (!canonicalForm)
                    {
                        continue;
                    }

                    // Line breaks normalized to '\n'
                    // http://www.w3.org/TR/xml-c14n#Terminology
                    entity = String.Empty;
                    break;
                }

                default:
                {
                    if (((ch < ' ') && (ch != '\n') && (ch != '\t')) ||
                        (encodeNonAscii && (ch >= 0x7F)) ||
                        ((ch >= 0x7F) && (ch <= 0x84)) ||
                        ((ch >= 0x86) && (ch <= 0x9F)) ||
                        ((ch >= 0xFDD0) && (ch <= 0xFDEF)))
                    {
                        // encode all control chars except CRLF/Tab: http://www.w3.org/TR/xml/#charsets
                        int utf16 = CharUtility.ConvertToUtf32(value, i);
                        entity = String.Concat("&#x", utf16.ToString("X", CultureInfo.InvariantCulture), ';');
                        break;
                    }
                    continue;
                }
                }

                if (i > start)
                {
                    // copy any leading unescaped chunk
                    writer.Write(value.Substring(start, i - start));
                }
                start = i + 1;

                // emit XML entity
                writer.Write(entity);
            }

            if (length > start)
            {
                // copy any trailing unescaped chunk
                writer.Write(value.Substring(start, length - start));
            }
        }
예제 #4
0
            protected virtual void WriteString(TextWriter writer, string value)
            {
                int start  = 0,
                    length = value.Length;

                writer.Write(JsonGrammar.OperatorStringDelim);

                for (int i = start; i < length; i++)
                {
                    char ch = value[i];

                    if (ch <= '\u001F' ||
                        ch >= '\u007F' ||
                        (this.encodeLessThan && ch == '<') ||                         // improves compatibility within script blocks
                        ch == JsonGrammar.OperatorStringDelim ||
                        ch == JsonGrammar.OperatorCharEscape)
                    {
                        if (i > start)
                        {
                            writer.Write(value.Substring(start, i - start));
                        }
                        start = i + 1;

                        switch (ch)
                        {
                        case JsonGrammar.OperatorStringDelim:
                        case JsonGrammar.OperatorCharEscape:
                        {
                            writer.Write(JsonGrammar.OperatorCharEscape);
                            writer.Write(ch);
                            continue;
                        }

                        case '\b':
                        {
                            writer.Write("\\b");
                            continue;
                        }

                        case '\f':
                        {
                            writer.Write("\\f");
                            continue;
                        }

                        case '\n':
                        {
                            writer.Write("\\n");
                            continue;
                        }

                        case '\r':
                        {
                            writer.Write("\\r");
                            continue;
                        }

                        case '\t':
                        {
                            writer.Write("\\t");
                            continue;
                        }

                        default:
                        {
                            writer.Write("\\u");
                            writer.Write(CharUtility.ConvertToUtf32(value, i).ToString("X4"));
                            continue;
                        }
                        }
                    }
                }

                if (length > start)
                {
                    writer.Write(value.Substring(start, length - start));
                }

                writer.Write(JsonGrammar.OperatorStringDelim);
            }