Examples

Current Articles | Categories | Search

By Jonathan Kehayias @ Monday, July 21, 2008 10:30 AM :: 2951 Views :: 1 Comments

I have seen a number of posts on various forums regarding issues with loading the System.Web assembly as Unsafe in SQL Server so that the HttpUtility.HtmlEncode/HtmlDecode method can be used to encode/decode an input for usage. The following function can be cataloged as SAFE in SQL Server and does exactly the same things that the Method in System.Web does for the HtmlDecode.

 

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Globalization;
using System.Text;
using System.IO;
using System.Collections;
 
public partial class UserDefinedFunctions
{
    private static readonly char[] s_entityEndingChars = new char[] { ';', '&' };
 
    [Microsoft.SqlServer.Server.SqlFunction]
    public static string HtmlDecoder(string s)
    {
        if (s == null)
        {
            return null;
        }
        if (s.IndexOf('&') < 0)
        {
            return s;
        }
        StringBuilder sb = new StringBuilder();
        StringWriter output = new StringWriter(sb);
        HtmlDecode(s, output);
        return sb.ToString();
    }
 
    public static void HtmlDecode(string s, TextWriter output)
    {
        if (s != null)
        {
            if (s.IndexOf('&') < 0)
            {
                output.Write(s);
            }
            else
            {
                int length = s.Length;
                for (int i = 0; i < length; i++)
                {
                    char ch = s[i];
                    if (ch == '&')
                    {
                        int num3 = s.IndexOfAny(s_entityEndingChars, i + 1);
                        if ((num3 > 0) && (s[num3] == ';'))
                        {
                            string entity = s.Substring(i + 1, (num3 - i) - 1);
                            if ((entity.Length > 1) && (entity[0] == '#'))
                            {
                                try
                                {
                                    if ((entity[1] == 'x') || (entity[1] == 'X'))
                                    {
                                        ch = (char)int.Parse(entity.Substring(2), NumberStyles.AllowHexSpecifier);
                                    }
                                    else
                                    {
                                        ch = (char)int.Parse(entity.Substring(1));
                                    }
                                    i = num3;
                                }
                                catch (FormatException)
                                {
                                    i++;
                                }
                                catch (ArgumentException)
                                {
                                    i++;
                                }
                            }
                            else
                            {
                                i = num3;
                                char ch2 = HtmlEntities.Lookup(entity);
                                if (ch2 != '\0')
                                {
                                    ch = ch2;
                                }
                                else
                                {
                                    output.Write('&');
                                    output.Write(entity);
                                    output.Write(';');
                                    goto Label_0103;
                                }
                            }
                        }
                    }
                    output.Write(ch);
                Label_0103: ;
                }
            }
        }
    }
 
    public class HtmlEntities
    {
        private static readonly string[] _entitiesList = new string[] {
            "\"-quot", "&-amp", "<-lt", ">-gt", "\x00a0-nbsp", "\x00a1-iexcl", "\x00a2-cent", "\x00a3-pound", "\x00a4-curren", "\x00a5-yen", "\x00a6-brvbar", "\x00a7-sect", "\x00a8-uml", "\x00a9-copy", "\x00aa-ordf", "\x00ab-laquo",
            "\x00ac-not", "\x00ad-shy", "\x00ae-reg", "\x00af-macr", "\x00b0-deg", "\x00b1-plusmn", "\x00b2-sup2", "\x00b3-sup3", "\x00b4-acute", "\x00b5-micro", "\x00b6-para", "\x00b7-middot", "\x00b8-cedil", "\x00b9-sup1", "\x00ba-ordm", "\x00bb-raquo",
            "\x00bc-frac14", "\x00bd-frac12", "\x00be-frac34", "\x00bf-iquest", "\x00c0-Agrave", "\x00c1-Aacute", "\x00c2-Acirc", "\x00c3-Atilde", "\x00c4-Auml", "\x00c5-Aring", "\x00c6-AElig", "\x00c7-Ccedil", "\x00c8-Egrave", "\x00c9-Eacute", "\x00ca-Ecirc", "\x00cb-Euml",
            "\x00cc-Igrave", "\x00cd-Iacute", "\x00ce-Icirc", "\x00cf-Iuml", "\x00d0-ETH", "\x00d1-Ntilde", "\x00d2-Ograve", "\x00d3-Oacute", "\x00d4-Ocirc", "\x00d5-Otilde", "\x00d6-Ouml", "\x00d7-times", "\x00d8-Oslash", "\x00d9-Ugrave", "\x00da-Uacute", "\x00db-Ucirc",
            "\x00dc-Uuml", "\x00dd-Yacute", "\x00de-THORN", "\x00df-szlig", "\x00e0-agrave", "\x00e1-aacute", "\x00e2-acirc", "\x00e3-atilde", "\x00e4-auml", "\x00e5-aring", "\x00e6-aelig", "\x00e7-ccedil", "\x00e8-egrave", "\x00e9-eacute", "\x00ea-ecirc", "\x00eb-euml",
            "\x00ec-igrave", "\x00ed-iacute", "\x00ee-icirc", "\x00ef-iuml", "\x00f0-eth", "\x00f1-ntilde", "\x00f2-ograve", "\x00f3-oacute", "\x00f4-ocirc", "\x00f5-otilde", "\x00f6-ouml", "\x00f7-divide", "\x00f8-oslash", "\x00f9-ugrave", "\x00fa-uacute", "\x00fb-ucirc",
            "\x00fc-uuml", "\x00fd-yacute", "\x00fe-thorn", "\x00ff-yuml", "Œ-OElig", "œ-oelig", "Š-Scaron", "š-scaron", "Ÿ-Yuml", "ƒ-fnof", "ˆ-circ", "˜-tilde", "Α-Alpha", "Β-Beta", "Γ-Gamma", "Δ-Delta",
            "Ε-Epsilon", "Ζ-Zeta", "Η-Eta", "Θ-Theta", "Ι-Iota", "Κ-Kappa", "Λ-Lambda", "Μ-Mu", "Ν-Nu", "Ξ-Xi", "Ο-Omicron", "Π-Pi", "Ρ-Rho", "Σ-Sigma", "Τ-Tau", "Υ-Upsilon",
            "Φ-Phi", "Χ-Chi", "Ψ-Psi", "Ω-Omega", "α-alpha", "β-beta", "γ-gamma", "δ-delta", "ε-epsilon", "ζ-zeta", "η-eta", "θ-theta", "ι-iota", "κ-kappa", "λ-lambda", "μ-mu",
            "ν-nu", "ξ-xi", "ο-omicron", "π-pi", "ρ-rho", "ς-sigmaf", "σ-sigma", "τ-tau", "υ-upsilon", "φ-phi", "χ-chi", "ψ-psi", "ω-omega", "ϑ-thetasym", "ϒ-upsih", "ϖ-piv",
            " -ensp", " -emsp", " -thinsp", "‌-zwnj", "‍-zwj", "‎-lrm", "‏-rlm", "–-ndash", "—-mdash", "‘-lsquo", "’-rsquo", "‚-sbquo", "“-ldquo", "”-rdquo", "„-bdquo", "†-dagger",
            "‡-Dagger", "•-bull", "…-hellip", "‰-permil", "′-prime", "″-Prime", "‹-lsaquo", "›-rsaquo", "‾-oline", "⁄-frasl", "€-euro", "ℑ-image", "℘-weierp", "ℜ-real", "™-trade", "ℵ-alefsym",
            "←-larr", "↑-uarr", "→-rarr", "↓-darr", "↔-harr", "↵-crarr", "⇐-lArr", "⇑-uArr", "⇒-rArr", "⇓-dArr", "⇔-hArr", "∀-forall", "∂-part", "∃-exist", "∅-empty", "∇-nabla",
            "∈-isin", "∉-notin", "∋-ni", "∏-prod", "∑-sum", "−-minus", "∗-lowast", "√-radic", "∝-prop", "∞-infin", "∠-ang", "∧-and", "∨-or", "∩-cap", "∪-cup", "∫-int",
            "∴-there4", "∼-sim", "≅-cong", "≈-asymp", "≠-ne", "≡-equiv", "≤-le", "≥-ge", "⊂-sub", "⊃-sup", "⊄-nsub", "⊆-sube", "⊇-supe", "⊕-oplus", "⊗-otimes", "⊥-perp",
            "⋅-sdot", "⌈-lceil", "⌉-rceil", "⌊-lfloor", "⌋-rfloor", "〈-lang", "〉-rang", "◊-loz", "♠-spades", "♣-clubs", "♥-hearts", "♦-diams"
         };
 
        public static char Lookup(string entity)
        {
            Hashtable hashtable = new Hashtable();
            foreach (string str in _entitiesList)
            {
                hashtable[str.Substring(2)] = str[0];
            }
 
            object obj2 = hashtable[entity];
            if (obj2 != null)
            {
                return (char)obj2;
            }
            return '\0';
        }
    }
};
 

 

Posted @ Monday, July 21, 2008 10:30 AM by Jonathan Kehayias
Previous Page | Next Page
Comments
By sdf sda on Tuesday, January 27, 2009
My HTML encoded text is from Team Foundation Server's HTML Field Type and Control - it allows for rich text formatting (maybe not the same thing as HTML). The first part of the text record I'm trying to decode starts:

<P><EM></EM>&nbsp;</P> <P><EM>&lt;Discription Update</EM> 4&gt;; <FONT size=3>Text text:</FONT> <FONT face="Courier New">Interface Design</FONT> <FONT color=#00ff00>Packages (IDPs) previously</FONT> formulated by the Enterpri<FONT style="BACKGROUND-COLOR: #ff8080">se with little to no coordination with the staff have now been finalized in coordination with. The resulting set of lack more than 40</FONT>% of the data currently used by. Additionally is reluctant to provide a daily “full data” feed like currently receives from. They have suggested a daily “change only record” feed, with periodic full data loads for data synchronization. This risk incorporates Risks 250, 255, 257, and 258. This risk replaces Risks 233, 235 and 237.</P>

However, while debugging your Decoder function, you first look for an ampersand (&) before doing any replacement, so the decoder skips over and outputs the first 12 characters of this string (the "<P><EM></EM>") before the first ampersand. Is this example not covered by your html decoder? Any quick fixes to do this?

Thanks.

You must be logged in to post a comment. You can login here

Survey

Which of the following CLR objects are you currently using in SQL Server?




Submit Survey  View Results

Links

  Search

What's New

 Subscribe in a reader

Q&A with Adam Machanic - Who's Afraid of SQLCLR by Jonathan Kehayias

You could almost hear the gasps of horror when Microsoft integrated the .NET Common Language Runtime (CLR) into SQL Server 2005. Run C# or VB.NET code inside SQL Server? For many database developers and administrators, it was like an alien had just burst through SQL Server’s midsection.

But SQL Server MVP Adam Machanic says that more and more developers and DBAs are discovering that far from destroying SQL Server performance and security, SQLCLR is actually a powerful ally in solving complex business and technical problems.

Read More on the PASS website..

SQLCLR String Splitting Part 2: Even Faster, Even More Scalable by Site Administrator

SQL Server MVP Adam Machanic shows a new way of parsing strings in SQL Server using SQLCLR that outperforms all conventional TSQL methods, as well as the most common SQLCLR implemenations, using a custom split function that allows streaming of the results.

Trading in xp_cmdshell for SQLCLR (Part 1) - List Directory Contents by Jonathan Kehayias

Learn how to use SQLCLR to get file system information instead of using xp_cmdshell on your SQL Servers.

Recent Examples


Copyright 2007 by SQLCLR.net Terms Of Use Privacy Statement
Website graphics provided by Matt Green Designs
Page generated in 0.5148165 seconds.

All information and example code on this site is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from its use.

This site is in no way affiliated with Microsoft. Unless specifically stated otherwise, nothing should be construed to represent the official positions or opinions of Microsoft and/or its Employees.