diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 19:05:49 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 19:05:49 +0300 |
commit | 43a25d93ebdabea52f99b05e15b06250cd8f07d7 (patch) | |
tree | dceebdc68925362117480a5d672bcff122fb625b /lib/gitlab/config | |
parent | 20c84b99005abd1c82101dfeff264ac50d2df211 (diff) |
Add latest changes from gitlab-org/gitlab@16-0-stable-eev16.0.0-rc42
Diffstat (limited to 'lib/gitlab/config')
-rw-r--r-- | lib/gitlab/config/entry/validators.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/config/loader/multi_doc_yaml.rb | 69 | ||||
-rw-r--r-- | lib/gitlab/config/loader/yaml.rb | 8 |
3 files changed, 39 insertions, 40 deletions
diff --git a/lib/gitlab/config/entry/validators.rb b/lib/gitlab/config/entry/validators.rb index fad2260d818..28cfb6d8fee 100644 --- a/lib/gitlab/config/entry/validators.rb +++ b/lib/gitlab/config/entry/validators.rb @@ -356,7 +356,7 @@ module Gitlab ports_size = value.count return if ports_size <= 1 - named_ports = value.select { |e| e.is_a?(Hash) }.map { |e| e[:name] }.compact.map(&:downcase) + named_ports = value.select { |e| e.is_a?(Hash) }.filter_map { |e| e[:name] }.map(&:downcase) if ports_size != named_ports.size record.errors.add(attribute, 'when there is more than one port, a unique name should be added') diff --git a/lib/gitlab/config/loader/multi_doc_yaml.rb b/lib/gitlab/config/loader/multi_doc_yaml.rb index 346adc79896..084d32a85bc 100644 --- a/lib/gitlab/config/loader/multi_doc_yaml.rb +++ b/lib/gitlab/config/loader/multi_doc_yaml.rb @@ -4,59 +4,50 @@ module Gitlab module Config module Loader class MultiDocYaml - TooManyDocumentsError = Class.new(Loader::FormatError) - DataTooLargeError = Class.new(Loader::FormatError) - NotHashError = Class.new(Loader::FormatError) + include Gitlab::Utils::StrongMemoize - MULTI_DOC_DIVIDER = /^---$/.freeze + MULTI_DOC_DIVIDER = /^---\s+/.freeze - def initialize(config, max_documents:, additional_permitted_classes: []) + def initialize(config, max_documents:, additional_permitted_classes: [], reject_empty: false) + @config = config @max_documents = max_documents - @safe_config = load_config(config, additional_permitted_classes) + @additional_permitted_classes = additional_permitted_classes + @reject_empty = reject_empty end - def load! - raise TooManyDocumentsError, 'The parsed YAML has too many documents' if too_many_documents? - raise DataTooLargeError, 'The parsed YAML is too big' if too_big? - raise NotHashError, 'Invalid configuration format' unless all_hashes? - - safe_config.map(&:deep_symbolize_keys) + def valid? + documents.all?(&:valid?) end - private - - attr_reader :safe_config, :max_documents - - def load_config(config, additional_permitted_classes) - config.split(MULTI_DOC_DIVIDER).filter_map do |document| - YAML.safe_load(document, - permitted_classes: [Symbol, *additional_permitted_classes], - permitted_symbols: [], - aliases: true - ) - end - rescue Psych::Exception => e - raise Loader::FormatError, e.message + def load_raw! + documents.map(&:load_raw!) end - def all_hashes? - safe_config.all?(Hash) + def load! + documents.map(&:load!) end - def too_many_documents? - safe_config.count > max_documents - end + private + + attr_reader :config, :max_documents, :additional_permitted_classes, :reject_empty + + # Valid YAML files can start with either a leading delimiter or no delimiter. + # To avoid counting a leading delimiter towards the document limit, + # this method splits the file by one more than the maximum number of permitted documents. + # It then discards the first document if it is blank. + def documents + docs = config + .split(MULTI_DOC_DIVIDER, max_documents_including_leading_delimiter) + .map { |d| Yaml.new(d, additional_permitted_classes: additional_permitted_classes) } - def too_big? - !deep_sizes.all?(&:valid?) + docs.shift if docs.first.blank? + docs.reject!(&:blank?) if reject_empty + docs end + strong_memoize_attr :documents - def deep_sizes - safe_config.map do |config| - Gitlab::Utils::DeepSize.new(config, - max_size: Gitlab::CurrentSettings.current_application_settings.max_yaml_size_bytes, - max_depth: Gitlab::CurrentSettings.current_application_settings.max_yaml_depth) - end + def max_documents_including_leading_delimiter + max_documents + 1 end end end diff --git a/lib/gitlab/config/loader/yaml.rb b/lib/gitlab/config/loader/yaml.rb index 7b87b5b8f97..7138663811e 100644 --- a/lib/gitlab/config/loader/yaml.rb +++ b/lib/gitlab/config/loader/yaml.rb @@ -1,5 +1,9 @@ # frozen_string_literal: true +# NOTE: DO NOT use this class for loading GitLab CI configuration files. +# Instead, use `Gitlab::Ci::Config::Yaml.load!`, which will properly handle +# CI configuration headers. + module Gitlab module Config module Loader @@ -34,6 +38,10 @@ module Gitlab @symbolized_config ||= load_raw!.deep_symbolize_keys end + def blank? + @config.blank? + end + private def hash? |