antisamy 0.2.1 → 0.3.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. data/CHANGELOG.rdoc +13 -0
  2. data/LICENSE.txt +20 -20
  3. data/README.rdoc +41 -41
  4. data/lib/antisamy.rb +46 -46
  5. data/lib/antisamy/css/css_filter.rb +187 -187
  6. data/lib/antisamy/css/css_scanner.rb +84 -84
  7. data/lib/antisamy/css/css_validator.rb +128 -128
  8. data/lib/antisamy/csspool/rsac.rb +1 -1
  9. data/lib/antisamy/csspool/rsac/sac.rb +14 -14
  10. data/lib/antisamy/csspool/rsac/sac/conditions.rb +5 -5
  11. data/lib/antisamy/csspool/rsac/sac/conditions/attribute_condition.rb +50 -50
  12. data/lib/antisamy/csspool/rsac/sac/conditions/begin_hyphen_condition.rb +18 -18
  13. data/lib/antisamy/csspool/rsac/sac/conditions/class_condition.rb +18 -18
  14. data/lib/antisamy/csspool/rsac/sac/conditions/combinator_condition.rb +36 -36
  15. data/lib/antisamy/csspool/rsac/sac/conditions/condition.rb +29 -29
  16. data/lib/antisamy/csspool/rsac/sac/conditions/id_condition.rb +23 -23
  17. data/lib/antisamy/csspool/rsac/sac/conditions/one_of_condition.rb +18 -18
  18. data/lib/antisamy/csspool/rsac/sac/conditions/pseudo_class_condition.rb +20 -20
  19. data/lib/antisamy/csspool/rsac/sac/document_handler.rb +66 -66
  20. data/lib/antisamy/csspool/rsac/sac/error_handler.rb +13 -13
  21. data/lib/antisamy/csspool/rsac/sac/generated_parser.rb +1012 -1012
  22. data/lib/antisamy/csspool/rsac/sac/generated_property_parser.rb +9284 -9284
  23. data/lib/antisamy/csspool/rsac/sac/lexeme.rb +27 -27
  24. data/lib/antisamy/csspool/rsac/sac/lexical_unit.rb +201 -201
  25. data/lib/antisamy/csspool/rsac/sac/parse_exception.rb +4 -4
  26. data/lib/antisamy/csspool/rsac/sac/parser.rb +109 -109
  27. data/lib/antisamy/csspool/rsac/sac/property_parser.rb +44 -44
  28. data/lib/antisamy/csspool/rsac/sac/selectors.rb +5 -5
  29. data/lib/antisamy/csspool/rsac/sac/selectors/child_selector.rb +36 -36
  30. data/lib/antisamy/csspool/rsac/sac/selectors/conditional_selector.rb +45 -45
  31. data/lib/antisamy/csspool/rsac/sac/selectors/descendant_selector.rb +36 -36
  32. data/lib/antisamy/csspool/rsac/sac/selectors/element_selector.rb +35 -35
  33. data/lib/antisamy/csspool/rsac/sac/selectors/selector.rb +25 -25
  34. data/lib/antisamy/csspool/rsac/sac/selectors/sibling_selector.rb +35 -35
  35. data/lib/antisamy/csspool/rsac/sac/selectors/simple_selector.rb +21 -21
  36. data/lib/antisamy/csspool/rsac/sac/token.rb +25 -25
  37. data/lib/antisamy/csspool/rsac/sac/tokenizer.rb +185 -185
  38. data/lib/antisamy/csspool/rsac/stylesheet.rb +3 -3
  39. data/lib/antisamy/csspool/rsac/stylesheet/rule.rb +20 -20
  40. data/lib/antisamy/csspool/rsac/stylesheet/stylesheet.rb +76 -76
  41. data/lib/antisamy/html/handler.rb +112 -99
  42. data/lib/antisamy/html/sax_filter.rb +305 -302
  43. data/lib/antisamy/html/scanner.rb +47 -43
  44. data/lib/antisamy/model/attribute.rb +19 -19
  45. data/lib/antisamy/model/css_property.rb +39 -39
  46. data/lib/antisamy/model/tag.rb +31 -31
  47. data/lib/antisamy/policy.rb +577 -545
  48. data/lib/antisamy/scan_results.rb +89 -89
  49. data/spec/antisamy_spec.rb +208 -142
  50. data/spec/spec_helper.rb +12 -12
  51. metadata +79 -81
@@ -1,84 +1,84 @@
1
- require 'open-uri'
2
- module AntiSamy
3
- # Css Scanner class
4
- class CssScanner
5
- attr_accessor :policy, :errors
6
- # Create a scanner with a given policy
7
- def initialize(policy)
8
- @policy = policy
9
- @errors = []
10
- end
11
- # Scan the input using the provided input and output encoding
12
- # will raise an error if nil input or the maximum input size is exceeded
13
- def scan_inline(a_value,name,max_input)
14
- return scan_sheet("#{name} { #{a_value} }",max_input,name)
15
- end
16
-
17
- def scan_sheet(input,limit,tag = nil)
18
- raise ArgumentError if input.nil?
19
- raise ScanError, "Max input Exceeded #{input.size} > #{limit}" if input.size > limit
20
- space_remaining = limit - input.size
21
- # check poilcy stuff
22
- if input =~ /^\s*<!\[CDATA\[(.*)\]\]>\s*$/
23
- input = $1
24
- end
25
- # validator needs token sizes
26
- filter = CssFilter.new(@policy,tag)
27
- parser = RSAC::Parser.new(filter)
28
- parser.error_handler = filter
29
- parser.logger = filter
30
- parser.parse(input)
31
- # Populate the results
32
- results = ScanResults.new(Time.now)
33
- if @policy.directive(Policy::USE_XHTML)
34
- result.clean_html = "<![CDATA[#{filter.clean}]]>"
35
- else
36
- results.clean_html = filter.clean
37
- end
38
- results.messages = filter.errors
39
- # check for style sheets
40
- sheets = filter.style_sheets
41
- max_sheets = @policy.directive(Policy::MAX_SHEETS).to_i
42
- max_sheets ||= 1
43
- import_sheets = 0
44
- if sheets.size > 0
45
- timeout = 1000
46
- if @policy.directive(Policy::CONN_TIMEOUT)
47
- timeout = @policy.directive(Policy::CONN_TIMEOUT).to_i
48
- end
49
- timeout /= 1000
50
- sheets.each do |sheet|
51
- sheet_content = ''
52
- begin
53
- open(sheet,{:read_timeout => timeout}) do |f|
54
- sheet_content = f.read(space_remaining)
55
- end
56
- space_remaining -= sheet_content.size
57
- if import_sheets > max_sheets
58
- # skip any remaing sheets if we exceeded the import count
59
- results.messages << ScanMessage.new(ScanMessage::ERROR_CSS_IMPORT_EXCEEDED,"@import",sheet)
60
- break;
61
- end
62
-
63
- if sheet_content.size > 0
64
- #r = scan_sheet(sheet_content,space_remaining)
65
- parser.parse(sheet_content)
66
- #results.messages << r.messages
67
- #results.messages.flatten!
68
- import_sheets += 1
69
- end
70
-
71
- if space_remaining <= 0 or sheet_content.empty?
72
- results.messages << ScanMessage.new(ScanMessage::ERROR_CSS_IMPORT_INPUT_SIZE,"@import",sheet)
73
- break
74
- end
75
- rescue Exception => e
76
- results.messages << ScanMessage.new(ScanMessage::ERROR_CSS_IMPORT_FAILURE,"@import",sheet)
77
- end
78
- # check the sheet rules
79
- end
80
- end
81
- results
82
- end
83
- end
84
- end
1
+ require 'open-uri'
2
+ module AntiSamy
3
+ # Css Scanner class
4
+ class CssScanner
5
+ attr_accessor :policy, :errors
6
+ # Create a scanner with a given policy
7
+ def initialize(policy)
8
+ @policy = policy
9
+ @errors = []
10
+ end
11
+ # Scan the input using the provided input and output encoding
12
+ # will raise an error if nil input or the maximum input size is exceeded
13
+ def scan_inline(a_value,name,max_input)
14
+ return scan_sheet("#{name} { #{a_value} }",max_input,name)
15
+ end
16
+
17
+ def scan_sheet(input,limit,tag = nil)
18
+ raise ArgumentError if input.nil?
19
+ raise ScanError, "Max input Exceeded #{input.size} > #{limit}" if input.size > limit
20
+ space_remaining = limit - input.size
21
+ # check poilcy stuff
22
+ if input =~ /^\s*<!\[CDATA\[(.*)\]\]>\s*$/
23
+ input = $1
24
+ end
25
+ # validator needs token sizes
26
+ filter = CssFilter.new(@policy,tag)
27
+ parser = RSAC::Parser.new(filter)
28
+ parser.error_handler = filter
29
+ parser.logger = filter
30
+ parser.parse(input)
31
+ # Populate the results
32
+ results = ScanResults.new(Time.now)
33
+ if @policy.directive(Policy::USE_XHTML)
34
+ result.clean_html = "<![CDATA[#{filter.clean}]]>"
35
+ else
36
+ results.clean_html = filter.clean
37
+ end
38
+ results.messages = filter.errors
39
+ # check for style sheets
40
+ sheets = filter.style_sheets
41
+ max_sheets = @policy.directive(Policy::MAX_SHEETS).to_i
42
+ max_sheets ||= 1
43
+ import_sheets = 0
44
+ if sheets.size > 0
45
+ timeout = 1000
46
+ if @policy.directive(Policy::CONN_TIMEOUT)
47
+ timeout = @policy.directive(Policy::CONN_TIMEOUT).to_i
48
+ end
49
+ timeout /= 1000
50
+ sheets.each do |sheet|
51
+ sheet_content = ''
52
+ begin
53
+ open(sheet,{:read_timeout => timeout}) do |f|
54
+ sheet_content = f.read(space_remaining)
55
+ end
56
+ space_remaining -= sheet_content.size
57
+ if import_sheets > max_sheets
58
+ # skip any remaing sheets if we exceeded the import count
59
+ results.messages << ScanMessage.new(ScanMessage::ERROR_CSS_IMPORT_EXCEEDED,"@import",sheet)
60
+ break;
61
+ end
62
+
63
+ if sheet_content.size > 0
64
+ #r = scan_sheet(sheet_content,space_remaining)
65
+ parser.parse(sheet_content)
66
+ #results.messages << r.messages
67
+ #results.messages.flatten!
68
+ import_sheets += 1
69
+ end
70
+
71
+ if space_remaining <= 0 or sheet_content.empty?
72
+ results.messages << ScanMessage.new(ScanMessage::ERROR_CSS_IMPORT_INPUT_SIZE,"@import",sheet)
73
+ break
74
+ end
75
+ rescue Exception => e
76
+ results.messages << ScanMessage.new(ScanMessage::ERROR_CSS_IMPORT_FAILURE,"@import",sheet)
77
+ end
78
+ # check the sheet rules
79
+ end
80
+ end
81
+ results
82
+ end
83
+ end
84
+ end
@@ -1,129 +1,129 @@
1
- module AntiSamy
2
- class CssValidator
3
-
4
- def initialize(policy)
5
- @policy = policy
6
- end
7
-
8
- # Check to see if this selector is valid according to the policy
9
- def valid_selector?(name,selector)
10
- #puts selector.inspect
11
- return false if selector.nil?
12
- case selector.selector_type
13
- when :SAC_CHILD_SELECTOR
14
- return valid_selector?(name,selector.selector) && valid_selector?(name,selector.ancestor)
15
- when :SAC_CONDITIONAL_SELECTOR
16
- return valid_selector?(name,selector.selector) && valid_condition?(name,selector.condition)
17
- when :SAC_DESCENDANT_SELECTOR
18
- return valid_selector?(name,selector.selector) && valid_selector?(name,selector.ancestor)
19
- when :SAC_ELEMENT_NODE_SELECTOR
20
- return valid_simple_selector(selector)
21
- when :SAC_DIRECT_ADJACENT_SELECTOR
22
- return valid_selector?(name,selector.selector) && valid_selector?(name,selector.sibling)
23
- when :SAC_ANY_NODE_SELECTOR
24
- return valid_simple_selector(selector)
25
- else
26
- raise ScanError, name
27
- end
28
- end
29
-
30
- # Validate a simple selector
31
- def valid_simple_selector(selector) #:nodoc:
32
- valid = false
33
- inclusion = @policy.expression("cssElementSelector")
34
- exclusion = @policy.expression("cssElementExclusion")
35
- begin
36
- css = selector.to_css
37
- valid = (css =~ inclusion) and (css !~ exclusion)
38
- rescue Exception=> e
39
- end
40
- valid
41
- end
42
-
43
- # Check if a given condition is valid according to the policy
44
- def valid_condition?(name,condition)
45
- type = condition.condition_type
46
- case type
47
- when :SAC_AND_CONDITION
48
- a = condition.first
49
- b = condition.second
50
- return valid_condition?(name,a) && valid_condition?(name,b)
51
- when :SAC_CLASS_CONDITION
52
- inclusion = @policy.expression("cssClassSelector")
53
- exclusion = @policy.expression("cssClassExclusion")
54
- return validate_condition(condition,inclusion,exclusion)
55
- when :SAC_ID_CONDITION
56
- inclusion = @policy.expression("cssIDSelector")
57
- exclusion = @policy.expression("cssIDExclusion")
58
- return validate_condition(condition,inclusion,exclusion)
59
- when :SAC_PSEUDO_CLASS_CONDITION
60
- inclusion = @policy.expression("cssPseudoElementSelector")
61
- exclusion = @policy.expression("cssPsuedoElementExclusion")
62
- return validate_condition(condition,inclusion,exclusion)
63
- when :SAC_ONE_OF_ATTRIBUTE_CONDITION
64
- inclusion = @policy.expression("cssAttributeSelector")
65
- exclusion = @policy.expression("cssAttributeExclusion")
66
- return validate_condition(condition,inclusion,exclusion)
67
- when :SAC_ATTRIBUTE_CONDITION
68
- inclusion = @policy.expression("cssAttributeSelector")
69
- exclusion = @policy.expression("cssAttributeExclusion")
70
- return validate_condition(condition,inclusion,exclusion)
71
- when :SAC_BEGIN_HYPHEN_ATTRIBUTE_CONDITION
72
- inclusion = @policy.expression("cssAttributeSelector")
73
- exclusion = @policy.expression("cssAttributeExclusion")
74
- return validate_condition(condition,inclusion,exclusion)
75
- else
76
- raise ScanError, name
77
- end
78
- end
79
-
80
- # validate the actual condition
81
- def validate_condition(condition,inclusion,exclusion) #:nodoc:
82
- valid = false
83
- begin
84
- css = condition.to_css
85
- valid = (css =~ inclusion) and (css !~ exclusion)
86
- rescue Exception=> e
87
- end
88
- valid
89
- end
90
-
91
- # Validate each property value according to teh policy
92
- def valid_property?(name,value)
93
- prop = @policy.property(name) unless name.nil?
94
- return false if prop.nil?
95
- value.each do |prop_value|
96
- v = prop_value.string_value
97
- return false unless validate_value(prop,v)
98
- end
99
- return true
100
- end
101
-
102
- # is this a valid property value
103
- def validate_value(property,value) #:nodoc:
104
- valid = false
105
- # Check static strings
106
- property.values.each do |al_val|
107
- valid = true if al_val.downcase.eql?(value.downcase)
108
- end
109
- # Check regular expressions
110
- unless valid
111
- property.expressions.each do |xp_val|
112
- valid = true if value =~ xp_value
113
- end
114
- end
115
- # check short hand
116
- unless valid
117
- property.refs.each do |ref|
118
- real = @policy.property(ref)
119
- if real
120
- valid = validate_value(real,value)
121
- end
122
- end
123
- end
124
- # We will check media above.
125
- return valid
126
- end
127
-
128
- end
1
+ module AntiSamy
2
+ class CssValidator
3
+
4
+ def initialize(policy)
5
+ @policy = policy
6
+ end
7
+
8
+ # Check to see if this selector is valid according to the policy
9
+ def valid_selector?(name,selector)
10
+ #puts selector.inspect
11
+ return false if selector.nil?
12
+ case selector.selector_type
13
+ when :SAC_CHILD_SELECTOR
14
+ return valid_selector?(name,selector.selector) && valid_selector?(name,selector.ancestor)
15
+ when :SAC_CONDITIONAL_SELECTOR
16
+ return valid_selector?(name,selector.selector) && valid_condition?(name,selector.condition)
17
+ when :SAC_DESCENDANT_SELECTOR
18
+ return valid_selector?(name,selector.selector) && valid_selector?(name,selector.ancestor)
19
+ when :SAC_ELEMENT_NODE_SELECTOR
20
+ return valid_simple_selector(selector)
21
+ when :SAC_DIRECT_ADJACENT_SELECTOR
22
+ return valid_selector?(name,selector.selector) && valid_selector?(name,selector.sibling)
23
+ when :SAC_ANY_NODE_SELECTOR
24
+ return valid_simple_selector(selector)
25
+ else
26
+ raise ScanError, name
27
+ end
28
+ end
29
+
30
+ # Validate a simple selector
31
+ def valid_simple_selector(selector) #:nodoc:
32
+ valid = false
33
+ inclusion = @policy.expression("cssElementSelector")
34
+ exclusion = @policy.expression("cssElementExclusion")
35
+ begin
36
+ css = selector.to_css
37
+ valid = (css =~ inclusion) and (css !~ exclusion)
38
+ rescue Exception=> e
39
+ end
40
+ valid
41
+ end
42
+
43
+ # Check if a given condition is valid according to the policy
44
+ def valid_condition?(name,condition)
45
+ type = condition.condition_type
46
+ case type
47
+ when :SAC_AND_CONDITION
48
+ a = condition.first
49
+ b = condition.second
50
+ return valid_condition?(name,a) && valid_condition?(name,b)
51
+ when :SAC_CLASS_CONDITION
52
+ inclusion = @policy.expression("cssClassSelector")
53
+ exclusion = @policy.expression("cssClassExclusion")
54
+ return validate_condition(condition,inclusion,exclusion)
55
+ when :SAC_ID_CONDITION
56
+ inclusion = @policy.expression("cssIDSelector")
57
+ exclusion = @policy.expression("cssIDExclusion")
58
+ return validate_condition(condition,inclusion,exclusion)
59
+ when :SAC_PSEUDO_CLASS_CONDITION
60
+ inclusion = @policy.expression("cssPseudoElementSelector")
61
+ exclusion = @policy.expression("cssPsuedoElementExclusion")
62
+ return validate_condition(condition,inclusion,exclusion)
63
+ when :SAC_ONE_OF_ATTRIBUTE_CONDITION
64
+ inclusion = @policy.expression("cssAttributeSelector")
65
+ exclusion = @policy.expression("cssAttributeExclusion")
66
+ return validate_condition(condition,inclusion,exclusion)
67
+ when :SAC_ATTRIBUTE_CONDITION
68
+ inclusion = @policy.expression("cssAttributeSelector")
69
+ exclusion = @policy.expression("cssAttributeExclusion")
70
+ return validate_condition(condition,inclusion,exclusion)
71
+ when :SAC_BEGIN_HYPHEN_ATTRIBUTE_CONDITION
72
+ inclusion = @policy.expression("cssAttributeSelector")
73
+ exclusion = @policy.expression("cssAttributeExclusion")
74
+ return validate_condition(condition,inclusion,exclusion)
75
+ else
76
+ raise ScanError, name
77
+ end
78
+ end
79
+
80
+ # validate the actual condition
81
+ def validate_condition(condition,inclusion,exclusion) #:nodoc:
82
+ valid = false
83
+ begin
84
+ css = condition.to_css
85
+ valid = (css =~ inclusion) and (css !~ exclusion)
86
+ rescue Exception=> e
87
+ end
88
+ valid
89
+ end
90
+
91
+ # Validate each property value according to teh policy
92
+ def valid_property?(name,value)
93
+ prop = @policy.property(name) unless name.nil?
94
+ return false if prop.nil?
95
+ value.each do |prop_value|
96
+ v = prop_value.string_value
97
+ return false unless validate_value(prop,v)
98
+ end
99
+ return true
100
+ end
101
+
102
+ # is this a valid property value
103
+ def validate_value(property,value) #:nodoc:
104
+ valid = false
105
+ # Check static strings
106
+ property.values.each do |al_val|
107
+ valid = true if al_val.downcase.eql?(value.downcase)
108
+ end
109
+ # Check regular expressions
110
+ unless valid
111
+ property.expressions.each do |xp_val|
112
+ valid = true if value =~ xp_value
113
+ end
114
+ end
115
+ # check short hand
116
+ unless valid
117
+ property.refs.each do |ref|
118
+ real = @policy.property(ref)
119
+ if real
120
+ valid = validate_value(real,value)
121
+ end
122
+ end
123
+ end
124
+ # We will check media above.
125
+ return valid
126
+ end
127
+
128
+ end
129
129
  end
@@ -1 +1 @@
1
- require 'antisamy/csspool/rsac/sac'
1
+ require 'antisamy/csspool/rsac/sac'
@@ -1,14 +1,14 @@
1
- require "antisamy/csspool/rsac/sac/conditions"
2
- require "antisamy/csspool/rsac/sac/selectors"
3
- require "antisamy/csspool/rsac/sac/parser"
4
- require "antisamy/csspool/rsac/stylesheet"
5
-
6
- module RSAC
7
- class << self
8
- def parse(text)
9
- parser = CSS::SAC::Parser.new
10
- parser.parse(text)
11
- parser
12
- end
13
- end
14
- end
1
+ require "antisamy/csspool/rsac/sac/conditions"
2
+ require "antisamy/csspool/rsac/sac/selectors"
3
+ require "antisamy/csspool/rsac/sac/parser"
4
+ require "antisamy/csspool/rsac/stylesheet"
5
+
6
+ module RSAC
7
+ class << self
8
+ def parse(text)
9
+ parser = CSS::SAC::Parser.new
10
+ parser.parse(text)
11
+ parser
12
+ end
13
+ end
14
+ end