Skip to content

Commit

Permalink
Add env to disable finding packages from paths
Browse files Browse the repository at this point in the history
  • Loading branch information
Bo98 committed Jul 24, 2024
1 parent 8e8ce4a commit 03b8976
Show file tree
Hide file tree
Showing 12 changed files with 61 additions and 4 deletions.
11 changes: 7 additions & 4 deletions Library/Homebrew/api/formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ def self.source_download(formula)
cache: HOMEBREW_CACHE_API_SOURCE/"#{tap}/#{git_head}/Formula",
)
download.fetch
Formulary.factory(download.symlink_location,
formula.active_spec_sym,
alias_path: formula.alias_path,
flags: formula.class.build_flags)

with_env(HOMEBREW_FORBID_PACKAGES_FROM_PATHS: nil) do
Formulary.factory(download.symlink_location,

Check warning on line 37 in Library/Homebrew/api/formula.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/api/formula.rb#L36-L37

Added lines #L36 - L37 were not covered by tests
formula.active_spec_sym,
alias_path: formula.alias_path,
flags: formula.class.build_flags)
end
end

def self.cached_json_file_path
Expand Down
1 change: 1 addition & 0 deletions Library/Homebrew/build.rb
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ def fixopt(formula)
end

begin
ENV.delete("HOMEBREW_FORBID_PACKAGES_FROM_PATHS")
args = Homebrew::Cmd::InstallCmd.new.args
Context.current = args.context

Expand Down
5 changes: 5 additions & 0 deletions Library/Homebrew/cask/cask_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ def self.try_new(ref, warn: false)
return if %w[.rb .json].exclude?(path.extname)
return unless path.expand_path.exist?

return if Homebrew::EnvConfig.forbid_packages_from_paths? &&
!path.realpath.to_s.start_with?("#{Caskroom.path}/", "#{HOMEBREW_LIBRARY}/Taps/")

new(path)
end

Expand Down Expand Up @@ -159,6 +162,8 @@ class FromURILoader < FromPathLoader
.returns(T.nilable(T.attached_class))
}
def self.try_new(ref, warn: false)
return if Homebrew::EnvConfig.forbid_packages_from_paths?

# Cache compiled regex
@uri_regex ||= begin
uri_regex = ::URI::DEFAULT_PARSER.make_regexp
Expand Down
5 changes: 5 additions & 0 deletions Library/Homebrew/env_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ module EnvConfig
description: "A space-separated list of taps. Homebrew will refuse to install a " \
"formula if it or any of its dependencies is in a tap on this list.",
},
HOMEBREW_FORBID_PACKAGES_FROM_PATHS: {
description: "If set, Homebrew will refuse to read packages provided from file paths, " \
"e.g. `brew install ./package.rb`.",
boolean: true,
},
HOMEBREW_FORCE_BREWED_CA_CERTIFICATES: {
description: "If set, always use a Homebrew-installed `ca-certificates` rather than the system version. " \
"Automatically set if the system version is too old.",
Expand Down
7 changes: 7 additions & 0 deletions Library/Homebrew/formulary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,8 @@ class FromBottleLoader < FormulaLoader
.returns(T.nilable(T.attached_class))
}
def self.try_new(ref, from: T.unsafe(nil), warn: false)
return if Homebrew::EnvConfig.forbid_packages_from_paths?

ref = ref.to_s

new(ref) if HOMEBREW_BOTTLES_EXTNAME_REGEX.match?(ref) && File.exist?(ref)
Expand Down Expand Up @@ -644,6 +646,9 @@ def self.try_new(ref, from: T.unsafe(nil), warn: false)

return unless path.expand_path.exist?

return if Homebrew::EnvConfig.forbid_packages_from_paths? &&
!path.realpath.to_s.start_with?("#{HOMEBREW_CELLAR}/", "#{HOMEBREW_LIBRARY}/Taps/")

options = if (tap = Tap.from_path(path))
# Only treat symlinks in taps as aliases.
if path.symlink?
Expand Down Expand Up @@ -696,6 +701,8 @@ class FromURILoader < FormulaLoader
.returns(T.nilable(T.attached_class))
}
def self.try_new(ref, from: T.unsafe(nil), warn: false)
return if Homebrew::EnvConfig.forbid_packages_from_paths?

# Cache compiled regex
@uri_regex ||= begin
uri_regex = ::URI::DEFAULT_PARSER.make_regexp
Expand Down
1 change: 1 addition & 0 deletions Library/Homebrew/postinstall.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
require "json/add/exception"

begin
ENV.delete("HOMEBREW_FORBID_PACKAGES_FROM_PATHS")
args = Homebrew::Cmd::Postinstall.new.args
error_pipe = UNIXSocket.open(ENV.fetch("HOMEBREW_ERROR_PIPE"), &:recv_io)
error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
Expand Down
3 changes: 3 additions & 0 deletions Library/Homebrew/sorbet/rbi/dsl/homebrew/env_config.rbi

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Library/Homebrew/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
TEST_TIMEOUT_SECONDS = 5 * 60

begin
ENV.delete("HOMEBREW_FORBID_PACKAGES_FROM_PATHS")
args = Homebrew::DevCmd::Test.new.args
Context.current = args.context

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
expect(described_class.try_new("https://brew.sh/")).not_to be_nil
end

it "returns nil when path loading is disabled" do
ENV["HOMEBREW_FORBID_PACKAGES_FROM_PATHS"] = "1"
expect(described_class.try_new(URI("file://#{TEST_FIXTURE_DIR}/cask/Casks/local-caffeine.rb"))).to be_nil
end

it "returns nil when given a string with Cask contents containing a URL" do
expect(described_class.try_new(<<~RUBY)).to be_nil
cask 'token' do
Expand Down
18 changes: 18 additions & 0 deletions Library/Homebrew/test/formulary_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,29 @@ class Wrong#{described_class.class_s(formula_name)} < Formula
expect(described_class.factory(formula_path)).to be_a(Formula)
end

it "errors when given a path but paths are disabled" do
ENV["HOMEBREW_FORBID_PACKAGES_FROM_PATHS"] = "1"
FileUtils.cp formula_path, HOMEBREW_TEMP
temp_formula_path = HOMEBREW_TEMP/formula_path.basename
expect do
described_class.factory(temp_formula_path)
ensure
temp_formula_path.unlink
end.to raise_error(FormulaUnavailableError)
end

it "returns a Formula when given a URL", :needs_utils_curl, :no_api do
formula = described_class.factory("file://#{formula_path}")
expect(formula).to be_a(Formula)
end

it "errors when given a URL but paths are disabled" do
ENV["HOMEBREW_FORBID_PACKAGES_FROM_PATHS"] = "1"
expect do
described_class.factory("file://#{formula_path}")
end.to raise_error(FormulaUnavailableError)
end

context "when given a bottle" do
subject(:formula) { described_class.factory(bottle) }

Expand Down
5 changes: 5 additions & 0 deletions docs/Manpage.md
Original file line number Diff line number Diff line change
Expand Up @@ -3771,6 +3771,11 @@ command execution e.g. `$(cat file)`.
: A space-separated list of taps. Homebrew will refuse to install a formula if
it or any of its dependencies is in a tap on this list.

`HOMEBREW_FORBID_PACKAGES_FROM_PATHS`

: If set, Homebrew will refuse to read packages provided from file paths, e.g.
`brew install ./package.rb`.

`HOMEBREW_FORCE_BREWED_CA_CERTIFICATES`

: If set, always use a Homebrew-installed `ca-certificates` rather than the
Expand Down
3 changes: 3 additions & 0 deletions manpages/brew.1
Original file line number Diff line number Diff line change
Expand Up @@ -2455,6 +2455,9 @@ How to contact the \fBHOMEBREW_FORBIDDEN_OWNER\fP, if set and necessary\.
\fBHOMEBREW_FORBIDDEN_TAPS\fP
A space\-separated list of taps\. Homebrew will refuse to install a formula if it or any of its dependencies is in a tap on this list\.
.TP
\fBHOMEBREW_FORBID_PACKAGES_FROM_PATHS\fP
If set, Homebrew will refuse to read packages provided from file paths, e\.g\. \fBbrew install \./package\.rb\fP\&\.
.TP
\fBHOMEBREW_FORCE_BREWED_CA_CERTIFICATES\fP
If set, always use a Homebrew\-installed \fBca\-certificates\fP rather than the system version\. Automatically set if the system version is too old\.
.TP
Expand Down

0 comments on commit 03b8976

Please sign in to comment.