github.com/google/osv-scalibr@v0.4.1/enricher/govulncheck/source/internal/url/url.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Derived from https://github.com/golang/go/blob/7c2b69080a0b9e35174cc9c93497b6e7176f8275/src/cmd/go/internal/web/url.go 16 // TODO(golang.org/issue/32456): If accepted, move these functions into the 17 // net/url package. 18 // 19 // Copyright 2023 The Go Authors. All rights reserved. 20 // Use of this source code is governed by a BSD-style 21 // license that can be found in the LICENSE file. 22 23 // Package url creates a url.URL object that is compatible with govulncheck 24 package url 25 26 import ( 27 "errors" 28 "net/url" 29 "path/filepath" 30 "strings" 31 ) 32 33 // ErrNotAbsolute is returned when the input path is not absolute. 34 var ErrNotAbsolute = errors.New("path is not absolute") 35 36 // FromFilePath creates a url.URL object from a file path. 37 func FromFilePath(path string) (*url.URL, error) { 38 if !filepath.IsAbs(path) { 39 return nil, ErrNotAbsolute 40 } 41 42 // If path has a Windows volume name, convert the volume to a host and prefix 43 // per https://blogs.msdn.microsoft.com/ie/2006/12/06/file-uris-in-windows/. 44 if vol := filepath.VolumeName(path); vol != "" { 45 if strings.HasPrefix(vol, `\\`) { 46 path = filepath.ToSlash(path[2:]) 47 i := strings.IndexByte(path, '/') 48 49 if i < 0 { 50 // A degenerate case. 51 // \\host.example.com (without a share name) 52 // becomes 53 // file://host.example.com/ 54 return &url.URL{ 55 Scheme: "file", 56 Host: path, 57 Path: "/", 58 }, nil 59 } 60 61 // \\host.example.com\Share\path\to\file 62 // becomes 63 // file://host.example.com/Share/path/to/file 64 return &url.URL{ 65 Scheme: "file", 66 Host: path[:i], 67 Path: filepath.ToSlash(path[i:]), 68 }, nil 69 } 70 71 // C:\path\to\file 72 // becomes 73 // file:///C:/path/to/file 74 return &url.URL{ 75 Scheme: "file", 76 Path: "/" + filepath.ToSlash(path), 77 }, nil 78 } 79 80 // /path/to/file 81 // becomes 82 // file:///path/to/file 83 return &url.URL{ 84 Scheme: "file", 85 Path: filepath.ToSlash(path), 86 }, nil 87 }