Skip to content

Commit dd7b954

Browse files
authored
Merge pull request #20057 from Homebrew/cask_loader_error_handling
cask_loader: improve error handling.
2 parents b23bc5e + e7f667c commit dd7b954

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

Library/Homebrew/cask/cask_loader.rb

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require "uri"
77
require "utils/curl"
88
require "extend/hash/keys"
9+
require "api"
910

1011
module Cask
1112
# Loads a cask from various sources.
@@ -104,15 +105,23 @@ def self.try_new(ref, warn: false)
104105
return
105106
end
106107

107-
return if %w[.rb .json].exclude?(path.extname)
108108
return unless path.expand_path.exist?
109+
return if invalid_path?(path)
109110

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

113114
new(path)
114115
end
115116

117+
sig { params(pathname: Pathname, valid_extnames: T::Array[String]).returns(T::Boolean) }
118+
def self.invalid_path?(pathname, valid_extnames: %w[.rb .json])
119+
return true if valid_extnames.exclude?(pathname.extname)
120+
121+
@invalid_basenames ||= %w[INSTALL_RECEIPT.json sbom.spdx.json].freeze
122+
@invalid_basenames.include?(pathname.basename.to_s)
123+
end
124+
116125
attr_reader :token, :path
117126

118127
sig { params(path: T.any(Pathname, String), token: String).void }
@@ -135,8 +144,10 @@ def load(config:)
135144
@content = path.read(encoding: "UTF-8")
136145
@config = config
137146

138-
if path.extname == ".json"
139-
return FromAPILoader.new(token, from_json: JSON.parse(@content), path:).load(config:)
147+
if !self.class.invalid_path?(path, valid_extnames: %w[.json]) &&
148+
(from_json = JSON.parse(@content).presence) &&
149+
from_json.is_a?(Hash)
150+
return FromAPILoader.new(token, from_json:, path:).load(config:)
140151
end
141152

142153
begin
@@ -284,7 +295,7 @@ class FromAPILoader
284295
sig { returns(Pathname) }
285296
attr_reader :path
286297

287-
sig { returns(T.nilable(Hash)) }
298+
sig { returns(T.nilable(T::Hash[T.any(String, Symbol), T.anything])) }
288299
attr_reader :from_json
289300

290301
sig {
@@ -306,7 +317,13 @@ def self.try_new(ref, warn: false)
306317
new("#{tap}/#{token}")
307318
end
308319

309-
sig { params(token: String, from_json: Hash, path: T.nilable(Pathname)).void }
320+
sig {
321+
params(
322+
token: String,
323+
from_json: T.nilable(T::Hash[T.any(String, Symbol), T.anything]),
324+
path: T.nilable(Pathname),
325+
).void
326+
}
310327
def initialize(token, from_json: T.unsafe(nil), path: nil)
311328
@token = token.sub(%r{^homebrew/(?:homebrew-)?cask/}i, "")
312329
@sourcefile_path = path || Homebrew::API::Cask.cached_json_file_path
@@ -400,7 +417,7 @@ def load(config:)
400417
container(**container_hash)
401418
end
402419

403-
json_cask[:artifacts].each do |artifact|
420+
json_cask[:artifacts]&.each do |artifact|
404421
# convert generic string replacements into actual ones
405422
artifact = cask.loader.from_h_gsubs(artifact, appdir)
406423
key = artifact.keys.first

0 commit comments

Comments
 (0)