summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-26 14:39:03 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-26 14:39:03 +0000
commit4837eb6d70c2337d0368037e41456cb257ed0a56 (patch)
tree2692e53cc0b6a8aabf4ecc241916994fab234d9e
parent0b2fef5394efa3d1a37e09ec6f622a371b9b071b (diff)
downloadgitlab-ce-4837eb6d70c2337d0368037e41456cb257ed0a56.tar.gz
Add latest changes from gitlab-org/security/gitlab@15-1-stable-ee
-rw-r--r--app/assets/javascripts/notebook/cells/output/html.vue9
-rw-r--r--app/graphql/types/incident_management/timeline_event_type.rb7
-rw-r--r--lib/banzai/pipeline/incident_management/timeline_event_pipeline.rb2
-rw-r--r--lib/gitlab/markdown_cache.rb2
-rw-r--r--spec/frontend/notebook/cells/output/html_sanitize_fixtures.js4
-rw-r--r--spec/frontend/notebook/cells/output/index_spec.js13
-rw-r--r--spec/lib/banzai/pipeline/incident_management/timeline_event_pipeline_spec.rb29
-rw-r--r--spec/models/incident_management/timeline_event_spec.rb15
-rw-r--r--spec/requests/api/graphql/project/incident_management/timeline_events_spec.rb10
9 files changed, 69 insertions, 22 deletions
diff --git a/app/assets/javascripts/notebook/cells/output/html.vue b/app/assets/javascripts/notebook/cells/output/html.vue
index 2d1d8845e41..fdcea300388 100644
--- a/app/assets/javascripts/notebook/cells/output/html.vue
+++ b/app/assets/javascripts/notebook/cells/output/html.vue
@@ -40,6 +40,13 @@ export default {
<template>
<div class="output">
<prompt type="Out" :count="count" :show-output="showOutput" />
- <div v-safe-html:[$options.safeHtmlConfig]="rawCode" class="gl-overflow-auto"></div>
+ <iframe
+ sandbox
+ :srcdoc="rawCode"
+ frameborder="0"
+ scrolling="no"
+ width="100%"
+ class="gl-overflow-auto"
+ ></iframe>
</div>
</template>
diff --git a/app/graphql/types/incident_management/timeline_event_type.rb b/app/graphql/types/incident_management/timeline_event_type.rb
index a6d3f57404b..690facc8732 100644
--- a/app/graphql/types/incident_management/timeline_event_type.rb
+++ b/app/graphql/types/incident_management/timeline_event_type.rb
@@ -33,11 +33,6 @@ module Types
null: true,
description: 'Text note of the timeline event.'
- field :note_html,
- GraphQL::Types::String,
- null: true,
- description: 'HTML note of the timeline event.'
-
field :promoted_from_note,
Types::Notes::NoteType,
null: true,
@@ -67,6 +62,8 @@ module Types
Types::TimeType,
null: false,
description: 'Timestamp when the event updated.'
+
+ markdown_field :note_html, null: true, description: 'HTML note of the timeline event.'
end
end
end
diff --git a/lib/banzai/pipeline/incident_management/timeline_event_pipeline.rb b/lib/banzai/pipeline/incident_management/timeline_event_pipeline.rb
index 01ee3f5d9e8..eef2b2674dd 100644
--- a/lib/banzai/pipeline/incident_management/timeline_event_pipeline.rb
+++ b/lib/banzai/pipeline/incident_management/timeline_event_pipeline.rb
@@ -11,9 +11,9 @@ module Banzai
def self.filters
@filters ||= FilterArray[
*super,
+ Filter::SanitizationFilter,
*Banzai::Pipeline::GfmPipeline.reference_filters,
Filter::EmojiFilter,
- Filter::SanitizationFilter,
Filter::ExternalLinkFilter,
Filter::ImageLinkFilter
]
diff --git a/lib/gitlab/markdown_cache.rb b/lib/gitlab/markdown_cache.rb
index 09ba95666de..f426f70800c 100644
--- a/lib/gitlab/markdown_cache.rb
+++ b/lib/gitlab/markdown_cache.rb
@@ -11,7 +11,7 @@ module Gitlab
# this if the change to the renderer output is a new feature or a
# minor bug fix.
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/330313
- CACHE_COMMONMARK_VERSION = 31
+ CACHE_COMMONMARK_VERSION = 32
CACHE_COMMONMARK_VERSION_START = 10
BaseError = Class.new(StandardError)
diff --git a/spec/frontend/notebook/cells/output/html_sanitize_fixtures.js b/spec/frontend/notebook/cells/output/html_sanitize_fixtures.js
index 70c7f56b62f..296d01ddd99 100644
--- a/spec/frontend/notebook/cells/output/html_sanitize_fixtures.js
+++ b/spec/frontend/notebook/cells/output/html_sanitize_fixtures.js
@@ -38,7 +38,7 @@ export default [
'</tr>\n',
'</table>',
].join(''),
- output: '<table>',
+ output: '<table data-myattr=&quot;XSS&quot;>',
},
],
// Note: style is sanitized out
@@ -98,7 +98,7 @@ export default [
'</svg>',
].join(),
output:
- '<svg xmlns="http://www.w3.org/2000/svg" width="388.84pt" version="1.0" id="svg2" height="115.02pt">',
+ '<svg height=&quot;115.02pt&quot; id=&quot;svg2&quot; version=&quot;1.0&quot; width=&quot;388.84pt&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;>',
},
],
];
diff --git a/spec/frontend/notebook/cells/output/index_spec.js b/spec/frontend/notebook/cells/output/index_spec.js
index 8e04e4c146c..5c36bcaef2a 100644
--- a/spec/frontend/notebook/cells/output/index_spec.js
+++ b/spec/frontend/notebook/cells/output/index_spec.js
@@ -52,16 +52,16 @@ describe('Output component', () => {
const htmlType = json.cells[4];
createComponent(htmlType.outputs[0]);
- expect(vm.$el.querySelector('p')).not.toBeNull();
- expect(vm.$el.querySelectorAll('p')).toHaveLength(1);
- expect(vm.$el.textContent.trim()).toContain('test');
+ const iframe = vm.$el.querySelector('iframe');
+ expect(iframe).not.toBeNull();
+ expect(iframe.srcdoc).toBe('<p>test</p>');
});
it('renders multiple raw HTML outputs', () => {
const htmlType = json.cells[4];
createComponent([htmlType.outputs[0], htmlType.outputs[0]]);
- expect(vm.$el.querySelectorAll('p')).toHaveLength(2);
+ expect(vm.$el.querySelectorAll('iframe')).toHaveLength(2);
});
});
@@ -90,7 +90,10 @@ describe('Output component', () => {
});
it('renders as an svg', () => {
- expect(vm.$el.querySelector('svg')).not.toBeNull();
+ const iframe = vm.$el.querySelector('iframe');
+
+ expect(iframe).not.toBeNull();
+ expect(iframe.srcdoc).toBe('<svg></svg>');
});
});
diff --git a/spec/lib/banzai/pipeline/incident_management/timeline_event_pipeline_spec.rb b/spec/lib/banzai/pipeline/incident_management/timeline_event_pipeline_spec.rb
index 09d2919c6c4..76f2dd4b659 100644
--- a/spec/lib/banzai/pipeline/incident_management/timeline_event_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/incident_management/timeline_event_pipeline_spec.rb
@@ -10,9 +10,9 @@ RSpec.describe Banzai::Pipeline::IncidentManagement::TimelineEventPipeline do
expect(described_class.filters).to eq(
[
*Banzai::Pipeline::PlainMarkdownPipeline.filters,
+ Banzai::Filter::SanitizationFilter,
*Banzai::Pipeline::GfmPipeline.reference_filters,
Banzai::Filter::EmojiFilter,
- Banzai::Filter::SanitizationFilter,
Banzai::Filter::ExternalLinkFilter,
Banzai::Filter::ImageLinkFilter
]
@@ -62,7 +62,32 @@ RSpec.describe Banzai::Pipeline::IncidentManagement::TimelineEventPipeline do
context 'when markdown contains emojis' do
let(:markdown) { ':+1:👍' }
- it { is_expected.to eq('<p>👍👍</p>') }
+ it 'renders emojis wrapped in <gl-emoji> tag' do
+ # rubocop:disable Layout/LineLength
+ is_expected.to eq(
+ %q(<p><gl-emoji title="thumbs up sign" data-name="thumbsup" data-unicode-version="6.0">👍</gl-emoji><gl-emoji title="thumbs up sign" data-name="thumbsup" data-unicode-version="6.0">👍</gl-emoji></p>)
+ )
+ # rubocop:enable Layout/LineLength
+ end
+ end
+
+ context 'when markdown contains labels' do
+ let(:label) { create(:label, project: project, title: 'backend') }
+ let(:markdown) { %Q(~"#{label.name}" ~unknown) }
+
+ it 'replaces existing label to a link' do
+ # rubocop:disable Layout/LineLength
+ is_expected.to match(
+ %r(<p>.+<a href=\"[\w/]+-/issues\?label_name=#{label.name}\".+style=\"background-color: #\d{6}\".*>#{label.name}</span></a></span> ~unknown</p>)
+ )
+ # rubocop:enable Layout/LineLength
+ end
+ end
+
+ context 'when markdown contains table' do
+ let(:markdown) { '<table><tr><th>table head</th><tr><tr><td>table content</td></tr></table>'}
+
+ it { is_expected.to eq('table headtable content') }
end
context 'when markdown contains a reference to an issue' do
diff --git a/spec/models/incident_management/timeline_event_spec.rb b/spec/models/incident_management/timeline_event_spec.rb
index 17150fc9266..9f4011fe6a7 100644
--- a/spec/models/incident_management/timeline_event_spec.rb
+++ b/spec/models/incident_management/timeline_event_spec.rb
@@ -47,11 +47,20 @@ RSpec.describe IncidentManagement::TimelineEvent do
describe '#cache_markdown_field' do
let(:note) { 'note **bold** _italic_ `code` ![image](/path/img.png) :+1:👍' }
+
+ let(:expected_image_html) do
+ '<a class="with-attachment-icon" href="/path/img.png" target="_blank" rel="noopener noreferrer">image</a>'
+ end
+
+ # rubocop:disable Layout/LineLength
+ let(:expected_emoji_html) do
+ '<gl-emoji title="thumbs up sign" data-name="thumbsup" data-unicode-version="6.0">👍</gl-emoji><gl-emoji title="thumbs up sign" data-name="thumbsup" data-unicode-version="6.0">👍</gl-emoji>'
+ end
+
let(:expected_note_html) do
- # rubocop:disable Layout/LineLength
- '<p>note <strong>bold</strong> <em>italic</em> <code>code</code> <a class="with-attachment-icon" href="/path/img.png" target="_blank" rel="noopener noreferrer">image</a> 👍👍</p>'
- # rubocop:enable Layout/LineLength
+ %Q(<p>note <strong>bold</strong> <em>italic</em> <code>code</code> #{expected_image_html} #{expected_emoji_html}</p>)
end
+ # rubocop:enable Layout/LineLength
before do
allow(Banzai::Renderer).to receive(:cacheless_render_field).and_call_original
diff --git a/spec/requests/api/graphql/project/incident_management/timeline_events_spec.rb b/spec/requests/api/graphql/project/incident_management/timeline_events_spec.rb
index 31fef75f679..bcbb1f11d43 100644
--- a/spec/requests/api/graphql/project/incident_management/timeline_events_spec.rb
+++ b/spec/requests/api/graphql/project/incident_management/timeline_events_spec.rb
@@ -6,11 +6,16 @@ RSpec.describe 'getting incident timeline events' do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
+ let_it_be(:private_project) { create(:project, :private) }
+ let_it_be(:issue) { create(:issue, project: private_project) }
let_it_be(:current_user) { create(:user) }
let_it_be(:updated_by_user) { create(:user) }
let_it_be(:incident) { create(:incident, project: project) }
let_it_be(:another_incident) { create(:incident, project: project) }
let_it_be(:promoted_from_note) { create(:note, project: project, noteable: incident) }
+ let_it_be(:issue_url) { project_issue_url(private_project, issue) }
+ let_it_be(:issue_ref) { "#{private_project.full_path}##{issue.iid}" }
+ let_it_be(:issue_link) { %Q(<a href="#{issue_url}">#{issue_url}</a>) }
let_it_be(:timeline_event) do
create(
@@ -18,7 +23,8 @@ RSpec.describe 'getting incident timeline events' do
incident: incident,
project: project,
updated_by_user: updated_by_user,
- promoted_from_note: promoted_from_note
+ promoted_from_note: promoted_from_note,
+ note: "Referencing #{issue.to_reference(full: true)} - Full URL #{issue_url}"
)
end
@@ -89,7 +95,7 @@ RSpec.describe 'getting incident timeline events' do
'title' => incident.title
},
'note' => timeline_event.note,
- 'noteHtml' => timeline_event.note_html,
+ 'noteHtml' => "<p>Referencing #{issue_ref} - Full URL #{issue_link}</p>",
'promotedFromNote' => {
'id' => promoted_from_note.to_global_id.to_s,
'body' => promoted_from_note.note