Introduce path Clean/Join helper functions (#23495)

Since #23493 has conflicts with latest commits, this PR is my proposal
for fixing #23371

Details are in the comments

And refactor the `modules/options` module, to make it always use
"filepath" to access local files.

Benefits:

* No need to do `util.CleanPath(strings.ReplaceAll(p, "\\", "/"))),
"/")` any more (not only one before)
* The function behaviors are clearly defined
This commit is contained in:
wxiaoguang 2023-03-22 04:02:49 +08:00 committed by GitHub
parent 253a00aaac
commit ce9dee5a1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 261 additions and 152 deletions

View file

@ -45,29 +45,19 @@ func AssetsHandlerFunc(opts *Options) http.HandlerFunc {
return
}
file := req.URL.Path
file = file[len(opts.Prefix):]
if len(file) == 0 {
resp.WriteHeader(http.StatusNotFound)
return
}
if strings.Contains(file, "\\") {
resp.WriteHeader(http.StatusBadRequest)
return
}
file = "/" + file
var written bool
var corsSent bool
if opts.CorsHandler != nil {
written = true
opts.CorsHandler(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
written = false
corsSent = true
})).ServeHTTP(resp, req)
}
if written {
// If CORS is not sent, the response must have been written by other handlers
if !corsSent {
return
}
file := req.URL.Path[len(opts.Prefix):]
// custom files
if opts.handle(resp, req, http.Dir(custPath), file) {
return
@ -102,8 +92,8 @@ func setWellKnownContentType(w http.ResponseWriter, file string) {
}
func (opts *Options) handle(w http.ResponseWriter, req *http.Request, fs http.FileSystem, file string) bool {
// use clean to keep the file is a valid path with no . or ..
f, err := fs.Open(util.CleanPath(file))
// actually, fs (http.FileSystem) is designed to be a safe interface, relative paths won't bypass its parent directory, it's also fine to do a clean here
f, err := fs.Open(util.PathJoinRelX(file))
if err != nil {
if os.IsNotExist(err) {
return false