loofah 0.4.2 → 2.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +604 -0
  3. data/MIT-LICENSE.txt +3 -1
  4. data/README.md +410 -0
  5. data/SECURITY.md +18 -0
  6. data/lib/loofah/concerns.rb +207 -0
  7. data/lib/loofah/elements.rb +98 -0
  8. data/lib/loofah/helpers.rb +91 -4
  9. data/lib/loofah/html4/document.rb +17 -0
  10. data/lib/loofah/html4/document_fragment.rb +15 -0
  11. data/lib/loofah/html5/document.rb +17 -0
  12. data/lib/loofah/html5/document_fragment.rb +15 -0
  13. data/lib/loofah/html5/libxml2_workarounds.rb +28 -0
  14. data/lib/loofah/html5/safelist.rb +1058 -0
  15. data/lib/loofah/html5/scrub.rb +211 -40
  16. data/lib/loofah/metahelpers.rb +18 -0
  17. data/lib/loofah/scrubber.rb +31 -13
  18. data/lib/loofah/scrubbers.rb +262 -31
  19. data/lib/loofah/version.rb +6 -0
  20. data/lib/loofah/xml/document.rb +2 -0
  21. data/lib/loofah/xml/document_fragment.rb +6 -9
  22. data/lib/loofah.rb +131 -52
  23. metadata +79 -158
  24. data/CHANGELOG.rdoc +0 -92
  25. data/DEPRECATED.rdoc +0 -12
  26. data/Manifest.txt +0 -34
  27. data/README.rdoc +0 -330
  28. data/Rakefile +0 -61
  29. data/TODO.rdoc +0 -4
  30. data/benchmark/benchmark.rb +0 -149
  31. data/benchmark/fragment.html +0 -96
  32. data/benchmark/helper.rb +0 -73
  33. data/benchmark/www.slashdot.com.html +0 -2560
  34. data/init.rb +0 -1
  35. data/lib/loofah/active_record.rb +0 -62
  36. data/lib/loofah/html/document.rb +0 -22
  37. data/lib/loofah/html/document_fragment.rb +0 -46
  38. data/lib/loofah/html5/whitelist.rb +0 -174
  39. data/lib/loofah/instance_methods.rb +0 -77
  40. data/lib/loofah/xss_foliate.rb +0 -212
  41. data/test/helper.rb +0 -8
  42. data/test/html5/test_sanitizer.rb +0 -248
  43. data/test/test_active_record.rb +0 -146
  44. data/test/test_ad_hoc.rb +0 -272
  45. data/test/test_api.rb +0 -128
  46. data/test/test_helpers.rb +0 -28
  47. data/test/test_scrubber.rb +0 -227
  48. data/test/test_scrubbers.rb +0 -144
  49. data/test/test_xss_foliate.rb +0 -171
  50. data.tar.gz.sig +0 -0
  51. metadata.gz.sig +0 -2
data/init.rb DELETED
@@ -1 +0,0 @@
1
- require "loofah"
@@ -1,62 +0,0 @@
1
- module Loofah
2
- #
3
- # Loofah can scrub ActiveRecord attributes in a before_validation callback:
4
- #
5
- # # in environment.rb
6
- # Rails::Initializer.run do |config|
7
- # config.gem 'loofah'
8
- # end
9
- #
10
- # # db/schema.rb
11
- # create_table "posts" do |t|
12
- # t.string "title"
13
- # t.string "body"
14
- # end
15
- #
16
- # # app/model/post.rb
17
- # class Post < ActiveRecord::Base
18
- # html_fragment :body, :scrub => :prune # scrubs 'body' in a before_validation
19
- # end
20
- #
21
- module ActiveRecordExtension
22
- #
23
- # :call-seq:
24
- # html_fragment(attribute, :scrub => scrubber_specification)
25
- #
26
- # Scrub an ActiveRecord attribute +attribute+ as an HTML *fragment*
27
- # using the method specified by +scrubber_specification+.
28
- #
29
- # +scrubber_specification+ must be an argument acceptable to Loofah::ScrubBehavior.scrub!, namely:
30
- #
31
- # * a symbol for one of the built-in scrubbers (see Loofah::Scrubbers for a full list)
32
- # * or a Scrubber instance. (see Loofah::Scrubber for help on implementing a custom scrubber)
33
- #
34
- def html_fragment(attr, options={})
35
- raise ArgumentError, "html_fragment requires :scrub option" unless method = options[:scrub]
36
- before_validation do |record|
37
- record[attr] = Loofah.scrub_fragment(record[attr], method).to_s
38
- end
39
- end
40
-
41
- #
42
- # :call-seq:
43
- # model.html_document(attribute, :scrub => scrubber_specification)
44
- #
45
- # Scrub an ActiveRecord attribute +attribute+ as an HTML *document*
46
- # using the method specified by +scrubber_specification+.
47
- #
48
- # +scrubber_specification+ must be an argument acceptable to Loofah::ScrubBehavior.scrub!, namely:
49
- #
50
- # * a symbol for one of the built-in scrubbers (see Loofah::Scrubbers for a full list)
51
- # * or a Scrubber instance.
52
- #
53
- def html_document(attr, options={})
54
- raise ArgumentError, "html_document requires :scrub option" unless method = options[:scrub]
55
- before_validation do |record|
56
- record[attr] = Loofah.scrub_document(record[attr], method).to_s
57
- end
58
- end
59
- end
60
- end
61
-
62
- ActiveRecord::Base.extend(Loofah::ActiveRecordExtension)
@@ -1,22 +0,0 @@
1
- module Loofah
2
- module HTML # :nodoc:
3
- #
4
- # Subclass of Nokogiri::HTML::Document.
5
- #
6
- # See Loofah::ScrubBehavior and Loofah::DocumentDecorator for additional methods.
7
- #
8
- class Document < Nokogiri::HTML::Document
9
- include Loofah::ScrubBehavior::Node
10
- include Loofah::DocumentDecorator
11
-
12
- #
13
- # Returns a plain-text version of the markup contained by the document
14
- #
15
- def text
16
- xpath("/html/body").inner_text
17
- end
18
- alias :inner_text :text
19
- alias :to_str :text
20
- end
21
- end
22
- end
@@ -1,46 +0,0 @@
1
- module Loofah
2
- module HTML # :nodoc:
3
- #
4
- # Subclass of Nokogiri::HTML::DocumentFragment.
5
- #
6
- # See Loofah::ScrubBehavior for additional methods.
7
- #
8
- class DocumentFragment < Nokogiri::HTML::DocumentFragment
9
- include Loofah::ScrubBehavior::Node
10
-
11
- class << self
12
- #
13
- # Overridden Nokogiri::HTML::DocumentFragment
14
- # constructor. Applications should use Loofah.fragment to
15
- # parse a fragment.
16
- #
17
- def parse tags
18
- self.new(Loofah::HTML::Document.new, tags)
19
- end
20
- end
21
-
22
- #
23
- # Returns the HTML markup contained by the fragment
24
- #
25
- def to_s
26
- serialize_roots.children.to_s
27
- end
28
- alias :serialize :to_s
29
-
30
- #
31
- # Returns a plain-text version of the markup contained by the fragment
32
- #
33
- def text
34
- serialize_roots.children.inner_text
35
- end
36
- alias :inner_text :text
37
- alias :to_str :text
38
-
39
- private
40
-
41
- def serialize_roots # :nodoc:
42
- xpath("./body").first || self
43
- end
44
- end
45
- end
46
- end
@@ -1,174 +0,0 @@
1
- module Loofah
2
- module HTML5 # :nodoc:
3
- #
4
- # HTML whitelist lifted from HTML5lib sanitizer code:
5
- #
6
- # http://code.google.com/p/html5lib/
7
- #
8
- # <html5_license>
9
- #
10
- # Copyright (c) 2006-2008 The Authors
11
- #
12
- # Contributors:
13
- # James Graham - jg307@cam.ac.uk
14
- # Anne van Kesteren - annevankesteren@gmail.com
15
- # Lachlan Hunt - lachlan.hunt@lachy.id.au
16
- # Matt McDonald - kanashii@kanashii.ca
17
- # Sam Ruby - rubys@intertwingly.net
18
- # Ian Hickson (Google) - ian@hixie.ch
19
- # Thomas Broyer - t.broyer@ltgt.net
20
- # Jacques Distler - distler@golem.ph.utexas.edu
21
- # Henri Sivonen - hsivonen@iki.fi
22
- # The Mozilla Foundation (contributions from Henri Sivonen since 2008)
23
- #
24
- # Permission is hereby granted, free of charge, to any person
25
- # obtaining a copy of this software and associated documentation
26
- # files (the "Software"), to deal in the Software without
27
- # restriction, including without limitation the rights to use, copy,
28
- # modify, merge, publish, distribute, sublicense, and/or sell copies
29
- # of the Software, and to permit persons to whom the Software is
30
- # furnished to do so, subject to the following conditions:
31
- #
32
- # The above copyright notice and this permission notice shall be
33
- # included in all copies or substantial portions of the Software.
34
- #
35
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
36
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
38
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
39
- # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
40
- # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
41
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
42
- # DEALINGS IN THE SOFTWARE.
43
- #
44
- # </html5_license>
45
- module WhiteList
46
- ACCEPTABLE_ELEMENTS = %w[a abbr acronym address area b big blockquote br
47
- button caption center cite code col colgroup dd del dfn dir div dl dt
48
- em fieldset font form h1 h2 h3 h4 h5 h6 hr i img input ins kbd label
49
- legend li map menu ol optgroup option p pre q s samp select small span
50
- strike strong sub sup table tbody td textarea tfoot th thead tr tt u
51
- ul var]
52
-
53
- MATHML_ELEMENTS = %w[annotation annotation-xml maction math merror mfrac
54
- mfenced mi mmultiscripts mn mo mover mpadded mphantom mprescripts mroot mrow
55
- mspace msqrt mstyle msub msubsup msup mtable mtd mtext mtr munder
56
- munderover none semantics]
57
-
58
- SVG_ELEMENTS = %w[a animate animateColor animateMotion animateTransform
59
- circle defs desc ellipse font-face font-face-name font-face-src foreignObject
60
- g glyph hkern linearGradient line marker metadata missing-glyph
61
- mpath path polygon polyline radialGradient rect set stop svg switch
62
- text title tspan use]
63
-
64
- ACCEPTABLE_ATTRIBUTES = %w[abbr accept accept-charset accesskey action
65
- align alt axis border cellpadding cellspacing char charoff charset
66
- checked cite class clear cols colspan color compact coords datetime
67
- dir disabled enctype for frame headers height href hreflang hspace id
68
- ismap label lang longdesc maxlength media method multiple name nohref
69
- noshade nowrap prompt readonly rel rev rows rowspan rules scope
70
- selected shape size span src start style summary tabindex target title
71
- type usemap valign value vspace width xml:lang]
72
-
73
- MATHML_ATTRIBUTES = %w[actiontype align close columnalign columnalign
74
- columnalign columnlines columnspacing columnspan depth display
75
- displaystyle encoding equalcolumns equalrows fence fontstyle fontweight
76
- frame height linethickness lspace mathbackground mathcolor mathvariant
77
- mathvariant maxsize minsize open other rowalign rowalign rowalign rowlines
78
- rowspacing rowspan rspace scriptlevel selection separator separators
79
- stretchy width width xlink:href xlink:show xlink:type xmlns xmlns:xlink]
80
-
81
- SVG_ATTRIBUTES = %w[accent-height accumulate additive alphabetic
82
- arabic-form ascent attributeName attributeType baseProfile bbox begin
83
- by calcMode cap-height class color color-rendering content cx cy d dx
84
- dy descent display dur end fill fill-opacity fill-rule font-family
85
- font-size font-stretch font-style font-variant font-weight from fx fy g1
86
- g2 glyph-name gradientUnits hanging height horiz-adv-x horiz-origin-x id
87
- ideographic k keyPoints keySplines keyTimes lang marker-end
88
- marker-mid marker-start markerHeight markerUnits markerWidth
89
- mathematical max min name offset opacity orient origin
90
- overline-position overline-thickness panose-1 path pathLength points
91
- preserveAspectRatio r refX refY repeatCount repeatDur
92
- requiredExtensions requiredFeatures restart rotate rx ry slope stemh
93
- stemv stop-color stop-opacity strikethrough-position
94
- strikethrough-thickness stroke stroke-dasharray stroke-dashoffset
95
- stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity
96
- stroke-width systemLanguage target text-anchor to transform type u1
97
- u2 underline-position underline-thickness unicode unicode-range
98
- units-per-em values version viewBox visibility width widths x
99
- x-height x1 x2 xlink:actuate xlink:arcrole xlink:href xlink:role
100
- xlink:show xlink:title xlink:type xml:base xml:lang xml:space xmlns
101
- xmlns:xlink y y1 y2 zoomAndPan]
102
-
103
- ATTR_VAL_IS_URI = %w[href src cite action longdesc xlink:href xml:base]
104
-
105
- SVG_ATTR_VAL_ALLOWS_REF = %w[clip-path color-profile cursor fill
106
- filter marker marker-start marker-mid marker-end mask stroke]
107
-
108
- SVG_ALLOW_LOCAL_HREF = %w[altGlyph animate animateColor animateMotion
109
- animateTransform cursor feImage filter linearGradient pattern
110
- radialGradient textpath tref set use]
111
-
112
- ACCEPTABLE_CSS_PROPERTIES = %w[azimuth background-color
113
- border-bottom-color border-collapse border-color border-left-color
114
- border-right-color border-top-color clear color cursor direction
115
- display elevation float font font-family font-size font-style
116
- font-variant font-weight height letter-spacing line-height overflow
117
- pause pause-after pause-before pitch pitch-range richness speak
118
- speak-header speak-numeral speak-punctuation speech-rate stress
119
- text-align text-decoration text-indent unicode-bidi vertical-align
120
- voice-family volume white-space width]
121
-
122
- ACCEPTABLE_CSS_KEYWORDS = %w[auto aqua black block blue bold both bottom
123
- brown center collapse dashed dotted fuchsia gray green !important
124
- italic left lime maroon medium none navy normal nowrap olive pointer
125
- purple red right solid silver teal top transparent underline white
126
- yellow]
127
-
128
- ACCEPTABLE_SVG_PROPERTIES = %w[fill fill-opacity fill-rule stroke
129
- stroke-width stroke-linecap stroke-linejoin stroke-opacity]
130
-
131
- ACCEPTABLE_PROTOCOLS = %w[ed2k ftp http https irc mailto news gopher nntp
132
- telnet webcal xmpp callto feed urn aim rsync tag ssh sftp rtsp afs]
133
-
134
- # subclasses may define their own versions of these constants
135
- ALLOWED_ELEMENTS = ACCEPTABLE_ELEMENTS + MATHML_ELEMENTS + SVG_ELEMENTS
136
- ALLOWED_ATTRIBUTES = ACCEPTABLE_ATTRIBUTES + MATHML_ATTRIBUTES + SVG_ATTRIBUTES
137
- ALLOWED_CSS_PROPERTIES = ACCEPTABLE_CSS_PROPERTIES
138
- ALLOWED_CSS_KEYWORDS = ACCEPTABLE_CSS_KEYWORDS
139
- ALLOWED_SVG_PROPERTIES = ACCEPTABLE_SVG_PROPERTIES
140
- ALLOWED_PROTOCOLS = ACCEPTABLE_PROTOCOLS
141
-
142
- VOID_ELEMENTS = %w[
143
- base
144
- link
145
- meta
146
- hr
147
- br
148
- img
149
- embed
150
- param
151
- area
152
- col
153
- input
154
- ]
155
-
156
- # additional tags we should consider safe since we have libxml2 fixing up our documents.
157
- TAGS_SAFE_WITH_LIBXML2 = %w[html head body]
158
- ALLOWED_ELEMENTS_WITH_LIBXML2 = ALLOWED_ELEMENTS + TAGS_SAFE_WITH_LIBXML2
159
- end
160
-
161
- #
162
- # The HTML5lib whitelist arrays, transformed into hashes for faster lookup.
163
- #
164
- module HashedWhiteList
165
- WhiteList.constants.each do |constant|
166
- next unless WhiteList.module_eval("#{constant}").is_a?(Array)
167
- module_eval <<-CODE
168
- #{constant} = {}
169
- WhiteList::#{constant}.each { |c| #{constant}[c] = true ; #{constant}[c.downcase] = true }
170
- CODE
171
- end
172
- end
173
- end
174
- end
@@ -1,77 +0,0 @@
1
- module Loofah
2
- #
3
- # Mixes +scrub!+ into Document, DocumentFragment, Node and NodeSet.
4
- #
5
- # Traverse the document or fragment, invoking the +scrubber+ on
6
- # each node.
7
- #
8
- # +scrubber+ must either be one of the symbols representing the
9
- # built-in scrubbers (see Scrubbers), or a Scrubber instance.
10
- #
11
- # span2div = Loofah::Scrubber.new do |node|
12
- # node.name = "div" if node.name == "span"
13
- # end
14
- # Loofah.fragment("<span>foo</span><p>bar</p>").scrub!(span2div).to_s
15
- # # => "<div>foo</div><p>bar</p>"
16
- #
17
- # or
18
- #
19
- # unsafe_html = "ohai! <div>div is safe</div> <script>but script is not</script>"
20
- # Loofah.fragment(unsafe_html).scrub!(:strip).to_s
21
- # # => "ohai! <div>div is safe</div> "
22
- #
23
- # Note that this method is called implicitly from
24
- # Loofah.scrub_fragment and Loofah.scrub_document.
25
- #
26
- # Please see Scrubber for more information on implementation and traversal, and
27
- # README.rdoc for more example usage.
28
- #
29
- module ScrubBehavior
30
- # see Loofah::ScrubBehavior
31
- module Node
32
- def scrub!(scrubber)
33
- #
34
- # yes. this should be three separate methods. but nokogiri
35
- # decorates (or not) based on whether the module name has
36
- # already been included. and since documents get decorated
37
- # just like their constituent nodes, we need to jam all the
38
- # logic into a single module.
39
- #
40
- scrubber = ScrubBehavior.resolve_scrubber(scrubber)
41
- case self
42
- when Nokogiri::XML::Document
43
- scrubber.traverse(root) if root
44
- when Nokogiri::XML::DocumentFragment
45
- children.each { |node| node.scrub!(scrubber) } # TODO: children.scrub! once Nokogiri 1.4.2 is out
46
- else
47
- scrubber.traverse(self)
48
- end
49
- self
50
- end
51
- end
52
-
53
- # see Loofah::ScrubBehavior
54
- module NodeSet
55
- def scrub!(scrubber)
56
- each { |node| node.scrub!(scrubber) }
57
- self
58
- end
59
- end
60
-
61
- def ScrubBehavior.resolve_scrubber(scrubber) # :nodoc:
62
- scrubber = Scrubbers::MAP[scrubber].new if Scrubbers::MAP[scrubber]
63
- unless scrubber.is_a?(Loofah::Scrubber)
64
- raise Loofah::ScrubberNotFound, "not a Scrubber or a scrubber name: #{scrubber.inspect}"
65
- end
66
- scrubber
67
- end
68
- end
69
-
70
- module DocumentDecorator # :nodoc:
71
- def initialize(*args, &block)
72
- super
73
- self.decorators(Nokogiri::XML::Node) << ScrubBehavior::Node
74
- self.decorators(Nokogiri::XML::NodeSet) << ScrubBehavior::NodeSet
75
- end
76
- end
77
- end
@@ -1,212 +0,0 @@
1
- module Loofah
2
- #
3
- # A replacement for
4
- # XssTerminate[http://github.com/look/xss_terminate/tree/master],
5
- # XssFoliate will strip all tags from your ActiveRecord models'
6
- # string and text attributes.
7
- #
8
- # Please read the Loofah documentation for an explanation of the
9
- # different scrubbing methods, and
10
- # Loofah::XssFoliate::ClassMethods for more information on the
11
- # methods.
12
- #
13
- # If you'd like to scrub all fields in all your models (and perhaps *opt-out* in specific models):
14
- #
15
- # # config/environment
16
- # LOOFAH_XSS_FOLIATE_ALL_MODELS = true
17
- # Rails::Initializer.run do |config|
18
- # config.gem "loofah"
19
- # end
20
- #
21
- # # db/schema.rb
22
- # create_table "posts" do |t|
23
- # t.string "title"
24
- # t.text "body"
25
- # t.string "author"
26
- # end
27
- #
28
- # # app/model/post.rb
29
- # class Post < ActiveRecord::Base
30
- # # by default, title, body and author will all be scrubbed down to their inner text
31
- # end
32
- #
33
- # OR
34
- #
35
- # # app/model/post.rb
36
- # class Post < ActiveRecord::Base
37
- # xss_foliate :except => :author # opt-out of sanitizing author
38
- # end
39
- #
40
- # OR
41
- #
42
- # xss_foliate :strip => [:title, body] # strip unsafe tags from both title and body
43
- #
44
- # OR
45
- #
46
- # xss_foliate :except => :title # scrub body and author but not title
47
- #
48
- # OR
49
- #
50
- # # remove all tags from title, remove unsafe tags from body
51
- # xss_foliate :sanitize => :title, :scrub => :body
52
- #
53
- # OR
54
- #
55
- # # old xss_terminate code will work if you s/_terminate/_foliate/
56
- # # was: xss_terminate :except => [:title], :sanitize => [:body]
57
- # xss_foliate :except => [:title], :sanitize => [:body]
58
- #
59
- # Alternatively, if you would like to *opt-in* to the models and attributes that are sanitized:
60
- #
61
- # # config/environment.rb
62
- # LOOFAH_XSS_FOLIATE_ALL_MODELS = false # default, this line could be omitted
63
- # Rails::Initializer.run do |config|
64
- # config.gem "loofah"
65
- # end
66
- #
67
- # # db/schema.rb
68
- # create_table "posts" do |t|
69
- # t.string "title"
70
- # t.text "body"
71
- # t.string "author"
72
- # end
73
- #
74
- # # app/model/post.rb
75
- # class Post < ActiveRecord::Base
76
- # xss_foliate # scrub title, body and author down to their inner text
77
- # end
78
- #
79
- module XssFoliate
80
- #
81
- # A replacement for
82
- # XssTerminate[http://github.com/look/xss_terminate/tree/master],
83
- # XssFoliate will strip all tags from your ActiveRecord models'
84
- # string and text attributes.
85
- #
86
- # See Loofah::XssFoliate for more example usage.
87
- #
88
- module ClassMethods
89
- # :stopdoc:
90
- VALID_OPTIONS = [:except, :strip, :escape, :prune, :text, :html5lib_sanitize, :sanitize]
91
- ALIASED_OPTIONS = {:html5lib_sanitize => :escape, :sanitize => :strip}
92
- REAL_OPTIONS = VALID_OPTIONS - ALIASED_OPTIONS.keys
93
- # :startdoc:
94
-
95
- #
96
- # Annotate your model with this method to specify which fields
97
- # you want scrubbed, and how you want them scrubbed. XssFoliate
98
- # assumes all character fields are HTML fragments (as opposed to
99
- # full documents, see the Loofah[http://loofah.rubyforge.org/]
100
- # documentation for a full explanation of the difference).
101
- #
102
- # Example call:
103
- #
104
- # xss_foliate :except => :author, :strip => :body, :prune => [:title, :description]
105
- #
106
- # *Note* that the values in the options hash can be either an
107
- # array of attributes or a single attribute.
108
- #
109
- # Options:
110
- #
111
- # :except => [fields] # don't scrub these fields
112
- # :strip => [fields] # strip unsafe tags from these fields
113
- # :escape => [fields] # escape unsafe tags from these fields
114
- # :prune => [fields] # prune unsafe tags and subtrees from these fields
115
- # :text => [fields] # remove everything except the inner text from these fields
116
- #
117
- # XssTerminate compatibility options (note that the default
118
- # behavior in XssTerminate corresponds to :text)
119
- #
120
- # :html5lib_sanitize => [fields] # same as :escape
121
- # :sanitize => [fields] # same as :strip
122
- #
123
- # The default is :text for all fields unless otherwise specified.
124
- #
125
- def xss_foliate(options = {})
126
- callback_already_declared = \
127
- if respond_to?(:before_validation_callback_chain)
128
- # Rails 2.1 and later
129
- before_validation_callback_chain.any? {|cb| cb.method == :xss_foliate_fields}
130
- else
131
- # Rails 2.0
132
- cbs = read_inheritable_attribute(:before_validation)
133
- (! cbs.nil?) && cbs.any? {|cb| cb == :xss_foliate_fields}
134
- end
135
-
136
- unless callback_already_declared
137
- before_validation :xss_foliate_fields
138
- class_inheritable_reader :xss_foliate_options
139
- include XssFoliate::InstanceMethods
140
- end
141
-
142
- options.keys.each do |option|
143
- raise ArgumentError, "unknown xss_foliate option #{option}" unless VALID_OPTIONS.include?(option)
144
- end
145
-
146
- REAL_OPTIONS.each do |option|
147
- options[option] = Array(options[option]).collect { |val| val.to_sym }
148
- end
149
-
150
- ALIASED_OPTIONS.each do |option, real|
151
- options[real] += Array(options.delete(option)).collect { |val| val.to_sym } if options[option]
152
- end
153
-
154
- write_inheritable_attribute(:xss_foliate_options, options)
155
- end
156
-
157
- #
158
- # Class method to determine whether or not this model is applying
159
- # xss_foliation to its attributes. Could be useful in test suites.
160
- #
161
- def xss_foliated?
162
- options = read_inheritable_attribute(:xss_foliate_options)
163
- ! (options.nil? || options.empty?)
164
- end
165
- end
166
-
167
- module InstanceMethods
168
-
169
- def xss_foliate_fields # :nodoc:
170
- # fix a bug with Rails internal AR::Base models that get loaded before
171
- # the plugin, like CGI::Sessions::ActiveRecordStore::Session
172
- return if xss_foliate_options.nil?
173
-
174
- self.class.columns.each do |column|
175
- next unless (column.type == :string || column.type == :text)
176
-
177
- field = column.name.to_sym
178
- value = self[field]
179
-
180
- next if value.nil? || !value.is_a?(String)
181
-
182
- if xss_foliate_options[:except].include?(field)
183
- next
184
-
185
- elsif xss_foliate_options[:strip].include?(field)
186
- fragment = Loofah.scrub_fragment(value, :strip)
187
- self[field] = fragment.nil? ? "" : fragment.to_s
188
-
189
- elsif xss_foliate_options[:prune].include?(field)
190
- fragment = Loofah.scrub_fragment(value, :prune)
191
- self[field] = fragment.nil? ? "" : fragment.to_s
192
-
193
- elsif xss_foliate_options[:escape].include?(field)
194
- fragment = Loofah.scrub_fragment(value, :escape)
195
- self[field] = fragment.nil? ? "" : fragment.to_s
196
-
197
- else # :text
198
- fragment = Loofah.scrub_fragment(value, :strip)
199
- self[field] = fragment.nil? ? "" : fragment.text
200
- end
201
- end
202
-
203
- end
204
- end
205
- end
206
- end
207
-
208
- ActiveRecord::Base.extend(Loofah::XssFoliate::ClassMethods)
209
-
210
- if defined?(LOOFAH_XSS_FOLIATE_ALL_MODELS) && LOOFAH_XSS_FOLIATE_ALL_MODELS
211
- ActiveRecord::Base.xss_foliate
212
- end
data/test/helper.rb DELETED
@@ -1,8 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
4
- require 'mocha'
5
- require 'acts_as_fu'
6
- require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "loofah"))
7
-
8
- puts "=> testing with Nokogiri #{Nokogiri::VERSION_INFO.inspect}"