From 4917a35413c4e628dc880e14f631c2b7edeaabab Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Mon, 30 Jan 2023 21:56:40 -0800 Subject: [PATCH 1/3] Add sanity check for cask token --- Library/Homebrew/api/cask-source.rb | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/api/cask-source.rb b/Library/Homebrew/api/cask-source.rb index 0c1cd67a21..1573ae485d 100644 --- a/Library/Homebrew/api/cask-source.rb +++ b/Library/Homebrew/api/cask-source.rb @@ -10,18 +10,25 @@ module Homebrew class << self extend T::Sig + CASK_TOKEN_REGEX = %r{^(homebrew/cask/)?[a-z0-9\-_]+$}.freeze + sig { params(token: String).returns(Hash) } def fetch(token) - token = token.sub(%r{^homebrew/cask/}, "") + token = token.delete_prefix("homebrew/cask/") Homebrew::API.fetch "cask-source/#{token}.rb", json: false end sig { params(token: String).returns(T::Boolean) } def available?(token) - fetch token - true - rescue ArgumentError - false + # Sanity check before hitting the API + return false unless token.match?(CASK_TOKEN_REGEX) + + begin + fetch token + true + rescue ArgumentError + false + end end end end From e0ad9600254400e7fde382f731a224db51dabfcc Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Tue, 31 Jan 2023 00:09:57 -0800 Subject: [PATCH 2/3] Load cask from API with fullname This allows homebrew/cask/caskname to work with the FromAPILoader. Also, creates new constant to hold the regex to validate main tap casks. --- Library/Homebrew/api/cask-source.rb | 4 +--- Library/Homebrew/cask/cask_loader.rb | 19 +++++++++---------- Library/Homebrew/tap_constants.rb | 2 ++ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Library/Homebrew/api/cask-source.rb b/Library/Homebrew/api/cask-source.rb index 1573ae485d..dd33332845 100644 --- a/Library/Homebrew/api/cask-source.rb +++ b/Library/Homebrew/api/cask-source.rb @@ -10,8 +10,6 @@ module Homebrew class << self extend T::Sig - CASK_TOKEN_REGEX = %r{^(homebrew/cask/)?[a-z0-9\-_]+$}.freeze - sig { params(token: String).returns(Hash) } def fetch(token) token = token.delete_prefix("homebrew/cask/") @@ -21,7 +19,7 @@ module Homebrew sig { params(token: String).returns(T::Boolean) } def available?(token) # Sanity check before hitting the API - return false unless token.match?(CASK_TOKEN_REGEX) + return false unless token.match?(HOMEBREW_MAIN_TAP_CASK_REGEX) begin fetch token diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index 6e66b043ee..5ff63cd88f 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -193,11 +193,16 @@ module Cask FLIGHT_STANZAS = [:preflight, :postflight, :uninstall_preflight, :uninstall_postflight].freeze def self.can_load?(ref) - Homebrew::API::Cask.all_casks.key? ref + return false unless Homebrew::EnvConfig.install_from_api? + return false unless ref.is_a?(String) + return false unless ref.match?(HOMEBREW_MAIN_TAP_CASK_REGEX) + + token = ref.delete_prefix("homebrew/cask/") + Homebrew::API::Cask.all_casks.key?(token) end def initialize(token) - @token = token + @token = token.delete_prefix("homebrew/cask/") @path = CaskLoader.default_path(token) end @@ -356,18 +361,12 @@ module Cask FromInstanceLoader, FromContentLoader, FromURILoader, + FromAPILoader, FromTapLoader, FromTapPathLoader, FromPathLoader, ].each do |loader_class| - next unless loader_class.can_load?(ref) - - if loader_class == FromTapLoader && Homebrew::EnvConfig.install_from_api? && - ref.start_with?("homebrew/cask/") && FromAPILoader.can_load?(ref) - return FromAPILoader.new(ref) - end - - return loader_class.new(ref) + return loader_class.new(ref) if loader_class.can_load?(ref) end if Homebrew::EnvConfig.install_from_api? && !need_path && Homebrew::API::CaskSource.available?(ref) diff --git a/Library/Homebrew/tap_constants.rb b/Library/Homebrew/tap_constants.rb index f5943ad124..b4801563b4 100644 --- a/Library/Homebrew/tap_constants.rb +++ b/Library/Homebrew/tap_constants.rb @@ -5,6 +5,8 @@ HOMEBREW_TAP_FORMULA_REGEX = %r{^([\w-]+)/([\w-]+)/([\w+-.@]+)$}.freeze # Match taps' casks, e.g. `someuser/sometap/somecask` HOMEBREW_TAP_CASK_REGEX = %r{^([\w-]+)/([\w-]+)/([a-z0-9\-_]+)$}.freeze +# Match main cask taps' casks, e.g. `homebrew/cask/somecask` or `somecask` +HOMEBREW_MAIN_TAP_CASK_REGEX = %r{^(homebrew/cask/)?[a-z0-9\-_]+$}.freeze # Match taps' directory paths, e.g. `HOMEBREW_LIBRARY/Taps/someuser/sometap` HOMEBREW_TAP_DIR_REGEX = %r{#{Regexp.escape(HOMEBREW_LIBRARY.to_s)}/Taps/(?[\w-]+)/(?[\w-]+)}.freeze # Match taps' formula paths, e.g. `HOMEBREW_LIBRARY/Taps/someuser/sometap/someformula` From 15c19308040134f25e2c73fa86724c1ef67960a4 Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Thu, 2 Feb 2023 18:43:53 -0800 Subject: [PATCH 3/3] Remove redundant FromAPILoader attempt After 32a0877 this logic has been changed so it's now always covered by `FromAPILoader.can_load?`. --- Library/Homebrew/cask/cask_loader.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index c885f7d6c2..e9ae5e4196 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -371,10 +371,6 @@ module Cask return loader_class.new(ref) if loader_class.can_load?(ref) end - if Homebrew::EnvConfig.install_from_api? && !need_path && Homebrew::API::Cask.all_casks.key?(ref) - return FromAPILoader.new(ref) - end - return FromTapPathLoader.new(default_path(ref)) if FromTapPathLoader.can_load?(default_path(ref)) case (possible_tap_casks = tap_paths(ref)).count