Update upstream source from tag 'upstream/10.7.6+dfsg'
Update to upstream version '10.7.6+dfsg'
with Debian dir d621e562d0
This commit is contained in:
commit
6dd2eb13f7
39 changed files with 167 additions and 272 deletions
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -2,6 +2,22 @@
|
||||||
documentation](doc/development/changelog.md) for instructions on adding your own
|
documentation](doc/development/changelog.md) for instructions on adding your own
|
||||||
entry.
|
entry.
|
||||||
|
|
||||||
|
## 10.7.6 (2018-06-21)
|
||||||
|
|
||||||
|
### Security (6 changes)
|
||||||
|
|
||||||
|
- Fix XSS vulnerability for table of content generation.
|
||||||
|
- Update sanitize gem to 4.6.5 to fix HTML injection vulnerability.
|
||||||
|
- HTML escape branch name in project graphs page.
|
||||||
|
- HTML escape the name of the user in ProjectsHelper#link_to_member.
|
||||||
|
- Don't show events from internal projects for anonymous users in public feed.
|
||||||
|
- XSS fix to use safe_params instead of params in url_for helpers.
|
||||||
|
|
||||||
|
### Other (1 change)
|
||||||
|
|
||||||
|
- Replacing gollum libraries for gitlab custom libs. !18343
|
||||||
|
|
||||||
|
|
||||||
## 10.7.5 (2018-05-28)
|
## 10.7.5 (2018-05-28)
|
||||||
|
|
||||||
### Security (3 changes)
|
### Security (3 changes)
|
||||||
|
|
15
Gemfile
15
Gemfile
|
@ -81,16 +81,9 @@ gem 'net-ldap'
|
||||||
|
|
||||||
# Git Wiki
|
# Git Wiki
|
||||||
# Required manually in config/initializers/gollum.rb to control load order
|
# Required manually in config/initializers/gollum.rb to control load order
|
||||||
# Before updating this gem, check if
|
gem 'gitlab-gollum-lib', '~> 4.2'
|
||||||
# https://github.com/gollum/gollum-lib/pull/292 has been merged.
|
|
||||||
# If it has, then remove the monkey patch for update_page, rename_page and raw_data_in_committer
|
|
||||||
# in config/initializers/gollum.rb
|
|
||||||
gem 'gollum-lib', '~> 4.2', require: false
|
|
||||||
|
|
||||||
# Before updating this gem, check if
|
gem 'gitlab-gollum-rugged_adapter', '~> 0.4.4', require: false
|
||||||
# https://github.com/gollum/rugged_adapter/pull/28 has been merged.
|
|
||||||
# If it has, then remove the monkey patch for tree_entry in config/initializers/gollum.rb
|
|
||||||
gem 'gollum-rugged_adapter', '~> 0.4.4', require: false
|
|
||||||
|
|
||||||
# Language detection
|
# Language detection
|
||||||
gem 'github-linguist', '~> 5.3.3', require: 'linguist'
|
gem 'github-linguist', '~> 5.3.3', require: 'linguist'
|
||||||
|
@ -146,7 +139,7 @@ gem 'creole', '~> 0.5.0'
|
||||||
gem 'wikicloth', '0.8.1'
|
gem 'wikicloth', '0.8.1'
|
||||||
gem 'asciidoctor', '~> 1.5.6'
|
gem 'asciidoctor', '~> 1.5.6'
|
||||||
gem 'asciidoctor-plantuml', '0.0.8'
|
gem 'asciidoctor-plantuml', '0.0.8'
|
||||||
gem 'rouge', '~> 2.0'
|
gem 'rouge', '~> 3.1'
|
||||||
gem 'truncato', '~> 0.7.9'
|
gem 'truncato', '~> 0.7.9'
|
||||||
gem 'bootstrap_form', '~> 2.7.0'
|
gem 'bootstrap_form', '~> 2.7.0'
|
||||||
gem 'nokogiri', '~> 1.8.2'
|
gem 'nokogiri', '~> 1.8.2'
|
||||||
|
@ -226,7 +219,7 @@ gem 'kubeclient', '~> 3.0'
|
||||||
gem 'd3_rails', '~> 3.5.0'
|
gem 'd3_rails', '~> 3.5.0'
|
||||||
|
|
||||||
# Sanitize user input
|
# Sanitize user input
|
||||||
gem 'sanitize', '~> 2.0'
|
gem 'sanitize', '~> 4.6.5'
|
||||||
gem 'babosa', '~> 1.0.2'
|
gem 'babosa', '~> 1.0.2'
|
||||||
|
|
||||||
# Sanitizes SVG input
|
# Sanitizes SVG input
|
||||||
|
|
42
Gemfile.lock
42
Gemfile.lock
|
@ -298,11 +298,22 @@ GEM
|
||||||
escape_utils (~> 1.1.0)
|
escape_utils (~> 1.1.0)
|
||||||
mime-types (>= 1.19)
|
mime-types (>= 1.19)
|
||||||
rugged (>= 0.25.1)
|
rugged (>= 0.25.1)
|
||||||
github-markup (1.6.1)
|
github-markup (1.7.0)
|
||||||
gitlab-flowdock-git-hook (1.0.1)
|
gitlab-flowdock-git-hook (1.0.1)
|
||||||
flowdock (~> 0.7)
|
flowdock (~> 0.7)
|
||||||
gitlab-grit (>= 2.4.1)
|
gitlab-grit (>= 2.4.1)
|
||||||
multi_json
|
multi_json
|
||||||
|
gitlab-gollum-lib (4.2.7.5)
|
||||||
|
gemojione (~> 3.2)
|
||||||
|
github-markup (~> 1.6)
|
||||||
|
gollum-grit_adapter (~> 1.0)
|
||||||
|
nokogiri (>= 1.6.1, < 2.0)
|
||||||
|
rouge (~> 3.1)
|
||||||
|
sanitize (~> 4.6.4)
|
||||||
|
stringex (~> 2.6)
|
||||||
|
gitlab-gollum-rugged_adapter (0.4.4)
|
||||||
|
mime-types (>= 1.15)
|
||||||
|
rugged (~> 0.25)
|
||||||
gitlab-grit (2.8.2)
|
gitlab-grit (2.8.2)
|
||||||
charlock_holmes (~> 0.6)
|
charlock_holmes (~> 0.6)
|
||||||
diff-lcs (~> 1.1)
|
diff-lcs (~> 1.1)
|
||||||
|
@ -322,17 +333,6 @@ GEM
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
gollum-grit_adapter (1.0.1)
|
gollum-grit_adapter (1.0.1)
|
||||||
gitlab-grit (~> 2.7, >= 2.7.1)
|
gitlab-grit (~> 2.7, >= 2.7.1)
|
||||||
gollum-lib (4.2.7)
|
|
||||||
gemojione (~> 3.2)
|
|
||||||
github-markup (~> 1.6)
|
|
||||||
gollum-grit_adapter (~> 1.0)
|
|
||||||
nokogiri (>= 1.6.1, < 2.0)
|
|
||||||
rouge (~> 2.1)
|
|
||||||
sanitize (~> 2.1)
|
|
||||||
stringex (~> 2.6)
|
|
||||||
gollum-rugged_adapter (0.4.4)
|
|
||||||
mime-types (>= 1.15)
|
|
||||||
rugged (~> 0.25)
|
|
||||||
gon (6.1.0)
|
gon (6.1.0)
|
||||||
actionpack (>= 3.0)
|
actionpack (>= 3.0)
|
||||||
json
|
json
|
||||||
|
@ -517,6 +517,8 @@ GEM
|
||||||
netrc (0.11.0)
|
netrc (0.11.0)
|
||||||
nokogiri (1.8.2)
|
nokogiri (1.8.2)
|
||||||
mini_portile2 (~> 2.3.0)
|
mini_portile2 (~> 2.3.0)
|
||||||
|
nokogumbo (1.5.0)
|
||||||
|
nokogiri
|
||||||
numerizer (0.1.1)
|
numerizer (0.1.1)
|
||||||
oauth (0.5.4)
|
oauth (0.5.4)
|
||||||
oauth2 (1.4.0)
|
oauth2 (1.4.0)
|
||||||
|
@ -744,7 +746,7 @@ GEM
|
||||||
retriable (3.1.1)
|
retriable (3.1.1)
|
||||||
rinku (2.0.0)
|
rinku (2.0.0)
|
||||||
rotp (2.1.2)
|
rotp (2.1.2)
|
||||||
rouge (2.2.1)
|
rouge (3.1.1)
|
||||||
rqrcode (0.7.0)
|
rqrcode (0.7.0)
|
||||||
chunky_png
|
chunky_png
|
||||||
rqrcode-rails3 (0.1.7)
|
rqrcode-rails3 (0.1.7)
|
||||||
|
@ -812,8 +814,10 @@ GEM
|
||||||
et-orbi (~> 1.0)
|
et-orbi (~> 1.0)
|
||||||
rugged (0.27.0)
|
rugged (0.27.0)
|
||||||
safe_yaml (1.0.4)
|
safe_yaml (1.0.4)
|
||||||
sanitize (2.1.0)
|
sanitize (4.6.5)
|
||||||
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.4.4)
|
nokogiri (>= 1.4.4)
|
||||||
|
nokogumbo (~> 1.4)
|
||||||
sass (3.5.5)
|
sass (3.5.5)
|
||||||
sass-listen (~> 4.0.0)
|
sass-listen (~> 4.0.0)
|
||||||
sass-listen (4.0.0)
|
sass-listen (4.0.0)
|
||||||
|
@ -904,7 +908,7 @@ GEM
|
||||||
state_machines-activerecord (0.5.1)
|
state_machines-activerecord (0.5.1)
|
||||||
activerecord (>= 4.1, < 6.0)
|
activerecord (>= 4.1, < 6.0)
|
||||||
state_machines-activemodel (>= 0.5.0)
|
state_machines-activemodel (>= 0.5.0)
|
||||||
stringex (2.7.1)
|
stringex (2.8.4)
|
||||||
sys-filesystem (1.1.6)
|
sys-filesystem (1.1.6)
|
||||||
ffi
|
ffi
|
||||||
sysexits (1.2.0)
|
sysexits (1.2.0)
|
||||||
|
@ -1061,11 +1065,11 @@ DEPENDENCIES
|
||||||
gitaly-proto (~> 0.96.0)
|
gitaly-proto (~> 0.96.0)
|
||||||
github-linguist (~> 5.3.3)
|
github-linguist (~> 5.3.3)
|
||||||
gitlab-flowdock-git-hook (~> 1.0.1)
|
gitlab-flowdock-git-hook (~> 1.0.1)
|
||||||
|
gitlab-gollum-lib (~> 4.2)
|
||||||
|
gitlab-gollum-rugged_adapter (~> 0.4.4)
|
||||||
gitlab-markup (~> 1.6.2)
|
gitlab-markup (~> 1.6.2)
|
||||||
gitlab-styles (~> 2.3)
|
gitlab-styles (~> 2.3)
|
||||||
gitlab_omniauth-ldap (~> 2.0.4)
|
gitlab_omniauth-ldap (~> 2.0.4)
|
||||||
gollum-lib (~> 4.2)
|
|
||||||
gollum-rugged_adapter (~> 0.4.4)
|
|
||||||
gon (~> 6.1.0)
|
gon (~> 6.1.0)
|
||||||
google-api-client (~> 0.19.8)
|
google-api-client (~> 0.19.8)
|
||||||
google-protobuf (= 3.5.1)
|
google-protobuf (= 3.5.1)
|
||||||
|
@ -1156,7 +1160,7 @@ DEPENDENCIES
|
||||||
redis-rails (~> 5.0.2)
|
redis-rails (~> 5.0.2)
|
||||||
request_store (~> 1.3)
|
request_store (~> 1.3)
|
||||||
responders (~> 2.0)
|
responders (~> 2.0)
|
||||||
rouge (~> 2.0)
|
rouge (~> 3.1)
|
||||||
rqrcode-rails3 (~> 0.1.7)
|
rqrcode-rails3 (~> 0.1.7)
|
||||||
rspec-parameterized
|
rspec-parameterized
|
||||||
rspec-rails (~> 3.6.0)
|
rspec-rails (~> 3.6.0)
|
||||||
|
@ -1170,7 +1174,7 @@ DEPENDENCIES
|
||||||
ruby_parser (~> 3.8)
|
ruby_parser (~> 3.8)
|
||||||
rufus-scheduler (~> 3.4)
|
rufus-scheduler (~> 3.4)
|
||||||
rugged (~> 0.27)
|
rugged (~> 0.27)
|
||||||
sanitize (~> 2.0)
|
sanitize (~> 4.6.5)
|
||||||
sass-rails (~> 5.0.6)
|
sass-rails (~> 5.0.6)
|
||||||
scss_lint (~> 0.56.0)
|
scss_lint (~> 0.56.0)
|
||||||
seed-fu (~> 2.3.7)
|
seed-fu (~> 2.3.7)
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
10.7.5
|
10.7.6
|
||||||
|
|
|
@ -5,6 +5,7 @@ class ApplicationController < ActionController::Base
|
||||||
include Gitlab::GonHelper
|
include Gitlab::GonHelper
|
||||||
include GitlabRoutingHelper
|
include GitlabRoutingHelper
|
||||||
include PageLayoutHelper
|
include PageLayoutHelper
|
||||||
|
include SafeParamsHelper
|
||||||
include SentryHelper
|
include SentryHelper
|
||||||
include WorkhorseHelper
|
include WorkhorseHelper
|
||||||
include EnforcesTwoFactorAuthentication
|
include EnforcesTwoFactorAuthentication
|
||||||
|
|
|
@ -57,7 +57,7 @@ module IssuableCollections
|
||||||
out_of_range = @issuables.current_page > total_pages # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
out_of_range = @issuables.current_page > total_pages # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||||
|
|
||||||
if out_of_range
|
if out_of_range
|
||||||
redirect_to(url_for(params.merge(page: total_pages, only_path: true)))
|
redirect_to(url_for(safe_params.merge(page: total_pages, only_path: true)))
|
||||||
end
|
end
|
||||||
|
|
||||||
out_of_range
|
out_of_range
|
||||||
|
|
|
@ -86,7 +86,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
|
||||||
out_of_range = todos.current_page > total_pages
|
out_of_range = todos.current_page > total_pages
|
||||||
|
|
||||||
if out_of_range
|
if out_of_range
|
||||||
redirect_to url_for(params.merge(page: total_pages, only_path: true))
|
redirect_to url_for(safe_params.merge(page: total_pages, only_path: true))
|
||||||
end
|
end
|
||||||
|
|
||||||
out_of_range
|
out_of_range
|
||||||
|
|
|
@ -33,6 +33,6 @@ class Groups::ApplicationController < ApplicationController
|
||||||
def build_canonical_path(group)
|
def build_canonical_path(group)
|
||||||
params[:group_id] = group.to_param
|
params[:group_id] = group.to_param
|
||||||
|
|
||||||
url_for(params)
|
url_for(safe_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -189,6 +189,6 @@ class GroupsController < Groups::ApplicationController
|
||||||
|
|
||||||
params[:id] = group.to_param
|
params[:id] = group.to_param
|
||||||
|
|
||||||
url_for(params)
|
url_for(safe_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,7 +25,7 @@ class Projects::ApplicationController < ApplicationController
|
||||||
params[:namespace_id] = project.namespace.to_param
|
params[:namespace_id] = project.namespace.to_param
|
||||||
params[:project_id] = project.to_param
|
params[:project_id] = project.to_param
|
||||||
|
|
||||||
url_for(params)
|
url_for(safe_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def repository
|
def repository
|
||||||
|
|
|
@ -404,7 +404,7 @@ class ProjectsController < Projects::ApplicationController
|
||||||
params[:namespace_id] = project.namespace.to_param
|
params[:namespace_id] = project.namespace.to_param
|
||||||
params[:id] = project.to_param
|
params[:id] = project.to_param
|
||||||
|
|
||||||
url_for(params)
|
url_for(safe_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def project_export_enabled
|
def project_export_enabled
|
||||||
|
|
|
@ -146,6 +146,6 @@ class UsersController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_canonical_path(user)
|
def build_canonical_path(user)
|
||||||
url_for(params.merge(username: user.to_param))
|
url_for(safe_params.merge(username: user.to_param))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -56,7 +56,7 @@ class UserRecentEventsFinder
|
||||||
|
|
||||||
visible = target_user
|
visible = target_user
|
||||||
.project_interactions
|
.project_interactions
|
||||||
.where(visibility_level: [Gitlab::VisibilityLevel::INTERNAL, Gitlab::VisibilityLevel::PUBLIC])
|
.where(visibility_level: Gitlab::VisibilityLevel.levels_for_user(current_user))
|
||||||
.select(:id)
|
.select(:id)
|
||||||
|
|
||||||
Gitlab::SQL::Union.new([authorized, visible]).to_sql
|
Gitlab::SQL::Union.new([authorized, visible]).to_sql
|
||||||
|
|
|
@ -259,7 +259,7 @@ module BlobHelper
|
||||||
options = []
|
options = []
|
||||||
|
|
||||||
if error == :collapsed
|
if error == :collapsed
|
||||||
options << link_to('load it anyway', url_for(params.merge(viewer: viewer.type, expanded: true, format: nil)))
|
options << link_to('load it anyway', url_for(safe_params.merge(viewer: viewer.type, expanded: true, format: nil)))
|
||||||
end
|
end
|
||||||
|
|
||||||
# If the error is `:server_side_but_stored_externally`, the simple viewer will show the same error,
|
# If the error is `:server_side_but_stored_externally`, the simple viewer will show the same error,
|
||||||
|
|
|
@ -180,7 +180,7 @@ module DiffHelper
|
||||||
private
|
private
|
||||||
|
|
||||||
def diff_btn(title, name, selected)
|
def diff_btn(title, name, selected)
|
||||||
params_copy = params.dup
|
params_copy = safe_params.dup
|
||||||
params_copy[:view] = name
|
params_copy[:view] = name
|
||||||
|
|
||||||
# Always use HTML to handle case where JSON diff rendered this button
|
# Always use HTML to handle case where JSON diff rendered this button
|
||||||
|
|
|
@ -40,7 +40,8 @@ module ProjectsHelper
|
||||||
name_tag_options[:class] << 'has-tooltip'
|
name_tag_options[:class] << 'has-tooltip'
|
||||||
end
|
end
|
||||||
|
|
||||||
content_tag(:span, sanitize(username), name_tag_options)
|
# NOTE: ActionView::Helpers::TagHelper#content_tag HTML escapes username
|
||||||
|
content_tag(:span, username, name_tag_options)
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_to_member(project, author, opts = {}, &block)
|
def link_to_member(project, author, opts = {}, &block)
|
||||||
|
|
11
app/helpers/safe_params_helper.rb
Normal file
11
app/helpers/safe_params_helper.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
module SafeParamsHelper
|
||||||
|
# Rails 5.0 requires to permit parameters if used in url helpers.
|
||||||
|
# Use this helper when generating links with `params.merge(...)`
|
||||||
|
def safe_params
|
||||||
|
if params.respond_to?(:permit!)
|
||||||
|
params.except(:host, :port, :protocol).permit!
|
||||||
|
else
|
||||||
|
params
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,5 @@
|
||||||
xml.title "#{current_user.name} issues"
|
xml.title "#{current_user.name} issues"
|
||||||
xml.link href: url_for(params), rel: "self", type: "application/atom+xml"
|
xml.link href: url_for(safe_params), rel: "self", type: "application/atom+xml"
|
||||||
xml.link href: issues_dashboard_url, rel: "alternate", type: "text/html"
|
xml.link href: issues_dashboard_url, rel: "alternate", type: "text/html"
|
||||||
xml.id issues_dashboard_url
|
xml.id issues_dashboard_url
|
||||||
xml.updated @issues.first.updated_at.xmlschema if @issues.reorder(nil).any?
|
xml.updated @issues.first.updated_at.xmlschema if @issues.reorder(nil).any?
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
- page_title _("Issues")
|
- page_title _("Issues")
|
||||||
- @breadcrumb_link = issues_dashboard_path(assignee_id: current_user.id)
|
- @breadcrumb_link = issues_dashboard_path(assignee_id: current_user.id)
|
||||||
= content_for :meta_tags do
|
= content_for :meta_tags do
|
||||||
= auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{current_user.name} issues")
|
= auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{current_user.name} issues")
|
||||||
|
|
||||||
.top-area
|
.top-area
|
||||||
= render 'shared/issuable/nav', type: :issues, display_count: !@no_filters_set
|
= render 'shared/issuable/nav', type: :issues, display_count: !@no_filters_set
|
||||||
.nav-controls
|
.nav-controls
|
||||||
= link_to params.merge(rss_url_options), class: 'btn has-tooltip', data: { container: 'body' }, title: 'Subscribe' do
|
= link_to safe_params.merge(rss_url_options), class: 'btn has-tooltip', data: { container: 'body' }, title: 'Subscribe' do
|
||||||
= icon('rss')
|
= icon('rss')
|
||||||
= render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", with_feature_enabled: 'issues', type: :issues
|
= render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", with_feature_enabled: 'issues', type: :issues
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
xml.title "#{@group.name} issues"
|
xml.title "#{@group.name} issues"
|
||||||
xml.link href: url_for(params), rel: "self", type: "application/atom+xml"
|
xml.link href: url_for(safe_params), rel: "self", type: "application/atom+xml"
|
||||||
xml.link href: issues_group_url, rel: "alternate", type: "text/html"
|
xml.link href: issues_group_url, rel: "alternate", type: "text/html"
|
||||||
xml.id issues_group_url
|
xml.id issues_group_url
|
||||||
xml.updated @issues.first.updated_at.xmlschema if @issues.reorder(nil).any?
|
xml.updated @issues.first.updated_at.xmlschema if @issues.reorder(nil).any?
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
- page_title "Issues"
|
- page_title "Issues"
|
||||||
= content_for :meta_tags do
|
= content_for :meta_tags do
|
||||||
= auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@group.name} issues")
|
= auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@group.name} issues")
|
||||||
|
|
||||||
- if group_issues_count(state: 'all').zero?
|
- if group_issues_count(state: 'all').zero?
|
||||||
= render 'shared/empty_states/issues', project_select_button: true
|
= render 'shared/empty_states/issues', project_select_button: true
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#js-peek{ data: { env: Peek.env,
|
#js-peek{ data: { env: Peek.env,
|
||||||
request_id: Peek.request_id,
|
request_id: Peek.request_id,
|
||||||
peek_url: peek_routes.results_url,
|
peek_url: peek_routes.results_url,
|
||||||
profile_url: url_for(params.merge(lineprofiler: 'true')) },
|
profile_url: url_for(safe_params.merge(lineprofiler: 'true')) },
|
||||||
class: Peek.env }
|
class: Peek.env }
|
||||||
|
|
||||||
#peek-view-performance-bar.hidden
|
#peek-view-performance-bar.hidden
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
- rich_type = viewer.type == :rich ? viewer.partial_name : nil
|
- rich_type = viewer.type == :rich ? viewer.partial_name : nil
|
||||||
- load_async = local_assigns.fetch(:load_async, viewer.load_async? && render_error.nil?)
|
- load_async = local_assigns.fetch(:load_async, viewer.load_async? && render_error.nil?)
|
||||||
|
|
||||||
- viewer_url = local_assigns.fetch(:viewer_url) { url_for(params.merge(viewer: viewer.type, format: :json)) } if load_async
|
- viewer_url = local_assigns.fetch(:viewer_url) { url_for(safe_params.merge(viewer: viewer.type, format: :json)) } if load_async
|
||||||
.blob-viewer{ data: { type: viewer.type, rich_type: rich_type, url: viewer_url }, class: ('hidden' if hidden) }
|
.blob-viewer{ data: { type: viewer.type, rich_type: rich_type, url: viewer_url }, class: ('hidden' if hidden) }
|
||||||
- if render_error
|
- if render_error
|
||||||
= render 'projects/blob/render_error', viewer: viewer
|
= render 'projects/blob/render_error', viewer: viewer
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- diff_file = viewer.diff_file
|
- diff_file = viewer.diff_file
|
||||||
- url = url_for(params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path, file_identifier: diff_file.file_identifier))
|
- url = url_for(safe_params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path, file_identifier: diff_file.file_identifier))
|
||||||
.nothing-here-block.diff-collapsed{ data: { diff_for_path: url } }
|
.nothing-here-block.diff-collapsed{ data: { diff_for_path: url } }
|
||||||
This diff is collapsed.
|
This diff is collapsed.
|
||||||
%a.click-to-expand Click to expand it.
|
%a.click-to-expand Click to expand it.
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
.files-changed-inner
|
.files-changed-inner
|
||||||
.inline-parallel-buttons.hidden-xs.hidden-sm
|
.inline-parallel-buttons.hidden-xs.hidden-sm
|
||||||
- if !diffs_expanded? && diff_files.any? { |diff_file| diff_file.collapsed? }
|
- if !diffs_expanded? && diff_files.any? { |diff_file| diff_file.collapsed? }
|
||||||
= link_to 'Expand all', url_for(params.merge(expanded: 1, format: nil)), class: 'btn btn-default'
|
= link_to 'Expand all', url_for(safe_params.merge(expanded: 1, format: nil)), class: 'btn btn-default'
|
||||||
- if show_whitespace_toggle
|
- if show_whitespace_toggle
|
||||||
- if current_controller?(:commit)
|
- if current_controller?(:commit)
|
||||||
= commit_diff_whitespace_link(diffs.project, @commit, class: 'hidden-xs')
|
= commit_diff_whitespace_link(diffs.project, @commit, class: 'hidden-xs')
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#{@commits_graph.start_date.strftime('%b %d')}
|
#{@commits_graph.start_date.strftime('%b %d')}
|
||||||
- end_time = capture do
|
- end_time = capture do
|
||||||
#{@commits_graph.end_date.strftime('%b %d')}
|
#{@commits_graph.end_date.strftime('%b %d')}
|
||||||
= (_("Commit statistics for %{ref} %{start_time} - %{end_time}") % { ref: "<strong>#{@ref}</strong>", start_time: start_time, end_time: end_time }).html_safe
|
= (_("Commit statistics for %{ref} %{start_time} - %{end_time}") % { ref: "<strong>#{h @ref}</strong>", start_time: start_time, end_time: end_time }).html_safe
|
||||||
|
|
||||||
.col-md-6
|
.col-md-6
|
||||||
.tree-ref-container
|
.tree-ref-container
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= link_to params.merge(rss_url_options), class: 'btn btn-default append-right-10 has-tooltip', title: 'Subscribe' do
|
= link_to safe_params.merge(rss_url_options), class: 'btn btn-default append-right-10 has-tooltip', title: 'Subscribe' do
|
||||||
= icon('rss')
|
= icon('rss')
|
||||||
- if @can_bulk_update
|
- if @can_bulk_update
|
||||||
= button_tag "Edit issues", class: "btn btn-default append-right-10 js-bulk-update-toggle"
|
= button_tag "Edit issues", class: "btn btn-default append-right-10 js-bulk-update-toggle"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
xml.title "#{@project.name} issues"
|
xml.title "#{@project.name} issues"
|
||||||
xml.link href: url_for(params), rel: "self", type: "application/atom+xml"
|
xml.link href: url_for(safe_params), rel: "self", type: "application/atom+xml"
|
||||||
xml.link href: project_issues_url(@project), rel: "alternate", type: "text/html"
|
xml.link href: project_issues_url(@project), rel: "alternate", type: "text/html"
|
||||||
xml.id project_issues_url(@project)
|
xml.id project_issues_url(@project)
|
||||||
xml.updated @issues.first.updated_at.xmlschema if @issues.reorder(nil).any?
|
xml.updated @issues.first.updated_at.xmlschema if @issues.reorder(nil).any?
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
- new_issue_email = @project.new_issuable_address(current_user, 'issue')
|
- new_issue_email = @project.new_issuable_address(current_user, 'issue')
|
||||||
|
|
||||||
= content_for :meta_tags do
|
= content_for :meta_tags do
|
||||||
= auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@project.name} issues")
|
= auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@project.name} issues")
|
||||||
|
|
||||||
- if project_issues(@project).exists?
|
- if project_issues(@project).exists?
|
||||||
%div{ class: (container_class) }
|
%div{ class: (container_class) }
|
||||||
|
|
|
@ -26,16 +26,16 @@
|
||||||
- else
|
- else
|
||||||
%ul.merge-request-tabs.nav-links.no-top.no-bottom
|
%ul.merge-request-tabs.nav-links.no-top.no-bottom
|
||||||
%li.commits-tab.active
|
%li.commits-tab.active
|
||||||
= link_to url_for(params), data: {target: 'div#commits', action: 'new', toggle: 'tab'} do
|
= link_to url_for(safe_params), data: {target: 'div#commits', action: 'new', toggle: 'tab'} do
|
||||||
Commits
|
Commits
|
||||||
%span.badge= @commits.size
|
%span.badge= @commits.size
|
||||||
- if @pipelines.any?
|
- if @pipelines.any?
|
||||||
%li.builds-tab
|
%li.builds-tab
|
||||||
= link_to url_for(params.merge(action: 'pipelines')), data: {target: 'div#pipelines', action: 'pipelines', toggle: 'tab'} do
|
= link_to url_for(safe_params.merge(action: 'pipelines')), data: {target: 'div#pipelines', action: 'pipelines', toggle: 'tab'} do
|
||||||
Pipelines
|
Pipelines
|
||||||
%span.badge= @pipelines.size
|
%span.badge= @pipelines.size
|
||||||
%li.diffs-tab
|
%li.diffs-tab
|
||||||
= link_to url_for(params.merge(action: 'diffs')), data: {target: 'div#diffs', action: 'diffs', toggle: 'tab'} do
|
= link_to url_for(safe_params.merge(action: 'diffs')), data: {target: 'div#diffs', action: 'diffs', toggle: 'tab'} do
|
||||||
Changes
|
Changes
|
||||||
%span.badge= @merge_request.diff_size
|
%span.badge= @merge_request.diff_size
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
-# This tab is always loaded via AJAX
|
-# This tab is always loaded via AJAX
|
||||||
- if @pipelines.any?
|
- if @pipelines.any?
|
||||||
#pipelines.pipelines.tab-pane
|
#pipelines.pipelines.tab-pane
|
||||||
= render 'projects/merge_requests/pipelines', endpoint: url_for(params.merge(action: 'pipelines', format: :json)), disable_initialization: true
|
= render 'projects/merge_requests/pipelines', endpoint: url_for(safe_params.merge(action: 'pipelines', format: :json)), disable_initialization: true
|
||||||
|
|
||||||
.mr-loading-status
|
.mr-loading-status
|
||||||
= spinner
|
= spinner
|
||||||
|
|
|
@ -7,139 +7,6 @@ module Gollum
|
||||||
end
|
end
|
||||||
require "gollum-lib"
|
require "gollum-lib"
|
||||||
|
|
||||||
module Gollum
|
|
||||||
class Committer
|
|
||||||
# Patch for UTF-8 path
|
|
||||||
def method_missing(name, *args)
|
|
||||||
index.send(name, *args)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Wiki
|
|
||||||
def pages(treeish = nil, limit: nil)
|
|
||||||
tree_list((treeish || @ref), limit: limit)
|
|
||||||
end
|
|
||||||
|
|
||||||
def tree_list(ref, limit: nil)
|
|
||||||
if (sha = @access.ref_to_sha(ref))
|
|
||||||
commit = @access.commit(sha)
|
|
||||||
tree_map_for(sha).inject([]) do |list, entry|
|
|
||||||
next list unless @page_class.valid_page_name?(entry.name)
|
|
||||||
|
|
||||||
list << entry.page(self, commit)
|
|
||||||
break list if limit && list.size >= limit
|
|
||||||
|
|
||||||
list
|
|
||||||
end
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Remove if https://github.com/gollum/gollum-lib/pull/292 has been merged
|
|
||||||
def update_page(page, name, format, data, commit = {})
|
|
||||||
name = name ? ::File.basename(name) : page.name
|
|
||||||
format ||= page.format
|
|
||||||
dir = ::File.dirname(page.path)
|
|
||||||
dir = '' if dir == '.'
|
|
||||||
filename = (rename = page.name != name) ? Gollum::Page.cname(name) : page.filename_stripped
|
|
||||||
|
|
||||||
multi_commit = !!commit[:committer]
|
|
||||||
committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
|
|
||||||
|
|
||||||
if !rename && page.format == format
|
|
||||||
committer.add(page.path, normalize(data))
|
|
||||||
else
|
|
||||||
committer.delete(page.path)
|
|
||||||
committer.add_to_index(dir, filename, format, data)
|
|
||||||
end
|
|
||||||
|
|
||||||
committer.after_commit do |index, _sha|
|
|
||||||
@access.refresh
|
|
||||||
index.update_working_dir(dir, page.filename_stripped, page.format)
|
|
||||||
index.update_working_dir(dir, filename, format)
|
|
||||||
end
|
|
||||||
|
|
||||||
multi_commit ? committer : committer.commit
|
|
||||||
end
|
|
||||||
|
|
||||||
# Remove if https://github.com/gollum/gollum-lib/pull/292 has been merged
|
|
||||||
def rename_page(page, rename, commit = {})
|
|
||||||
return false if page.nil?
|
|
||||||
return false if rename.nil? || rename.empty?
|
|
||||||
|
|
||||||
(target_dir, target_name) = ::File.split(rename)
|
|
||||||
(source_dir, source_name) = ::File.split(page.path)
|
|
||||||
source_name = page.filename_stripped
|
|
||||||
|
|
||||||
# File.split gives us relative paths with ".", commiter.add_to_index doesn't like that.
|
|
||||||
target_dir = '' if target_dir == '.'
|
|
||||||
source_dir = '' if source_dir == '.'
|
|
||||||
target_dir = target_dir.gsub(/^\//, '') # rubocop:disable Style/RegexpLiteral
|
|
||||||
|
|
||||||
# if the rename is a NOOP, abort
|
|
||||||
if source_dir == target_dir && source_name == target_name
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
multi_commit = !!commit[:committer]
|
|
||||||
committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
|
|
||||||
|
|
||||||
# This piece only works for multi_commit
|
|
||||||
# If we are in a commit batch and one of the previous operations
|
|
||||||
# has updated the page, any information we ask to the page can be outdated.
|
|
||||||
# Therefore, we should ask first to the current committer tree to see if
|
|
||||||
# there is any updated change.
|
|
||||||
raw_data = raw_data_in_committer(committer, source_dir, page.filename) ||
|
|
||||||
raw_data_in_committer(committer, source_dir, "#{target_name}.#{Page.format_to_ext(page.format)}") ||
|
|
||||||
page.raw_data
|
|
||||||
|
|
||||||
committer.delete(page.path)
|
|
||||||
committer.add_to_index(target_dir, target_name, page.format, raw_data)
|
|
||||||
|
|
||||||
committer.after_commit do |index, _sha|
|
|
||||||
@access.refresh
|
|
||||||
index.update_working_dir(source_dir, source_name, page.format)
|
|
||||||
index.update_working_dir(target_dir, target_name, page.format)
|
|
||||||
end
|
|
||||||
|
|
||||||
multi_commit ? committer : committer.commit
|
|
||||||
end
|
|
||||||
|
|
||||||
# Remove if https://github.com/gollum/gollum-lib/pull/292 has been merged
|
|
||||||
def raw_data_in_committer(committer, dir, filename)
|
|
||||||
data = nil
|
|
||||||
|
|
||||||
[*dir.split(::File::SEPARATOR), filename].each do |key|
|
|
||||||
data = data ? data[key] : committer.tree[key]
|
|
||||||
break unless data
|
|
||||||
end
|
|
||||||
|
|
||||||
data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module Git
|
|
||||||
class Git
|
|
||||||
def tree_entry(commit, path)
|
|
||||||
pathname = Pathname.new(path)
|
|
||||||
tmp_entry = nil
|
|
||||||
|
|
||||||
pathname.each_filename do |dir|
|
|
||||||
tmp_entry = if tmp_entry.nil?
|
|
||||||
commit.tree[dir]
|
|
||||||
else
|
|
||||||
@repo.lookup(tmp_entry[:oid])[dir]
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil unless tmp_entry
|
|
||||||
end
|
|
||||||
tmp_entry
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
config.after_initialize do
|
config.after_initialize do
|
||||||
Gollum::Page.per_page = Kaminari.config.default_per_page
|
Gollum::Page.per_page = Kaminari.config.default_per_page
|
||||||
|
|
|
@ -25,10 +25,11 @@ module Banzai
|
||||||
# Only push these customizations once
|
# Only push these customizations once
|
||||||
return if customized?(whitelist[:transformers])
|
return if customized?(whitelist[:transformers])
|
||||||
|
|
||||||
# Allow table alignment; we whitelist specific style properties in a
|
# Allow table alignment; we whitelist specific text-align values in a
|
||||||
# transformer below
|
# transformer below
|
||||||
whitelist[:attributes]['th'] = %w(style)
|
whitelist[:attributes]['th'] = %w(style)
|
||||||
whitelist[:attributes]['td'] = %w(style)
|
whitelist[:attributes]['td'] = %w(style)
|
||||||
|
whitelist[:css] = { properties: ['text-align'] }
|
||||||
|
|
||||||
# Allow span elements
|
# Allow span elements
|
||||||
whitelist[:elements].push('span')
|
whitelist[:elements].push('span')
|
||||||
|
|
|
@ -92,7 +92,7 @@ module Banzai
|
||||||
def text
|
def text
|
||||||
return '' unless node
|
return '' unless node
|
||||||
|
|
||||||
@text ||= node.text
|
@text ||= EscapeUtils.escape_html(node.text)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -3,6 +3,7 @@ require 'spec_helper'
|
||||||
describe 'Project Graph', :js do
|
describe 'Project Graph', :js do
|
||||||
let(:user) { create :user }
|
let(:user) { create :user }
|
||||||
let(:project) { create(:project, :repository, namespace: user.namespace) }
|
let(:project) { create(:project, :repository, namespace: user.namespace) }
|
||||||
|
let(:branch_name) { 'master' }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
project.add_master(user)
|
project.add_master(user)
|
||||||
|
@ -12,7 +13,7 @@ describe 'Project Graph', :js do
|
||||||
|
|
||||||
shared_examples 'page should have commits graphs' do
|
shared_examples 'page should have commits graphs' do
|
||||||
it 'renders commits' do
|
it 'renders commits' do
|
||||||
expect(page).to have_content('Commit statistics for master')
|
expect(page).to have_content("Commit statistics for #{branch_name}")
|
||||||
expect(page).to have_content('Commits per day of month')
|
expect(page).to have_content('Commits per day of month')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -57,6 +58,23 @@ describe 'Project Graph', :js do
|
||||||
it_behaves_like 'page should have languages graphs'
|
it_behaves_like 'page should have languages graphs'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'chart graph with HTML escaped branch name' do
|
||||||
|
let(:branch_name) { '<h1>evil</h1>' }
|
||||||
|
|
||||||
|
before do
|
||||||
|
project.repository.create_branch(branch_name, 'master')
|
||||||
|
|
||||||
|
visit charts_project_graph_path(project, branch_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'page should have commits graphs'
|
||||||
|
|
||||||
|
it 'HTML escapes branch name' do
|
||||||
|
expect(page.body).to include("Commit statistics for <strong>#{ERB::Util.html_escape(branch_name)}</strong>")
|
||||||
|
expect(page.body).not_to include(branch_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when CI enabled' do
|
context 'when CI enabled' do
|
||||||
before do
|
before do
|
||||||
project.enable_ci
|
project.enable_ci
|
||||||
|
|
|
@ -1,31 +1,50 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe UserRecentEventsFinder do
|
describe UserRecentEventsFinder do
|
||||||
let(:user) { create(:user) }
|
let(:current_user) { create(:user) }
|
||||||
let(:project) { create(:project) }
|
let(:project_owner) { create(:user) }
|
||||||
let(:project_owner) { project.creator }
|
let(:private_project) { create(:project, :private, creator: project_owner) }
|
||||||
let!(:event) { create(:event, project: project, author: project_owner) }
|
let(:internal_project) { create(:project, :internal, creator: project_owner) }
|
||||||
|
let(:public_project) { create(:project, :public, creator: project_owner) }
|
||||||
|
let!(:private_event) { create(:event, project: private_project, author: project_owner) }
|
||||||
|
let!(:internal_event) { create(:event, project: internal_project, author: project_owner) }
|
||||||
|
let!(:public_event) { create(:event, project: public_project, author: project_owner) }
|
||||||
|
|
||||||
subject(:finder) { described_class.new(user, project_owner) }
|
subject(:finder) { described_class.new(current_user, project_owner) }
|
||||||
|
|
||||||
describe '#execute' do
|
describe '#execute' do
|
||||||
it 'does not include the event when a user does not have access to the project' do
|
context 'current user does not have access to projects' do
|
||||||
expect(finder.execute).to be_empty
|
it 'returns public and internal events' do
|
||||||
|
records = finder.execute
|
||||||
|
|
||||||
|
expect(records).to include(public_event, internal_event)
|
||||||
|
expect(records).not_to include(private_event)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the user has access to a project' do
|
context 'when current user has access to the projects' do
|
||||||
before do
|
before do
|
||||||
project.add_developer(user)
|
private_project.add_developer(current_user)
|
||||||
|
internal_project.add_developer(current_user)
|
||||||
|
public_project.add_developer(current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'includes the event' do
|
it 'returns all the events' do
|
||||||
expect(finder.execute).to include(event)
|
expect(finder.execute).to include(private_event, internal_event, public_event)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not include the event if the user cannot read cross project' do
|
it 'does not include the events if the user cannot read cross project' do
|
||||||
expect(Ability).to receive(:allowed?).with(user, :read_cross_project) { false }
|
expect(Ability).to receive(:allowed?).with(current_user, :read_cross_project) { false }
|
||||||
expect(finder.execute).to be_empty
|
expect(finder.execute).to be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when current user is anonymous' do
|
||||||
|
let(:current_user) { nil }
|
||||||
|
|
||||||
|
it 'returns public events only' do
|
||||||
|
expect(finder.execute).to eq([public_event])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -244,7 +244,7 @@ describe ProjectsHelper do
|
||||||
describe '#link_to_member' do
|
describe '#link_to_member' do
|
||||||
let(:group) { build_stubbed(:group) }
|
let(:group) { build_stubbed(:group) }
|
||||||
let(:project) { build_stubbed(:project, group: group) }
|
let(:project) { build_stubbed(:project, group: group) }
|
||||||
let(:user) { build_stubbed(:user) }
|
let(:user) { build_stubbed(:user, name: '<h1>Administrator</h1>') }
|
||||||
|
|
||||||
describe 'using the default options' do
|
describe 'using the default options' do
|
||||||
it 'returns an HTML link to the user' do
|
it 'returns an HTML link to the user' do
|
||||||
|
@ -252,6 +252,13 @@ describe ProjectsHelper do
|
||||||
|
|
||||||
expect(link).to match(%r{/#{user.username}})
|
expect(link).to match(%r{/#{user.username}})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'HTML escapes the name of the user' do
|
||||||
|
link = helper.link_to_member(project, user)
|
||||||
|
|
||||||
|
expect(link).to include(ERB::Util.html_escape(user.name))
|
||||||
|
expect(link).not_to include(user.name)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe 'gollum' do
|
|
||||||
let(:project) { create(:project) }
|
|
||||||
let(:user) { project.owner }
|
|
||||||
let(:wiki) { ProjectWiki.new(project, user) }
|
|
||||||
let(:gollum_wiki) { Gollum::Wiki.new(wiki.repository.path) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
create_page(page_name, 'content1')
|
|
||||||
end
|
|
||||||
|
|
||||||
after do
|
|
||||||
destroy_page(page_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with simple paths' do
|
|
||||||
let(:page_name) { 'page1' }
|
|
||||||
|
|
||||||
it 'returns the entry hash if it matches the file name' do
|
|
||||||
expect(tree_entry(page_name)).not_to be_nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns nil if the path does not fit completely' do
|
|
||||||
expect(tree_entry("foo/#{page_name}")).to be_nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with complex paths' do
|
|
||||||
let(:page_name) { '/foo/bar/page2' }
|
|
||||||
|
|
||||||
it 'returns the entry hash if it matches the file name' do
|
|
||||||
expect(tree_entry(page_name)).not_to be_nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns nil if the path does not fit completely' do
|
|
||||||
expect(tree_entry("foo1/bar/page2")).to be_nil
|
|
||||||
expect(tree_entry("foo/bar1/page2")).to be_nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def tree_entry(name)
|
|
||||||
gollum_wiki.repo.git.tree_entry(wiki_commits[0].commit, name + '.md')
|
|
||||||
end
|
|
||||||
|
|
||||||
def wiki_commits
|
|
||||||
gollum_wiki.repo.commits
|
|
||||||
end
|
|
||||||
|
|
||||||
def commit_details
|
|
||||||
Gitlab::Git::Wiki::CommitDetails.new(user.name, user.email, "test commit")
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_page(name, content)
|
|
||||||
wiki.wiki.write_page(name, :markdown, content, commit_details)
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy_page(name)
|
|
||||||
page = wiki.find_page(name).page
|
|
||||||
wiki.delete_page(page, "test commit")
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -93,6 +93,16 @@ describe Banzai::Filter::SanitizationFilter do
|
||||||
expect(doc.at_css('td')['style']).to eq 'text-align: center'
|
expect(doc.at_css('td')['style']).to eq 'text-align: center'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'disallows `text-align` property in `style` attribute on other elements' do
|
||||||
|
html = <<~HTML
|
||||||
|
<div style="text-align: center">Text</div>
|
||||||
|
HTML
|
||||||
|
|
||||||
|
doc = filter(html)
|
||||||
|
|
||||||
|
expect(doc.at_css('div')['style']).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
it 'allows `span` elements' do
|
it 'allows `span` elements' do
|
||||||
exp = act = %q{<span>Hello</span>}
|
exp = act = %q{<span>Hello</span>}
|
||||||
expect(filter(act).to_html).to eq exp
|
expect(filter(act).to_html).to eq exp
|
||||||
|
@ -224,7 +234,7 @@ describe Banzai::Filter::SanitizationFilter do
|
||||||
|
|
||||||
'protocol-based JS injection: spaces and entities' => {
|
'protocol-based JS injection: spaces and entities' => {
|
||||||
input: '<a href="  javascript:alert(\'XSS\');">foo</a>',
|
input: '<a href="  javascript:alert(\'XSS\');">foo</a>',
|
||||||
output: '<a href="">foo</a>'
|
output: '<a href>foo</a>'
|
||||||
},
|
},
|
||||||
|
|
||||||
'protocol whitespace' => {
|
'protocol whitespace' => {
|
||||||
|
|
|
@ -139,5 +139,14 @@ describe Banzai::Filter::TableOfContentsFilter do
|
||||||
expect(items[5].ancestors).to include(items[4])
|
expect(items[5].ancestors).to include(items[4])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'header text contains escaped content' do
|
||||||
|
let(:content) { '<img src="x" onerror="alert(42)">' }
|
||||||
|
let(:results) { result(header(1, content)) }
|
||||||
|
|
||||||
|
it 'outputs escaped content' do
|
||||||
|
expect(doc.inner_html).to include(content)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue