aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/rubocops/checksum_cop.rb
blob: dcaf60e7d3faaad0235cb7384da8346342f5267b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
require_relative "./extend/formula_cop"

module RuboCop
  module Cop
    module FormulaAudit
      class Checksum < FormulaCop
        def audit_formula(_node, _class_node, _parent_class_node, body_node)
          return if body_node.nil?
          if method_called_ever?(body_node, :md5)
            problem "MD5 checksums are deprecated, please use SHA256"
          end

          if method_called_ever?(body_node, :sha1)
            problem "SHA1 checksums are deprecated, please use SHA256"
          end

          sha256_calls = find_every_method_call_by_name(body_node, :sha256)
          sha256_calls.each do |sha256_call|
            sha256_node = get_checksum_node(sha256_call)
            audit_sha256(sha256_node)
          end
        end

        def audit_sha256(checksum)
          return if checksum.nil?
          if regex_match_group(checksum, /^$/)
            problem "sha256 is empty"
            return
          end

          if string_content(checksum).size != 64 && regex_match_group(checksum, /^\w*$/)
            problem "sha256 should be 64 characters"
          end

          return unless regex_match_group(checksum, /[^a-f0-9]+/i)
          problem "sha256 contains invalid characters"
        end
      end

      class ChecksumCase < FormulaCop
        def audit_formula(_node, _class_node, _parent_class_node, body_node)
          return if body_node.nil?
          sha256_calls = find_every_method_call_by_name(body_node, :sha256)
          sha256_calls.each do |sha256_call|
            checksum = get_checksum_node(sha256_call)
            next if checksum.nil?
            next unless regex_match_group(checksum, /[A-F]+/)
            problem "sha256 should be lowercase"
          end
        end

        private

        def autocorrect(node)
          lambda do |corrector|
            correction = node.source.downcase
            corrector.insert_before(node.source_range, correction)
            corrector.remove(node.source_range)
          end
        end
      end
    end
  end
end