]> source.dussan.org Git - redmine.git/commitdiff
Merged r20962 from trunk to 4.0-stable (#35085).
authorGo MAEDA <maeda@farend.jp>
Fri, 23 Apr 2021 02:18:32 +0000 (02:18 +0000)
committerGo MAEDA <maeda@farend.jp>
Fri, 23 Apr 2021 02:18:32 +0000 (02:18 +0000)
git-svn-id: http://svn.redmine.org/redmine/branches/4.0-stable@20965 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/controllers/repositories_controller.rb
app/models/repository.rb
lib/redmine/scm/adapters/abstract_adapter.rb
lib/redmine/scm/adapters/git_adapter.rb
lib/redmine/scm/adapters/mercurial_adapter.rb

index a49beadc4b910fd5487fecb14ca9d3088349454c..aec6533e1e8721190a9143c850470ec0b00b8d14 100644 (file)
@@ -305,7 +305,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])
@@ -316,14 +316,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.to_s.match(REV_PARAM_RE) && @rev_to.to_s.match(REV_PARAM_RE)
-      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
@@ -408,4 +406,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
index 256222f50655ee7d509e89e67a145946260aa473..b106cf7bf991c54b0d4ab5e8c69652a80e1143ec 100644 (file)
@@ -459,6 +459,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
index 7f3b8093fbddfe10a470ffc523f08f6c111ae34c..55d6d61638e5a7fa3f6daa1b741537decf673d82 100644 (file)
@@ -176,7 +176,16 @@ module Redmine
           (path[-1,1] == "/") ? path[0..-2] : path
         end
 
-      private
+        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
           info = self.info
           info ? info.root_url : nil
index 4f889d0b14e6d70a06fba9cb562d510cd0c98621..a04e5cb6af9b62dbda0062e31b39c76ed02f06a5 100644 (file)
@@ -380,6 +380,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
index a3b672d26bad3490369cb422b1aa2c2e1d1b572f..d443ac0ce9e056a544aff0d2c8f8f7ae67d4c6df 100644 (file)
@@ -281,6 +281,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