Projects STRLCPY syft Commits 6afbffce
🤬
  • ■ ■ ■ ■ ■
    syft/formats/common/spdxhelpers/to_format_model_test.go
    skipped 12 lines
    13 13   "github.com/anchore/syft/syft/file"
    14 14   "github.com/anchore/syft/syft/pkg"
    15 15   "github.com/anchore/syft/syft/sbom"
    16  - "github.com/anchore/syft/syft/source"
    17 16  )
    18 17   
    19 18  // TODO: Add ToFormatModel tests
    skipped 485 lines
    505 504   }{
    506 505   {
    507 506   name: "short filename",
    508  - it: source.Coordinates{
     507 + it: file.Coordinates{
    509 508   RealPath: "/short/path/file.txt",
    510 509   },
    511 510   expected: "File-short-path-file.txt",
    512 511   },
    513 512   {
    514 513   name: "long filename",
    515  - it: source.Coordinates{
     514 + it: file.Coordinates{
    516 515   RealPath: "/some/long/path/with/a/lot/of-text/that-contains-a/file.txt",
    517 516   },
    518 517   expected: "File-...a-lot-of-text-that-contains-a-file.txt",
    skipped 21 lines
  • ■ ■ ■ ■ ■ ■
    syft/internal/fileresolver/directory.go
    skipped 53 lines
    54 54   if err != nil {
    55 55   return nil, fmt.Errorf("could not get CWD: %w", err)
    56 56   }
    57  - // we have to account for the root being accessed through a symlink path and always resolve the real path. Otherwise
    58  - // we will not be able to normalize given paths that fall under the resolver
    59  - cleanCWD, err := filepath.EvalSymlinks(currentWD)
    60  - if err != nil {
    61  - return nil, fmt.Errorf("could not evaluate CWD symlinks: %w", err)
    62  - }
    63 57   
    64 58   cleanRoot, err := filepath.EvalSymlinks(root)
    65 59   if err != nil {
    skipped 14 lines
    80 74   
    81 75   var currentWdRelRoot string
    82 76   if path.IsAbs(cleanRoot) {
    83  - currentWdRelRoot, err = filepath.Rel(cleanCWD, cleanRoot)
     77 + currentWdRelRoot, err = filepath.Rel(currentWD, cleanRoot)
    84 78   if err != nil {
    85 79   return nil, fmt.Errorf("could not determine given root path to CWD: %w", err)
    86 80   }
    skipped 4 lines
    91 85   return &Directory{
    92 86   path: cleanRoot,
    93 87   base: cleanBase,
    94  - currentWd: cleanCWD,
     88 + currentWd: currentWD,
    95 89   currentWdRelativeToRoot: currentWdRelRoot,
    96 90   tree: filetree.New(),
    97 91   index: filetree.NewIndex(),
    skipped 34 lines
    132 126   return userPath, nil
    133 127  }
    134 128   
     129 +// responsePath takes a path from the underlying fs domain and converts it to a path that is relative to the root of the directory resolver.
    135 130  func (r Directory) responsePath(path string) string {
    136 131   // check to see if we need to encode back to Windows from posix
    137 132   if runtime.GOOS == WindowsOS {
    skipped 236 lines
  • ■ ■ ■ ■ ■ ■
    syft/internal/fileresolver/directory_indexer.go
    skipped 7 lines
    8 8   "path"
    9 9   "path/filepath"
    10 10   "runtime"
     11 + "strings"
    11 12   
    12 13   "github.com/wagoodman/go-partybus"
    13 14   "github.com/wagoodman/go-progress"
    skipped 105 lines
    119 120   return roots, nil
    120 121   }
    121 122   
     123 + shouldIndexFullTree, err := isRealPath(root)
     124 + if err != nil {
     125 + return nil, err
     126 + }
     127 + 
     128 + if !shouldIndexFullTree {
     129 + newRoots, err := r.indexBranch(root, stager)
     130 + if err != nil {
     131 + return nil, fmt.Errorf("unable to index branch=%q: %w", root, err)
     132 + }
     133 + 
     134 + roots = append(roots, newRoots...)
     135 + 
     136 + return roots, nil
     137 + }
     138 + 
    122 139   err = filepath.Walk(root,
    123 140   func(path string, info os.FileInfo, err error) error {
    124 141   stager.Current = path
    skipped 16 lines
    141 158   }
    142 159   
    143 160   return roots, nil
     161 +}
     162 + 
     163 +func isRealPath(root string) (bool, error) {
     164 + rootParent := filepath.Clean(filepath.Dir(root))
     165 + 
     166 + realRootParent, err := filepath.EvalSymlinks(rootParent)
     167 + if err != nil {
     168 + return false, err
     169 + }
     170 + 
     171 + realRootParent = filepath.Clean(realRootParent)
     172 + 
     173 + return rootParent == realRootParent, nil
     174 +}
     175 + 
     176 +func (r *directoryIndexer) indexBranch(root string, stager *progress.Stage) ([]string, error) {
     177 + rootRealPath, err := filepath.EvalSymlinks(root)
     178 + if err != nil {
     179 + return nil, err
     180 + }
     181 + 
     182 + // there is a symlink within the path to the root, we need to index the real root parent first
     183 + // then capture the symlinks to the root path
     184 + roots, err := r.indexTree(rootRealPath, stager)
     185 + if err != nil {
     186 + return nil, fmt.Errorf("unable to index real root=%q: %w", rootRealPath, err)
     187 + }
     188 + 
     189 + // walk down all ancestor paths and shallow-add non-existing elements to the tree
     190 + for idx, p := range allContainedPaths(root) {
     191 + var targetPath string
     192 + if idx != 0 {
     193 + parent := path.Dir(p)
     194 + cleanParent, err := filepath.EvalSymlinks(parent)
     195 + if err != nil {
     196 + return nil, fmt.Errorf("unable to evaluate symlink for contained path parent=%q: %w", parent, err)
     197 + }
     198 + targetPath = filepath.Join(cleanParent, filepath.Base(p))
     199 + } else {
     200 + targetPath = p
     201 + }
     202 + 
     203 + stager.Current = targetPath
     204 + 
     205 + lstat, err := os.Lstat(targetPath)
     206 + newRoot, err := r.indexPath(targetPath, lstat, err)
     207 + if err != nil && !errors.Is(err, ErrSkipPath) && !errors.Is(err, fs.SkipDir) {
     208 + return nil, fmt.Errorf("unable to index ancestor path=%q: %w", targetPath, err)
     209 + }
     210 + if newRoot != "" {
     211 + roots = append(roots, newRoot)
     212 + }
     213 + }
     214 + 
     215 + return roots, nil
     216 +}
     217 + 
     218 +func allContainedPaths(p string) []string {
     219 + var all []string
     220 + var currentPath string
     221 + 
     222 + cleanPath := strings.TrimSpace(p)
     223 + 
     224 + if cleanPath == "" {
     225 + return nil
     226 + }
     227 + 
     228 + // iterate through all parts of the path, replacing path elements with link resolutions where possible.
     229 + for idx, part := range strings.Split(filepath.Clean(cleanPath), file.DirSeparator) {
     230 + if idx == 0 && part == "" {
     231 + currentPath = file.DirSeparator
     232 + continue
     233 + }
     234 + 
     235 + // cumulatively gather where we are currently at and provide a rich object
     236 + currentPath = path.Join(currentPath, part)
     237 + all = append(all, currentPath)
     238 + }
     239 + return all
    144 240  }
    145 241   
    146 242  func (r *directoryIndexer) indexPath(path string, info os.FileInfo, err error) (string, error) {
    skipped 220 lines
  • ■ ■ ■ ■ ■
    syft/internal/fileresolver/directory_indexer_test.go
    skipped 225 lines
    226 226   var observedPaths []string
    227 227   pathObserver := func(p string, _ os.FileInfo, _ error) error {
    228 228   fields := strings.Split(p, "test-fixtures/symlinks-prune-indexing")
    229  - if len(fields) != 2 {
    230  - t.Fatalf("unable to parse path: %s", p)
     229 + if len(fields) < 2 {
     230 + return nil
    231 231   }
    232 232   clean := strings.TrimLeft(fields[1], "/")
    233 233   if clean != "" {
    skipped 27 lines
    261 261   "path/5/6/7/8/dont-index-me-twice-either.txt",
    262 262   "path/file.txt",
    263 263   // everything below is after the original tree is indexed, and we are now indexing additional roots from symlinks
    264  - "path", // considered from symlink before-path, but pruned
    265  - "before-path/file.txt", // considered from symlink c-file.txt, but pruned
    266  - "before-path", // considered from symlink c-path, but pruned
     264 + "path", // considered from symlink before-path, but pruned
     265 + "path/file.txt", // leaf
     266 + "before-path", // considered from symlink c-path, but pruned
     267 + "path/file.txt", // leaf
     268 + "before-path", // considered from symlink c-path, but pruned
    267 269   }
    268 270   
    269 271   assert.Equal(t, expected, observedPaths, "visited paths differ \n %s", cmp.Diff(expected, observedPaths))
    skipped 12 lines
    282 284   for _, ref := range allRefs {
    283 285   fields := strings.Split(string(ref.RealPath), "test-fixtures/symlinks-prune-indexing")
    284 286   if len(fields) != 2 {
    285  - t.Fatalf("unable to parse path: %s", ref.RealPath)
     287 + continue
    286 288   }
    287 289   clean := strings.TrimLeft(fields[1], "/")
    288 290   if clean == "" {
    skipped 38 lines
    327 329   
    328 330  }
    329 331   
     332 +func Test_allContainedPaths(t *testing.T) {
     333 + 
     334 + tests := []struct {
     335 + name string
     336 + path string
     337 + want []string
     338 + }{
     339 + {
     340 + name: "empty",
     341 + path: "",
     342 + want: nil,
     343 + },
     344 + {
     345 + name: "single relative",
     346 + path: "a",
     347 + want: []string{"a"},
     348 + },
     349 + {
     350 + name: "single absolute",
     351 + path: "/a",
     352 + want: []string{"/a"},
     353 + },
     354 + {
     355 + name: "multiple relative",
     356 + path: "a/b/c",
     357 + want: []string{"a", "a/b", "a/b/c"},
     358 + },
     359 + {
     360 + name: "multiple absolute",
     361 + path: "/a/b/c",
     362 + want: []string{"/a", "/a/b", "/a/b/c"},
     363 + },
     364 + {
     365 + name: "multiple absolute with extra slashs",
     366 + path: "///a/b//c/",
     367 + want: []string{"/a", "/a/b", "/a/b/c"},
     368 + },
     369 + {
     370 + name: "relative with single dot",
     371 + path: "a/./b",
     372 + want: []string{"a", "a/b"},
     373 + },
     374 + {
     375 + name: "relative with double single dot",
     376 + path: "a/../b",
     377 + want: []string{"b"},
     378 + },
     379 + }
     380 + for _, tt := range tests {
     381 + t.Run(tt.name, func(t *testing.T) {
     382 + assert.Equal(t, tt.want, allContainedPaths(tt.path))
     383 + })
     384 + }
     385 +}
     386 + 
  • ■ ■ ■ ■ ■ ■
    syft/internal/fileresolver/directory_test.go
    skipped 21 lines
    22 22   "github.com/anchore/syft/syft/file"
    23 23  )
    24 24   
     25 +func TestDirectoryResolver_FilesByPath_request_response(t *testing.T) {
     26 + // /
     27 + // somewhere/
     28 + // outside.txt
     29 + // root-link -> ./
     30 + // path/
     31 + // to/
     32 + // abs-inside.txt -> /path/to/the/file.txt # absolute link to somewhere inside of the root
     33 + // rel-inside.txt -> ./the/file.txt # relative link to somewhere inside of the root
     34 + // the/
     35 + // file.txt
     36 + // abs-outside.txt -> /somewhere/outside.txt # absolute link to outside of the root
     37 + // rel-outside -> ../../../somewhere/outside.txt # relative link to outside of the root
     38 + //
     39 + 
     40 + testDir, err := os.Getwd()
     41 + require.NoError(t, err)
     42 + relative := filepath.Join("test-fixtures", "req-resp")
     43 + absolute := filepath.Join(testDir, relative)
     44 + 
     45 + absInsidePath := filepath.Join(absolute, "path", "to", "abs-inside.txt")
     46 + absOutsidePath := filepath.Join(absolute, "path", "to", "the", "abs-outside.txt")
     47 + 
     48 + relativeViaLink := filepath.Join(relative, "root-link")
     49 + absoluteViaLink := filepath.Join(absolute, "root-link")
     50 + 
     51 + relativeViaDoubleLink := filepath.Join(relative, "root-link", "root-link")
     52 + absoluteViaDoubleLink := filepath.Join(absolute, "root-link", "root-link")
     53 + 
     54 + cleanup := func() {
     55 + _ = os.Remove(absInsidePath)
     56 + _ = os.Remove(absOutsidePath)
     57 + }
     58 + 
     59 + // ensure the absolute symlinks are cleaned up from any previous runs
     60 + cleanup()
     61 + 
     62 + require.NoError(t, os.Symlink(filepath.Join(absolute, "path", "to", "the", "file.txt"), absInsidePath))
     63 + require.NoError(t, os.Symlink(filepath.Join(absolute, "somewhere", "outside.txt"), absOutsidePath))
     64 + 
     65 + t.Cleanup(cleanup)
     66 + 
     67 + cases := []struct {
     68 + name string
     69 + cwd string
     70 + root string
     71 + base string
     72 + input string
     73 + expectedRealPath string
     74 + expectedVirtualPath string
     75 + }{
     76 + {
     77 + name: "relative root, relative request, direct",
     78 + root: relative,
     79 + input: "path/to/the/file.txt",
     80 + expectedRealPath: "path/to/the/file.txt",
     81 + },
     82 + {
     83 + name: "abs root, relative request, direct",
     84 + root: absolute,
     85 + input: "path/to/the/file.txt",
     86 + expectedRealPath: "path/to/the/file.txt",
     87 + },
     88 + {
     89 + name: "relative root, abs request, direct",
     90 + root: relative,
     91 + input: "/path/to/the/file.txt",
     92 + expectedRealPath: "path/to/the/file.txt",
     93 + },
     94 + {
     95 + name: "abs root, abs request, direct",
     96 + root: absolute,
     97 + input: "/path/to/the/file.txt",
     98 + expectedRealPath: "path/to/the/file.txt",
     99 + },
     100 + // cwd within root...
     101 + {
     102 + name: "relative root, relative request, direct, cwd within root",
     103 + cwd: filepath.Join(relative, "path/to"),
     104 + root: "../../",
     105 + input: "path/to/the/file.txt",
     106 + expectedRealPath: "path/to/the/file.txt",
     107 + },
     108 + {
     109 + name: "abs root, relative request, direct, cwd within root",
     110 + cwd: filepath.Join(relative, "path/to"),
     111 + root: absolute,
     112 + input: "path/to/the/file.txt",
     113 + expectedRealPath: "path/to/the/file.txt",
     114 + },
     115 + {
     116 + name: "relative root, abs request, direct, cwd within root",
     117 + cwd: filepath.Join(relative, "path/to"),
     118 + root: "../../",
     119 + input: "/path/to/the/file.txt",
     120 + expectedRealPath: "path/to/the/file.txt",
     121 + },
     122 + {
     123 + name: "abs root, abs request, direct, cwd within root",
     124 + cwd: filepath.Join(relative, "path/to"),
     125 + 
     126 + root: absolute,
     127 + input: "/path/to/the/file.txt",
     128 + expectedRealPath: "path/to/the/file.txt",
     129 + },
     130 + // cwd within symlink root...
     131 + {
     132 + name: "relative root, relative request, direct, cwd within symlink root",
     133 + cwd: relativeViaLink,
     134 + root: "./",
     135 + input: "path/to/the/file.txt",
     136 + // note: why not expect "path/to/the/file.txt" here?
     137 + // this is because we don't know that the path used to access this path (which is a link within
     138 + // the root) resides within the root. Without this information it appears as if this file resides
     139 + // outside the root.
     140 + expectedRealPath: filepath.Join(absolute, "path/to/the/file.txt"),
     141 + //expectedRealPath: "path/to/the/file.txt",
     142 + expectedVirtualPath: "path/to/the/file.txt",
     143 + },
     144 + {
     145 + name: "abs root, relative request, direct, cwd within symlink root",
     146 + cwd: relativeViaLink,
     147 + root: absoluteViaLink,
     148 + input: "path/to/the/file.txt",
     149 + expectedRealPath: "path/to/the/file.txt",
     150 + },
     151 + {
     152 + name: "relative root, abs request, direct, cwd within symlink root",
     153 + cwd: relativeViaLink,
     154 + root: "./",
     155 + input: "/path/to/the/file.txt",
     156 + // note: why not expect "path/to/the/file.txt" here?
     157 + // this is because we don't know that the path used to access this path (which is a link within
     158 + // the root) resides within the root. Without this information it appears as if this file resides
     159 + // outside the root.
     160 + expectedRealPath: filepath.Join(absolute, "path/to/the/file.txt"),
     161 + //expectedRealPath: "path/to/the/file.txt",
     162 + expectedVirtualPath: "path/to/the/file.txt",
     163 + },
     164 + {
     165 + name: "abs root, abs request, direct, cwd within symlink root",
     166 + cwd: relativeViaLink,
     167 + root: absoluteViaLink,
     168 + input: "/path/to/the/file.txt",
     169 + expectedRealPath: "path/to/the/file.txt",
     170 + },
     171 + // cwd within symlink root, request nested within...
     172 + {
     173 + name: "relative root, relative nested request, direct, cwd within symlink root",
     174 + cwd: relativeViaLink,
     175 + root: "./path",
     176 + input: "to/the/file.txt",
     177 + // note: why not expect "to/the/file.txt" here?
     178 + // this is because we don't know that the path used to access this path (which is a link within
     179 + // the root) resides within the root. Without this information it appears as if this file resides
     180 + // outside the root.
     181 + expectedRealPath: filepath.Join(absolute, "path/to/the/file.txt"),
     182 + //expectedRealPath: "to/the/file.txt",
     183 + expectedVirtualPath: "to/the/file.txt",
     184 + },
     185 + {
     186 + name: "abs root, relative nested request, direct, cwd within symlink root",
     187 + cwd: relativeViaLink,
     188 + root: filepath.Join(absoluteViaLink, "path"),
     189 + input: "to/the/file.txt",
     190 + expectedRealPath: "to/the/file.txt",
     191 + },
     192 + {
     193 + name: "relative root, abs nested request, direct, cwd within symlink root",
     194 + cwd: relativeViaLink,
     195 + root: "./path",
     196 + input: "/to/the/file.txt",
     197 + // note: why not expect "to/the/file.txt" here?
     198 + // this is because we don't know that the path used to access this path (which is a link within
     199 + // the root) resides within the root. Without this information it appears as if this file resides
     200 + // outside the root.
     201 + expectedRealPath: filepath.Join(absolute, "path/to/the/file.txt"),
     202 + //expectedRealPath: "to/the/file.txt",
     203 + expectedVirtualPath: "to/the/file.txt",
     204 + },
     205 + {
     206 + name: "abs root, abs nested request, direct, cwd within symlink root",
     207 + cwd: relativeViaLink,
     208 + root: filepath.Join(absoluteViaLink, "path"),
     209 + input: "/to/the/file.txt",
     210 + expectedRealPath: "to/the/file.txt",
     211 + },
     212 + // cwd within DOUBLE symlink root...
     213 + {
     214 + name: "relative root, relative request, direct, cwd within (double) symlink root",
     215 + cwd: relativeViaDoubleLink,
     216 + root: "./",
     217 + input: "path/to/the/file.txt",
     218 + // note: why not expect "path/to/the/file.txt" here?
     219 + // this is because we don't know that the path used to access this path (which is a link within
     220 + // the root) resides within the root. Without this information it appears as if this file resides
     221 + // outside the root.
     222 + expectedRealPath: filepath.Join(absolute, "path/to/the/file.txt"),
     223 + //expectedRealPath: "path/to/the/file.txt",
     224 + expectedVirtualPath: "path/to/the/file.txt",
     225 + },
     226 + {
     227 + name: "abs root, relative request, direct, cwd within (double) symlink root",
     228 + cwd: relativeViaDoubleLink,
     229 + root: absoluteViaDoubleLink,
     230 + input: "path/to/the/file.txt",
     231 + expectedRealPath: "path/to/the/file.txt",
     232 + },
     233 + {
     234 + name: "relative root, abs request, direct, cwd within (double) symlink root",
     235 + cwd: relativeViaDoubleLink,
     236 + root: "./",
     237 + input: "/path/to/the/file.txt",
     238 + // note: why not expect "path/to/the/file.txt" here?
     239 + // this is because we don't know that the path used to access this path (which is a link within
     240 + // the root) resides within the root. Without this information it appears as if this file resides
     241 + // outside the root.
     242 + expectedRealPath: filepath.Join(absolute, "path/to/the/file.txt"),
     243 + //expectedRealPath: "path/to/the/file.txt",
     244 + expectedVirtualPath: "path/to/the/file.txt",
     245 + },
     246 + {
     247 + name: "abs root, abs request, direct, cwd within (double) symlink root",
     248 + cwd: relativeViaDoubleLink,
     249 + root: absoluteViaDoubleLink,
     250 + input: "/path/to/the/file.txt",
     251 + expectedRealPath: "path/to/the/file.txt",
     252 + },
     253 + // cwd within DOUBLE symlink root, request nested within...
     254 + {
     255 + name: "relative root, relative nested request, direct, cwd within (double) symlink root",
     256 + cwd: relativeViaDoubleLink,
     257 + root: "./path",
     258 + input: "to/the/file.txt",
     259 + // note: why not expect "path/to/the/file.txt" here?
     260 + // this is because we don't know that the path used to access this path (which is a link within
     261 + // the root) resides within the root. Without this information it appears as if this file resides
     262 + // outside the root.
     263 + expectedRealPath: filepath.Join(absolute, "path/to/the/file.txt"),
     264 + //expectedRealPath: "to/the/file.txt",
     265 + expectedVirtualPath: "to/the/file.txt",
     266 + },
     267 + {
     268 + name: "abs root, relative nested request, direct, cwd within (double) symlink root",
     269 + cwd: relativeViaDoubleLink,
     270 + root: filepath.Join(absoluteViaDoubleLink, "path"),
     271 + input: "to/the/file.txt",
     272 + expectedRealPath: "to/the/file.txt",
     273 + },
     274 + {
     275 + name: "relative root, abs nested request, direct, cwd within (double) symlink root",
     276 + cwd: relativeViaDoubleLink,
     277 + root: "./path",
     278 + input: "/to/the/file.txt",
     279 + // note: why not expect "path/to/the/file.txt" here?
     280 + // this is because we don't know that the path used to access this path (which is a link within
     281 + // the root) resides within the root. Without this information it appears as if this file resides
     282 + // outside the root.
     283 + expectedRealPath: filepath.Join(absolute, "path/to/the/file.txt"),
     284 + //expectedRealPath: "to/the/file.txt",
     285 + expectedVirtualPath: "to/the/file.txt",
     286 + },
     287 + {
     288 + name: "abs root, abs nested request, direct, cwd within (double) symlink root",
     289 + cwd: relativeViaDoubleLink,
     290 + root: filepath.Join(absoluteViaDoubleLink, "path"),
     291 + input: "/to/the/file.txt",
     292 + expectedRealPath: "to/the/file.txt",
     293 + },
     294 + // cwd within DOUBLE symlink root, request nested DEEP within...
     295 + {
     296 + name: "relative root, relative nested request, direct, cwd deep within (double) symlink root",
     297 + cwd: filepath.Join(relativeViaDoubleLink, "path", "to"),
     298 + root: "../",
     299 + input: "to/the/file.txt",
     300 + // note: why not expect "path/to/the/file.txt" here?
     301 + // this is because we don't know that the path used to access this path (which is a link within
     302 + // the root) resides within the root. Without this information it appears as if this file resides
     303 + // outside the root.
     304 + expectedRealPath: filepath.Join(absolute, "path/to/the/file.txt"),
     305 + //expectedRealPath: "to/the/file.txt",
     306 + expectedVirtualPath: "to/the/file.txt",
     307 + },
     308 + {
     309 + name: "abs root, relative nested request, direct, cwd deep within (double) symlink root",
     310 + cwd: filepath.Join(relativeViaDoubleLink, "path", "to"),
     311 + root: filepath.Join(absoluteViaDoubleLink, "path"),
     312 + input: "to/the/file.txt",
     313 + expectedRealPath: "to/the/file.txt",
     314 + },
     315 + {
     316 + name: "relative root, abs nested request, direct, cwd deep within (double) symlink root",
     317 + cwd: filepath.Join(relativeViaDoubleLink, "path", "to"),
     318 + root: "../",
     319 + input: "/to/the/file.txt",
     320 + // note: why not expect "path/to/the/file.txt" here?
     321 + // this is because we don't know that the path used to access this path (which is a link within
     322 + // the root) resides within the root. Without this information it appears as if this file resides
     323 + // outside the root.
     324 + expectedRealPath: filepath.Join(absolute, "path/to/the/file.txt"),
     325 + //expectedRealPath: "to/the/file.txt",
     326 + expectedVirtualPath: "to/the/file.txt",
     327 + },
     328 + {
     329 + name: "abs root, abs nested request, direct, cwd deep within (double) symlink root",
     330 + cwd: filepath.Join(relativeViaDoubleLink, "path", "to"),
     331 + root: filepath.Join(absoluteViaDoubleLink, "path"),
     332 + input: "/to/the/file.txt",
     333 + expectedRealPath: "to/the/file.txt",
     334 + },
     335 + // link to outside of root cases...
     336 + {
     337 + name: "relative root, relative request, abs indirect (outside of root)",
     338 + root: filepath.Join(relative, "path"),
     339 + input: "to/the/abs-outside.txt",
     340 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     341 + expectedVirtualPath: "to/the/abs-outside.txt",
     342 + },
     343 + {
     344 + name: "abs root, relative request, abs indirect (outside of root)",
     345 + root: filepath.Join(absolute, "path"),
     346 + input: "to/the/abs-outside.txt",
     347 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     348 + expectedVirtualPath: "to/the/abs-outside.txt",
     349 + },
     350 + {
     351 + name: "relative root, abs request, abs indirect (outside of root)",
     352 + root: filepath.Join(relative, "path"),
     353 + input: "/to/the/abs-outside.txt",
     354 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     355 + expectedVirtualPath: "to/the/abs-outside.txt",
     356 + },
     357 + {
     358 + name: "abs root, abs request, abs indirect (outside of root)",
     359 + root: filepath.Join(absolute, "path"),
     360 + input: "/to/the/abs-outside.txt",
     361 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     362 + expectedVirtualPath: "to/the/abs-outside.txt",
     363 + },
     364 + {
     365 + name: "relative root, relative request, relative indirect (outside of root)",
     366 + root: filepath.Join(relative, "path"),
     367 + input: "to/the/rel-outside.txt",
     368 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     369 + expectedVirtualPath: "to/the/rel-outside.txt",
     370 + },
     371 + {
     372 + name: "abs root, relative request, relative indirect (outside of root)",
     373 + root: filepath.Join(absolute, "path"),
     374 + input: "to/the/rel-outside.txt",
     375 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     376 + expectedVirtualPath: "to/the/rel-outside.txt",
     377 + },
     378 + {
     379 + name: "relative root, abs request, relative indirect (outside of root)",
     380 + root: filepath.Join(relative, "path"),
     381 + input: "/to/the/rel-outside.txt",
     382 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     383 + expectedVirtualPath: "to/the/rel-outside.txt",
     384 + },
     385 + {
     386 + name: "abs root, abs request, relative indirect (outside of root)",
     387 + root: filepath.Join(absolute, "path"),
     388 + input: "/to/the/rel-outside.txt",
     389 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     390 + expectedVirtualPath: "to/the/rel-outside.txt",
     391 + },
     392 + // link to outside of root cases... cwd within symlink root
     393 + {
     394 + name: "relative root, relative request, abs indirect (outside of root), cwd within symlink root",
     395 + cwd: relativeViaLink,
     396 + root: "path",
     397 + input: "to/the/abs-outside.txt",
     398 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     399 + expectedVirtualPath: "to/the/abs-outside.txt",
     400 + },
     401 + {
     402 + name: "abs root, relative request, abs indirect (outside of root), cwd within symlink root",
     403 + cwd: relativeViaLink,
     404 + root: filepath.Join(absolute, "path"),
     405 + input: "to/the/abs-outside.txt",
     406 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     407 + expectedVirtualPath: "to/the/abs-outside.txt",
     408 + },
     409 + {
     410 + name: "relative root, abs request, abs indirect (outside of root), cwd within symlink root",
     411 + cwd: relativeViaLink,
     412 + root: "path",
     413 + input: "/to/the/abs-outside.txt",
     414 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     415 + expectedVirtualPath: "to/the/abs-outside.txt",
     416 + },
     417 + {
     418 + name: "abs root, abs request, abs indirect (outside of root), cwd within symlink root",
     419 + cwd: relativeViaLink,
     420 + root: filepath.Join(absolute, "path"),
     421 + input: "/to/the/abs-outside.txt",
     422 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     423 + expectedVirtualPath: "to/the/abs-outside.txt",
     424 + },
     425 + {
     426 + name: "relative root, relative request, relative indirect (outside of root), cwd within symlink root",
     427 + cwd: relativeViaLink,
     428 + root: "path",
     429 + input: "to/the/rel-outside.txt",
     430 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     431 + expectedVirtualPath: "to/the/rel-outside.txt",
     432 + },
     433 + {
     434 + name: "abs root, relative request, relative indirect (outside of root), cwd within symlink root",
     435 + cwd: relativeViaLink,
     436 + root: filepath.Join(absolute, "path"),
     437 + input: "to/the/rel-outside.txt",
     438 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     439 + expectedVirtualPath: "to/the/rel-outside.txt",
     440 + },
     441 + {
     442 + name: "relative root, abs request, relative indirect (outside of root), cwd within symlink root",
     443 + cwd: relativeViaLink,
     444 + root: "path",
     445 + input: "/to/the/rel-outside.txt",
     446 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     447 + expectedVirtualPath: "to/the/rel-outside.txt",
     448 + },
     449 + {
     450 + name: "abs root, abs request, relative indirect (outside of root), cwd within symlink root",
     451 + cwd: relativeViaLink,
     452 + root: filepath.Join(absolute, "path"),
     453 + input: "/to/the/rel-outside.txt",
     454 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     455 + expectedVirtualPath: "to/the/rel-outside.txt",
     456 + },
     457 + {
     458 + name: "relative root, relative request, relative indirect (outside of root), cwd within DOUBLE symlink root",
     459 + cwd: relativeViaDoubleLink,
     460 + root: "path",
     461 + input: "to/the/rel-outside.txt",
     462 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     463 + expectedVirtualPath: "to/the/rel-outside.txt",
     464 + },
     465 + {
     466 + name: "abs root, relative request, relative indirect (outside of root), cwd within DOUBLE symlink root",
     467 + cwd: relativeViaDoubleLink,
     468 + root: filepath.Join(absolute, "path"),
     469 + input: "to/the/rel-outside.txt",
     470 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     471 + expectedVirtualPath: "to/the/rel-outside.txt",
     472 + },
     473 + {
     474 + name: "relative root, abs request, relative indirect (outside of root), cwd within DOUBLE symlink root",
     475 + cwd: relativeViaDoubleLink,
     476 + root: "path",
     477 + input: "/to/the/rel-outside.txt",
     478 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     479 + expectedVirtualPath: "to/the/rel-outside.txt",
     480 + },
     481 + {
     482 + name: "abs root, abs request, relative indirect (outside of root), cwd within DOUBLE symlink root",
     483 + cwd: relativeViaDoubleLink,
     484 + root: filepath.Join(absolute, "path"),
     485 + input: "/to/the/rel-outside.txt",
     486 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     487 + expectedVirtualPath: "to/the/rel-outside.txt",
     488 + },
     489 + }
     490 + for _, c := range cases {
     491 + t.Run(c.name, func(t *testing.T) {
     492 + 
     493 + // we need to mimic a shell, otherwise we won't get a path within a symlink
     494 + targetPath := filepath.Join(testDir, c.cwd)
     495 + t.Setenv("PWD", filepath.Clean(targetPath))
     496 + 
     497 + require.NoError(t, err)
     498 + require.NoError(t, os.Chdir(targetPath))
     499 + t.Cleanup(func() {
     500 + require.NoError(t, os.Chdir(testDir))
     501 + })
     502 + 
     503 + resolver, err := NewFromDirectory(c.root, c.base)
     504 + require.NoError(t, err)
     505 + require.NotNil(t, resolver)
     506 + 
     507 + refs, err := resolver.FilesByPath(c.input)
     508 + require.NoError(t, err)
     509 + if c.expectedRealPath == "" {
     510 + require.Empty(t, refs)
     511 + return
     512 + }
     513 + require.Len(t, refs, 1)
     514 + assert.Equal(t, c.expectedRealPath, refs[0].RealPath, "real path different")
     515 + assert.Equal(t, c.expectedVirtualPath, refs[0].VirtualPath, "virtual path different")
     516 + })
     517 + }
     518 +}
     519 + 
    25 520  func TestDirectoryResolver_FilesByPath_relativeRoot(t *testing.T) {
    26 521   cases := []struct {
    27 522   name string
    skipped 927 lines
  • ■ ■ ■ ■ ■
    syft/internal/fileresolver/test-fixtures/req-resp/path/to/rel-inside.txt
     1 +./the/file.txt
  • ■ ■ ■ ■ ■ ■
    syft/internal/fileresolver/test-fixtures/req-resp/path/to/the/file.txt
     1 +file-1
     2 + 
  • ■ ■ ■ ■ ■
    syft/internal/fileresolver/test-fixtures/req-resp/path/to/the/rel-outside.txt
     1 +../../../somewhere/outside.txt
  • ■ ■ ■ ■ ■ ■
    syft/internal/fileresolver/test-fixtures/req-resp/somewhere/outside.txt
     1 +file-2
     2 + 
  • ■ ■ ■ ■ ■ ■
    syft/internal/fileresolver/unindexed_directory_test.go
    skipped 22 lines
    23 23   "github.com/anchore/syft/syft/file"
    24 24  )
    25 25   
     26 +func Test_UnindexDirectoryResolver_RequestRelativePathWithinSymlink(t *testing.T) {
     27 + pwd, err := os.Getwd()
     28 + 
     29 + // we need to mimic a shell, otherwise we won't get a path within a symlink
     30 + targetPath := filepath.Join(pwd, "./test-fixtures/symlinked-root/nested/link-root/nested")
     31 + t.Setenv("PWD", targetPath)
     32 + 
     33 + require.NoError(t, err)
     34 + require.NoError(t, os.Chdir(targetPath))
     35 + t.Cleanup(func() {
     36 + require.NoError(t, os.Chdir(pwd))
     37 + })
     38 + 
     39 + resolver := NewFromUnindexedDirectory("./")
     40 + require.NoError(t, err)
     41 + 
     42 + locations, err := resolver.FilesByPath("file2.txt")
     43 + require.NoError(t, err)
     44 + require.Len(t, locations, 1)
     45 + 
     46 + // TODO: this is technically not correct behavior since this is reporting the symlink path (virtual path) and
     47 + // not the real path.
     48 + require.False(t, filepath.IsAbs(locations[0].RealPath), "should be relative path")
     49 +}
     50 + 
     51 +func Test_UnindexDirectoryResolver_FilesByPath_request_response(t *testing.T) {
     52 + // /
     53 + // somewhere/
     54 + // outside.txt
     55 + // root-link -> ./
     56 + // path/
     57 + // to/
     58 + // abs-inside.txt -> /path/to/the/file.txt # absolute link to somewhere inside of the root
     59 + // rel-inside.txt -> ./the/file.txt # relative link to somewhere inside of the root
     60 + // the/
     61 + // file.txt
     62 + // abs-outside.txt -> /somewhere/outside.txt # absolute link to outside of the root
     63 + // rel-outside -> ../../../somewhere/outside.txt # relative link to outside of the root
     64 + //
     65 + 
     66 + testDir, err := os.Getwd()
     67 + require.NoError(t, err)
     68 + relative := filepath.Join("test-fixtures", "req-resp")
     69 + absolute := filepath.Join(testDir, relative)
     70 + 
     71 + absInsidePath := filepath.Join(absolute, "path", "to", "abs-inside.txt")
     72 + absOutsidePath := filepath.Join(absolute, "path", "to", "the", "abs-outside.txt")
     73 + 
     74 + relativeViaLink := filepath.Join(relative, "root-link")
     75 + absoluteViaLink := filepath.Join(absolute, "root-link")
     76 + 
     77 + relativeViaDoubleLink := filepath.Join(relative, "root-link", "root-link")
     78 + absoluteViaDoubleLink := filepath.Join(absolute, "root-link", "root-link")
     79 + 
     80 + cleanup := func() {
     81 + _ = os.Remove(absInsidePath)
     82 + _ = os.Remove(absOutsidePath)
     83 + }
     84 + 
     85 + // ensure the absolute symlinks are cleaned up from any previous runs
     86 + cleanup()
     87 + 
     88 + require.NoError(t, os.Symlink(filepath.Join(absolute, "path", "to", "the", "file.txt"), absInsidePath))
     89 + require.NoError(t, os.Symlink(filepath.Join(absolute, "somewhere", "outside.txt"), absOutsidePath))
     90 + 
     91 + t.Cleanup(cleanup)
     92 + 
     93 + cases := []struct {
     94 + name string
     95 + cwd string
     96 + root string
     97 + base string
     98 + input string
     99 + expectedRealPath string
     100 + expectedVirtualPath string
     101 + }{
     102 + {
     103 + name: "relative root, relative request, direct",
     104 + root: relative,
     105 + input: "path/to/the/file.txt",
     106 + expectedRealPath: "path/to/the/file.txt",
     107 + },
     108 + {
     109 + name: "abs root, relative request, direct",
     110 + root: absolute,
     111 + input: "path/to/the/file.txt",
     112 + expectedRealPath: "path/to/the/file.txt",
     113 + },
     114 + {
     115 + name: "relative root, abs request, direct",
     116 + root: relative,
     117 + input: "/path/to/the/file.txt",
     118 + expectedRealPath: "path/to/the/file.txt",
     119 + },
     120 + {
     121 + name: "abs root, abs request, direct",
     122 + root: absolute,
     123 + input: "/path/to/the/file.txt",
     124 + expectedRealPath: "path/to/the/file.txt",
     125 + },
     126 + // cwd within root...
     127 + {
     128 + name: "relative root, relative request, direct, cwd within root",
     129 + cwd: filepath.Join(relative, "path/to"),
     130 + root: "../../",
     131 + input: "path/to/the/file.txt",
     132 + expectedRealPath: "path/to/the/file.txt",
     133 + },
     134 + {
     135 + name: "abs root, relative request, direct, cwd within root",
     136 + cwd: filepath.Join(relative, "path/to"),
     137 + root: absolute,
     138 + input: "path/to/the/file.txt",
     139 + expectedRealPath: "path/to/the/file.txt",
     140 + },
     141 + {
     142 + name: "relative root, abs request, direct, cwd within root",
     143 + cwd: filepath.Join(relative, "path/to"),
     144 + root: "../../",
     145 + input: "/path/to/the/file.txt",
     146 + expectedRealPath: "path/to/the/file.txt",
     147 + },
     148 + {
     149 + name: "abs root, abs request, direct, cwd within root",
     150 + cwd: filepath.Join(relative, "path/to"),
     151 + 
     152 + root: absolute,
     153 + input: "/path/to/the/file.txt",
     154 + expectedRealPath: "path/to/the/file.txt",
     155 + },
     156 + // cwd within symlink root...
     157 + {
     158 + name: "relative root, relative request, direct, cwd within symlink root",
     159 + cwd: relativeViaLink,
     160 + root: "./",
     161 + input: "path/to/the/file.txt",
     162 + // note: this is inconsistent with the directory resolver. The real path is essentially the virtual path
     163 + // in this case for the unindexed resolver, which is not correct.
     164 + expectedRealPath: "path/to/the/file.txt",
     165 + },
     166 + {
     167 + name: "abs root, relative request, direct, cwd within symlink root",
     168 + cwd: relativeViaLink,
     169 + root: absoluteViaLink,
     170 + input: "path/to/the/file.txt",
     171 + expectedRealPath: "path/to/the/file.txt",
     172 + },
     173 + {
     174 + name: "relative root, abs request, direct, cwd within symlink root",
     175 + cwd: relativeViaLink,
     176 + root: "./",
     177 + input: "/path/to/the/file.txt",
     178 + // note: this is inconsistent with the directory resolver. The real path is essentially the virtual path
     179 + // in this case for the unindexed resolver, which is not correct.
     180 + expectedRealPath: "path/to/the/file.txt",
     181 + },
     182 + {
     183 + name: "abs root, abs request, direct, cwd within symlink root",
     184 + cwd: relativeViaLink,
     185 + root: absoluteViaLink,
     186 + input: "/path/to/the/file.txt",
     187 + expectedRealPath: "path/to/the/file.txt",
     188 + },
     189 + // cwd within symlink root, request nested within...
     190 + {
     191 + name: "relative root, relative nested request, direct, cwd within symlink root",
     192 + cwd: relativeViaLink,
     193 + root: "./path",
     194 + input: "to/the/file.txt",
     195 + // note: this is inconsistent with the directory resolver. The real path is essentially the virtual path
     196 + // in this case for the unindexed resolver, which is not correct.
     197 + expectedRealPath: "to/the/file.txt",
     198 + },
     199 + {
     200 + name: "abs root, relative nested request, direct, cwd within symlink root",
     201 + cwd: relativeViaLink,
     202 + root: filepath.Join(absoluteViaLink, "path"),
     203 + input: "to/the/file.txt",
     204 + expectedRealPath: "to/the/file.txt",
     205 + },
     206 + {
     207 + name: "relative root, abs nested request, direct, cwd within symlink root",
     208 + cwd: relativeViaLink,
     209 + root: "./path",
     210 + input: "/to/the/file.txt",
     211 + // note: this is inconsistent with the directory resolver. The real path is essentially the virtual path
     212 + // in this case for the unindexed resolver, which is not correct.
     213 + expectedRealPath: "to/the/file.txt",
     214 + },
     215 + {
     216 + name: "abs root, abs nested request, direct, cwd within symlink root",
     217 + cwd: relativeViaLink,
     218 + root: filepath.Join(absoluteViaLink, "path"),
     219 + input: "/to/the/file.txt",
     220 + expectedRealPath: "to/the/file.txt",
     221 + },
     222 + // cwd within DOUBLE symlink root...
     223 + {
     224 + name: "relative root, relative request, direct, cwd within (double) symlink root",
     225 + cwd: relativeViaDoubleLink,
     226 + root: "./",
     227 + input: "path/to/the/file.txt",
     228 + // note: this is inconsistent with the directory resolver. The real path is essentially the virtual path
     229 + // in this case for the unindexed resolver, which is not correct.
     230 + expectedRealPath: "path/to/the/file.txt",
     231 + },
     232 + {
     233 + name: "abs root, relative request, direct, cwd within (double) symlink root",
     234 + cwd: relativeViaDoubleLink,
     235 + root: absoluteViaDoubleLink,
     236 + input: "path/to/the/file.txt",
     237 + expectedRealPath: "path/to/the/file.txt",
     238 + },
     239 + {
     240 + name: "relative root, abs request, direct, cwd within (double) symlink root",
     241 + cwd: relativeViaDoubleLink,
     242 + root: "./",
     243 + input: "/path/to/the/file.txt",
     244 + // note: this is inconsistent with the directory resolver. The real path is essentially the virtual path
     245 + // in this case for the unindexed resolver, which is not correct.
     246 + expectedRealPath: "path/to/the/file.txt",
     247 + },
     248 + {
     249 + name: "abs root, abs request, direct, cwd within (double) symlink root",
     250 + cwd: relativeViaDoubleLink,
     251 + root: absoluteViaDoubleLink,
     252 + input: "/path/to/the/file.txt",
     253 + expectedRealPath: "path/to/the/file.txt",
     254 + },
     255 + // cwd within DOUBLE symlink root, request nested within...
     256 + {
     257 + name: "relative root, relative nested request, direct, cwd within (double) symlink root",
     258 + cwd: relativeViaDoubleLink,
     259 + root: "./path",
     260 + input: "to/the/file.txt",
     261 + // note: this is inconsistent with the directory resolver. The real path is essentially the virtual path
     262 + // in this case for the unindexed resolver, which is not correct.
     263 + expectedRealPath: "to/the/file.txt",
     264 + },
     265 + {
     266 + name: "abs root, relative nested request, direct, cwd within (double) symlink root",
     267 + cwd: relativeViaDoubleLink,
     268 + root: filepath.Join(absoluteViaDoubleLink, "path"),
     269 + input: "to/the/file.txt",
     270 + expectedRealPath: "to/the/file.txt",
     271 + },
     272 + {
     273 + name: "relative root, abs nested request, direct, cwd within (double) symlink root",
     274 + cwd: relativeViaDoubleLink,
     275 + root: "./path",
     276 + input: "/to/the/file.txt",
     277 + // note: this is inconsistent with the directory resolver. The real path is essentially the virtual path
     278 + // in this case for the unindexed resolver, which is not correct.
     279 + expectedRealPath: "to/the/file.txt",
     280 + },
     281 + {
     282 + name: "abs root, abs nested request, direct, cwd within (double) symlink root",
     283 + cwd: relativeViaDoubleLink,
     284 + root: filepath.Join(absoluteViaDoubleLink, "path"),
     285 + input: "/to/the/file.txt",
     286 + expectedRealPath: "to/the/file.txt",
     287 + },
     288 + // cwd within DOUBLE symlink root, request nested DEEP within...
     289 + {
     290 + name: "relative root, relative nested request, direct, cwd deep within (double) symlink root",
     291 + cwd: filepath.Join(relativeViaDoubleLink, "path", "to"),
     292 + root: "../",
     293 + input: "to/the/file.txt",
     294 + // note: this is inconsistent with the directory resolver. The real path is essentially the virtual path
     295 + // in this case for the unindexed resolver, which is not correct.
     296 + expectedRealPath: "to/the/file.txt",
     297 + },
     298 + {
     299 + name: "abs root, relative nested request, direct, cwd deep within (double) symlink root",
     300 + cwd: filepath.Join(relativeViaDoubleLink, "path", "to"),
     301 + root: filepath.Join(absoluteViaDoubleLink, "path"),
     302 + input: "to/the/file.txt",
     303 + expectedRealPath: "to/the/file.txt",
     304 + },
     305 + {
     306 + name: "relative root, abs nested request, direct, cwd deep within (double) symlink root",
     307 + cwd: filepath.Join(relativeViaDoubleLink, "path", "to"),
     308 + root: "../",
     309 + input: "/to/the/file.txt",
     310 + // note: this is inconsistent with the directory resolver. The real path is essentially the virtual path
     311 + // in this case for the unindexed resolver, which is not correct.
     312 + expectedRealPath: "to/the/file.txt",
     313 + },
     314 + {
     315 + name: "abs root, abs nested request, direct, cwd deep within (double) symlink root",
     316 + cwd: filepath.Join(relativeViaDoubleLink, "path", "to"),
     317 + root: filepath.Join(absoluteViaDoubleLink, "path"),
     318 + input: "/to/the/file.txt",
     319 + expectedRealPath: "to/the/file.txt",
     320 + },
     321 + // link to outside of root cases...
     322 + {
     323 + name: "relative root, relative request, abs indirect (outside of root)",
     324 + root: filepath.Join(relative, "path"),
     325 + input: "to/the/abs-outside.txt",
     326 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     327 + expectedVirtualPath: "to/the/abs-outside.txt",
     328 + },
     329 + {
     330 + name: "abs root, relative request, abs indirect (outside of root)",
     331 + root: filepath.Join(absolute, "path"),
     332 + input: "to/the/abs-outside.txt",
     333 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     334 + expectedVirtualPath: "to/the/abs-outside.txt",
     335 + },
     336 + {
     337 + name: "relative root, abs request, abs indirect (outside of root)",
     338 + root: filepath.Join(relative, "path"),
     339 + input: "/to/the/abs-outside.txt",
     340 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     341 + expectedVirtualPath: "to/the/abs-outside.txt",
     342 + },
     343 + {
     344 + name: "abs root, abs request, abs indirect (outside of root)",
     345 + root: filepath.Join(absolute, "path"),
     346 + input: "/to/the/abs-outside.txt",
     347 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     348 + expectedVirtualPath: "to/the/abs-outside.txt",
     349 + },
     350 + {
     351 + name: "relative root, relative request, relative indirect (outside of root)",
     352 + root: filepath.Join(relative, "path"),
     353 + input: "to/the/rel-outside.txt",
     354 + //expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     355 + // TODO: the real path is not correct
     356 + expectedRealPath: "../somewhere/outside.txt",
     357 + expectedVirtualPath: "to/the/rel-outside.txt",
     358 + },
     359 + {
     360 + name: "abs root, relative request, relative indirect (outside of root)",
     361 + root: filepath.Join(absolute, "path"),
     362 + input: "to/the/rel-outside.txt",
     363 + //expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     364 + // TODO: the real path is not correct
     365 + expectedRealPath: "../somewhere/outside.txt",
     366 + expectedVirtualPath: "to/the/rel-outside.txt",
     367 + },
     368 + {
     369 + name: "relative root, abs request, relative indirect (outside of root)",
     370 + root: filepath.Join(relative, "path"),
     371 + input: "/to/the/rel-outside.txt",
     372 + //expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     373 + // TODO: the real path is not correct
     374 + expectedRealPath: "../somewhere/outside.txt",
     375 + expectedVirtualPath: "to/the/rel-outside.txt",
     376 + },
     377 + {
     378 + name: "abs root, abs request, relative indirect (outside of root)",
     379 + root: filepath.Join(absolute, "path"),
     380 + input: "/to/the/rel-outside.txt",
     381 + //expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     382 + // TODO: the real path is not correct
     383 + expectedRealPath: "../somewhere/outside.txt",
     384 + expectedVirtualPath: "to/the/rel-outside.txt",
     385 + },
     386 + // link to outside of root cases... cwd within symlink root
     387 + {
     388 + name: "relative root, relative request, abs indirect (outside of root), cwd within symlink root",
     389 + cwd: relativeViaLink,
     390 + root: "path",
     391 + input: "to/the/abs-outside.txt",
     392 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     393 + expectedVirtualPath: "to/the/abs-outside.txt",
     394 + },
     395 + {
     396 + name: "abs root, relative request, abs indirect (outside of root), cwd within symlink root",
     397 + cwd: relativeViaLink,
     398 + root: filepath.Join(absolute, "path"),
     399 + input: "to/the/abs-outside.txt",
     400 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     401 + expectedVirtualPath: "to/the/abs-outside.txt",
     402 + },
     403 + {
     404 + name: "relative root, abs request, abs indirect (outside of root), cwd within symlink root",
     405 + cwd: relativeViaLink,
     406 + root: "path",
     407 + input: "/to/the/abs-outside.txt",
     408 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     409 + expectedVirtualPath: "to/the/abs-outside.txt",
     410 + },
     411 + {
     412 + name: "abs root, abs request, abs indirect (outside of root), cwd within symlink root",
     413 + cwd: relativeViaLink,
     414 + root: filepath.Join(absolute, "path"),
     415 + input: "/to/the/abs-outside.txt",
     416 + expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     417 + expectedVirtualPath: "to/the/abs-outside.txt",
     418 + },
     419 + {
     420 + name: "relative root, relative request, relative indirect (outside of root), cwd within symlink root",
     421 + cwd: relativeViaLink,
     422 + root: "path",
     423 + input: "to/the/rel-outside.txt",
     424 + //expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     425 + // TODO: the real path is not correct
     426 + expectedRealPath: "../somewhere/outside.txt",
     427 + expectedVirtualPath: "to/the/rel-outside.txt",
     428 + },
     429 + {
     430 + name: "abs root, relative request, relative indirect (outside of root), cwd within symlink root",
     431 + cwd: relativeViaLink,
     432 + root: filepath.Join(absolute, "path"),
     433 + input: "to/the/rel-outside.txt",
     434 + //expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     435 + // TODO: the real path is not correct
     436 + expectedRealPath: "../somewhere/outside.txt",
     437 + expectedVirtualPath: "to/the/rel-outside.txt",
     438 + },
     439 + {
     440 + name: "relative root, abs request, relative indirect (outside of root), cwd within symlink root",
     441 + cwd: relativeViaLink,
     442 + root: "path",
     443 + input: "/to/the/rel-outside.txt",
     444 + //expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     445 + // TODO: the real path is not correct
     446 + expectedRealPath: "../somewhere/outside.txt",
     447 + expectedVirtualPath: "to/the/rel-outside.txt",
     448 + },
     449 + {
     450 + name: "abs root, abs request, relative indirect (outside of root), cwd within symlink root",
     451 + cwd: relativeViaLink,
     452 + root: filepath.Join(absolute, "path"),
     453 + input: "/to/the/rel-outside.txt",
     454 + //expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     455 + // TODO: the real path is not correct
     456 + expectedRealPath: "../somewhere/outside.txt",
     457 + expectedVirtualPath: "to/the/rel-outside.txt",
     458 + },
     459 + {
     460 + name: "relative root, relative request, relative indirect (outside of root), cwd within DOUBLE symlink root",
     461 + cwd: relativeViaDoubleLink,
     462 + root: "path",
     463 + input: "to/the/rel-outside.txt",
     464 + //expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     465 + // TODO: the real path is not correct
     466 + expectedRealPath: "../somewhere/outside.txt",
     467 + expectedVirtualPath: "to/the/rel-outside.txt",
     468 + },
     469 + {
     470 + name: "abs root, relative request, relative indirect (outside of root), cwd within DOUBLE symlink root",
     471 + cwd: relativeViaDoubleLink,
     472 + root: filepath.Join(absolute, "path"),
     473 + input: "to/the/rel-outside.txt",
     474 + //expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     475 + // TODO: the real path is not correct
     476 + expectedRealPath: "../somewhere/outside.txt",
     477 + expectedVirtualPath: "to/the/rel-outside.txt",
     478 + },
     479 + {
     480 + name: "relative root, abs request, relative indirect (outside of root), cwd within DOUBLE symlink root",
     481 + cwd: relativeViaDoubleLink,
     482 + root: "path",
     483 + input: "/to/the/rel-outside.txt",
     484 + //expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     485 + // TODO: the real path is not correct
     486 + expectedRealPath: "../somewhere/outside.txt",
     487 + expectedVirtualPath: "to/the/rel-outside.txt",
     488 + },
     489 + {
     490 + name: "abs root, abs request, relative indirect (outside of root), cwd within DOUBLE symlink root",
     491 + cwd: relativeViaDoubleLink,
     492 + root: filepath.Join(absolute, "path"),
     493 + input: "/to/the/rel-outside.txt",
     494 + //expectedRealPath: filepath.Join(absolute, "/somewhere/outside.txt"),
     495 + // TODO: the real path is not correct
     496 + expectedRealPath: "../somewhere/outside.txt",
     497 + expectedVirtualPath: "to/the/rel-outside.txt",
     498 + },
     499 + }
     500 + for _, c := range cases {
     501 + t.Run(c.name, func(t *testing.T) {
     502 + 
     503 + // we need to mimic a shell, otherwise we won't get a path within a symlink
     504 + targetPath := filepath.Join(testDir, c.cwd)
     505 + t.Setenv("PWD", filepath.Clean(targetPath))
     506 + 
     507 + require.NoError(t, err)
     508 + require.NoError(t, os.Chdir(targetPath))
     509 + t.Cleanup(func() {
     510 + require.NoError(t, os.Chdir(testDir))
     511 + })
     512 + 
     513 + resolver := NewFromUnindexedDirectory(c.root)
     514 + require.NotNil(t, resolver)
     515 + 
     516 + refs, err := resolver.FilesByPath(c.input)
     517 + require.NoError(t, err)
     518 + if c.expectedRealPath == "" {
     519 + require.Empty(t, refs)
     520 + return
     521 + }
     522 + require.Len(t, refs, 1)
     523 + assert.Equal(t, c.expectedRealPath, refs[0].RealPath, "real path different")
     524 + assert.Equal(t, c.expectedVirtualPath, refs[0].VirtualPath, "virtual path different")
     525 + })
     526 + }
     527 +}
     528 + 
    26 529  func Test_UnindexedDirectoryResolver_Basic(t *testing.T) {
    27 530   wd, err := os.Getwd()
    28 531   require.NoError(t, err)
    skipped 755 lines
  • ■ ■ ■ ■ ■
    syft/pkg/cataloger/kernel/cataloger_test.go
    skipped 6 lines
    7 7   "github.com/anchore/syft/syft/file"
    8 8   "github.com/anchore/syft/syft/pkg"
    9 9   "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
    10  - "github.com/anchore/syft/syft/source"
    11 10  )
    12 11   
    13 12  func Test_KernelCataloger(t *testing.T) {
    skipped 36 lines
    50 49   ),
    51 50   Licenses: pkg.NewLicenseSet(
    52 51   pkg.NewLicenseFromLocations("GPL v2",
    53  - source.NewVirtualLocation(
     52 + file.NewVirtualLocation(
    54 53   "/lib/modules/6.0.7-301.fc37.x86_64/kernel/drivers/tty/ttynull.ko",
    55 54   "/lib/modules/6.0.7-301.fc37.x86_64/kernel/drivers/tty/ttynull.ko",
    56 55   ),
    skipped 43 lines
  • ■ ■ ■ ■ ■ ■
    syft/pkg/license_set_test.go
    skipped 7 lines
    8 8   "github.com/anchore/syft/internal"
    9 9   "github.com/anchore/syft/syft/file"
    10 10   "github.com/anchore/syft/syft/license"
    11  - "github.com/anchore/syft/syft/source"
    12 11  )
    13 12   
    14 13  func TestLicenseSet_Add(t *testing.T) {
    skipped 44 lines
    59 58   {
    60 59   name: "deduplicate licenses with locations",
    61 60   licenses: []License{
    62  - NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(source.Coordinates{RealPath: "/place", FileSystemID: "1"})),
    63  - NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(source.Coordinates{RealPath: "/place", FileSystemID: "1"})),
    64  - NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(source.Coordinates{RealPath: "/place", FileSystemID: "2"})),
     61 + NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"})),
     62 + NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"})),
     63 + NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "2"})),
    65 64   },
    66 65   want: []License{
    67 66   NewLicenseFromLocations(
    68 67   "MIT",
    69  - file.NewLocationFromCoordinates(source.Coordinates{RealPath: "/place", FileSystemID: "1"}),
    70  - file.NewLocationFromCoordinates(source.Coordinates{RealPath: "/place", FileSystemID: "2"}),
     68 + file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"}),
     69 + file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "2"}),
    71 70   ),
    72 71   },
    73 72   },
    skipped 1 lines
    75 74   name: "same licenses with different locations",
    76 75   licenses: []License{
    77 76   NewLicense("MIT"),
    78  - NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(source.Coordinates{RealPath: "/place", FileSystemID: "2"})),
    79  - NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(source.Coordinates{RealPath: "/place", FileSystemID: "1"})),
     77 + NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "2"})),
     78 + NewLicenseFromLocations("MIT", file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"})),
    80 79   },
    81 80   want: []License{
    82 81   NewLicenseFromLocations(
    83 82   "MIT",
    84  - file.NewLocationFromCoordinates(source.Coordinates{RealPath: "/place", FileSystemID: "1"}),
    85  - file.NewLocationFromCoordinates(source.Coordinates{RealPath: "/place", FileSystemID: "2"}),
     83 + file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "1"}),
     84 + file.NewLocationFromCoordinates(file.Coordinates{RealPath: "/place", FileSystemID: "2"}),
    86 85   ),
    87 86   },
    88 87   },
    skipped 53 lines
Please wait...
Page is in error, reload to recover