mirror of
https://github.com/goreleaser/nfpm
synced 2026-10-16 05:03:55 +02:00
* fix(ipk): normalize file modes before writing tar headers
The `type: tree` walk in files.PrepareForPackager stores the raw
fs.FileMode in Content.FileInfo.Mode, so a walked directory also carries
fs.ModeDir (bit 31). Writing that value straight into a tar header makes
archive/tar switch just that header to GNU format with base-256 (binary)
numeric encoding, because 0x800001ED does not fit the 7-digit octal mode
field.
Raw mode field for a walked directory, before this change:
name='./usr/share/doc/sub/' mode = 80 00 00 00 80 00 01 ed (base-256)
and after:
name='./usr/share/doc/sub/' mode = 0000755 (octal ASCII)
This is the ipk half of the same defect that #1113 fixed for apk. The
apk packager keeps a normalizeFileMode helper and a table test for it;
ipk never got one. deb already masks with fm & 0o7777, and rpm normalizes
in normalizeFileMode, so ipk was the last packager writing the raw value.
Two call sites are affected:
- ipk/ipk.go, the TypeDir/TypeImplicitDir branch
- ipk/tar.go, writeFile, which overrode tar.FileInfoHeader's Perm()
masking with an unmasked int64(file.Mode())
Special bits are preserved from both the Go flags (fs.ModeSetuid,
fs.ModeSetgid, fs.ModeSticky) and the traditional octal positions, so
this does not regress the setuid support the writeFile comment calls out.
Tests:
- TestIPKTreeDirectoryModeIsNotBase256 builds a tree package and reads
the data.tar.gz headers back, asserting permission bits only and
that the mode field is not base-256
- TestNormalizeIPKFileMode is the conversion table test
- TestIPKTreePreservesSpecialModeBits guards the setuid/setgid
direction, configuring the mode explicitly since filesystems with
nosuid drop the bit on chmod
go test ./... -count=1, go vet ./... and go test ./ipk/ -race all pass.
* test(ipk): derive expected tree modes from disk, not hardcoded 0o755
TestIPKTreeDirectoryModeIsNotBase256 hardcoded 0o755/0o644 for the walked
tree entries, but os.MkdirAll and os.WriteFile are masked by the process
umask. Under a restrictive umask (0o077) the directory lands on disk as
0o700 and the test failed on the mode assertion instead of on the
base-256 header encoding it is meant to cover:
expected: int(493)
actual : int64(448)
Stat the source entries and mask by info.Umask, matching how the apk
packager asserts the same invariant. The fix under test is unaffected:
with the old call sites restored the test still fails with actual
0x80000000, which is the fs.ModeDir bit the normalization removes.
---------
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
Co-authored-by: Yunare Maia <yunaremaia@users.noreply.github.com>
Co-authored-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: cb68ab4e-96d3-4658-a1c0-c2c33e8c52a0