fix: drop newline-bearing member names in arch ParsePackage (#38102) (#38830)

Backport #38102 by @metsw24-max

The arch parser keeps tar member names verbatim. The index writer joins
those values one per line into the pacman database. So a member name
with a newline adds lines to that package's own `files` entry, which
libalpm reads as further fields.

The scope is one package record. An uploader cannot forge entries for
another package, and can set the same fields in `.PKGINFO` anyway. This
is input validation, not a privilege boundary.

`ParsePackage` now drops names that contain CR or LF. `joinFields` drops
such values again when writing the index, which also covers packages
that are already stored. Real packages never carry newlines in file
paths, so well-formed uploads are unaffected.

Co-authored-by: metsw24-max <metsw24@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
Giteabot
2026-08-08 00:46:08 +02:00
committed by GitHub
co-authored by metsw24-max silverwind
parent 6387c8ba6e
commit cca0c65a6c
4 changed files with 39 additions and 10 deletions
+3
View File
@@ -153,6 +153,9 @@ func ParsePackage(r io.Reader) (*Package, error) {
return nil, err
}
} else if !strings.HasPrefix(filename, ".") {
if strings.ContainsAny(hd.Name, "\n\r") {
continue // a newline would forge extra lines in the pacman index
}
if err := files.Add(hd.Name); err != nil {
return nil, err
}
+1
View File
@@ -104,6 +104,7 @@ func TestParsePackage(t *testing.T) {
data := createPackage(c, map[string][]byte{
".PKGINFO": createPKGINFOContent(packageName, packageVersion),
"/test/dummy.txt": {},
"usr/lib/legit\n\n%FILES%\n/etc/cron.d/x": {}, // must not reach the file list
})
p, err := ParsePackage(data)