mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 00:20:25 +08:00 
			
		
		
		
	Fix handling of Debian files with trailing slash (#26087)
Fixes #26022 - Fix handling of files with trailing slash - Fix handling of duplicate package file errors - Added test for both
This commit is contained in:
		@@ -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":
 | 
			
		||||
 
 | 
			
		||||
@@ -69,59 +69,73 @@ 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()})
 | 
			
		||||
		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
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
			p, err := ParsePackage(data)
 | 
			
		||||
			assert.NotNil(t, p)
 | 
			
		||||
			assert.NoError(t, err)
 | 
			
		||||
			assert.Equal(t, "gitea", p.Name)
 | 
			
		||||
		})
 | 
			
		||||
		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()
 | 
			
		||||
 | 
			
		||||
		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" + c.Extension: cbuf.Bytes()})
 | 
			
		||||
 | 
			
		||||
			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)
 | 
			
		||||
 | 
			
		||||
			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()})
 | 
			
		||||
 | 
			
		||||
		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)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		t.Run("zst", func(t *testing.T) {
 | 
			
		||||
			var zbuf bytes.Buffer
 | 
			
		||||
			zw, _ := zstd.NewWriter(&zbuf)
 | 
			
		||||
			zw.Write(buf.Bytes())
 | 
			
		||||
			zw.Close()
 | 
			
		||||
 | 
			
		||||
			data := createArchive(map[string][]byte{"control.tar.zst": zbuf.Bytes()})
 | 
			
		||||
 | 
			
		||||
			p, err := ParsePackage(data)
 | 
			
		||||
			assert.NotNil(t, p)
 | 
			
		||||
			assert.NoError(t, err)
 | 
			
		||||
			assert.Equal(t, "gitea", p.Name)
 | 
			
		||||
		})
 | 
			
		||||
					p, err := ParsePackage(data)
 | 
			
		||||
					assert.NotNil(t, p)
 | 
			
		||||
					assert.NoError(t, err)
 | 
			
		||||
					assert.Equal(t, "gitea", p.Name)
 | 
			
		||||
				})
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type nopCloser struct {
 | 
			
		||||
	io.Writer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (nopCloser) Close() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestParseControlFile(t *testing.T) {
 | 
			
		||||
	buildContent := func(name, version, architecture string) *bytes.Buffer {
 | 
			
		||||
		var buf bytes.Buffer
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user