Class: Homebrew::Vulns::AdvisoryOverrides Private
- Defined in:
- vulns/advisory_overrides.rb
Overview
This class is part of a private API. This class may only be used in the Homebrew/brew repository. Third parties should avoid using this class if possible, as it may be removed or changed without warning.
Reviewed formula identity and candidate-specific corrections for advisory matching. These are intentionally keyed by formula, and range corrections are further keyed by upstream advisory identifier, so a bad upstream range cannot silently change unrelated matches.
Defined Under Namespace
Classes: Entry, Error, RegistryPackageOverride
Class Method Summary collapse
Instance Method Summary collapse
- #advisory_override(formula_name, identifiers) ⇒ Entry? private
-
#initialize(data) ⇒ void
constructor
private
Keep formula and advisory entry validation, including the effective override requirement, in sync with advisory-database spec/overrides_spec.rb.
-
#preserve_homebrew_ranges?(formula_name, identifiers) ⇒ Boolean
private
A protection under any alias applies to the whole family, independently of whichever alias supplies the upstream state or version override.
- #registry_package_override(formula_name) ⇒ RegistryPackageOverride? private
- #skip_formula?(formula_name) ⇒ Boolean private
Constructor Details
#initialize(data) ⇒ void
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Keep formula and advisory entry validation, including the effective override requirement, in sync with advisory-database spec/overrides_spec.rb.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'vulns/advisory_overrides.rb', line 43 def initialize(data) @skipped_formulae = T.let({}, T::Hash[String, T::Boolean]) @registry_packages = T.let({}, T::Hash[String, RegistryPackageOverride]) @advisories = T.let({}, T::Hash[String, T::Hash[String, Entry]]) @preserved_homebrew_ranges = T.let({}, T::Hash[String, T::Array[String]]) root = hash(data, "top level") root.each do |formula_name, raw_formula| raise Error, "Formula names must be strings" unless formula_name.is_a?(String) formula = hash(raw_formula, formula_name) reject_unknown_keys(formula, %w[skip advisories registry_package], formula_name) skip = formula.fetch("skip", false) raise Error, "#{formula_name}.skip must be true or false" unless [true, false].include?(skip) @skipped_formulae[formula_name] = true if skip if formula.key?("registry_package") location = "#{formula_name}.registry_package" package = hash(formula.fetch("registry_package"), location) reject_unknown_keys(package, REGISTRY_PACKAGE_KEYS, location) missing = REGISTRY_PACKAGE_KEYS - package.keys raise Error, "#{location} is missing key(s): #{missing.join(", ")}" if missing.any? ecosystem = nonblank_string(package.fetch("ecosystem"), "#{location}.ecosystem") name = nonblank_string(package.fetch("name"), "#{location}.name") unless Identify.registry_package_for(ecosystem:, name:) raise Error, "#{location} must identify a supported registry package with a canonical OSV name" end @registry_packages[formula_name] = RegistryPackageOverride.new(ecosystem:, name:) end next unless formula.key?("advisories") raw_advisories = hash(formula.fetch("advisories"), "#{formula_name}.advisories") parsed = T.let({}, T::Hash[String, Entry]) raw_advisories.each do |identifier, raw_entry| raise Error, "#{formula_name} advisory identifiers must be strings" unless identifier.is_a?(String) entry = hash(raw_entry, "#{formula_name}.advisories.#{identifier}") reject_unknown_keys(entry, %w[range_state upstream_fixed_in preserve_homebrew_ranges], "#{formula_name}.advisories.#{identifier}") preserve_ranges = entry.fetch("preserve_homebrew_ranges", false) unless [true, false].include?(preserve_ranges) raise Error, "#{formula_name}.advisories.#{identifier}.preserve_homebrew_ranges must be true or false" end (@preserved_homebrew_ranges[formula_name] ||= []) << identifier if preserve_ranges state = T.let(nil, T.nilable(Symbol)) if entry.key?("range_state") raw_state = entry.fetch("range_state") state = raw_state.to_sym if raw_state.is_a?(String) if state.nil? || VALID_STATES.exclude?(state) raise Error, "#{formula_name}.advisories.#{identifier}.range_state must be " \ "affected, fixed, or not_applicable" end end fixed_in_overridden = entry.key?("upstream_fixed_in") fixed_in = entry["upstream_fixed_in"] if !fixed_in.nil? && !fixed_in.is_a?(String) raise Error, "#{formula_name}.advisories.#{identifier}.upstream_fixed_in must be a string or null" end if state.nil? && !fixed_in_overridden && !preserve_ranges raise Error, "#{formula_name}.advisories.#{identifier} must override at least one field" end if state || fixed_in_overridden parsed[identifier] = Entry.new(state:, fixed_in:, fixed_in_overridden:) end end @advisories[formula_name] = parsed.freeze end @skipped_formulae.freeze @registry_packages.freeze @advisories.freeze @preserved_homebrew_ranges.each_value(&:freeze) @preserved_homebrew_ranges.freeze end |
Class Method Details
.from_file(path) ⇒ AdvisoryOverrides
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
34 35 36 37 38 |
# File 'vulns/advisory_overrides.rb', line 34 def self.from_file(path) new(YAML.safe_load(path.read, permitted_classes: [], permitted_symbols: [], aliases: false)) rescue Psych::Exception => e raise Error, "Failed to parse advisory overrides at #{path}: #{e.}" end |
Instance Method Details
#advisory_override(formula_name, identifiers) ⇒ Entry?
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
137 138 139 140 141 142 143 144 145 146 |
# File 'vulns/advisory_overrides.rb', line 137 def advisory_override(formula_name, identifiers) formula = @advisories[formula_name] return unless formula identifiers.each do |identifier| override = formula[identifier] return override if override end nil end |
#preserve_homebrew_ranges?(formula_name, identifiers) ⇒ Boolean
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
A protection under any alias applies to the whole family, independently of whichever alias supplies the upstream state or version override.
151 152 153 |
# File 'vulns/advisory_overrides.rb', line 151 def preserve_homebrew_ranges?(formula_name, identifiers) @preserved_homebrew_ranges.fetch(formula_name, []).intersect?(identifiers) end |
#registry_package_override(formula_name) ⇒ RegistryPackageOverride?
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
132 133 134 |
# File 'vulns/advisory_overrides.rb', line 132 def registry_package_override(formula_name) @registry_packages[formula_name] end |
#skip_formula?(formula_name) ⇒ Boolean
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
127 128 129 |
# File 'vulns/advisory_overrides.rb', line 127 def skip_formula?(formula_name) @skipped_formulae.key?(formula_name) end |