Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/ci/build/policy/refs.rb2
-rw-r--r--lib/gitlab/ci/config/entry/policy.rb4
-rw-r--r--lib/gitlab/config/entry/validators.rb16
-rw-r--r--lib/gitlab/git/wiki.rb10
-rw-r--r--lib/gitlab/gitaly_client/wiki_service.rb9
-rw-r--r--lib/gitlab/graphql/query_analyzers/log_query_complexity.rb18
-rw-r--r--lib/gitlab/prometheus_client.rb32
-rw-r--r--lib/gitlab/untrusted_regexp/ruby_syntax.rb39
8 files changed, 105 insertions, 25 deletions
diff --git a/lib/gitlab/ci/build/policy/refs.rb b/lib/gitlab/ci/build/policy/refs.rb
index 360424bec11..c3005303fd8 100644
--- a/lib/gitlab/ci/build/policy/refs.rb
+++ b/lib/gitlab/ci/build/policy/refs.rb
@@ -35,7 +35,7 @@ module Gitlab
# patterns can be matched only when branch or tag is used
# the pattern matching does not work for merge requests pipelines
if pipeline.branch? || pipeline.tag?
- if regexp = Gitlab::UntrustedRegexp::RubySyntax.fabricate(pattern)
+ if regexp = Gitlab::UntrustedRegexp::RubySyntax.fabricate(pattern, fallback: true)
regexp.match?(pipeline.ref)
else
pattern == pipeline.ref
diff --git a/lib/gitlab/ci/config/entry/policy.rb b/lib/gitlab/ci/config/entry/policy.rb
index adc3660d950..7b14218d3ea 100644
--- a/lib/gitlab/ci/config/entry/policy.rb
+++ b/lib/gitlab/ci/config/entry/policy.rb
@@ -17,7 +17,7 @@ module Gitlab
include ::Gitlab::Config::Entry::Validatable
validations do
- validates :config, array_of_strings_or_regexps: true
+ validates :config, array_of_strings_or_regexps_with_fallback: true
end
def value
@@ -38,7 +38,7 @@ module Gitlab
validate :variables_expressions_syntax
with_options allow_nil: true do
- validates :refs, array_of_strings_or_regexps: true
+ validates :refs, array_of_strings_or_regexps_with_fallback: true
validates :kubernetes, allowed_values: %w[active]
validates :variables, array_of_strings: true
validates :changes, array_of_strings: true
diff --git a/lib/gitlab/config/entry/validators.rb b/lib/gitlab/config/entry/validators.rb
index d0ee94370ba..746fe83f90f 100644
--- a/lib/gitlab/config/entry/validators.rb
+++ b/lib/gitlab/config/entry/validators.rb
@@ -129,6 +129,12 @@ module Gitlab
end
end
+ protected
+
+ def fallback
+ false
+ end
+
private
def matches_syntax?(value)
@@ -137,7 +143,7 @@ module Gitlab
def validate_regexp(value)
matches_syntax?(value) &&
- Gitlab::UntrustedRegexp::RubySyntax.valid?(value)
+ Gitlab::UntrustedRegexp::RubySyntax.valid?(value, fallback: fallback)
end
end
@@ -162,6 +168,14 @@ module Gitlab
end
end
+ class ArrayOfStringsOrRegexpsWithFallbackValidator < ArrayOfStringsOrRegexpsValidator
+ protected
+
+ def fallback
+ true
+ end
+ end
+
class ArrayOfStringsOrStringValidator < RegexpValidator
def validate_each(record, attribute, value)
unless validate_array_of_strings_or_string(value)
diff --git a/lib/gitlab/git/wiki.rb b/lib/gitlab/git/wiki.rb
index c43331bed60..a0dd4a24363 100644
--- a/lib/gitlab/git/wiki.rb
+++ b/lib/gitlab/git/wiki.rb
@@ -86,9 +86,9 @@ module Gitlab
end
end
- def pages(limit: 0)
+ def pages(limit: 0, sort: nil, direction_desc: false)
wrapped_gitaly_errors do
- gitaly_get_all_pages(limit: limit)
+ gitaly_get_all_pages(limit: limit, sort: sort, direction_desc: direction_desc)
end
end
@@ -168,8 +168,10 @@ module Gitlab
Gitlab::Git::WikiFile.new(wiki_file)
end
- def gitaly_get_all_pages(limit: 0)
- gitaly_wiki_client.get_all_pages(limit: limit).map do |wiki_page, version|
+ def gitaly_get_all_pages(limit: 0, sort: nil, direction_desc: false)
+ gitaly_wiki_client.get_all_pages(
+ limit: limit, sort: sort, direction_desc: direction_desc
+ ).map do |wiki_page, version|
Gitlab::Git::WikiPage.new(wiki_page, version)
end
end
diff --git a/lib/gitlab/gitaly_client/wiki_service.rb b/lib/gitlab/gitaly_client/wiki_service.rb
index 15c9463e2f2..e036cdcd800 100644
--- a/lib/gitlab/gitaly_client/wiki_service.rb
+++ b/lib/gitlab/gitaly_client/wiki_service.rb
@@ -87,8 +87,13 @@ module Gitlab
wiki_page_from_iterator(response)
end
- def get_all_pages(limit: 0)
- request = Gitaly::WikiGetAllPagesRequest.new(repository: @gitaly_repo, limit: limit)
+ def get_all_pages(limit: 0, sort: nil, direction_desc: false)
+ sort_value = Gitaly::WikiGetAllPagesRequest::SortBy.resolve(sort.to_s.upcase.to_sym)
+
+ params = { repository: @gitaly_repo, limit: limit, direction_desc: direction_desc }
+ params[:sort] = sort_value if sort_value
+
+ request = Gitaly::WikiGetAllPagesRequest.new(params)
response = GitalyClient.call(@repository.storage, :wiki_service, :wiki_get_all_pages, request, timeout: GitalyClient.medium_timeout)
pages = []
diff --git a/lib/gitlab/graphql/query_analyzers/log_query_complexity.rb b/lib/gitlab/graphql/query_analyzers/log_query_complexity.rb
new file mode 100644
index 00000000000..95db130dbfc
--- /dev/null
+++ b/lib/gitlab/graphql/query_analyzers/log_query_complexity.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Graphql
+ module QueryAnalyzers
+ class LogQueryComplexity
+ class << self
+ def analyzer
+ GraphQL::Analysis::QueryComplexity.new do |query, complexity|
+ # temporary until https://gitlab.com/gitlab-org/gitlab-ce/issues/59587
+ Rails.logger.info("[GraphQL Query Complexity] #{complexity} | admin? #{query.context[:current_user]&.admin?}")
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/prometheus_client.rb b/lib/gitlab/prometheus_client.rb
index 45828c77a33..b4de7cd2bce 100644
--- a/lib/gitlab/prometheus_client.rb
+++ b/lib/gitlab/prometheus_client.rb
@@ -6,6 +6,14 @@ module Gitlab
Error = Class.new(StandardError)
QueryError = Class.new(Gitlab::PrometheusClient::Error)
+ # Target number of data points for `query_range`.
+ # Please don't exceed the limit of 11000 data points
+ # See https://github.com/prometheus/prometheus/blob/91306bdf24f5395e2601773316945a478b4b263d/web/api/v1/api.go#L347
+ QUERY_RANGE_DATA_POINTS = 600
+
+ # Minimal value of the `step` parameter for `query_range` in seconds.
+ QUERY_RANGE_MIN_STEP = 60
+
attr_reader :rest_client, :headers
def initialize(rest_client)
@@ -23,12 +31,18 @@ module Gitlab
end
def query_range(query, start: 8.hours.ago, stop: Time.now)
+ start = start.to_f
+ stop = stop.to_f
+ step = self.class.compute_step(start, stop)
+
get_result('matrix') do
- json_api_get('query_range',
- query: query,
- start: start.to_f,
- end: stop.to_f,
- step: 1.minute.to_i)
+ json_api_get(
+ 'query_range',
+ query: query,
+ start: start,
+ end: stop,
+ step: step
+ )
end
end
@@ -40,6 +54,14 @@ module Gitlab
json_api_get('series', 'match': matches, start: start.to_f, end: stop.to_f)
end
+ def self.compute_step(start, stop)
+ diff = stop - start
+
+ step = (diff / QUERY_RANGE_DATA_POINTS).ceil
+
+ [QUERY_RANGE_MIN_STEP, step].max
+ end
+
private
def json_api_get(type, args = {})
diff --git a/lib/gitlab/untrusted_regexp/ruby_syntax.rb b/lib/gitlab/untrusted_regexp/ruby_syntax.rb
index 91f300f97d0..6adf119aa75 100644
--- a/lib/gitlab/untrusted_regexp/ruby_syntax.rb
+++ b/lib/gitlab/untrusted_regexp/ruby_syntax.rb
@@ -6,7 +6,7 @@ module Gitlab
# and converts that to RE2 representation:
# /<regexp>/<flags>
class RubySyntax
- PATTERN = %r{^/(?<regexp>.+)/(?<flags>[ismU]*)$}.freeze
+ PATTERN = %r{^/(?<regexp>.*)/(?<flags>[ismU]*)$}.freeze
# Checks if pattern matches a regexp pattern
# but does not enforce it's validity
@@ -16,28 +16,47 @@ module Gitlab
# The regexp can match the pattern `/.../`, but may not be fabricatable:
# it can be invalid or incomplete: `/match ( string/`
- def self.valid?(pattern)
- !!self.fabricate(pattern)
+ def self.valid?(pattern, fallback: false)
+ !!self.fabricate(pattern, fallback: fallback)
end
- def self.fabricate(pattern)
- self.fabricate!(pattern)
+ def self.fabricate(pattern, fallback: false)
+ self.fabricate!(pattern, fallback: fallback)
rescue RegexpError
nil
end
- def self.fabricate!(pattern)
+ def self.fabricate!(pattern, fallback: false)
raise RegexpError, 'Pattern is not string!' unless pattern.is_a?(String)
matches = pattern.match(PATTERN)
raise RegexpError, 'Invalid regular expression!' if matches.nil?
- expression = matches[:regexp]
- flags = matches[:flags]
- expression.prepend("(?#{flags})") if flags.present?
+ begin
+ create_untrusted_regexp(matches[:regexp], matches[:flags])
+ rescue RegexpError
+ raise unless fallback &&
+ Feature.enabled?(:allow_unsafe_ruby_regexp, default_enabled: false)
- UntrustedRegexp.new(expression, multiline: false)
+ create_ruby_regexp(matches[:regexp], matches[:flags])
+ end
end
+
+ def self.create_untrusted_regexp(pattern, flags)
+ pattern.prepend("(?#{flags})") if flags.present?
+
+ UntrustedRegexp.new(pattern, multiline: false)
+ end
+ private_class_method :create_untrusted_regexp
+
+ def self.create_ruby_regexp(pattern, flags)
+ options = 0
+ options += Regexp::IGNORECASE if flags&.include?('i')
+ options += Regexp::MULTILINE if flags&.include?('m')
+
+ Regexp.new(pattern, options)
+ end
+ private_class_method :create_ruby_regexp
end
end
end