From ee664acb356f8123f4f6b00b73c1e1cf0866c7fb Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 20 Oct 2022 09:40:42 +0000 Subject: Add latest changes from gitlab-org/gitlab@15-5-stable-ee --- lib/banzai/filter/markdown_engines/common_mark.rb | 2 + lib/banzai/filter/pathological_markdown_filter.rb | 27 --------- lib/banzai/filter/table_of_contents_filter.rb | 4 +- lib/banzai/filter/truncate_visible_filter.rb | 69 +++++++++++++++++++++++ lib/banzai/filter/wiki_link_filter/rewriter.rb | 11 +++- lib/banzai/pipeline/ascii_doc_pipeline.rb | 1 + lib/banzai/pipeline/plain_markdown_pipeline.rb | 1 - lib/banzai/pipeline/post_process_pipeline.rb | 1 + 8 files changed, 86 insertions(+), 30 deletions(-) delete mode 100644 lib/banzai/filter/pathological_markdown_filter.rb create mode 100644 lib/banzai/filter/truncate_visible_filter.rb (limited to 'lib/banzai') diff --git a/lib/banzai/filter/markdown_engines/common_mark.rb b/lib/banzai/filter/markdown_engines/common_mark.rb index cf368e28beb..7abfadc612b 100644 --- a/lib/banzai/filter/markdown_engines/common_mark.rb +++ b/lib/banzai/filter/markdown_engines/common_mark.rb @@ -56,3 +56,5 @@ module Banzai end end end + +Banzai::Filter::MarkdownEngines::CommonMark.prepend_mod diff --git a/lib/banzai/filter/pathological_markdown_filter.rb b/lib/banzai/filter/pathological_markdown_filter.rb deleted file mode 100644 index 0f94150c7a1..00000000000 --- a/lib/banzai/filter/pathological_markdown_filter.rb +++ /dev/null @@ -1,27 +0,0 @@ -# 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/filter/table_of_contents_filter.rb b/lib/banzai/filter/table_of_contents_filter.rb index 179afd840a5..1c794a81d9d 100644 --- a/lib/banzai/filter/table_of_contents_filter.rb +++ b/lib/banzai/filter/table_of_contents_filter.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'cgi/util' + # Generated HTML is transformed back to GFM by app/assets/javascripts/behaviors/markdown/nodes/table_of_contents.js module Banzai module Filter @@ -93,7 +95,7 @@ module Banzai def text return '' unless node - @text ||= EscapeUtils.escape_html(node.text) + @text ||= CGI.escapeHTML(node.text) end private diff --git a/lib/banzai/filter/truncate_visible_filter.rb b/lib/banzai/filter/truncate_visible_filter.rb new file mode 100644 index 00000000000..edd6efd4706 --- /dev/null +++ b/lib/banzai/filter/truncate_visible_filter.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +module Banzai + module Filter + class TruncateVisibleFilter < HTML::Pipeline::Filter + # Truncates the document to `truncate_visible_max_chars` characters, + # excluding any HTML tags. + + MATCH_CODE = 'pre > code > .line' + + def call + return doc unless context[:truncate_visible_max_chars].present? + + max_chars = context[:truncate_visible_max_chars] + content_length = 0 + @truncated = false + + doc.traverse do |node| + if node.text? || node.content.empty? + if truncated + node.remove + next + end + + handle_line_breaks(node) + truncate_content(content_length, max_chars, node) + + content_length += node.content.length + end + + truncate_if_block(node) + end + + doc + end + + private + + attr_reader :truncated + + def truncate_content(content_length, max_chars, node) + num_remaining = max_chars - content_length + return unless node.content.length > num_remaining + + node.content = node.content.truncate(num_remaining) + @truncated = true + end + + # Handle line breaks within a node + def handle_line_breaks(node) + return unless node.content.strip.lines.length > 1 + + node.content = "#{node.content.lines.first.chomp}..." + @truncated = true + end + + # If `node` is the first block element, and the + # text hasn't already been truncated, then append "..." to the node contents + # and return true. Otherwise return false. + def truncate_if_block(node) + return if truncated + return unless node.element? && (node.description&.block? || node.matches?(MATCH_CODE)) + + node.inner_html = "#{node.inner_html}..." if node.next_sibling + @truncated = true + end + end + end +end diff --git a/lib/banzai/filter/wiki_link_filter/rewriter.rb b/lib/banzai/filter/wiki_link_filter/rewriter.rb index b4c2e7efae3..455cac98841 100644 --- a/lib/banzai/filter/wiki_link_filter/rewriter.rb +++ b/lib/banzai/filter/wiki_link_filter/rewriter.rb @@ -42,7 +42,7 @@ module Banzai def apply_relative_link_rules! if @uri.relative? && @uri.path.present? link = @uri.path - link = ::File.join(@wiki_base_path, link) unless link.starts_with?(@wiki_base_path) + link = ::File.join(@wiki_base_path, link) unless prefixed_with_base_path?(link) link = "#{link}##{@uri.fragment}" if @uri.fragment @uri = Addressable::URI.parse(link) end @@ -55,6 +55,15 @@ module Banzai def repository_upload? @uri.relative? && @uri.path.starts_with?(Wikis::CreateAttachmentService::ATTACHMENT_PATH) end + + def prefixed_with_base_path?(link) + link.starts_with?(@wiki_base_path) || link.starts_with?(old_wiki_base_path) + end + + # before we added `/-/` to all our paths + def old_wiki_base_path + @wiki_base_path.sub('/-/', '/') + end end end end diff --git a/lib/banzai/pipeline/ascii_doc_pipeline.rb b/lib/banzai/pipeline/ascii_doc_pipeline.rb index 90edc7010f4..b652d8d89cf 100644 --- a/lib/banzai/pipeline/ascii_doc_pipeline.rb +++ b/lib/banzai/pipeline/ascii_doc_pipeline.rb @@ -13,6 +13,7 @@ module Banzai Filter::ColorFilter, Filter::ImageLazyLoadFilter, Filter::ImageLinkFilter, + Filter::WikiLinkFilter, Filter::AsciiDocPostProcessingFilter ] end diff --git a/lib/banzai/pipeline/plain_markdown_pipeline.rb b/lib/banzai/pipeline/plain_markdown_pipeline.rb index fb6f6e9077d..1da0f72996b 100644 --- a/lib/banzai/pipeline/plain_markdown_pipeline.rb +++ b/lib/banzai/pipeline/plain_markdown_pipeline.rb @@ -5,7 +5,6 @@ module Banzai class PlainMarkdownPipeline < BasePipeline def self.filters FilterArray[ - Filter::PathologicalMarkdownFilter, Filter::MarkdownPreEscapeFilter, Filter::MarkdownFilter, Filter::MarkdownPostEscapeFilter diff --git a/lib/banzai/pipeline/post_process_pipeline.rb b/lib/banzai/pipeline/post_process_pipeline.rb index da2262cdf83..f8035698b9b 100644 --- a/lib/banzai/pipeline/post_process_pipeline.rb +++ b/lib/banzai/pipeline/post_process_pipeline.rb @@ -5,6 +5,7 @@ module Banzai class PostProcessPipeline < BasePipeline def self.filters @filters ||= FilterArray[ + Filter::TruncateVisibleFilter, *internal_link_filters, Filter::AbsoluteLinkFilter, Filter::BroadcastMessagePlaceholdersFilter -- cgit v1.2.3