summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/repositories_controller.rb21
-rw-r--r--app/models/repository.rb4
-rw-r--r--lib/redmine/scm/adapters/abstract_adapter.rb8
-rw-r--r--lib/redmine/scm/adapters/git_adapter.rb12
-rw-r--r--lib/redmine/scm/adapters/mercurial_adapter.rb9
5 files changed, 46 insertions, 8 deletions
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index dfa96cc0e..45e969ba4 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -330,7 +330,7 @@ class RepositoriesController < ApplicationController
render_404
end
- REV_PARAM_RE = %r{\A[a-f0-9]*\Z}i
+ REV_PARAM_RE = %r{\A[a-f0-9]*\z}i
def find_project_repository
@project = Project.find(params[:id])
@@ -341,14 +341,12 @@ class RepositoriesController < ApplicationController
end
(render_404; return false) unless @repository
@path = params[:path].is_a?(Array) ? params[:path].join('/') : params[:path].to_s
- @rev = params[:rev].blank? ? @repository.default_branch : params[:rev].to_s.strip
- @rev_to = params[:rev_to]
- unless REV_PARAM_RE.match?(@rev.to_s) && REV_PARAM_RE.match?(@rev_to.to_s)
- if @repository.branches.blank?
- raise InvalidRevisionParam
- end
- end
+ @rev = params[:rev].to_s.strip.presence || @repository.default_branch
+ raise InvalidRevisionParam unless valid_name?(@rev)
+
+ @rev_to = params[:rev_to].to_s.strip.presence
+ raise InvalidRevisionParam unless valid_name?(@rev_to)
rescue ActiveRecord::RecordNotFound
render_404
rescue InvalidRevisionParam
@@ -433,4 +431,11 @@ class RepositoriesController < ApplicationController
'attachment'
end
end
+
+ def valid_name?(rev)
+ return true if rev.nil?
+ return true if REV_PARAM_RE.match?(rev)
+
+ @repository ? @repository.valid_name?(rev) : true
+ end
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index e65c800e6..4e76c3453 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -463,6 +463,10 @@ class Repository < ActiveRecord::Base
scope
end
+ def valid_name?(name)
+ scm.valid_name?(name)
+ end
+
protected
# Validates repository url based against an optional regular expression
diff --git a/lib/redmine/scm/adapters/abstract_adapter.rb b/lib/redmine/scm/adapters/abstract_adapter.rb
index dae621866..d0c3293a6 100644
--- a/lib/redmine/scm/adapters/abstract_adapter.rb
+++ b/lib/redmine/scm/adapters/abstract_adapter.rb
@@ -176,6 +176,14 @@ module Redmine
(path[-1, 1] == "/") ? path[0..-2] : path
end
+ def valid_name?(name)
+ return true if name.nil?
+ return true if name.is_a?(Integer) && name > 0
+ return true if name.is_a?(String) && name =~ /\A[0-9]*\z/
+
+ false
+ end
+
private
def retrieve_root_url
diff --git a/lib/redmine/scm/adapters/git_adapter.rb b/lib/redmine/scm/adapters/git_adapter.rb
index b85bd0296..363476cd4 100644
--- a/lib/redmine/scm/adapters/git_adapter.rb
+++ b/lib/redmine/scm/adapters/git_adapter.rb
@@ -420,6 +420,18 @@ module Redmine
nil
end
+ def valid_name?(name)
+ return false unless name.is_a?(String)
+
+ return false if name.start_with?('-', '/', 'refs/heads/', 'refs/remotes/')
+ return false if name == 'HEAD'
+
+ git_cmd ['show-ref', '--heads', '--tags', '--quiet', '--', name]
+ true
+ rescue ScmCommandAborted
+ false
+ end
+
class Revision < Redmine::Scm::Adapters::Revision
# Returns the readable identifier
def format_identifier
diff --git a/lib/redmine/scm/adapters/mercurial_adapter.rb b/lib/redmine/scm/adapters/mercurial_adapter.rb
index 6ab5ec69d..075636ce1 100644
--- a/lib/redmine/scm/adapters/mercurial_adapter.rb
+++ b/lib/redmine/scm/adapters/mercurial_adapter.rb
@@ -296,6 +296,15 @@ module Redmine
Annotate.new
end
+ def valid_name?(name)
+ return false unless name.nil? || name.is_a?(String)
+
+ # Mercurials names don't need to be checked further as its CLI
+ # interface is restrictive enough to reject any invalid names on its
+ # own.
+ true
+ end
+
class Revision < Redmine::Scm::Adapters::Revision
# Returns the readable identifier
def format_identifier