/// <summary>
        /// 获取属性过滤策略
        /// </summary>
        /// <param name="policy"></param>
        /// <param name="name"></param>
        /// <param name="tag"></param>
        /// <returns></returns>
        public static PolicyHtmlAttribute AllowedAttribute(this IFilterPolicy policy, string name, PolicyHtmlTag tag)
        {
            var tagAttr    = tag.AllowedAttributes.ContainsKey(name) ? tag.AllowedAttributes[name] : null;
            var globalAttr = policy.GlobalHtmlAttribute(name);

            if (tagAttr == null && globalAttr == null)
            {
                return(null);
            }
            var commonAttr = CommonHtmlAttribute(policy, name);

            return(new PolicyHtmlAttribute(name)
            {
                OnInvalid = tagAttr?.OnInvalid ?? globalAttr.OnInvalid,
                AllowedValues = tagAttr?.AllowedValues ?? globalAttr?.AllowedValues ?? commonAttr?.AllowedValues,
                AllowedRegExp = tagAttr?.AllowedRegExp ?? globalAttr?.AllowedRegExp ?? commonAttr?.AllowedRegExp
            });
        }
Beispiel #2
0
        /// <summary>
        /// 验证html标签
        /// </summary>
        /// <param name="node"></param>
        /// <param name="tagName"></param>
        /// <param name="tag"></param>
        protected virtual void ValidateAction(IElement node, string tagName, PolicyHtmlTag tag)
        {
            var parentNode = node.Parent;

            #region 过滤样式
            if ("style".Equals(tagName, StringComparison.OrdinalIgnoreCase))
            {
                try
                {
                    node.InnerHtml = CssFilter.Filters(node.InnerHtml);
                }
                catch
                {
                    parentNode.RemoveChild(node);
                }
            }
            #endregion

            #region 过滤属性
            for (int currentAttributeIndex = 0; currentAttributeIndex < node.Attributes.Length; currentAttributeIndex++)
            {
                var    attribute = node.Attributes[currentAttributeIndex];
                string name = attribute.Name, _value = attribute.Value;
                var    attr = Policy.AllowedAttribute(name, tag);

                #region 如果是白名单之外的属性移除掉
                if (attr == null)
                {
                    node.RemoveAttribute(name);
                    currentAttributeIndex--;
                    continue;
                }
                #endregion
                #region 元素内嵌样式
                if ("style".Equals(name, StringComparison.OrdinalIgnoreCase))
                {
                    try
                    {
                        attribute.Value = CssFilter.Filters(_value);
                        if (string.IsNullOrWhiteSpace(attribute.Value))
                        {
                            node.RemoveAttribute(name);
                            currentAttributeIndex--;
                        }
                    }
                    catch
                    {
                        node.RemoveAttribute(name);
                        currentAttributeIndex--;
                    }
                    continue;
                }
                #endregion
                //如果未能通过验证,将执行指定的操作
                if (!Policy.ValidateAttribute(attr, _value))
                {
                    switch (attr.OnInvalid)
                    {
                    case PolicyHtmlAttributeOnInvalid.RemoveTag:
                        //删除当前的元素并退出函数
                        parentNode.RemoveChild(node);
                        return;

                    case PolicyHtmlAttributeOnInvalid.FilterTag:
                        //删除当前节点,但保留其有效的子节点
                        PromoteChildren(node);
                        return;

                    default:
                        //删除当前的属性,指针往回调
                        node.RemoveAttribute(attr.Name);
                        currentAttributeIndex--;
                        break;
                    }
                }
            }
            #endregion
            //过滤当前元素的子节点
            FiltersTags(node.ChildNodes);
        }