html-proofer 3.4.0 → 3.5.0

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: dbcb9a266ebfc0ded83c471ce4c39b316707cdc8
4
- data.tar.gz: 95eaa7fb30840606d11dc234eb9b6e5917971100
3
+ metadata.gz: c8e32513d55bbc3b6fe0b8b238199fa0270c13a4
4
+ data.tar.gz: 6b1f6264dae93f15f2e09e4542e2f7b5d6ffff3c
5
5
  SHA512:
6
- metadata.gz: 91e54490b69b026d0e2ddefbdc6a89858c6943b3193a2f80b389835f45d10708f5b9abb919c3eece6a6827b0630afc67f2d1d49b0c60c5a669fcdf6ecfdac444
7
- data.tar.gz: a97d14e881323aa66e7a7c31bd1db5f007890d3715ba0950a9bf51f44117f076e982cc7c85a0b1e9433f5c4dfd5d5ecb12212b5d92108d4c21c7e4e3bbdc885e
6
+ metadata.gz: b9f3c3a6028eb2eae4b3fb0f999702c80c06b3a89a6a715ee7f1d5b09d12b50ca47bd739c8696d1b6ff531f647afa3b85d1ee29c04fb0c81fa5e60896787661f
7
+ data.tar.gz: b5eaa5f478efd12a53161a91218da9661a979dfe91cd1ba2873b365ec94ec0c9b2f9d8202befacb062c92da6820cd83a914e54fa9c83046a12648ba11b862337
data/bin/htmlproofer CHANGED
@@ -23,6 +23,7 @@ Mercenary.program(:htmlproofer) do |p|
23
23
  p.option 'check_html', '--check-html', 'Enables HTML validation errors from Nokogiri (default: `false`).'
24
24
  p.option 'check_img_http', '--check-img-http', 'Fails an image if it\'s marked as `http` (default: `false`).'
25
25
  p.option 'check_opengraph', '--check-opengraph', 'Enables the Open Graph checker (default: `false`).'
26
+ p.option 'check_sri', '--check-sri', 'Check that `<link>` and `<script>` external resources do use SRI (default: `false`).'
26
27
  p.option 'directory_index_file', '--directory-index-file', String, 'Sets the file to look for when a link refers to a directory. (default: `index.html`)'
27
28
  p.option 'disable_external', '--disable-external', 'If `true`, does not run the external link checker, which can take a lot of time (default: `false`)'
28
29
  p.option 'empty_alt_ignore', '--empty-alt-ignore', 'If `true`, ignores images with empty alt tags'
data/lib/html-proofer.rb CHANGED
@@ -14,6 +14,7 @@ require 'fileutils'
14
14
 
15
15
  begin
16
16
  require 'awesome_print'
17
+ require 'pry'
17
18
  rescue LoadError; end
18
19
 
19
20
  module HTMLProofer
@@ -38,8 +38,11 @@ class LinkCheck < ::HTMLProofer::Check
38
38
 
39
39
  # intentionally here because we still want valid? & missing_href? to execute
40
40
  next if @link.non_http_remote?
41
- # does the file even exist?
41
+
42
42
  if !@link.internal? && @link.remote?
43
+ # we need to skip these for now; although the domain main be valid,
44
+ # curl/Typheous inaccurately return 404s for some links. cc https://git.io/vyCFx
45
+ next if @link.try(:rel) == 'dns-prefetch'
43
46
  add_to_external_urls(@link.href)
44
47
  next
45
48
  elsif !@link.internal? && !@link.exists?
@@ -22,8 +22,19 @@ class ScriptCheck < ::HTMLProofer::Check
22
22
  elsif !@script.exists?
23
23
  add_issue("internal script #{@script.src} does not exist", line: line, content: content)
24
24
  end
25
+ check_sri(line, content) if @script.check_sri?
25
26
  end
26
27
 
27
28
  external_urls
28
29
  end
30
+
31
+ def check_sri(line, content)
32
+ if !defined? @script.integrity and !defined? @script.crossorigin
33
+ add_issue("SRI and CORS not provided in: #{@script.src}", line: line, content: content)
34
+ elsif !defined? @script.integrity
35
+ add_issue("Integrity is missing in: #{@script.src}", line: line, content: content)
36
+ elsif !defined? @script.crossorigin
37
+ add_issue("CORS not provided for external resource in: #{@script.src}", line: line, content: content)
38
+ end
39
+ end
29
40
  end
@@ -12,6 +12,7 @@ module HTMLProofer
12
12
  :check_img_http => false,
13
13
  :check_opengraph => false,
14
14
  :checks_to_ignore => [],
15
+ :check_sri => false,
15
16
  :directory_index_file => 'index.html',
16
17
  :disable_external => false,
17
18
  :empty_alt_ignore => false,
@@ -26,6 +26,10 @@ module HTMLProofer
26
26
 
27
27
  @html = check.html
28
28
 
29
+ parent_attributes = obj.ancestors.map { |a| a.try(:attributes) }
30
+ parent_attributes.pop # remove document at the end
31
+ @parent_ignorable = parent_attributes.any? { |a| !a["data-proofer-ignore"].nil? }
32
+
29
33
  # fix up missing protocols
30
34
  @href.insert 0, 'http:' if @href =~ %r{^//}
31
35
  @src.insert 0, 'http:' if @src =~ %r{^//}
@@ -75,6 +79,7 @@ module HTMLProofer
75
79
 
76
80
  def ignore?
77
81
  return true if @data_proofer_ignore
82
+ return true if @parent_ignorable
78
83
 
79
84
  return true if url =~ /^javascript:/
80
85
 
@@ -103,6 +108,10 @@ module HTMLProofer
103
108
  @check.options[:check_img_http]
104
109
  end
105
110
 
111
+ def check_sri?
112
+ @check.options[:check_sri]
113
+ end
114
+
106
115
  # path is external to the file
107
116
  def external?
108
117
  !internal?
@@ -121,7 +121,13 @@ module HTMLProofer
121
121
  end
122
122
 
123
123
  def clean_url(href)
124
- Addressable::URI.parse(href).normalize
124
+ # catch any obvious issues, like strings in port numbers
125
+ parsed = Addressable::URI.parse(href)
126
+ if href !~ %r{^([!#$&-;=?-\[\]_a-z~]|%[0-9a-fA-F]{2})+$}
127
+ parsed.normalize
128
+ else
129
+ href
130
+ end
125
131
  end
126
132
 
127
133
  def queue_request(method, href, filenames)
@@ -149,14 +155,14 @@ module HTMLProofer
149
155
  end
150
156
  elsif response.timed_out?
151
157
  handle_timeout(href, filenames, response_code)
152
- elsif response_code == 0
158
+ elsif response_code.zero?
153
159
  handle_failure(effective_url, filenames, response_code, response.return_message)
154
160
  elsif method == :head
155
161
  queue_request(:get, href, filenames)
156
162
  else
157
163
  return if @options[:only_4xx] && !response_code.between?(400, 499)
158
164
  # Received a non-successful http response.
159
- msg = "External link #{href} failed: #{response_code} #{response.return_message}"
165
+ msg = "External link #{href.chomp('/')} failed: #{response_code} #{response.return_message}"
160
166
  add_external_issue(filenames, msg, response_code)
161
167
  @cache.add(href, filenames, response_code, msg)
162
168
  end
@@ -179,21 +185,21 @@ module HTMLProofer
179
185
 
180
186
  return unless body_doc.xpath(xpath).empty?
181
187
 
182
- msg = "External link #{href} failed: #{effective_url} exists, but the hash '#{hash}' does not"
188
+ msg = "External link #{href.chomp('/')} failed: #{effective_url} exists, but the hash '#{hash}' does not"
183
189
  add_external_issue(filenames, msg, response.code)
184
190
  @cache.add(href, filenames, response.code, msg)
185
191
  true
186
192
  end
187
193
 
188
194
  def handle_timeout(href, filenames, response_code)
189
- msg = "External link #{href} failed: got a time out (response code #{response_code})"
195
+ msg = "External link #{href.chomp('/')} failed: got a time out (response code #{response_code})"
190
196
  @cache.add(href, filenames, 0, msg)
191
197
  return if @options[:only_4xx]
192
198
  add_external_issue(filenames, msg, response_code)
193
199
  end
194
200
 
195
201
  def handle_failure(href, filenames, response_code, return_message)
196
- msg = "External link #{href} failed: response code #{response_code} means something's wrong.
202
+ msg = "External link #{href.chomp('/')} failed: response code #{response_code} means something's wrong.
197
203
  It's possible libcurl couldn't connect to the server or perhaps the request timed out.
198
204
  Sometimes, making too many requests at once also breaks things.
199
205
  Either way, the return message (if any) from the server is: #{return_message}"
@@ -1,3 +1,3 @@
1
1
  module HTMLProofer
2
- VERSION = '3.4.0'.freeze
2
+ VERSION = '3.5.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html-proofer
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.0
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garen Torikian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-16 00:00:00.000000000 Z
11
+ date: 2017-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mercenary
@@ -170,6 +170,20 @@ dependencies:
170
170
  - - ">="
171
171
  - !ruby/object:Gem::Version
172
172
  version: '0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: pry
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: 0.10.0
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - "~>"
185
+ - !ruby/object:Gem::Version
186
+ version: 0.10.0
173
187
  - !ruby/object:Gem::Dependency
174
188
  name: awesome_print
175
189
  requirement: !ruby/object:Gem::Requirement