blob: 60e2d1eae4a1f938f0ea3a2eee52e3426c33a383 [file] [log] [blame]
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Code adapted from
// https://github.com/golang/go/blob/2ebe77a2fda1ee9ff6fd9a3e08933ad1ebaea039/src/cmd/go/internal/web/url.go
// TODO(go.dev/issue/32456): if accepted, use the new API.
package vuln
import (
"errors"
"net/url"
"path/filepath"
"runtime"
)
var errNotAbsolute = errors.New("path is not absolute")
// URLToFilePath converts a file-scheme url to a file path.
func URLToFilePath(u *url.URL) (string, error) {
if u.Scheme != "file" {
return "", errors.New("non-file URL")
}
checkAbs := func(path string) (string, error) {
if !filepath.IsAbs(path) {
return "", errNotAbsolute
}
return path, nil
}
if u.Path == "" {
if u.Host != "" || u.Opaque == "" {
return "", errors.New("file URL missing path")
}
return checkAbs(filepath.FromSlash(u.Opaque))
}
path, err := convertFileURLPath(u.Host, u.Path)
if err != nil {
return path, err
}
return checkAbs(path)
}
func convertFileURLPath(host, path string) (string, error) {
if runtime.GOOS == "windows" {
return "", errors.New("windows not supported")
}
switch host {
case "", "localhost":
default:
return "", errors.New("file URL specifies non-local host")
}
return filepath.FromSlash(path), nil
}