Fix more HOMEBREW_FORBID_PACKAGES_FROM_PATHS issues

- Ensure that we're overriding it where necessary internally (but not
  allowing this to be used as a public opt-out API)
- Better handle formulae from paths that look like taps
This commit is contained in:
Mike McQuaid 2025-08-14 19:35:11 +01:00
parent b0b8e23856
commit c143b03280
No known key found for this signature in database
6 changed files with 36 additions and 17 deletions

View File

@ -1102,6 +1102,9 @@ then
fi fi
unset SUDO unset SUDO
# Remove internal variables
unset HOMEBREW_INTERNAL_ALLOW_PACKAGES_FROM_PATHS
if [[ -n "${HOMEBREW_BASH_COMMAND}" ]] if [[ -n "${HOMEBREW_BASH_COMMAND}" ]]
then then
# source rather than executing directly to ensure the entire file is read into # source rather than executing directly to ensure the entire file is read into

View File

@ -227,7 +227,10 @@ class Build
end end
begin begin
ENV.delete("HOMEBREW_FORBID_PACKAGES_FROM_PATHS") # Undocumented opt-out for internal use.
# We need to allow formulae from paths here due to how we pass them through.
ENV["HOMEBREW_INTERNAL_ALLOW_PACKAGES_FROM_PATHS"] = "1"
args = Homebrew::Cmd::InstallCmd.new.args args = Homebrew::Cmd::InstallCmd.new.args
Context.current = args.context Context.current = args.context

View File

@ -632,6 +632,9 @@ module Homebrew
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def forbid_packages_from_paths? def forbid_packages_from_paths?
# Undocumented opt-out for internal use.
return false if ENV["HOMEBREW_INTERNAL_ALLOW_PACKAGES_FROM_PATHS"].present?
return true if ENV["HOMEBREW_FORBID_PACKAGES_FROM_PATHS"].present? return true if ENV["HOMEBREW_FORBID_PACKAGES_FROM_PATHS"].present?
# Provide an opt-out for tests and developers. # Provide an opt-out for tests and developers.

View File

@ -619,17 +619,21 @@ module Formulary
if Homebrew::EnvConfig.forbid_packages_from_paths? if Homebrew::EnvConfig.forbid_packages_from_paths?
path_realpath = path.realpath.to_s path_realpath = path.realpath.to_s
path_string = path.to_s path_string = path.to_s
if !path_realpath.start_with?("#{HOMEBREW_CELLAR}/", "#{HOMEBREW_LIBRARY}/Taps/", "#{HOMEBREW_CACHE}/") && unless path_realpath.start_with?("#{HOMEBREW_CELLAR}/", "#{HOMEBREW_LIBRARY}/Taps/", "#{HOMEBREW_CACHE}/")
(path_string.include?("/") || path_string.end_with?(".rb")) if path_string.include?("./") || path_string.end_with?(".rb") || path_string.count("/") != 2
raise <<~WARNING raise <<~WARNING
Rejecting formula at #{path_string} because it's not in a tap. Rejecting formula at #{path_string} because it's not in a tap.
Homebrew requires formulae to be in a tap. Homebrew requires formulae to be in a tap.
To create a tap, run e.g. To create a tap, run e.g.
brew tap-new <user|org>/<repository> brew tap-new <user|org>/<repository>
To create a formula in a tap run e.g. To create a formula in a tap run e.g.
brew create <url> --tap=<user|org>/<repository> brew create <url> --tap=<user|org>/<repository>
WARNING WARNING
elsif path_string.count("/") == 2
# Looks like a tap, let's quietly return but not error.
return
end
end end
end end

View File

@ -14,7 +14,10 @@ require "cmd/postinstall"
require "json/add/exception" require "json/add/exception"
begin begin
ENV.delete("HOMEBREW_FORBID_PACKAGES_FROM_PATHS") # Undocumented opt-out for internal use.
# We need to allow formulae from paths here due to how we pass them through.
ENV["HOMEBREW_INTERNAL_ALLOW_PACKAGES_FROM_PATHS"] = "1"
args = Homebrew::Cmd::Postinstall.new.args args = Homebrew::Cmd::Postinstall.new.args
error_pipe = Utils::UNIXSocketExt.open(ENV.fetch("HOMEBREW_ERROR_PIPE"), &:recv_io) error_pipe = Utils::UNIXSocketExt.open(ENV.fetch("HOMEBREW_ERROR_PIPE"), &:recv_io)
error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
@ -29,7 +32,7 @@ begin
formula.run_post_install formula.run_post_install
# Handle all possible exceptions. # Handle all possible exceptions.
rescue Exception => e # rubocop:disable Lint/RescueException rescue Exception => e # rubocop:disable Lint/RescueException
error_pipe.puts e.to_json error_pipe&.puts e.to_json
error_pipe.close error_pipe&.close
exit! 1 exit! 1
end end

View File

@ -19,7 +19,10 @@ require "json/add/exception"
DEFAULT_TEST_TIMEOUT_SECONDS = 5 * 60 DEFAULT_TEST_TIMEOUT_SECONDS = 5 * 60
begin begin
ENV.delete("HOMEBREW_FORBID_PACKAGES_FROM_PATHS") # Undocumented opt-out for internal use.
# We need to allow formulae from paths here due to how we pass them through.
ENV["HOMEBREW_INTERNAL_ALLOW_PACKAGES_FROM_PATHS"] = "1"
args = Homebrew::DevCmd::Test.new.args args = Homebrew::DevCmd::Test.new.args
Context.current = args.context Context.current = args.context
@ -55,8 +58,8 @@ begin
end end
# Any exceptions during the test run are reported. # Any exceptions during the test run are reported.
rescue Exception => e # rubocop:disable Lint/RescueException rescue Exception => e # rubocop:disable Lint/RescueException
error_pipe.puts e.to_json error_pipe&.puts e.to_json
error_pipe.close error_pipe&.close
ensure ensure
pid = Process.pid.to_s pid = Process.pid.to_s
if which("pgrep") && which("pkill") && system("pgrep", "-P", pid, out: File::NULL) if which("pgrep") && which("pkill") && system("pgrep", "-P", pid, out: File::NULL)