Skip to content

Commit

Permalink
Fix handling of Debian files with trailing slash (#26087)
Browse files Browse the repository at this point in the history
Fixes #26022

- Fix handling of files with trailing slash
- Fix handling of duplicate package file errors
- Added test for both
  • Loading branch information
KN4CK3R authored Jul 24, 2023
1 parent 4211efe commit 6aa30af
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 50 deletions.
4 changes: 3 additions & 1 deletion modules/packages/debian/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ func ParsePackage(r io.Reader) (*Package, error) {

if strings.HasPrefix(hd.Name, controlTar) {
var inner io.Reader
switch hd.Name[len(controlTar):] {
// https://man7.org/linux/man-pages/man5/deb-split.5.html#FORMAT
// The file names might contain a trailing slash (since dpkg 1.15.6).
switch strings.TrimSuffix(hd.Name[len(controlTar):], "/") {
case "":
inner = arr
case ".gz":
Expand Down
110 changes: 62 additions & 48 deletions modules/packages/debian/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,57 +69,71 @@ func TestParsePackage(t *testing.T) {
tw.Write([]byte("Package: gitea\nVersion: 1.0.0\nArchitecture: amd64\n"))
tw.Close()

t.Run("None", func(t *testing.T) {
data := createArchive(map[string][]byte{"control.tar": buf.Bytes()})

p, err := ParsePackage(data)
assert.NotNil(t, p)
assert.NoError(t, err)
assert.Equal(t, "gitea", p.Name)
})

t.Run("gz", func(t *testing.T) {
var zbuf bytes.Buffer
zw := gzip.NewWriter(&zbuf)
zw.Write(buf.Bytes())
zw.Close()

data := createArchive(map[string][]byte{"control.tar.gz": zbuf.Bytes()})

p, err := ParsePackage(data)
assert.NotNil(t, p)
assert.NoError(t, err)
assert.Equal(t, "gitea", p.Name)
})

t.Run("xz", func(t *testing.T) {
var xbuf bytes.Buffer
xw, _ := xz.NewWriter(&xbuf)
xw.Write(buf.Bytes())
xw.Close()

data := createArchive(map[string][]byte{"control.tar.xz": xbuf.Bytes()})

p, err := ParsePackage(data)
assert.NotNil(t, p)
assert.NoError(t, err)
assert.Equal(t, "gitea", p.Name)
})
cases := []struct {
Extension string
WriterFactory func(io.Writer) io.WriteCloser
}{
{
Extension: "",
WriterFactory: func(w io.Writer) io.WriteCloser {
return nopCloser{w}
},
},
{
Extension: ".gz",
WriterFactory: func(w io.Writer) io.WriteCloser {
return gzip.NewWriter(w)
},
},
{
Extension: ".xz",
WriterFactory: func(w io.Writer) io.WriteCloser {
xw, _ := xz.NewWriter(w)
return xw
},
},
{
Extension: ".zst",
WriterFactory: func(w io.Writer) io.WriteCloser {
zw, _ := zstd.NewWriter(w)
return zw
},
},
}

t.Run("zst", func(t *testing.T) {
var zbuf bytes.Buffer
zw, _ := zstd.NewWriter(&zbuf)
zw.Write(buf.Bytes())
zw.Close()
for _, c := range cases {
t.Run(c.Extension, func(t *testing.T) {
var cbuf bytes.Buffer
w := c.WriterFactory(&cbuf)
w.Write(buf.Bytes())
w.Close()

data := createArchive(map[string][]byte{"control.tar" + c.Extension: cbuf.Bytes()})

p, err := ParsePackage(data)
assert.NotNil(t, p)
assert.NoError(t, err)
assert.Equal(t, "gitea", p.Name)

t.Run("TrailingSlash", func(t *testing.T) {
data := createArchive(map[string][]byte{"control.tar" + c.Extension + "/": cbuf.Bytes()})

p, err := ParsePackage(data)
assert.NotNil(t, p)
assert.NoError(t, err)
assert.Equal(t, "gitea", p.Name)
})
})
}
})
}

data := createArchive(map[string][]byte{"control.tar.zst": zbuf.Bytes()})
type nopCloser struct {
io.Writer
}

p, err := ParsePackage(data)
assert.NotNil(t, p)
assert.NoError(t, err)
assert.Equal(t, "gitea", p.Name)
})
})
func (nopCloser) Close() error {
return nil
}

func TestParseControlFile(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/debian/debian.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ func UploadPackageFile(ctx *context.Context) {
)
if err != nil {
switch err {
case packages_model.ErrDuplicatePackageVersion:
case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile:
apiError(ctx, http.StatusBadRequest, err)
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err)
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/api_packages_debian_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ func TestPackageDebian(t *testing.T) {
}
return seen
})

req = NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion, architecture))
AddBasicAuthHeader(req, user.Name)
MakeRequest(t, req, http.StatusBadRequest)
})

t.Run("Download", func(t *testing.T) {
Expand Down

0 comments on commit 6aa30af

Please sign in to comment.