ndr_support 5.4.2 → 5.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
- SHA1:
3
- metadata.gz: 07ba3c21f982adf4857b352bf87e1046dd393090
4
- data.tar.gz: 5dd49f19587d0071d82565e1912a775ec065d986
2
+ SHA256:
3
+ metadata.gz: 6e21f71716e6733363c47fb4fb1f457ec616a913902729cb40fa8a227a77d530
4
+ data.tar.gz: 9b251bf890fb3d835c256fe81d136d51327e749970c21bad0a77529e12655384
5
5
  SHA512:
6
- metadata.gz: 58504a8eabba9ab32fb4ab2a0e6f935101614f92c7bcd7eb6db606d3404394290cd8f6f8d7921d7606ca42c1924e1183a7301882558a912c15c39c5644484088
7
- data.tar.gz: cdcbd43264a63a9427bfdca4c5e0f57e51a8d29fb3273e247d7c06004dba86d98b788effc60823b33e8ba1950ef60ab78217cb4cdba6b67ff2b6d5174c99ce67
6
+ metadata.gz: f603f2982d2615bfc0a4b1963f324ee633a1e9fa8248c575ae52a74403b3dc514a1cbec13b2f162f351e297d6d3df50e9cd8ace0692571f3f8202603fd969598
7
+ data.tar.gz: 9c3248c3286b5eba6ebf757a8e1f43958c585718f768de8798be3d482a5cfda28e36dfba1286782d9701d587aa3bc7465828f5c576e17bf0ccce377ce974743f
@@ -0,0 +1,21 @@
1
+ ## [Unreleased]
2
+ *no unreleased changes*
3
+
4
+ ## 5.5.0 / 2018-11-16
5
+ ### Added
6
+ * Add `ThreatScanner` to wrap ClamAV for virus detection (#10)
7
+
8
+ ### Fixed
9
+ * Added missing bank holidays for 2017-2019 (#9)
10
+
11
+ ## 5.4.2 / 2018-08-06
12
+ ### Fixed
13
+ * Fix Daterange equality comparisons
14
+
15
+ ## 5.4.1 / 2018-07-09
16
+ ### Fixed
17
+ * ensure Range#exclude? is available
18
+
19
+ ## 5.4.0 / 2018-05-09
20
+ ### Added
21
+ * Support Rails 5.2
@@ -14,6 +14,10 @@ file safety:
14
14
  risk. As a secondary protection, it''s excluded from the .gem file by ndr_support.gemspec'
15
15
  reviewed_by: brian.shand
16
16
  safe_revision: c88f5ac8c12fd657bb142144e0d3afaa7f9bc361
17
+ CHANGELOG.md:
18
+ comments:
19
+ reviewed_by: josh.pencheon
20
+ safe_revision: ea1f7dc9a164981570ee2ad7c38197fdb17a6880
17
21
  CODE_OF_CONDUCT.md:
18
22
  comments:
19
23
  reviewed_by: timgentry
@@ -57,15 +61,15 @@ file safety:
57
61
  lib/ndr_support.rb:
58
62
  comments:
59
63
  reviewed_by: josh.pencheon
60
- safe_revision: 2685f35c907af6968a69eabb5ab9424b490d0f40
64
+ safe_revision: ed8ff421cc9353456af13a37049a07ce2545aac1
61
65
  lib/ndr_support/array.rb:
62
66
  comments:
63
67
  reviewed_by: pauleves
64
68
  safe_revision: 4a4ed24d2cfe7e1736baadf4cf6e0fece6823be1
65
69
  lib/ndr_support/concerns/working_days.rb:
66
70
  comments:
67
- reviewed_by: pauleves
68
- safe_revision: 5f9c98dcad6f6889d2431eb98cf07b1f5c3e57be
71
+ reviewed_by: josh.pencheon
72
+ safe_revision: e5671bd9435490d521028d02bc91ccb47c74c580
69
73
  lib/ndr_support/date_and_time_extensions.rb:
70
74
  comments:
71
75
  reviewed_by: josh.pencheon
@@ -138,14 +142,18 @@ file safety:
138
142
  comments:
139
143
  reviewed_by: timgentry
140
144
  safe_revision: 62337584a32e5c30c2e9af7cd998a9df684885cc
145
+ lib/ndr_support/threat_scanner.rb:
146
+ comments:
147
+ reviewed_by: josh.pencheon
148
+ safe_revision: ed8ff421cc9353456af13a37049a07ce2545aac1
141
149
  lib/ndr_support/utf8_encoding.rb:
142
150
  comments:
143
- reviewed_by: timgentry
144
- safe_revision: 29595e6431587ff9b7db6e3ad3abbb3577bff99c
151
+ reviewed_by: josh.pencheon
152
+ safe_revision: 8e024a4bacfd36e172aad4b800f1960faae0b4b6
145
153
  lib/ndr_support/utf8_encoding/control_characters.rb:
146
154
  comments:
147
- reviewed_by: timgentry
148
- safe_revision: d210b982841611381a0df02d8f2db9c13e41e42f
155
+ reviewed_by: josh.pencheon
156
+ safe_revision: 8e024a4bacfd36e172aad4b800f1960faae0b4b6
149
157
  lib/ndr_support/utf8_encoding/force_binary.rb:
150
158
  comments:
151
159
  reviewed_by: timgentry
@@ -156,16 +164,16 @@ file safety:
156
164
  safe_revision: f7adf44fc2772e1926df37abfd9041d41c303328
157
165
  lib/ndr_support/version.rb:
158
166
  comments:
159
- reviewed_by: brian.shand
160
- safe_revision: a4ba32dcdab4a08db5851767282008ca3e7d8672
167
+ reviewed_by: josh.pencheon
168
+ safe_revision: ea1f7dc9a164981570ee2ad7c38197fdb17a6880
161
169
  lib/ndr_support/yaml/serialization_migration.rb:
162
170
  comments:
163
171
  reviewed_by: timgentry
164
172
  safe_revision: 29595e6431587ff9b7db6e3ad3abbb3577bff99c
165
173
  ndr_support.gemspec:
166
174
  comments:
167
- reviewed_by: brian.shand
168
- safe_revision: e8d08f6466acbdd4cbd6cbf90f1cfa45ffd656ec
175
+ reviewed_by: josh.pencheon
176
+ safe_revision: c197b91c07807345f2caf07ec4c14d8b9cbb4e53
169
177
  test/array_test.rb:
170
178
  comments:
171
179
  reviewed_by: timgentry
@@ -236,8 +244,12 @@ file safety:
236
244
  safe_revision: 1955bf30ffe581610981f0148569e252cba02926
237
245
  test/test_helper.rb:
238
246
  comments:
239
- reviewed_by: brian.shand
240
- safe_revision: 4533a155924f8a1415dd64e251a7f8311ece3bd8
247
+ reviewed_by: josh.pencheon
248
+ safe_revision: 34ae80f2952f0bfd18688541862774cbaaa6c5f5
249
+ test/threat_scanner_test.rb:
250
+ comments:
251
+ reviewed_by: josh.pencheon
252
+ safe_revision: ed8ff421cc9353456af13a37049a07ce2545aac1
241
253
  test/utf8_encoding/control_characters_test.rb:
242
254
  comments:
243
255
  reviewed_by: timgentry
@@ -13,6 +13,7 @@ require 'ndr_support/safe_file'
13
13
  require 'ndr_support/safe_path'
14
14
  require 'ndr_support/string/cleaning'
15
15
  require 'ndr_support/string/conversions'
16
+ require 'ndr_support/threat_scanner'
16
17
  require 'ndr_support/utf8_encoding'
17
18
  require 'ndr_support/version'
18
19
  require 'ndr_support/yaml/serialization_migration'
@@ -50,6 +50,33 @@ module WorkingDays
50
50
  '2016-08-29', # Monday - Summer bank holiday
51
51
  '2016-12-26', # Monday - Boxing Day
52
52
  '2016-12-27', # Tuesday - Christmas Day (substitute day)
53
+ # 2017
54
+ '2017-01-02', # Monday - New Year's Day
55
+ '2017-04-14', # Friday - Good Friday
56
+ '2017-04-17', # Monday - Easter Monday
57
+ '2017-05-01', # Monday - Early May bank holiday
58
+ '2017-05-29', # Monday - Spring bank holiday
59
+ '2017-08-28', # Monday - Summer bank holiday
60
+ '2017-12-25', # Monday - Christmas Day
61
+ '2017-12-26', # Tuesday - Boxing Day
62
+ # 2018
63
+ '2018-01-01', # Monday - New Year's Day
64
+ '2018-03-30', # Friday - Good Friday
65
+ '2018-04-02', # Monday - Easter Monday
66
+ '2018-05-07', # Monday - Early May bank holiday
67
+ '2018-05-28', # Monday - Spring bank holiday
68
+ '2018-08-27', # Monday - Summer bank holiday
69
+ '2018-12-25', # Tuesday - Christmas Day
70
+ '2018-12-26', # Wednesday - Boxing Day
71
+ # 2019
72
+ '2019-01-01', # Tuesday - New Year's Day
73
+ '2019-04-19', # Friday - Good Friday
74
+ '2019-04-22', # Monday - Easter Monday
75
+ '2019-05-06', # Monday - Early May bank holiday
76
+ '2019-05-27', # Monday - Spring bank holiday
77
+ '2019-08-26', # Monday - Summer bank holiday
78
+ '2019-12-25', # Wednesday - Christmas Day
79
+ '2019-12-26', # Thursday - Boxing Day
53
80
  ].map { |str| Date.parse(str) }
54
81
 
55
82
  # How many complete working days there are until the given
@@ -0,0 +1,64 @@
1
+ require 'English'
2
+
3
+ # Runs a virus/malware check against the given path, using ClamAV.
4
+ #
5
+ # Sample usage:
6
+ #
7
+ # # Call with a file object:
8
+ # ThreatScanner.new(@unknown_tempfile).check!
9
+ #
10
+ # # ...or with a path:
11
+ # ThreatScanner.new('path/to/README').check!
12
+ #
13
+ class ThreatScanner
14
+ class Error < StandardError; end
15
+
16
+ class MissingFileError < Error; end
17
+ class MissingScannerError < Error; end
18
+ class ScannerOperationError < Error; end
19
+ class ThreatDetectedError < Error; end
20
+
21
+ def self.installed?
22
+ system('which clamdscan > /dev/null 2>&1')
23
+ end
24
+
25
+ attr_reader :path
26
+
27
+ def initialize(path)
28
+ @path = path.respond_to?(:path) ? path.path : path
29
+ end
30
+
31
+ # Returns true if the given file is deemed safe, and false if it could not
32
+ # be checked. Raises if a threat is detected, or the file did not exist.
33
+ def check
34
+ check!
35
+ rescue MissingScannerError, ScannerOperationError
36
+ false
37
+ end
38
+
39
+ # Returns true if the given file is deemed safe, and raises an exception
40
+ # otherwise (if the file is unsafe / does not exist / scanner broke etc).
41
+ def check!
42
+ check_existence! && check_installed! && run_scanner!
43
+ end
44
+
45
+ private
46
+
47
+ def check_existence!
48
+ File.exist?(@path) || raise(MissingFileError, "#{@path} does not exist!")
49
+ end
50
+
51
+ def check_installed!
52
+ self.class.installed? || raise(MissingScannerError, 'no scanner is available')
53
+ end
54
+
55
+ def run_scanner!
56
+ `clamdscan --fdpass --quiet #{Shellwords.escape(@path)}`
57
+
58
+ case $CHILD_STATUS.exitstatus
59
+ when 0 then true
60
+ when 1 then raise(ThreatDetectedError, "possible virus detected at #{@path}!")
61
+ else raise(ScannerOperationError, 'the scan was unable to complete')
62
+ end
63
+ end
64
+ end
@@ -16,6 +16,9 @@ module UTF8Encoding
16
16
  # How should unmappable characters be escaped, when forcing encoding?
17
17
  REPLACEMENT_SCHEME = lambda { |char| '0x' + char.ord.to_s(16).rjust(2, '0') }
18
18
 
19
+ UTF8 = 'UTF-8'.freeze
20
+ BINARY = 'BINARY'.freeze
21
+
19
22
  # Returns a new string with valid UTF-8 encoding,
20
23
  # or raises an exception if encoding fails.
21
24
  def ensure_utf8(string, source_encoding = nil)
@@ -51,7 +54,7 @@ module UTF8Encoding
51
54
  ensure_utf8!(string, source_encoding)
52
55
  rescue UTF8CoercionError
53
56
  # ...before going back-to-basics, and replacing things that don't map:
54
- string.encode!('UTF-8', 'BINARY', :fallback => REPLACEMENT_SCHEME)
57
+ string.encode!(UTF8, BINARY, :fallback => REPLACEMENT_SCHEME)
55
58
  end
56
59
 
57
60
  private
@@ -60,7 +63,7 @@ module UTF8Encoding
60
63
  candidates.detect do |encoding|
61
64
  begin
62
65
  # Attempt to encode as UTF-8 from source `encoding`:
63
- string.encode!('UTF-8', encoding)
66
+ string.encode!(UTF8, encoding)
64
67
  # If that worked, we're done; otherwise, move on.
65
68
  string.valid_encoding?
66
69
  rescue EncodingError
@@ -5,9 +5,7 @@ module UTF8Encoding
5
5
  # escaped, using standard replacement scheme.
6
6
  module ControlCharacters
7
7
  # The range of characters we consider:
8
- CONTROL_CHARACTERS = /[\x00-\x1f]|\x7f/
9
- # Exceptions that are allowed:
10
- ALLOWED_CONTROL_CHARACTERS = %W( \x09 \x0a \x0d )
8
+ CONTROL_CHARACTERS = /[\x00-\x08]|[\x0b-\x0c]|[\x0e-\x1f]|\x7f/
11
9
 
12
10
  # Recursively escape any control characters in `object`.
13
11
  def escape_control_chars_in_object!(object)
@@ -31,11 +29,7 @@ module UTF8Encoding
31
29
  # Escapes in-place any control characters in `string`, before returning it.
32
30
  def escape_control_chars!(string)
33
31
  string.gsub!(CONTROL_CHARACTERS) do |character|
34
- if ALLOWED_CONTROL_CHARACTERS.include?(character)
35
- character
36
- else
37
- UTF8Encoding::REPLACEMENT_SCHEME[character]
38
- end
32
+ UTF8Encoding::REPLACEMENT_SCHEME[character]
39
33
  end
40
34
  string
41
35
  end
@@ -3,5 +3,5 @@
3
3
  # This defines the NdrSupport version. If you change it, rebuild and commit the gem.
4
4
  # Use "rake build" to build the gem, see rake -T for all bundler rake tasks.
5
5
  module NdrSupport
6
- VERSION = '5.4.2'
6
+ VERSION = '5.5.0'
7
7
  end
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency 'minitest', '>= 5.0.0'
33
33
  spec.add_development_dependency 'mocha', '~> 1.1'
34
34
 
35
- spec.add_development_dependency 'ndr_dev_support', '~> 3.0'
35
+ spec.add_development_dependency 'ndr_dev_support', '~> 3.1', '>= 3.1.3'
36
36
  spec.add_development_dependency 'guard'
37
37
  spec.add_development_dependency 'listen', '< 3.1' # Bundle 1.12 should be (but isn't) resolving Ruby 2.1 issue
38
38
  spec.add_development_dependency 'guard-rubocop'
@@ -3,7 +3,7 @@ SimpleCov.start
3
3
 
4
4
  require 'minitest/autorun'
5
5
  require 'minitest/unit'
6
- require 'mocha/mini_test'
6
+ require 'mocha/minitest'
7
7
 
8
8
  require 'active_record'
9
9
  require 'active_support/time'
@@ -0,0 +1,75 @@
1
+ require 'test_helper'
2
+
3
+ # This tests our ThreatScanner extension
4
+ class ThreatScannerTest < Minitest::Test
5
+ def setup
6
+ @tempfile = Tempfile.new
7
+ @scanner = ThreatScanner.new(@tempfile)
8
+
9
+ ThreatScanner.stubs(installed?: true)
10
+ ThreatScanner.any_instance.stubs(:`)
11
+ end
12
+
13
+ def teardown
14
+ @tempfile.close!
15
+ end
16
+
17
+ test 'can be initialised with a file' do
18
+ assert_equal @tempfile.path, @scanner.path
19
+ end
20
+
21
+ test 'can be initialised with a path' do
22
+ scanner = ThreatScanner.new(@tempfile.path)
23
+ assert_equal @tempfile.path, scanner.path
24
+ end
25
+
26
+ test 'returns true if no threat is detected (when being strict)' do
27
+ Process::Status.any_instance.stubs(exitstatus: 0)
28
+ assert_equal true, @scanner.check!
29
+ end
30
+
31
+ test 'raises if a threat is detected (when being strict)' do
32
+ Process::Status.any_instance.stubs(exitstatus: 1)
33
+ assert_raises(ThreatScanner::ThreatDetectedError) { @scanner.check! }
34
+ end
35
+
36
+ test 'raises if the file does not exist (when being strict)' do
37
+ @tempfile.close!
38
+ assert_raises(ThreatScanner::MissingFileError) { @scanner.check! }
39
+ end
40
+
41
+ test 'raises if ClamAV is not installed (when being strict)' do
42
+ ThreatScanner.stubs(installed?: false)
43
+ assert_raises(ThreatScanner::MissingScannerError) { @scanner.check! }
44
+ end
45
+
46
+ test 'raises if there is an operational error (when being strict)' do
47
+ Process::Status.any_instance.stubs(exitstatus: 2)
48
+ assert_raises(ThreatScanner::ScannerOperationError) { @scanner.check! }
49
+ end
50
+
51
+ test 'returns true if no threat is detected (when being relaxed)' do
52
+ Process::Status.any_instance.stubs(exitstatus: 0)
53
+ assert_equal true, @scanner.check
54
+ end
55
+
56
+ test 'raises if a threat is detected (when being relaxed)' do
57
+ Process::Status.any_instance.stubs(exitstatus: 1)
58
+ assert_raises(ThreatScanner::ThreatDetectedError) { @scanner.check }
59
+ end
60
+
61
+ test 'raises if the file does not exist (when being relaxed)' do
62
+ @tempfile.close!
63
+ assert_raises(ThreatScanner::MissingFileError) { @scanner.check }
64
+ end
65
+
66
+ test 'returns false if ClamAV is not installed (when being relaxed)' do
67
+ ThreatScanner.stubs(installed?: false)
68
+ assert_equal false, @scanner.check
69
+ end
70
+
71
+ test 'returns false if there is an operational error (when being relaxed)' do
72
+ Process::Status.any_instance.stubs(exitstatus: 2)
73
+ assert_equal false, @scanner.check
74
+ end
75
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ndr_support
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.4.2
4
+ version: 5.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - NCRS Development Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-07 00:00:00.000000000 Z
11
+ date: 2018-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -112,14 +112,20 @@ dependencies:
112
112
  requirements:
113
113
  - - "~>"
114
114
  - !ruby/object:Gem::Version
115
- version: '3.0'
115
+ version: '3.1'
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: 3.1.3
116
119
  type: :development
117
120
  prerelease: false
118
121
  version_requirements: !ruby/object:Gem::Requirement
119
122
  requirements:
120
123
  - - "~>"
121
124
  - !ruby/object:Gem::Version
122
- version: '3.0'
125
+ version: '3.1'
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: 3.1.3
123
129
  - !ruby/object:Gem::Dependency
124
130
  name: guard
125
131
  requirement: !ruby/object:Gem::Requirement
@@ -226,6 +232,7 @@ extra_rdoc_files: []
226
232
  files:
227
233
  - ".gitignore"
228
234
  - ".rubocop.yml"
235
+ - CHANGELOG.md
229
236
  - CODE_OF_CONDUCT.md
230
237
  - Gemfile
231
238
  - Guardfile
@@ -258,6 +265,7 @@ files:
258
265
  - lib/ndr_support/string/cleaning.rb
259
266
  - lib/ndr_support/string/conversions.rb
260
267
  - lib/ndr_support/tasks.rb
268
+ - lib/ndr_support/threat_scanner.rb
261
269
  - lib/ndr_support/utf8_encoding.rb
262
270
  - lib/ndr_support/utf8_encoding/control_characters.rb
263
271
  - lib/ndr_support/utf8_encoding/force_binary.rb
@@ -283,6 +291,7 @@ files:
283
291
  - test/string/cleaning_test.rb
284
292
  - test/string/conversions_test.rb
285
293
  - test/test_helper.rb
294
+ - test/threat_scanner_test.rb
286
295
  - test/utf8_encoding/control_characters_test.rb
287
296
  - test/utf8_encoding/force_binary_test.rb
288
297
  - test/utf8_encoding_test.rb
@@ -307,7 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
307
316
  version: '0'
308
317
  requirements: []
309
318
  rubyforge_project:
310
- rubygems_version: 2.5.2.3
319
+ rubygems_version: 2.7.6
311
320
  signing_key:
312
321
  specification_version: 4
313
322
  summary: NDR Support library
@@ -330,6 +339,7 @@ test_files:
330
339
  - test/string/cleaning_test.rb
331
340
  - test/string/conversions_test.rb
332
341
  - test/test_helper.rb
342
+ - test/threat_scanner_test.rb
333
343
  - test/utf8_encoding/control_characters_test.rb
334
344
  - test/utf8_encoding/force_binary_test.rb
335
345
  - test/utf8_encoding_test.rb