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:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-26 17:37:09 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-26 17:37:20 +0300
commit25ed7b6ae4712518e96d4719b75dd293c57404a2 (patch)
tree102e02b15909f27a82b6cf64e7b878f0b201b383 /lib
parentdaf5ae5bd439f1f32363d410129d5b9e73fbb539 (diff)
Add latest changes from gitlab-org/security/gitlab@15-3-stable-ee
Diffstat (limited to 'lib')
-rw-r--r--lib/banzai/filter/commit_trailers_filter.rb34
-rw-r--r--lib/banzai/filter/pathological_markdown_filter.rb27
-rw-r--r--lib/banzai/pipeline/plain_markdown_pipeline.rb1
-rw-r--r--lib/gitlab/git/rugged_impl/tree.rb9
-rw-r--r--lib/gitlab/git/tree.rb9
-rw-r--r--lib/gitlab/gitaly_client/commit_service.rb8
6 files changed, 63 insertions, 25 deletions
diff --git a/lib/banzai/filter/commit_trailers_filter.rb b/lib/banzai/filter/commit_trailers_filter.rb
index a615abc1989..817bea42757 100644
--- a/lib/banzai/filter/commit_trailers_filter.rb
+++ b/lib/banzai/filter/commit_trailers_filter.rb
@@ -17,21 +17,10 @@ module Banzai
include ActionView::Helpers::TagHelper
include AvatarsHelper
- TRAILER_REGEXP = /(?<label>[[:alpha:]-]+-by:)/i.freeze
- AUTHOR_REGEXP = /(?<author_name>.+)/.freeze
- # Devise.email_regexp wouldn't work here since its designed to match
- # against strings that only contains email addresses; the \A and \z
- # around the expression will only match if the string being matched
- # contains just the email nothing else.
- MAIL_REGEXP = /&lt;(?<author_email>[^@\s]+@[^@\s]+)&gt;/.freeze
- FILTER_REGEXP = /(?<trailer>^\s*#{TRAILER_REGEXP}\s*#{AUTHOR_REGEXP}\s+#{MAIL_REGEXP}$)/mi.freeze
-
def call
doc.xpath('descendant-or-self::text()').each do |node|
content = node.to_html
- next unless content.match(FILTER_REGEXP)
-
html = trailer_filter(content)
next if html == content
@@ -52,11 +41,24 @@ module Banzai
# Returns a String with all trailer lines replaced with links to GitLab
# users and mailto links to non GitLab users. All links have `data-trailer`
# and `data-user` attributes attached.
+ #
+ # The code intentionally avoids using Regex for security and performance
+ # reasons: https://gitlab.com/gitlab-org/gitlab/-/issues/363734
def trailer_filter(text)
- text.gsub(FILTER_REGEXP) do |author_match|
- label = $~[:label]
- "#{label} #{parse_user($~[:author_name], $~[:author_email], label)}"
- end
+ text.lines.map! do |line|
+ trailer, rest = line.split(':', 2)
+
+ next line unless trailer.downcase.end_with?('-by') && rest.present?
+
+ chunks = rest.split
+ author_email = chunks.pop.delete_prefix('&lt;').delete_suffix('&gt;')
+ next line unless Devise.email_regexp.match(author_email)
+
+ author_name = chunks.join(' ').strip
+ trailer = "#{trailer.strip}:"
+
+ "#{trailer} #{link_to_user_or_email(author_name, author_email, trailer)}\n"
+ end.join
end
# Find a GitLab user using the supplied email and generate
@@ -67,7 +69,7 @@ module Banzai
# trailer - String trailer used in the commit message
#
# Returns a String with a link to the user.
- def parse_user(name, email, trailer)
+ def link_to_user_or_email(name, email, trailer)
link_to_user User.find_by_any_email(email),
name: name,
email: email,
diff --git a/lib/banzai/filter/pathological_markdown_filter.rb b/lib/banzai/filter/pathological_markdown_filter.rb
new file mode 100644
index 00000000000..0f94150c7a1
--- /dev/null
+++ b/lib/banzai/filter/pathological_markdown_filter.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Banzai
+ module Filter
+ class PathologicalMarkdownFilter < HTML::Pipeline::TextFilter
+ # It's not necessary for this to be precise - we just need to detect
+ # when there are a non-trivial number of unclosed image links.
+ # So we don't really care about code blocks, etc.
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/370428
+ REGEX = /!\[(?:[^\]])+?!\[/.freeze
+ DETECTION_MAX = 10
+
+ def call
+ count = 0
+
+ @text.scan(REGEX) do |_match|
+ count += 1
+ break if count > DETECTION_MAX
+ end
+
+ return @text if count <= DETECTION_MAX
+
+ "_Unable to render markdown - too many unclosed markdown image links detected._"
+ end
+ end
+ end
+end
diff --git a/lib/banzai/pipeline/plain_markdown_pipeline.rb b/lib/banzai/pipeline/plain_markdown_pipeline.rb
index 1da0f72996b..fb6f6e9077d 100644
--- a/lib/banzai/pipeline/plain_markdown_pipeline.rb
+++ b/lib/banzai/pipeline/plain_markdown_pipeline.rb
@@ -5,6 +5,7 @@ module Banzai
class PlainMarkdownPipeline < BasePipeline
def self.filters
FilterArray[
+ Filter::PathologicalMarkdownFilter,
Filter::MarkdownPreEscapeFilter,
Filter::MarkdownFilter,
Filter::MarkdownPostEscapeFilter
diff --git a/lib/gitlab/git/rugged_impl/tree.rb b/lib/gitlab/git/rugged_impl/tree.rb
index bc0af12d7e3..66cfc02130b 100644
--- a/lib/gitlab/git/rugged_impl/tree.rb
+++ b/lib/gitlab/git/rugged_impl/tree.rb
@@ -16,9 +16,10 @@ module Gitlab
TREE_SORT_ORDER = { tree: 0, blob: 1, commit: 2 }.freeze
override :tree_entries
- def tree_entries(repository, sha, path, recursive, pagination_params = nil)
+ def tree_entries(repository, sha, path, recursive, skip_flat_paths, pagination_params = nil)
if use_rugged?(repository, :rugged_tree_entries)
- entries = execute_rugged_call(:tree_entries_with_flat_path_from_rugged, repository, sha, path, recursive)
+ entries = execute_rugged_call(
+ :tree_entries_with_flat_path_from_rugged, repository, sha, path, recursive, skip_flat_paths)
if pagination_params
paginated_response(entries, pagination_params[:limit], pagination_params[:page_token].to_s)
@@ -60,11 +61,11 @@ module Gitlab
[result, cursor]
end
- def tree_entries_with_flat_path_from_rugged(repository, sha, path, recursive)
+ def tree_entries_with_flat_path_from_rugged(repository, sha, path, recursive, skip_flat_paths)
tree_entries_from_rugged(repository, sha, path, recursive).tap do |entries|
# This was an optimization to reduce N+1 queries for Gitaly
# (https://gitlab.com/gitlab-org/gitaly/issues/530).
- rugged_populate_flat_path(repository, sha, path, entries)
+ rugged_populate_flat_path(repository, sha, path, entries) unless skip_flat_paths
end
end
diff --git a/lib/gitlab/git/tree.rb b/lib/gitlab/git/tree.rb
index eb008507397..f0eef619e13 100644
--- a/lib/gitlab/git/tree.rb
+++ b/lib/gitlab/git/tree.rb
@@ -15,15 +15,16 @@ module Gitlab
# Uses rugged for raw objects
#
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/320
- def where(repository, sha, path = nil, recursive = false, pagination_params = nil)
+ def where(repository, sha, path = nil, recursive = false, skip_flat_paths = true, pagination_params = nil)
path = nil if path == '' || path == '/'
- tree_entries(repository, sha, path, recursive, pagination_params)
+ tree_entries(repository, sha, path, recursive, skip_flat_paths, pagination_params)
end
- def tree_entries(repository, sha, path, recursive, pagination_params = nil)
+ def tree_entries(repository, sha, path, recursive, skip_flat_paths, pagination_params = nil)
wrapped_gitaly_errors do
- repository.gitaly_commit_client.tree_entries(repository, sha, path, recursive, pagination_params)
+ repository.gitaly_commit_client.tree_entries(
+ repository, sha, path, recursive, skip_flat_paths, pagination_params)
end
end
diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb
index 9fb34f74c82..0f306a9825d 100644
--- a/lib/gitlab/gitaly_client/commit_service.rb
+++ b/lib/gitlab/gitaly_client/commit_service.rb
@@ -5,6 +5,8 @@ module Gitlab
class CommitService
include Gitlab::EncodingHelper
+ TREE_ENTRIES_DEFAULT_LIMIT = 100_000
+
def initialize(repository)
@gitaly_repo = repository.gitaly_repository
@repository = repository
@@ -111,12 +113,16 @@ module Gitlab
nil
end
- def tree_entries(repository, revision, path, recursive, pagination_params)
+ def tree_entries(repository, revision, path, recursive, skip_flat_paths, pagination_params)
+ pagination_params ||= {}
+ pagination_params[:limit] ||= TREE_ENTRIES_DEFAULT_LIMIT
+
request = Gitaly::GetTreeEntriesRequest.new(
repository: @gitaly_repo,
revision: encode_binary(revision),
path: path.present? ? encode_binary(path) : '.',
recursive: recursive,
+ skip_flat_paths: skip_flat_paths,
pagination_params: pagination_params
)
request.sort = Gitaly::GetTreeEntriesRequest::SortBy::TREES_FIRST if pagination_params