Class: Banzai::Filter::MermaidFilter

Inherits:
HTML::Pipeline::Filter
  • Object
show all
Includes:
Concerns::AssetProxying, Concerns::PipelineTimingCheck, Gitlab::Utils::SanitizeNodeLink
Defined in:
lib/banzai/filter/mermaid_filter.rb

Constant Summary collapse

CSS =
'pre[data-canonical-lang="mermaid"] > code'
XPATH =
Gitlab::Utils::Nokogiri.css_to_xpath(CSS).freeze

Constants included from Gitlab::Utils::SanitizeNodeLink

Gitlab::Utils::SanitizeNodeLink::ATTRS_TO_SANITIZE, Gitlab::Utils::SanitizeNodeLink::UNSAFE_PROTOCOLS

Constants included from Concerns::PipelineTimingCheck

Concerns::PipelineTimingCheck::MAX_PIPELINE_SECONDS

Instance Method Summary collapse

Methods included from Gitlab::Utils::SanitizeNodeLink

#permit_url?, #remove_unsafe_links, #safe_protocol?, #sanitize_unsafe_links

Methods included from Concerns::AssetProxying

#asset_proxy_enabled?, #asset_proxy_url, #can_skip_asset_proxy_for_url?, #validate_asset_proxying

Methods included from Concerns::PipelineTimingCheck

#exceeded_pipeline_max?

Instance Method Details

#callObject



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/banzai/filter/mermaid_filter.rb', line 14

def call
  # When the asset proxy is enabled, we pre-generate asset proxy URLs for any URLs we find in
  # the source and pass them through to the frontend.  The frontend substitutes the asset proxy
  # URLs for any image srcs in the Mermaid result, dropping the image if there's no match --
  # i.e. we fail safe and don't load unproxied images.  This means we can sanitise an image from
  # Mermaid by just not including an asset proxy URL for it.  If we don't need to proxy the image,
  # we set the key to `true` to signal it's permitted.

  base_re = URI::DEFAULT_PARSER.make_regexp
  # Try to match surrounding single-quotes, such that the trailing one doesn't get included as
  # part of the path, query or fragment, as is permitted by the parser.  If we don't do this,
  # a URL in text like <img src='https://hello.com/wow.gif'> will match "https://hello.com/wow.gif'".
  uri_re = /(?<bare>#{base_re})|'(?<sq>#{base_re})'/

  doc.xpath(XPATH).each do |node|
    node.add_class('js-render-mermaid')

    next unless asset_proxy_enabled?

    proxied_urls = {}

    node.content.scan(uri_re) do
      uri = $~['bare'] || $~['sq']

      next unless permit_url?(uri)

      proxied_urls[uri] ||= can_skip_asset_proxy_for_url?(uri) ? true : asset_proxy_url(uri)
    end

    # The presence of data-proxied-urls indicates we should perform the image checks.
    # (If it's the empty object, '{}', that means all images should be removed!)
    node['data-proxied-urls'] = proxied_urls.to_json
  end

  doc
end

#validateObject



51
52
53
# File 'lib/banzai/filter/mermaid_filter.rb', line 51

def validate
  validate_asset_proxying
end