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
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/banzai/filter/syntax_highlight_filter_spec.rb')
-rw-r--r--spec/lib/banzai/filter/syntax_highlight_filter_spec.rb238
1 files changed, 93 insertions, 145 deletions
diff --git a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
index ef46fd62486..aee4bd93207 100644
--- a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
+++ b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
@@ -19,202 +19,150 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
end
end
- shared_examples_for 'renders correct markdown' do
- context "when no language is specified" do
- it "highlights as plaintext" do
- result = filter('<pre><code>def fun end</code></pre>')
+ context "when no language is specified" do
+ it "highlights as plaintext" do
+ result = filter('<pre><code>def fun end</code></pre>')
- expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">def fun end</span></code></pre><copy-code></copy-code></div>')
- end
-
- include_examples "XSS prevention", ""
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">def fun end</span></code></pre><copy-code></copy-code></div>')
end
- context "when contains mermaid diagrams" do
- it "ignores mermaid blocks" do
- result = filter('<pre data-mermaid-style="display"><code>mermaid code</code></pre>')
+ include_examples "XSS prevention", ""
+ end
- expect(result.to_html).to eq('<pre data-mermaid-style="display"><code>mermaid code</code></pre>')
- end
+ context "when contains mermaid diagrams" do
+ it "ignores mermaid blocks" do
+ result = filter('<pre data-mermaid-style="display"><code>mermaid code</code></pre>')
+
+ expect(result.to_html).to eq('<pre data-mermaid-style="display"><code>mermaid code</code></pre>')
end
+ end
- context "when a valid language is specified" do
- it "highlights as that language" do
- result = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- filter('<pre lang="ruby"><code>def fun end</code></pre>')
- else
- filter('<pre><code lang="ruby">def fun end</code></pre>')
- end
+ context "when <pre> contains multiple <code> tags" do
+ it "ignores the block" do
+ result = filter('<pre><code>one</code> and <code>two</code></pre>')
- expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-ruby" lang="ruby" v-pre="true"><code><span id="LC1" class="line" lang="ruby"><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></span></code></pre><copy-code></copy-code></div>')
- end
+ expect(result.to_html).to eq('<pre><code>one</code> and <code>two</code></pre>')
+ end
+ end
- include_examples "XSS prevention", "ruby"
+ context "when a valid language is specified" do
+ it "highlights as that language" do
+ result = filter('<pre lang="ruby"><code>def fun end</code></pre>')
+
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-ruby" lang="ruby" v-pre="true"><code><span id="LC1" class="line" lang="ruby"><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></span></code></pre><copy-code></copy-code></div>')
end
- context "when an invalid language is specified" do
- it "highlights as plaintext" do
- result = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- filter('<pre lang="gnuplot"><code>This is a test</code></pre>')
- else
- filter('<pre><code lang="gnuplot">This is a test</code></pre>')
- end
+ include_examples "XSS prevention", "ruby"
+ end
- expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre><copy-code></copy-code></div>')
- end
+ context "when an invalid language is specified" do
+ it "highlights as plaintext" do
+ result = filter('<pre lang="gnuplot"><code>This is a test</code></pre>')
- include_examples "XSS prevention", "gnuplot"
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre><copy-code></copy-code></div>')
end
- context "languages that should be passed through" do
- let(:delimiter) { described_class::LANG_PARAMS_DELIMITER }
- let(:data_attr) { described_class::LANG_PARAMS_ATTR }
+ include_examples "XSS prevention", "gnuplot"
+ end
- %w(math mermaid plantuml suggestion).each do |lang|
- context "when #{lang} is specified" do
- it "highlights as plaintext but with the correct language attribute and class" do
- result = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- filter(%{<pre lang="#{lang}"><code>This is a test</code></pre>})
- else
- filter(%{<pre><code lang="#{lang}">This is a test</code></pre>})
- end
+ context "languages that should be passed through" do
+ let(:delimiter) { described_class::LANG_PARAMS_DELIMITER }
+ let(:data_attr) { described_class::LANG_PARAMS_ATTR }
- expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
- end
+ %w(math mermaid plantuml suggestion).each do |lang|
+ context "when #{lang} is specified" do
+ it "highlights as plaintext but with the correct language attribute and class" do
+ result = filter(%{<pre lang="#{lang}"><code>This is a test</code></pre>})
- include_examples "XSS prevention", lang
+ expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
end
- context "when #{lang} has extra params" do
- let(:lang_params) { 'foo-bar-kux' }
-
- let(:xss_lang) do
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- "#{lang} data-meta=\"foo-bar-kux\"&lt;script&gt;alert(1)&lt;/script&gt;"
- else
- "#{lang}#{described_class::LANG_PARAMS_DELIMITER}&lt;script&gt;alert(1)&lt;/script&gt;"
- end
- end
-
- it "includes data-lang-params tag with extra information" do
- result = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- filter(%{<pre lang="#{lang}" data-meta="#{lang_params}"><code>This is a test</code></pre>})
- else
- filter(%{<pre><code lang="#{lang}#{delimiter}#{lang_params}">This is a test</code></pre>})
- end
-
- expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
- end
-
- include_examples "XSS prevention", lang
-
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- include_examples "XSS prevention",
- "#{lang} data-meta=\"foo-bar-kux\"&lt;script&gt;alert(1)&lt;/script&gt;"
- else
- include_examples "XSS prevention",
- "#{lang}#{described_class::LANG_PARAMS_DELIMITER}&lt;script&gt;alert(1)&lt;/script&gt;"
- end
-
- include_examples "XSS prevention",
- "#{lang} data-meta=\"foo-bar-kux\"<script>alert(1)</script>"
- end
+ include_examples "XSS prevention", lang
end
- context 'when multiple param delimiters are used' do
- let(:lang) { 'suggestion' }
- let(:lang_params) { '-1+10' }
+ context "when #{lang} has extra params" do
+ let(:lang_params) { 'foo-bar-kux' }
+ let(:xss_lang) { "#{lang} data-meta=\"foo-bar-kux\"&lt;script&gt;alert(1)&lt;/script&gt;" }
- let(:expected_result) do
- %{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params} more-things" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>}
- end
-
- context 'when delimiter is space' do
- it 'delimits on the first appearance' do
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- result = filter(%{<pre lang="#{lang}" data-meta="#{lang_params} more-things"><code>This is a test</code></pre>})
+ it "includes data-lang-params tag with extra information" do
+ result = filter(%{<pre lang="#{lang}" data-meta="#{lang_params}"><code>This is a test</code></pre>})
- expect(result.to_html.delete("\n")).to eq(expected_result)
- else
- result = filter(%{<pre><code lang="#{lang}#{delimiter}#{lang_params}#{delimiter}more-things">This is a test</code></pre>})
-
- expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params}#{delimiter}more-things" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
- end
- end
+ expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
end
- context 'when delimiter is colon' do
- it 'delimits on the first appearance' do
- result = filter(%{<pre lang="#{lang}#{delimiter}#{lang_params} more-things"><code>This is a test</code></pre>})
+ include_examples "XSS prevention", lang
- if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- expect(result.to_html.delete("\n")).to eq(expected_result)
- else
- expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class=\"code highlight js-syntax-highlight language-plaintext\" lang=\"plaintext\" v-pre=\"true\"><code><span id=\"LC1\" class=\"line\" lang=\"plaintext\">This is a test</span></code></pre><copy-code></copy-code></div>})
- end
- end
- end
+ include_examples "XSS prevention",
+ "#{lang} data-meta=\"foo-bar-kux\"&lt;script&gt;alert(1)&lt;/script&gt;"
+
+ include_examples "XSS prevention",
+ "#{lang} data-meta=\"foo-bar-kux\"<script>alert(1)</script>"
end
end
- context "when sourcepos metadata is available" do
- it "includes it in the highlighted code block" do
- result = filter('<pre data-sourcepos="1:1-3:3"><code lang="plaintext">This is a test</code></pre>')
+ context 'when multiple param delimiters are used' do
+ let(:lang) { 'suggestion' }
+ let(:lang_params) { '-1+10' }
- expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre><copy-code></copy-code></div>')
+ let(:expected_result) do
+ %{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params} more-things" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>}
end
- end
- context "when Rouge lexing fails" do
- before do
- allow_next_instance_of(Rouge::Lexers::Ruby) do |instance|
- allow(instance).to receive(:stream_tokens).and_raise(StandardError)
+ context 'when delimiter is space' do
+ it 'delimits on the first appearance' do
+ result = filter(%{<pre lang="#{lang}" data-meta="#{lang_params} more-things"><code>This is a test</code></pre>})
+
+ expect(result.to_html.delete("\n")).to eq(expected_result)
end
end
- it "highlights as plaintext" do
- result = if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- filter('<pre lang="ruby"><code>This is a test</code></pre>')
- else
- filter('<pre><code lang="ruby">This is a test</code></pre>')
- end
+ context 'when delimiter is colon' do
+ it 'delimits on the first appearance' do
+ result = filter(%{<pre lang="#{lang}#{delimiter}#{lang_params} more-things"><code>This is a test</code></pre>})
- expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight" lang="" v-pre="true"><code><span id="LC1" class="line" lang="">This is a test</span></code></pre><copy-code></copy-code></div>')
+ expect(result.to_html.delete("\n")).to eq(expected_result)
+ end
end
-
- include_examples "XSS prevention", "ruby"
end
+ end
- context "when Rouge lexing fails after a retry" do
- before do
- allow_next_instance_of(Rouge::Lexers::PlainText) do |instance|
- allow(instance).to receive(:stream_tokens).and_raise(StandardError)
- end
- end
+ context "when sourcepos metadata is available" do
+ it "includes it in the highlighted code block" do
+ result = filter('<pre data-sourcepos="1:1-3:3"><code lang="plaintext">This is a test</code></pre>')
- it "does not add highlighting classes" do
- result = filter('<pre><code>This is a test</code></pre>')
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre><copy-code></copy-code></div>')
+ end
+ end
- expect(result.to_html).to eq('<pre><code>This is a test</code></pre>')
+ context "when Rouge lexing fails" do
+ before do
+ allow_next_instance_of(Rouge::Lexers::Ruby) do |instance|
+ allow(instance).to receive(:stream_tokens).and_raise(StandardError)
end
+ end
+
+ it "highlights as plaintext" do
+ result = filter('<pre lang="ruby"><code>This is a test</code></pre>')
- include_examples "XSS prevention", "ruby"
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight" lang="" v-pre="true"><code><span id="LC1" class="line" lang="">This is a test</span></code></pre><copy-code></copy-code></div>')
end
+
+ include_examples "XSS prevention", "ruby"
end
- context 'using ruby-based HTML renderer' do
+ context "when Rouge lexing fails after a retry" do
before do
- stub_feature_flags(use_cmark_renderer: false)
+ allow_next_instance_of(Rouge::Lexers::PlainText) do |instance|
+ allow(instance).to receive(:stream_tokens).and_raise(StandardError)
+ end
end
- it_behaves_like 'renders correct markdown'
- end
+ it "does not add highlighting classes" do
+ result = filter('<pre><code>This is a test</code></pre>')
- context 'using c-based HTML renderer' do
- before do
- stub_feature_flags(use_cmark_renderer: true)
+ expect(result.to_html).to eq('<pre><code>This is a test</code></pre>')
end
- it_behaves_like 'renders correct markdown'
+ include_examples "XSS prevention", "ruby"
end
end