/// <summary>Test if the supplied attribute is allowed by this whitelist for this tag</summary> /// <param name="tagName">tag to consider allowing the attribute in</param> /// <param name="el">element under test, to confirm protocol</param> /// <param name="attr">attribute under test</param> /// <returns>true if allowed</returns> protected internal virtual bool IsSafeAttribute(String tagName, iText.StyledXmlParser.Jsoup.Nodes.Element el, iText.StyledXmlParser.Jsoup.Nodes.Attribute attr) { Whitelist.TagName tag = Whitelist.TagName.ValueOf(tagName); Whitelist.AttributeKey key = Whitelist.AttributeKey.ValueOf(attr.Key); if (attributes.ContainsKey(tag)) { if (attributes.Get(tag).Contains(key)) { if (protocols.ContainsKey(tag)) { IDictionary <Whitelist.AttributeKey, ICollection <Whitelist.Protocol> > attrProts = protocols.Get(tag); // ok if not defined protocol; otherwise test return(!attrProts.ContainsKey(key) || TestValidProtocol(el, attr, attrProts.Get(key))); } else { // attribute found, no protocols defined, so OK return(true); } } } // no attributes defined for tag, try :all tag return(!tagName.Equals(":all") && IsSafeAttribute(":all", el, attr)); }
/// <summary>Add an enforced attribute to a tag.</summary> /// <remarks> /// Add an enforced attribute to a tag. An enforced attribute will always be added to the element. If the element /// already has the attribute set, it will be overridden. /// <para /> /// E.g.: <code>addEnforcedAttribute("a", "rel", "nofollow")</code> will make all <code>a</code> tags output as /// <code><a href="..." rel="nofollow"></code> /// </remarks> /// <param name="tag">The tag the enforced attribute is for. The tag will be added to the allowed tag list if necessary. /// </param> /// <param name="key">The attribute key</param> /// <param name="value">The enforced attribute value</param> /// <returns>this (for chaining)</returns> public virtual iText.StyledXmlParser.Jsoup.Safety.Whitelist AddEnforcedAttribute(String tag, String key, String value) { Validate.NotEmpty(tag); Validate.NotEmpty(key); Validate.NotEmpty(value); Whitelist.TagName tagName = Whitelist.TagName.ValueOf(tag); if (!tagNames.Contains(tagName)) { tagNames.Add(tagName); } Whitelist.AttributeKey attrKey = Whitelist.AttributeKey.ValueOf(key); Whitelist.AttributeValue attrVal = Whitelist.AttributeValue.ValueOf(value); if (enforcedAttributes.ContainsKey(tagName)) { enforcedAttributes.Get(tagName).Put(attrKey, attrVal); } else { IDictionary <Whitelist.AttributeKey, Whitelist.AttributeValue> attrMap = new Dictionary <Whitelist.AttributeKey , Whitelist.AttributeValue>(); attrMap.Put(attrKey, attrVal); enforcedAttributes.Put(tagName, attrMap); } return(this); }
/// <summary>Remove allowed URL protocols for an element's URL attribute.</summary> /// <remarks> /// Remove allowed URL protocols for an element's URL attribute. /// <para /> /// E.g.: <code>removeProtocols("a", "href", "ftp")</code> /// </remarks> /// <param name="tag">Tag the URL protocol is for</param> /// <param name="key">Attribute key</param> /// <param name="protocols">List of invalid protocols</param> /// <returns>this, for chaining</returns> public virtual iText.StyledXmlParser.Jsoup.Safety.Whitelist RemoveProtocols(String tag, String key, params String[] protocols) { Validate.NotEmpty(tag); Validate.NotEmpty(key); Validate.NotNull(protocols); Whitelist.TagName tagName = Whitelist.TagName.ValueOf(tag); Whitelist.AttributeKey attrKey = Whitelist.AttributeKey.ValueOf(key); if (this.protocols.ContainsKey(tagName)) { IDictionary <Whitelist.AttributeKey, ICollection <Whitelist.Protocol> > attrMap = this.protocols.Get(tagName); if (attrMap.ContainsKey(attrKey)) { ICollection <Whitelist.Protocol> protSet = attrMap.Get(attrKey); foreach (String protocol in protocols) { Validate.NotEmpty(protocol); Whitelist.Protocol prot = Whitelist.Protocol.ValueOf(protocol); protSet.Remove(prot); } if (protSet.IsEmpty()) { // Remove protocol set if empty attrMap.JRemove(attrKey); if (attrMap.IsEmpty()) { // Remove entry for tag if empty this.protocols.JRemove(tagName); } } } } return(this); }
/// <summary>Add a list of allowed attributes to a tag.</summary> /// <remarks> /// Add a list of allowed attributes to a tag. (If an attribute is not allowed on an element, it will be removed.) /// <para /> /// E.g.: <code>addAttributes("a", "href", "class")</code> allows <code>href</code> and <code>class</code> attributes /// on <code>a</code> tags. /// <para /> /// To make an attribute valid for <b>all tags</b>, use the pseudo tag <code>:all</code>, e.g. /// <code>addAttributes(":all", "class")</code>. /// </remarks> /// <param name="tag">The tag the attributes are for. The tag will be added to the allowed tag list if necessary. /// </param> /// <param name="keys">List of valid attributes for the tag</param> /// <returns>this (for chaining)</returns> public virtual iText.StyledXmlParser.Jsoup.Safety.Whitelist AddAttributes(String tag, params String[] keys ) { Validate.NotEmpty(tag); Validate.NotNull(keys); Validate.IsTrue(keys.Length > 0, "No attributes supplied."); Whitelist.TagName tagName = Whitelist.TagName.ValueOf(tag); if (!tagNames.Contains(tagName)) { tagNames.Add(tagName); } ICollection <Whitelist.AttributeKey> attributeSet = new HashSet <Whitelist.AttributeKey>(); foreach (String key in keys) { Validate.NotEmpty(key); attributeSet.Add(Whitelist.AttributeKey.ValueOf(key)); } if (attributes.ContainsKey(tagName)) { ICollection <Whitelist.AttributeKey> currentSet = attributes.Get(tagName); currentSet.AddAll(attributeSet); } else { attributes.Put(tagName, attributeSet); } return(this); }
internal virtual Attributes GetEnforcedAttributes(String tagName) { Attributes attrs = new Attributes(); Whitelist.TagName tag = Whitelist.TagName.ValueOf(tagName); if (enforcedAttributes.ContainsKey(tag)) { IDictionary <Whitelist.AttributeKey, Whitelist.AttributeValue> keyVals = enforcedAttributes.Get(tag); foreach (KeyValuePair <Whitelist.AttributeKey, Whitelist.AttributeValue> entry in keyVals) { attrs.Put(entry.Key.ToString(), entry.Value.ToString()); } } return(attrs); }
/// <summary>Remove a list of allowed elements from a whitelist.</summary> /// <remarks>Remove a list of allowed elements from a whitelist. (If a tag is not allowed, it will be removed from the HTML.) /// </remarks> /// <param name="tags">tag names to disallow</param> /// <returns>this (for chaining)</returns> public virtual iText.StyledXmlParser.Jsoup.Safety.Whitelist RemoveTags(params String[] tags) { Validate.NotNull(tags); foreach (String tag in tags) { Validate.NotEmpty(tag); Whitelist.TagName tagName = Whitelist.TagName.ValueOf(tag); if (tagNames.Remove(tagName)) { // Only look in sub-maps if tag was allowed attributes.JRemove(tagName); enforcedAttributes.JRemove(tagName); protocols.JRemove(tagName); } } return(this); }
/// <summary>Remove a previously configured enforced attribute from a tag.</summary> /// <param name="tag">The tag the enforced attribute is for.</param> /// <param name="key">The attribute key</param> /// <returns>this (for chaining)</returns> public virtual iText.StyledXmlParser.Jsoup.Safety.Whitelist RemoveEnforcedAttribute(String tag, String key ) { Validate.NotEmpty(tag); Validate.NotEmpty(key); Whitelist.TagName tagName = Whitelist.TagName.ValueOf(tag); if (tagNames.Contains(tagName) && enforcedAttributes.ContainsKey(tagName)) { Whitelist.AttributeKey attrKey = Whitelist.AttributeKey.ValueOf(key); IDictionary <Whitelist.AttributeKey, Whitelist.AttributeValue> attrMap = enforcedAttributes.Get(tagName); attrMap.JRemove(attrKey); if (attrMap.IsEmpty()) { // Remove tag from enforced attribute map if no enforced attributes are present enforcedAttributes.JRemove(tagName); } } return(this); }
/// <summary>Remove a list of allowed attributes from a tag.</summary> /// <remarks> /// Remove a list of allowed attributes from a tag. (If an attribute is not allowed on an element, it will be removed.) /// <para /> /// E.g.: <code>removeAttributes("a", "href", "class")</code> disallows <code>href</code> and <code>class</code> /// attributes on <code>a</code> tags. /// <para /> /// To make an attribute invalid for <b>all tags</b>, use the pseudo tag <code>:all</code>, e.g. /// <code>removeAttributes(":all", "class")</code>. /// </remarks> /// <param name="tag">The tag the attributes are for.</param> /// <param name="keys">List of invalid attributes for the tag</param> /// <returns>this (for chaining)</returns> public virtual iText.StyledXmlParser.Jsoup.Safety.Whitelist RemoveAttributes(String tag, params String[] keys ) { Validate.NotEmpty(tag); Validate.NotNull(keys); Validate.IsTrue(keys.Length > 0, "No attributes supplied."); Whitelist.TagName tagName = Whitelist.TagName.ValueOf(tag); ICollection <Whitelist.AttributeKey> attributeSet = new HashSet <Whitelist.AttributeKey>(); foreach (String key in keys) { Validate.NotEmpty(key); attributeSet.Add(Whitelist.AttributeKey.ValueOf(key)); } if (tagNames.Contains(tagName) && attributes.ContainsKey(tagName)) { // Only look in sub-maps if tag was allowed ICollection <Whitelist.AttributeKey> currentSet = attributes.Get(tagName); currentSet.RemoveAll(attributeSet); if (currentSet.IsEmpty()) { // Remove tag from attribute map if no attributes are allowed for tag attributes.JRemove(tagName); } } if (tag.Equals(":all")) { // Attribute needs to be removed from all individually set tags foreach (Whitelist.TagName name in attributes.Keys) { ICollection <Whitelist.AttributeKey> currentSet = attributes.Get(name); currentSet.RemoveAll(attributeSet); if (currentSet.IsEmpty()) { // Remove tag from attribute map if no attributes are allowed for tag attributes.JRemove(name); } } } return(this); }
/// <summary>Add allowed URL protocols for an element's URL attribute.</summary> /// <remarks> /// Add allowed URL protocols for an element's URL attribute. This restricts the possible values of the attribute to /// URLs with the defined protocol. /// <para /> /// E.g.: <code>addProtocols("a", "href", "ftp", "http", "https")</code> /// <para /> /// To allow a link to an in-page URL anchor (i.e. <code><a href="#anchor"></code>, add a <code>#</code>:<br /> /// E.g.: <code>addProtocols("a", "href", "#")</code> /// </remarks> /// <param name="tag">Tag the URL protocol is for</param> /// <param name="key">Attribute key</param> /// <param name="protocols">List of valid protocols</param> /// <returns>this, for chaining</returns> public virtual iText.StyledXmlParser.Jsoup.Safety.Whitelist AddProtocols(String tag, String key, params String [] protocols) { Validate.NotEmpty(tag); Validate.NotEmpty(key); Validate.NotNull(protocols); Whitelist.TagName tagName = Whitelist.TagName.ValueOf(tag); Whitelist.AttributeKey attrKey = Whitelist.AttributeKey.ValueOf(key); IDictionary <Whitelist.AttributeKey, ICollection <Whitelist.Protocol> > attrMap; ICollection <Whitelist.Protocol> protSet; if (this.protocols.ContainsKey(tagName)) { attrMap = this.protocols.Get(tagName); } else { attrMap = new Dictionary <Whitelist.AttributeKey, ICollection <Whitelist.Protocol> >(); this.protocols.Put(tagName, attrMap); } if (attrMap.ContainsKey(attrKey)) { protSet = attrMap.Get(attrKey); } else { protSet = new HashSet <Whitelist.Protocol>(); attrMap.Put(attrKey, protSet); } foreach (String protocol in protocols) { Validate.NotEmpty(protocol); Whitelist.Protocol prot = Whitelist.Protocol.ValueOf(protocol); protSet.Add(prot); } return(this); }