antisamy 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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