Skip to content

Commit

Permalink
Use :all instead of '*' to specify attributes to be added to all elem…
Browse files Browse the repository at this point in the history
…ents; slight tweaks and documentation.
  • Loading branch information
rgrove committed Feb 15, 2009
1 parent 4cf7ab4 commit c0495a8
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 15 deletions.
3 changes: 3 additions & 0 deletions HISTORY
Expand Up @@ -7,6 +7,9 @@ Version ? (?)
preserved rather than being decoded and re-encoded.
* The ' character is now encoded as ' instead of ' to prevent
problems in IE6.
* You can now specify the symbol :all in place of an element name in the
attributes config hash to allow certain attributes on all elements. [Thanks
to Mutwin Kraus]

Version 1.0.5 (2009-02-05)
* Fixed a bug introduced in version 1.0.3 that prevented non-whitelisted
Expand Down
13 changes: 10 additions & 3 deletions README.rdoc
Expand Up @@ -15,7 +15,7 @@ or maliciously-formed HTML. When in doubt, Sanitize always errs on the side of
caution.

*Author*:: Ryan Grove (mailto:ryan@wonko.com)
*Version*:: 1.0.5 (2009-02-05)
*Version*:: ? (?)
*Copyright*:: Copyright (c) 2009 Ryan Grove. All rights reserved.
*License*:: MIT License (http://opensource.org/licenses/mit-license.php)
*Website*:: http://github.com/rgrove/sanitize
Expand All @@ -24,7 +24,6 @@ caution.

* RubyGems
* Hpricot 0.6+
* HTMLEntities 4.0.0+

== Usage

Expand Down Expand Up @@ -100,6 +99,14 @@ attributes in lowercase.
'img' => ['alt', 'src', 'title']
}

If you'd like to allow certain attributes on all elements, use the symbol
<code>:all</code> instead of an element name.

:attributes => {
:all => ['class'],
'a' => ['href', 'title'],
}

==== :add_attributes

Attributes to add to specific elements. If the attribute already exists, it will
Expand All @@ -122,7 +129,7 @@ protocol at all), it will be removed.
}

If you'd like to allow the use of relative URLs which don't have a protocol,
include the special value <code>:relative</code> in the protocol array:
include the symbol <code>:relative</code> in the protocol array:

:protocols => {
'a' => {'href' => ['http', 'https', :relative]}
Expand Down
15 changes: 9 additions & 6 deletions lib/sanitize.rb
Expand Up @@ -94,10 +94,17 @@ def clean!(html)

node.raw_attributes ||= {}

if @config[:attributes].has_key?(name) || @config[:attributes].has_key?('*')
attr_whitelist = ((@config[:attributes][name] || []) +
(@config[:attributes][:all] || [])).uniq

if attr_whitelist.empty?
# Delete all attributes from elements with no whitelisted
# attributes.
node.raw_attributes = {}
else
# Delete any attribute that isn't in the whitelist for this element.
node.raw_attributes.delete_if do |key, value|
!(@config[:attributes]['*'] ? @config[:attributes][name] + @config[:attributes]['*'] : @config[:attributes][name]).include?(key.to_s.downcase)
!attr_whitelist.include?(key.to_s.downcase)
end

# Delete remaining attributes that use unacceptable protocols.
Expand All @@ -115,10 +122,6 @@ def clean!(html)
end
end
end
else
# Delete all attributes from elements with no whitelisted
# attributes.
node.raw_attributes = {}
end

# Add required attributes.
Expand Down
17 changes: 11 additions & 6 deletions test/spec_sanitize.rb
Expand Up @@ -235,6 +235,17 @@
end
end

describe 'Custom configs' do
should 'allow attributes on all elements if whitelisted under :all' do
input = '<p class="foo">bar</p>'

Sanitize.clean(input).should.equal('bar')
Sanitize.clean(input, {:elements => ['p'], :attributes => {:all => ['class']}}).should.equal(input)
Sanitize.clean(input, {:elements => ['p'], :attributes => {'div' => ['class']}}).should.equal('<p>bar</p>')
Sanitize.clean(input, {:elements => ['p'], :attributes => {'p' => ['title'], :all => ['class']}}).should.equal(input)
end
end

describe 'Sanitize.clean' do
should 'not modify the input string' do
input = '<b>foo</b>'
Expand All @@ -246,12 +257,6 @@
input = '<b>foo</b>'
Sanitize.clean(input).should.equal('foo')
end

should 'not modify attributes allowed for the * element in any element' do
input = '<div id="bar">foo</div>'
Sanitize.clean(input).should.not.equal(input)
Sanitize.clean(input, {:elements => ['div'], :attributes => {'div' => ['class'], '*' => ['id']}}).should.equal(input)
end
end

describe 'Sanitize.clean!' do
Expand Down

0 comments on commit c0495a8

Please sign in to comment.