using System.Text;

namespace Vinno.vCloud.Disk
{
    public static class DefenseInjectionHelper
    {
        /**
         * 将容易引起xss漏洞的半角字符直接替换成全角字符
         *
         * @param s
         * @return
         */
        public static string XssEncode(this string s)
        {
            if (string.IsNullOrWhiteSpace(s))
            {
                return string.Empty;
            }
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < s.Length; i++)
            {
                char c = s[i];
                switch (c)
                {
                    case '>':
                        sb.Append('>');// 全角大于号
                        break;
                    case '<':
                        sb.Append('<');// 全角小于号
                        break;
                    case '\'':
                        sb.Append('‘');// 全角单引号
                        break;
                    case '\"':
                        sb.Append('“');// 全角双引号
                        break;
                    case '&':
                        sb.Append('&');// 全角
                        break;
                    case '\\':
                        sb.Append('\');// 全角斜线
                        break;
                    case '#':
                        sb.Append('#');// 全角井号
                        break;
                    case '%':    // < 字符的 URL 编码形式表示的 ASCII 字符(十六进制格式) 是: %3c
                        ProcessUrlEncoder(sb, s, i);
                        break;
                    default:
                        sb.Append(c);
                        break;
                }
            }
            return sb.ToString().Trim();
        }
        private static void ProcessUrlEncoder(StringBuilder sb, string s, int index)
        {
            if (s.Length >= index + 2)
            {
                if (s[index + 1] == '3' && (s[index + 2] == 'c' || s[index + 2] == 'C'))
                {    // %3c, %3C
                    sb.Append('<');
                    return;
                }
                if (s[index + 1] == '6' && s[index + 2] == '0')
                {    // %3c (0x3c=60)
                    sb.Append('<');
                    return;
                }
                if (s[index + 1] == '3' && (s[index + 2] == 'e' || s[index + 2] == 'E'))
                {    // %3e, %3E
                    sb.Append('>');
                    return;
                }
                if (s[index + 1] == '6' && s[index + 2] == '2')
                {    // %3e (0x3e=62)
                    sb.Append('>');
                    return;
                }
            }
            sb.Append(s[index]);
        }
    }
}