mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	Fixes: #22843 
### Cause:
affdd40296/services/repository/files/content.go (L161)
Previously, we did not escape the **"%"** that might be in "treePath"
when call "url.parse()".

This function will check whether "%" is the beginning of an escape
character. Obviously, the "%" in the example (hello%mother.txt) is not
that. So, the function will return a error.
### Solution:
We can escape "treePath" by call "url.PathEscape()" function firstly.
### Screenshot:

---------
Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: Andrew Thornton <art27@cantab.net>
		
	
		
			
				
	
	
		
			104 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2021 The Gitea Authors. All rights reserved.
 | 
						|
// SPDX-License-Identifier: MIT
 | 
						|
 | 
						|
package lfs
 | 
						|
 | 
						|
import (
 | 
						|
	"net/url"
 | 
						|
	"os"
 | 
						|
	"path"
 | 
						|
	"path/filepath"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"code.gitea.io/gitea/modules/log"
 | 
						|
	"code.gitea.io/gitea/modules/util"
 | 
						|
)
 | 
						|
 | 
						|
// DetermineEndpoint determines an endpoint from the clone url or uses the specified LFS url.
 | 
						|
func DetermineEndpoint(cloneurl, lfsurl string) *url.URL {
 | 
						|
	if len(lfsurl) > 0 {
 | 
						|
		return endpointFromURL(lfsurl)
 | 
						|
	}
 | 
						|
	return endpointFromCloneURL(cloneurl)
 | 
						|
}
 | 
						|
 | 
						|
func endpointFromCloneURL(rawurl string) *url.URL {
 | 
						|
	ep := endpointFromURL(rawurl)
 | 
						|
	if ep == nil {
 | 
						|
		return ep
 | 
						|
	}
 | 
						|
 | 
						|
	ep.Path = strings.TrimSuffix(ep.Path, "/")
 | 
						|
 | 
						|
	if ep.Scheme == "file" {
 | 
						|
		return ep
 | 
						|
	}
 | 
						|
 | 
						|
	if path.Ext(ep.Path) == ".git" {
 | 
						|
		ep.Path += "/info/lfs"
 | 
						|
	} else {
 | 
						|
		ep.Path += ".git/info/lfs"
 | 
						|
	}
 | 
						|
 | 
						|
	return ep
 | 
						|
}
 | 
						|
 | 
						|
func endpointFromURL(rawurl string) *url.URL {
 | 
						|
	if strings.HasPrefix(rawurl, "/") {
 | 
						|
		return endpointFromLocalPath(rawurl)
 | 
						|
	}
 | 
						|
 | 
						|
	u, err := url.Parse(rawurl)
 | 
						|
	if err != nil {
 | 
						|
		log.Error("lfs.endpointFromUrl: %v", err)
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	switch u.Scheme {
 | 
						|
	case "http", "https":
 | 
						|
		return u
 | 
						|
	case "git":
 | 
						|
		u.Scheme = "https"
 | 
						|
		return u
 | 
						|
	case "file":
 | 
						|
		return u
 | 
						|
	default:
 | 
						|
		if _, err := os.Stat(rawurl); err == nil {
 | 
						|
			return endpointFromLocalPath(rawurl)
 | 
						|
		}
 | 
						|
 | 
						|
		log.Error("lfs.endpointFromUrl: unknown url")
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func endpointFromLocalPath(path string) *url.URL {
 | 
						|
	var slash string
 | 
						|
	if abs, err := filepath.Abs(path); err == nil {
 | 
						|
		if !strings.HasPrefix(abs, "/") {
 | 
						|
			slash = "/"
 | 
						|
		}
 | 
						|
		path = abs
 | 
						|
	}
 | 
						|
 | 
						|
	var gitpath string
 | 
						|
	if filepath.Base(path) == ".git" {
 | 
						|
		gitpath = path
 | 
						|
		path = filepath.Dir(path)
 | 
						|
	} else {
 | 
						|
		gitpath = filepath.Join(path, ".git")
 | 
						|
	}
 | 
						|
 | 
						|
	if _, err := os.Stat(gitpath); err == nil {
 | 
						|
		path = gitpath
 | 
						|
	} else if _, err := os.Stat(path); err != nil {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	path = "file://" + slash + util.PathEscapeSegments(filepath.ToSlash(path))
 | 
						|
 | 
						|
	u, _ := url.Parse(path)
 | 
						|
 | 
						|
	return u
 | 
						|
}
 |