Conversation
6b30fc3 to
20764b2
Compare
|
Also, the new test file needs the license header the rest of the repo carries. |
memfs.Lstat delegated to getNode, which resolves symlinks in every path component including the last one, so Lstat on a symlink returned the target's FileInfo and the ModeSymlink bit was never set. getNode keeps Stat semantics and Lstat now stops at a final symlink, matching lstat(2). The install path is what makes that reachable. The tar.TypeDir case accepts a path that already exists as a symlink to a directory, but it asked Stat for the mode, and Stat resolves the final component, so it could never observe ModeSymlink: every such path fell through to MkdirAll instead. Ask Lstat for the entry itself and keep Stat for the target, which still has to be a directory. The Stat call that decides whether the directory already existed, and therefore whether its metadata gets set below, is left alone. Whether the symlink survives is not enough to pin this down, since MkdirAll over a path that already resolves to a directory is a no-op in memory, so the test records whether MkdirAll is reached at all. Fixes chainguard-dev#1543 Signed-off-by: Eljees <3.14hell@gmail.com>
20764b2 to
51083b5
Compare
|
Both points addressed, and you were right that the PR did not reach what #1543 is about. The The test needed a second look. My first version only asserted that the symlink survived, and it passed with What the branch actually decides is whether and with The license header is on Also rebased onto current |
Upstream added TestLazilyInstallAPKFilesRejectsOutOfRangeOwner at the end of pkg/apk/apk/install_test.go, where this branch had already added TestInstallAPKFilesKeepsSymlinkToDirectory. Both tests are kept; nothing else in the merge needed a decision. Signed-off-by: Eljees <57435526+Eljees@users.noreply.github.com>
Fixes #1543.
memfs.LstatcalledgetNode, which resolves symlinks in every path component including the last one. SoLstaton a path that is itself a symlink returned the target'sFileInfoand never set theModeSymlinkbit — exactly the caveat spelled out in the comment that used to sit aboveLstat. Any caller that checks "is this already a symlink?" before replacing it therefore saw a regular file, which is what the issue reports.getNodeCountLinksnow takes afollowFinalflag.getNode(and thereforeStat) passestrueand behaves exactly as before;Lstatgoes through a variant that passesfalse, so a symlink in the final component is returned as itself while intermediate components are still resolved — POSIXlstat(2)semantics. Symlink targets encountered during resolution are always followed fully, regardless of the outer call.Three tests in
pkg/apk/fs/memfs_lstat_test.go:Lstaton a symlink reportsModeSymlink— fails onmain, passes here;Staton the same path still resolves to the target (mode and size), so the existing behaviour is pinned;Lstaton a regular file reached through an intermediate directory symlink (/usr/lib64 -> lib) still resolves that intermediate component and does not report a symlink.go test ./pkg/apk/fs/...,go vetandgofmtare clean.