cmd/kgz: linter fixes.

This commit is contained in:
2025-11-18 18:55:58 -08:00
parent e30e3e9b75
commit 25a562865c

View File

@@ -8,12 +8,14 @@ import (
"flag" "flag"
"fmt" "fmt"
"io" "io"
"math"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
goutilslib "git.wntrmute.dev/kyle/goutils/lib"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
goutilslib "git.wntrmute.dev/kyle/goutils/lib"
) )
const gzipExt = ".gz" const gzipExt = ".gz"
@@ -59,16 +61,61 @@ func buildKGExtra(uid, gid, mode uint32, ctimeS int64, ctimeNs int32) []byte {
} }
// Wrap in gzip subfield: [ID1 ID2 LEN(lo) LEN(hi) PAYLOAD] // Wrap in gzip subfield: [ID1 ID2 LEN(lo) LEN(hi) PAYLOAD]
// Guard against payload length overflow to uint16 for the extra subfield length.
if len(payload) > int(math.MaxUint16) {
return nil
}
extra := make([]byte, 4+len(payload)) extra := make([]byte, 4+len(payload))
extra[0] = kgzExtraID[0] extra[0] = kgzExtraID[0]
extra[1] = kgzExtraID[1] extra[1] = kgzExtraID[1]
binary.LittleEndian.PutUint16(extra[2:], uint16(len(payload))) binary.LittleEndian.PutUint16(extra[2:], uint16(len(payload)&0xFFFF)) //#nosec G115 - masked
copy(extra[4:], payload) copy(extra[4:], payload)
return extra return extra
} }
// clampToInt32 clamps an int value into the int32 range using a switch to
// satisfy linters that prefer switch over if-else chains for ordered checks.
func clampToInt32(v int) int32 {
switch {
case v > int(math.MaxInt32):
return math.MaxInt32
case v < int(math.MinInt32):
return math.MinInt32
default:
return int32(v)
}
}
// buildExtraForPath prepares the gzip Extra field for kgz by collecting
// uid/gid/mode and ctime information, applying any overrides, and encoding it.
func buildExtraForPath(st unix.Stat_t, path string, setUID, setGID int) []byte {
uid := st.Uid
gid := st.Gid
if setUID >= 0 {
if uint64(setUID) <= math.MaxUint32 {
uid = uint32(setUID & 0xFFFFFFFF) //#nosec G115 - masked
}
}
if setGID >= 0 {
if uint64(setGID) <= math.MaxUint32 {
gid = uint32(setGID & 0xFFFFFFFF) //#nosec G115 - masked
}
}
mode := uint32(st.Mode & 0o7777)
// Use portable helper to gather ctime
var cts int64
var ctns int32
if ft, err := goutilslib.LoadFileTime(path); err == nil {
cts = ft.Changed.Unix()
ctns = clampToInt32(ft.Changed.Nanosecond())
}
return buildKGExtra(uid, gid, mode, cts, ctns)
}
// parseKGExtra scans a gzip Extra blob and returns kgz metadata if present. // parseKGExtra scans a gzip Extra blob and returns kgz metadata if present.
func parseKGExtra(extra []byte) (uid, gid, mode uint32, ctimeS int64, ctimeNs int32, ok bool) { func parseKGExtra(extra []byte) (uint32, uint32, uint32, int64, int32, bool) {
i := 0 i := 0
for i+4 <= len(extra) { for i+4 <= len(extra) {
id1 := extra[i] id1 := extra[i]
@@ -95,7 +142,16 @@ func parseKGExtra(extra []byte) (uid, gid, mode uint32, ctimeS int64, ctimeNs in
if s.Version != 1 { if s.Version != 1 {
return 0, 0, 0, 0, 0, false return 0, 0, 0, 0, 0, false
} }
return uint32(s.UID), uint32(s.GID), uint32(s.Mode), s.CTimeSec, s.CTimeNSec, true // Validate ranges before converting from int -> uint32 to avoid overflow.
if s.UID < 0 || s.GID < 0 || s.Mode < 0 {
return 0, 0, 0, 0, 0, false
}
if uint64(s.UID) > math.MaxUint32 || uint64(s.GID) > math.MaxUint32 || uint64(s.Mode) > math.MaxUint32 {
return 0, 0, 0, 0, 0, false
}
return uint32(s.UID & 0xFFFFFFFF), uint32(s.GID & 0xFFFFFFFF),
uint32(s.Mode & 0xFFFFFFFF), s.CTimeSec, s.CTimeNSec, true //#nosec G115 - masked
} }
i += l i += l
} }
@@ -111,7 +167,7 @@ func compress(path, target string, level int, includeExtra bool, setUID, setGID
// Gather file metadata // Gather file metadata
var st unix.Stat_t var st unix.Stat_t
if err := unix.Stat(path, &st); err != nil { if err = unix.Stat(path, &st); err != nil {
return fmt.Errorf("stat source: %w", err) return fmt.Errorf("stat source: %w", err)
} }
fi, err := sourceFile.Stat() fi, err := sourceFile.Stat()
@@ -132,23 +188,7 @@ func compress(path, target string, level int, includeExtra bool, setUID, setGID
// Set header metadata // Set header metadata
gzipCompressor.ModTime = fi.ModTime() gzipCompressor.ModTime = fi.ModTime()
if includeExtra { if includeExtra {
uid := uint32(st.Uid) gzipCompressor.Extra = buildExtraForPath(st, path, setUID, setGID)
gid := uint32(st.Gid)
if setUID >= 0 {
uid = uint32(setUID)
}
if setGID >= 0 {
gid = uint32(setGID)
}
mode := uint32(st.Mode & 0o7777)
// Use portable helper to gather ctime
var cts int64
var ctns int32
if ft, err := goutilslib.LoadFileTime(path); err == nil {
cts = ft.Changed.Unix()
ctns = int32(ft.Changed.Nanosecond())
}
gzipCompressor.Extra = buildKGExtra(uid, gid, mode, cts, ctns)
} }
defer gzipCompressor.Close() defer gzipCompressor.Close()