aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
authorMarkus Reiter2017-05-22 02:23:33 +0200
committerGitHub2017-05-22 02:23:33 +0200
commit8f068a356dfe4769905d2487533b9e8124287098 (patch)
tree9097e725239a045c34e0e3aafb9ea67ee7e4d15d /Library
parent6d8c170e50b6ee232e4f8958c92735bf411a72e9 (diff)
parent473bdadbcd0f87fdeda98f73b25bb47a14221281 (diff)
downloadbrew-8f068a356dfe4769905d2487533b9e8124287098.tar.bz2
Merge pull request #2601 from reitermarkus/audit-version-checksum
Add audit check to see if both version and checksum changed.
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/cask/lib/hbc/audit.rb25
-rw-r--r--Library/Homebrew/cask/lib/hbc/auditor.rb12
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/internal_audit_modified_casks.rb3
-rw-r--r--Library/Homebrew/dev-cmd/audit.rb9
-rw-r--r--Library/Homebrew/formula_versions.rb20
-rw-r--r--Library/Homebrew/utils/git.rb28
6 files changed, 89 insertions, 8 deletions
diff --git a/Library/Homebrew/cask/lib/hbc/audit.rb b/Library/Homebrew/cask/lib/hbc/audit.rb
index 12cefb939..cee1fe807 100644
--- a/Library/Homebrew/cask/lib/hbc/audit.rb
+++ b/Library/Homebrew/cask/lib/hbc/audit.rb
@@ -1,16 +1,18 @@
require "hbc/checkable"
require "hbc/download"
require "digest"
+require "utils/git"
module Hbc
class Audit
include Checkable
- attr_reader :cask, :download
+ attr_reader :cask, :commit_range, :download
- def initialize(cask, download: false, check_token_conflicts: false, command: SystemCommand)
+ def initialize(cask, download: false, check_token_conflicts: false, commit_range: nil, command: SystemCommand)
@cask = cask
@download = download
+ @commit_range = commit_range
@check_token_conflicts = check_token_conflicts
@command = command
end
@@ -21,6 +23,7 @@ module Hbc
def run!
check_required_stanzas
+ check_version_and_checksum
check_version
check_sha256
check_appcast
@@ -57,6 +60,24 @@ module Hbc
add_error "at least one activatable artifact stanza is required" if installable_artifacts.empty?
end
+ def check_version_and_checksum
+ return if @cask.sourcefile_path.nil?
+
+ tap = Tap.select { |t| t.cask_file?(@cask.sourcefile_path) }.first
+ return if tap.nil?
+
+ return if commit_range.nil?
+ previous_cask_contents = Git.last_revision_of_file(tap.path, @cask.sourcefile_path, before_commit: commit_range)
+ return if previous_cask_contents.empty?
+
+ previous_cask = CaskLoader.load_from_string(previous_cask_contents)
+
+ return unless previous_cask.version == cask.version
+ return if previous_cask.sha256 == cask.sha256
+
+ add_error "only sha256 changed (see: https://github.com/caskroom/homebrew-cask/blob/master/doc/cask_language_reference/stanzas/sha256.md)"
+ end
+
def check_version
return unless cask.version
check_no_string_version_latest
diff --git a/Library/Homebrew/cask/lib/hbc/auditor.rb b/Library/Homebrew/cask/lib/hbc/auditor.rb
index ec17f3cad..48f36a54d 100644
--- a/Library/Homebrew/cask/lib/hbc/auditor.rb
+++ b/Library/Homebrew/cask/lib/hbc/auditor.rb
@@ -1,14 +1,15 @@
module Hbc
class Auditor
- def self.audit(cask, audit_download: false, check_token_conflicts: false)
- new(cask, audit_download, check_token_conflicts).audit
+ def self.audit(cask, audit_download: false, check_token_conflicts: false, commit_range: nil)
+ new(cask, audit_download, check_token_conflicts, commit_range).audit
end
- attr_reader :cask
+ attr_reader :cask, :commit_range
- def initialize(cask, audit_download, check_token_conflicts)
+ def initialize(cask, audit_download, check_token_conflicts, commit_range)
@cask = cask
@audit_download = audit_download
+ @commit_range = commit_range
@check_token_conflicts = check_token_conflicts
end
@@ -50,7 +51,8 @@ module Hbc
def audit_cask_instance(cask)
download = audit_download? && Download.new(cask)
audit = Audit.new(cask, download: download,
- check_token_conflicts: check_token_conflicts?)
+ check_token_conflicts: check_token_conflicts?,
+ commit_range: commit_range)
audit.run!
puts audit.summary
audit.success?
diff --git a/Library/Homebrew/cask/lib/hbc/cli/internal_audit_modified_casks.rb b/Library/Homebrew/cask/lib/hbc/cli/internal_audit_modified_casks.rb
index 9467cccc7..1a8ca0e98 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/internal_audit_modified_casks.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/internal_audit_modified_casks.rb
@@ -97,7 +97,8 @@ module Hbc
audit_download = audit_download?(cask, cask_file)
check_token_conflicts = added_cask_files.include?(cask_file)
success = Auditor.audit(cask, audit_download: audit_download,
- check_token_conflicts: check_token_conflicts)
+ check_token_conflicts: check_token_conflicts,
+ commit_range: commit_range)
failed_casks << cask unless success
end
diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb
index 3c42b45a1..516388c68 100644
--- a/Library/Homebrew/dev-cmd/audit.rb
+++ b/Library/Homebrew/dev-cmd/audit.rb
@@ -746,6 +746,15 @@ class FormulaAuditor
return if @new_formula
fv = FormulaVersions.new(formula)
+
+ previous_version_and_checksum = fv.previous_version_and_checksum("origin/master")
+ [:stable, :devel].each do |spec_sym|
+ next unless spec = formula.send(spec_sym)
+ next unless previous_version_and_checksum[spec_sym][:version] == spec.version
+ next if previous_version_and_checksum[spec_sym][:checksum] == spec.checksum
+ problem "#{spec_sym}: sha256 changed without the version also changing; please create an issue upstream to rule out malicious circumstances and to find out why the file changed."
+ end
+
attributes = [:revision, :version_scheme]
attributes_map = fv.version_attributes_map(attributes, "origin/master")
diff --git a/Library/Homebrew/formula_versions.rb b/Library/Homebrew/formula_versions.rb
index 70706a2f0..5c4e0ecc9 100644
--- a/Library/Homebrew/formula_versions.rb
+++ b/Library/Homebrew/formula_versions.rb
@@ -63,6 +63,26 @@ class FormulaVersions
map
end
+ def previous_version_and_checksum(branch)
+ map = {}
+
+ rev_list(branch) do |rev|
+ formula_at_revision(rev) do |f|
+ [:stable, :devel].each do |spec_sym|
+ next unless spec = f.send(spec_sym)
+ map[spec_sym] ||= { version: spec.version, checksum: spec.checksum }
+ end
+
+ break if map[:stable] && map[:devel]
+ end
+ end
+
+ map[:stable] ||= {}
+ map[:devel] ||= {}
+
+ map
+ end
+
def version_attributes_map(attributes, branch)
attributes_map = {}
return attributes_map if attributes.empty?
diff --git a/Library/Homebrew/utils/git.rb b/Library/Homebrew/utils/git.rb
index 1b4d24894..43d93b64e 100644
--- a/Library/Homebrew/utils/git.rb
+++ b/Library/Homebrew/utils/git.rb
@@ -1,3 +1,31 @@
+require "open3"
+
+module Git
+ module_function
+
+ def last_revision_commit_of_file(repo, file, before_commit: nil)
+ args = [before_commit.nil? ? "--skip=1" : before_commit.split("..").first]
+
+ out, = Open3.capture3(
+ HOMEBREW_SHIMS_PATH/"scm/git", "-C", repo,
+ "log", "--oneline", "--max-count=1", *args, "--", file
+ )
+ out.split(" ").first
+ end
+
+ def last_revision_of_file(repo, file, before_commit: nil)
+ relative_file = Pathname(file).relative_path_from(repo)
+
+ commit_hash = last_revision_commit_of_file(repo, file, before_commit: before_commit)
+
+ out, = Open3.capture3(
+ HOMEBREW_SHIMS_PATH/"scm/git", "-C", repo,
+ "show", "#{commit_hash}:#{relative_file}"
+ )
+ out
+ end
+end
+
module Utils
def self.git_available?
return @git if instance_variable_defined?(:@git)