Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix internal formula json v3 frozen hash parsing bug #17201

Merged
merged 1 commit into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion Library/Homebrew/extend/cachable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ def cache
@cache ||= T.let({}, T.nilable(T::Hash[T.untyped, T.untyped]))
end

# NOTE: We overwrite here instead of using `Hash#clear` to handle frozen hashes.
sig { void }
def clear_cache
cache.clear
overwrite_cache!({})
Comment on lines +10 to +13
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The internal JSON v3 format gets parsed into a frozen hash with JSON.parse(string, frozen: true) and then gets moved into the cache with Cachable#overwrite_cache! so the cache is frozen in that case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if there are any real downsides to creating a new hash here instead of using Hash#clear.

Edit: I guess we could also do this if we don't want to create new hashes here.

def clear_cache
  cache.frozen? ? overwrite_cache!({}) : cache.clear
end

end

private
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/formulary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def self.load_formula_from_api(name, flags:)
end

if info&.key?("uses_from_macos")
bounds = info["uses_from_macos"] || {}
bounds = info["uses_from_macos"].dup || {}
bounds.deep_transform_keys!(&:to_sym)
bounds.deep_transform_values!(&:to_sym)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

allow(Homebrew::API).to receive(:fetch_json_api_file)
.with("internal/v3/homebrew-core.jws.json")
.and_return([JSON.parse(internal_tap_json), false])
.and_return([JSON.parse(internal_tap_json, freeze: true), false])

# `Tap.tap_migration_oldnames` looks for renames in every
# tap so `CoreCaskTap.tap_migrations` gets called and tries to
Expand Down