Commit 39f25225 authored by Stan Hu's avatar Stan Hu

Make sure there's only one slash as path separator

In Ruby 2.4, `URI.join("http://test//", "a").to_s` will
remove the double slash, however it's not the case in
Ruby 2.5. Using chomp should work better for the intention,
as we're not trying to allow things like ../ or / paths
resolution.

Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/53180
parent 4aa41d07
...@@ -83,7 +83,7 @@ module ImportHelper ...@@ -83,7 +83,7 @@ module ImportHelper
private private
def github_project_url(full_path) def github_project_url(full_path)
URI.join(github_root_url, full_path).to_s Gitlab::Utils.append_path(github_root_url, full_path)
end end
def github_root_url def github_root_url
...@@ -95,6 +95,6 @@ module ImportHelper ...@@ -95,6 +95,6 @@ module ImportHelper
end end
def gitea_project_url(full_path) def gitea_project_url(full_path)
URI.join(@gitea_host_url, full_path).to_s Gitlab::Utils.append_path(@gitea_host_url, full_path)
end end
end end
...@@ -86,14 +86,16 @@ class BambooService < CiService ...@@ -86,14 +86,16 @@ class BambooService < CiService
end end
def read_build_page(response) def read_build_page(response)
key =
if response.code != 200 || response.dig('results', 'results', 'size') == '0' if response.code != 200 || response.dig('results', 'results', 'size') == '0'
# If actual build link can't be determined, send user to build summary page. # If actual build link can't be determined, send user to build summary page.
URI.join("#{bamboo_url}/", "browse/#{build_key}").to_s build_key
else else
# If actual build link is available, go to build result page. # If actual build link is available, go to build result page.
result_key = response.dig('results', 'results', 'result', get_build_result_index, 'planResultKey', 'key') response.dig('results', 'results', 'result', get_build_result_index, 'planResultKey', 'key')
URI.join("#{bamboo_url}/", "browse/#{result_key}").to_s
end end
build_url("browse/#{key}")
end end
def read_commit_status(response) def read_commit_status(response)
...@@ -117,7 +119,7 @@ class BambooService < CiService ...@@ -117,7 +119,7 @@ class BambooService < CiService
end end
def build_url(path) def build_url(path)
URI.join("#{bamboo_url}/", path).to_s Gitlab::Utils.append_path(bamboo_url, path)
end end
def get_path(path, query_params = {}) def get_path(path, query_params = {})
......
...@@ -39,11 +39,9 @@ class DroneCiService < CiService ...@@ -39,11 +39,9 @@ class DroneCiService < CiService
end end
def commit_status_path(sha, ref) def commit_status_path(sha, ref)
url = [drone_url, Gitlab::Utils.append_path(
"gitlab/#{project.full_path}/commits/#{sha}", drone_url,
"?branch=#{URI.encode(ref.to_s)}&access_token=#{token}"] "gitlab/#{project.full_path}/commits/#{sha}?branch=#{URI.encode(ref.to_s)}&access_token=#{token}")
URI.join(*url).to_s
end end
def commit_status(sha, ref) def commit_status(sha, ref)
...@@ -74,11 +72,9 @@ class DroneCiService < CiService ...@@ -74,11 +72,9 @@ class DroneCiService < CiService
end end
def build_page(sha, ref) def build_page(sha, ref)
url = [drone_url, Gitlab::Utils.append_path(
"gitlab/#{project.full_path}/redirect/commits/#{sha}", drone_url,
"?branch=#{URI.encode(ref.to_s)}"] "gitlab/#{project.full_path}/redirect/commits/#{sha}?branch=#{URI.encode(ref.to_s)}")
URI.join(*url).to_s
end end
def title def title
......
...@@ -54,7 +54,7 @@ class JiraService < IssueTrackerService ...@@ -54,7 +54,7 @@ class JiraService < IssueTrackerService
{ {
username: self.username, username: self.username,
password: self.password, password: self.password,
site: URI.join(url, '/').to_s, site: URI.join(url, '/').to_s, # Intended to find the root
context_path: url.path.chomp('/'), context_path: url.path.chomp('/'),
auth_type: :basic, auth_type: :basic,
read_timeout: 120, read_timeout: 120,
......
...@@ -34,10 +34,9 @@ class MockCiService < CiService ...@@ -34,10 +34,9 @@ class MockCiService < CiService
# http://jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c # http://jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c
# #
def build_page(sha, ref) def build_page(sha, ref)
url = [mock_service_url, Gitlab::Utils.append_path(
"#{project.namespace.path}/#{project.path}/status/#{sha}"] mock_service_url,
"#{project.namespace.path}/#{project.path}/status/#{sha}")
URI.join(*url).to_s
end end
# Return string with build status or :error symbol # Return string with build status or :error symbol
...@@ -61,10 +60,9 @@ class MockCiService < CiService ...@@ -61,10 +60,9 @@ class MockCiService < CiService
end end
def commit_status_path(sha) def commit_status_path(sha)
url = [mock_service_url, Gitlab::Utils.append_path(
"#{project.namespace.path}/#{project.path}/status/#{sha}.json"] mock_service_url,
"#{project.namespace.path}/#{project.path}/status/#{sha}.json")
URI.join(*url).to_s
end end
def read_commit_status(response) def read_commit_status(response)
......
...@@ -132,7 +132,7 @@ class TeamcityService < CiService ...@@ -132,7 +132,7 @@ class TeamcityService < CiService
end end
def build_url(path) def build_url(path)
URI.join("#{teamcity_url}/", path).to_s Gitlab::Utils.append_path(teamcity_url, path)
end end
def get_path(path) def get_path(path)
......
...@@ -165,7 +165,7 @@ ...@@ -165,7 +165,7 @@
.input-group .input-group
.input-group-prepend .input-group-prepend
.input-group-text .input-group-text
#{URI.join(root_url, @project.namespace.full_path)}/ #{Gitlab::Utils.append_path(root_url, @project.namespace.full_path)}/
= f.text_field :path, class: 'form-control' = f.text_field :path, class: 'form-control'
%ul %ul
%li Be careful. Renaming a project's repository can have unintended side effects. %li Be careful. Renaming a project's repository can have unintended side effects.
......
---
title: Make sure there's only one slash as path separator
merge_request: 22954
author:
type: other
...@@ -29,6 +29,7 @@ module Banzai ...@@ -29,6 +29,7 @@ module Banzai
end end
def absolute_link_attr(uri) def absolute_link_attr(uri)
# Here we really want to expand relative path to absolute path
URI.join(Gitlab.config.gitlab.url, uri).to_s URI.join(Gitlab.config.gitlab.url, uri).to_s
end end
end end
......
...@@ -88,35 +88,19 @@ module BitbucketServer ...@@ -88,35 +88,19 @@ module BitbucketServer
def build_url(path) def build_url(path)
return path if path.starts_with?(root_url) return path if path.starts_with?(root_url)
url_join_paths(root_url, path) Gitlab::Utils.append_path(root_url, path)
end end
def root_url def root_url
url_join_paths(base_uri, "/rest/api/#{api_version}") Gitlab::Utils.append_path(base_uri, "rest/api/#{api_version}")
end end
def delete_url(resource, path) def delete_url(resource, path)
if resource == :branches if resource == :branches
url_join_paths(base_uri, "/rest/branch-utils/#{api_version}#{path}") Gitlab::Utils.append_path(base_uri, "rest/branch-utils/#{api_version}#{path}")
else else
build_url(path) build_url(path)
end end
end end
# URI.join is stupid in that slashes are important:
#
# # URI.join('http://example.com/subpath', 'hello')
# => http://example.com/hello
#
# We really want http://example.com/subpath/hello
#
def url_join_paths(*paths)
paths.map { |path| strip_slashes(path) }.join(SEPARATOR)
end
def strip_slashes(path)
path = path[1..-1] if path.starts_with?(SEPARATOR)
path.chomp(SEPARATOR)
end
end end
end end
...@@ -8,7 +8,10 @@ module Gitlab ...@@ -8,7 +8,10 @@ module Gitlab
def add_gon_variables def add_gon_variables
gon.api_version = 'v4' gon.api_version = 'v4'
gon.default_avatar_url = URI.join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s gon.default_avatar_url =
Gitlab::Utils.append_path(
Gitlab.config.gitlab.url,
ActionController::Base.helpers.image_path('no_avatar.png'))
gon.max_file_size = Gitlab::CurrentSettings.max_attachment_size gon.max_file_size = Gitlab::CurrentSettings.max_attachment_size
gon.asset_host = ActionController::Base.asset_host gon.asset_host = ActionController::Base.asset_host
gon.webpack_public_path = webpack_public_path gon.webpack_public_path = webpack_public_path
......
...@@ -63,7 +63,7 @@ module Gitlab ...@@ -63,7 +63,7 @@ module Gitlab
end end
def repository_url(name) def repository_url(name)
URI.join(remote, name).to_s Gitlab::Utils.append_path(remote, name)
end end
def remote def remote
......
...@@ -38,7 +38,7 @@ module Gitlab ...@@ -38,7 +38,7 @@ module Gitlab
def go_body(path) def go_body(path)
config = Gitlab.config config = Gitlab.config
project_url = URI.join(config.gitlab.url, path) project_url = Gitlab::Utils.append_path(config.gitlab.url, path)
import_prefix = strip_url(project_url.to_s) import_prefix = strip_url(project_url.to_s)
repository_url = if Gitlab::CurrentSettings.enabled_git_access_protocol == 'ssh' repository_url = if Gitlab::CurrentSettings.enabled_git_access_protocol == 'ssh'
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment