erb_lint 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8866aae317226178c623de53d4c5e0791643c894
4
- data.tar.gz: fac55efcf4a15f251f537af97039b8669960c00b
3
+ metadata.gz: 3a211bea7ec247bcf1d79ede8f37db1b6b7d1b8c
4
+ data.tar.gz: 362ca7b4ffb1f184818889166cb572198c1def7e
5
5
  SHA512:
6
- metadata.gz: b92425a8c4fbe2c65fde42a8dab091c841e2bc0f70b29833e49c06fc99acc85b42639dc9129f200b99195930e9f7fbb96d58fdcaaefb947cd40ad76008ffe765
7
- data.tar.gz: aefbb18d6756d5e08045c4d5c8c0afb6ef8fb897f0b73c72fe905158b40d1cbc1114bfada2ec59029165b1a9d72930a172c17b6cfe059a11283bf8ec80e41bc9
6
+ metadata.gz: 45c2ff7d03c2ec43e37562887ad9cdc9f396b0084bf290036a848aa820fed661a0f99a49d120be62100aa15c640fa4374f5937c9accb0066a06028632ac56e8f
7
+ data.tar.gz: 16279ef10a1f004fe97309dde027de0bf244ac0a9e047b9a0ff04be73d5d9d71494e1e2ab08d584b9123ee96f35a05525ff7b8ff09d005d3f75f000c009eacbf
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'better_html'
4
+
3
5
  module ERBLint
4
6
  module Linters
5
7
  # Checks for deprecated classes in the start tags of HTML elements.
@@ -22,144 +24,65 @@ module ERBLint
22
24
  @addendum = config.fetch('addendum', '')
23
25
  end
24
26
 
25
- protected
26
-
27
- def lint_lines(lines)
27
+ def lint_file(file_content)
28
28
  errors = []
29
-
30
- lines.each_with_index do |line, index|
31
- start_tags = StartTagHelper.start_tags(line)
32
- start_tags.each do |start_tag|
33
- start_tag.attributes.select(&:class?).each do |class_attr|
34
- class_attr.value.split(' ').each do |class_name|
35
- errors.push(*generate_errors(class_name, index + 1))
36
- end
37
- end
38
- end
29
+ iterator = build_iterator(file_content)
30
+ each_class_name_with_line(iterator) do |class_name, line|
31
+ errors.push(*generate_errors(class_name, line))
32
+ end
33
+ each_texthtml_script(iterator) do |text_node|
34
+ errors.push(*lint_file(text_node.content))
39
35
  end
40
36
  errors
41
37
  end
42
38
 
43
39
  private
44
40
 
45
- def generate_errors(class_name, line_number)
46
- violated_rules(class_name).map do |violated_rule|
47
- suggestion = " #{violated_rule[:suggestion]}".rstrip
48
- message = "Deprecated class `%s` detected matching the pattern `%s`.%s #{@addendum}".strip
49
- {
50
- line: line_number,
51
- message: format(message, class_name, violated_rule[:class_expr], suggestion)
52
- }
53
- end
41
+ def build_iterator(file_content)
42
+ BetterHtml::NodeIterator.new(file_content, template_language: :html)
54
43
  end
55
44
 
56
- def violated_rules(class_name)
57
- @deprecated_ruleset.select do |deprecated_rule|
58
- /\A#{deprecated_rule[:class_expr]}\z/.match(class_name)
45
+ def each_class_name_with_line(iterator)
46
+ each_element_with_index(iterator) do |element, _index|
47
+ klass = element.find_attr('class')
48
+ next unless klass
49
+ klass.value_without_quotes.split(' ').each do |class_name|
50
+ yield class_name, klass.name_parts.first.location.line
51
+ end
59
52
  end
60
53
  end
61
- end
62
-
63
- # Provides methods and classes for finding HTML start tags and their attributes.
64
- module StartTagHelper
65
- # These patterns cover a superset of the W3 HTML5 specification.
66
- # Additional cases not included in the spec include those that are still rendered by some browsers.
67
-
68
- # Attribute Patterns
69
- # https://www.w3.org/TR/html5/syntax.html#syntax-attributes
70
-
71
- # attribute names must be non empty and can't contain a certain set of special characters
72
- ATTRIBUTE_NAME_PATTERN = %r{[^\s"'>\/=]+}
73
-
74
- ATTRIBUTE_VALUE_PATTERN = %r{
75
- "([^"]*)" | # double-quoted value
76
- '([^']*)' | # single-quoted value
77
- ([^\s"'=<>`]+) # unquoted non-empty value without special characters
78
- }x
79
-
80
- # attributes can be empty or have an attribute value
81
- ATTRIBUTE_PATTERN = %r{
82
- #{ATTRIBUTE_NAME_PATTERN} # attribute name
83
- (
84
- \s*=\s* # any whitespace around equals sign
85
- (#{ATTRIBUTE_VALUE_PATTERN}) # attribute value
86
- )? # attributes can be empty or have an assignemnt.
87
- }x
88
-
89
- # Start tag Patterns
90
- # https://www.w3.org/TR/html5/syntax.html#syntax-start-tag
91
-
92
- TAG_NAME_PATTERN = /[A-Za-z0-9]+/ # maybe add _ < ? etc later since it gets interpreted by some browsers
93
54
 
94
- START_TAG_PATTERN = %r{
95
- <(#{TAG_NAME_PATTERN}) # start of tag with tag name
96
- (
97
- (
98
- \s+ # required whitespace between tag name and first attribute and between attributes
99
- #{ATTRIBUTE_PATTERN} # attributes
100
- )*
101
- )? # having an attribute block is optional
102
- \/?> # void or foreign elements can have a slash before tag close
103
- }x
104
-
105
- # Represents and provides an interface for a start tag found in the HTML.
106
- class StartTag
107
- attr_accessor :tag_name, :attributes
108
-
109
- def initialize(tag_name, attributes)
110
- @tag_name = tag_name
111
- @attributes = attributes
55
+ def each_element_with_index(iterator)
56
+ iterator.nodes.each_with_index do |node, index|
57
+ yield node, index if node.element?
112
58
  end
113
59
  end
114
60
 
115
- # Represents and provides an interface for an attribute found in a start tag in the HTML.
116
- class Attribute
117
- ATTR_NAME_CLASS_PATTERN = /\Aclass\z/i # attribute names are case-insensitive
118
- attr_accessor :attribute_name, :value
119
-
120
- def initialize(attribute_name, value)
121
- @attribute_name = attribute_name
122
- @value = value
123
- end
61
+ def each_texthtml_script(iterator)
62
+ each_element_with_index(iterator) do |element, index|
63
+ type = element.find_attr('type')
64
+ next unless type
65
+ next unless 'text/html' == type.value_without_quotes
66
+ next_node = iterator.nodes[index + 1]
124
67
 
125
- def class?
126
- ATTR_NAME_CLASS_PATTERN.match(@attribute_name)
68
+ yield next_node if next_node&.text?
127
69
  end
128
70
  end
129
71
 
130
- class << self
131
- def start_tags(line)
132
- # TODO: Implement String Scanner to track quotes before the start tag begins to ensure that it is
133
- # not enclosed inside of a string. Alternatively this problem would be solved by using
134
- # a 3rd party parser like Nokogiri::XML
135
-
136
- start_tag_matching_groups = line.scan(/(#{START_TAG_PATTERN})/)
137
- start_tag_matching_groups.map do |start_tag_matching_group|
138
- tag_name = start_tag_matching_group[1]
139
-
140
- # attributes_string can be nil if there is no space after the tag name (and therefore no attributes).
141
- attributes_string = start_tag_matching_group[2] || ''
142
-
143
- attribute_list = attributes(attributes_string)
144
-
145
- StartTag.new(tag_name, attribute_list)
146
- end
72
+ def generate_errors(class_name, line_number)
73
+ violated_rules(class_name).map do |violated_rule|
74
+ suggestion = " #{violated_rule[:suggestion]}".rstrip
75
+ message = "Deprecated class `%s` detected matching the pattern `%s`.%s #{@addendum}".strip
76
+ {
77
+ line: line_number,
78
+ message: format(message, class_name, violated_rule[:class_expr], suggestion)
79
+ }
147
80
  end
81
+ end
148
82
 
149
- private
150
-
151
- def attributes(attributes_string)
152
- attributes_string.scan(/(#{ATTRIBUTE_PATTERN})/).map do |attribute_matching_group|
153
- entire_string = attribute_matching_group[0]
154
- value_with_equal_sign = attribute_matching_group[1] || '' # This can be nil if attribute is empty
155
- name = entire_string.sub(value_with_equal_sign, '')
156
-
157
- # The 3 captures [3..5] are the possibilities specified in ATTRIBUTE_VALUE_PATTERN
158
- possible_value_formats = attribute_matching_group[3..5]
159
- value = possible_value_formats.reduce { |a, e| a.nil? ? e : a }
160
-
161
- Attribute.new(name, value)
162
- end
83
+ def violated_rules(class_name)
84
+ @deprecated_ruleset.select do |deprecated_rule|
85
+ /\A#{deprecated_rule[:class_expr]}\z/.match(class_name)
163
86
  end
164
87
  end
165
88
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'better_html'
4
+ require 'better_html/test_helper/safe_erb_tester'
5
+
6
+ module ERBLint
7
+ module Linters
8
+ # Detect unsafe ruby interpolations into javascript.
9
+ class ErbSafety < Linter
10
+ include LinterRegistry
11
+ include BetterHtml::TestHelper::SafeErbTester
12
+
13
+ def initialize(config)
14
+ end
15
+
16
+ def lint_file(file_content)
17
+ errors = []
18
+ tester = Tester.new(file_content)
19
+ tester.errors.each do |error|
20
+ errors << format_error(error)
21
+ end
22
+ errors
23
+ end
24
+
25
+ private
26
+
27
+ def format_error(error)
28
+ {
29
+ line: error.token.location.line,
30
+ message: error.message
31
+ }
32
+ end
33
+ end
34
+ end
35
+ end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erb_lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Chan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-27 00:00:00.000000000 Z
11
+ date: 2017-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: html_tokenizer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: better_html
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.5
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.5
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: rspec
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -49,6 +77,7 @@ files:
49
77
  - lib/erb_lint/linter.rb
50
78
  - lib/erb_lint/linter_registry.rb
51
79
  - lib/erb_lint/linters/deprecated_classes.rb
80
+ - lib/erb_lint/linters/erb_safety.rb
52
81
  - lib/erb_lint/linters/final_newline.rb
53
82
  - lib/erb_lint/runner.rb
54
83
  homepage: https://github.com/justinthec/erb-lint