github.com/google/osv-scalibr@v0.4.1/enricher/reachability/java/utils.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 package java 16 17 import ( 18 "io/fs" 19 "os" 20 "path/filepath" 21 "strings" 22 "syscall" 23 24 scalibrfs "github.com/google/osv-scalibr/fs" 25 ) 26 27 // mkdirAll simulates the same logic as os.MkdirAll but uses os.Root as input. 28 // Code logic copied from https://cs.opensource.google/go/go/+/refs/tags/go1.24.4:src/os/path.go;l=19 29 func mkdirAll(jarRoot *os.Root, path string, perm os.FileMode) error { 30 // Fast path: if we can tell whether path is a directory or file, stop with success or error. 31 dir, err := jarRoot.Stat(path) 32 if err == nil { 33 if dir.IsDir() { 34 return nil 35 } 36 37 return &os.PathError{Op: "mkdir", Path: path, Err: syscall.ENOTDIR} 38 } 39 40 // Slow path: make sure parent exists and then call Mkdir for path. 41 42 // Extract the parent folder from path by first removing any trailing 43 // path separator and then scanning backward until finding a path 44 // separator or reaching the beginning of the string. 45 i := len(path) - 1 46 47 for i >= 0 && os.IsPathSeparator(path[i]) { 48 i-- 49 } 50 for i >= 0 && !os.IsPathSeparator(path[i]) { 51 i-- 52 } 53 if i < 0 { 54 i = 0 55 } 56 57 // recurse to ensure parent directory exists. 58 if parent := path[:i]; len(parent) > 0 { 59 err = mkdirAll(jarRoot, parent, perm) 60 if err != nil { 61 return err 62 } 63 } 64 65 // Parent now exists; invoke Mkdir and use its result. 66 err = jarRoot.Mkdir(path, perm) 67 if err != nil { 68 // Handle arguments like "foo/." by 69 // double-checking that directory doesn't exist. 70 dir, err1 := jarRoot.Lstat(path) 71 if err1 == nil && dir.IsDir() { 72 return nil 73 } 74 75 return err 76 } 77 78 return nil 79 } 80 81 func openFromRoot(root *scalibrfs.ScanRoot, fullPath string) (fs.File, error) { 82 rootPath := root.Path 83 84 relPath := fullPath 85 if strings.HasPrefix(fullPath, rootPath) { 86 relPath = fullPath[len(rootPath):] 87 } 88 89 return root.FS.Open(filepath.ToSlash(relPath)) 90 }