在 2017年11月2日星期四 CST 上午9:13:38,Sébastien Delafond 写道:
> On Nov/02, Boyuan Yang wrote:
> > Control: severity -1 grave
> > Control: tags -1 + fixed-upstream
> > 
> > Upstream now has a fix in trunk code. Just cherry-picked the fix and
> > confirmed that everything works well. I'm looking forward to seeing a
> > fixed version into Debian testing/unstable and stable/oldstable
> > updates into Stretch and Jessie.
> 
> #655 references a bunch of commits, did you merge them all ? I don't
>  like to include trunk commits, and would rather wait for 1.2.0, but if
>  the diff is actually small and well contained, I'm willing to review it
>  prior to uploading it.
> 
> Cheers,
> 
> --Seb

I'm not sure about the ETA of 1.2.0 release so reviewing in advance might be 
better.

I'm using a slightly modified version of patch from upstream pull request [1]. 
The patch is attached here. You may want to remove tests and test suite inside 
to make minimum changes. The core part is the modification of deb/deb.go.

Regards,
Boyuan Yang

[1] https://github.com/smira/aptly/pull/658
From: Harald Sitter <sit...@kde.org>
Date: Tue, 31 Oct 2017 11:36:31 +0100
Subject: make deb reader handle new control.tar options introduced in dpkg
 1.17.6

newly supported is uncompressed control.tar and xz compressed
control.tar.xz. latter is used by ubuntu for dbgsym ddebs.

Fixes #655
---
 deb/deb.go                                         |  39 +++++++++++++++++----
 deb/deb_test.go                                    |  11 +++++-
 ...sym_5.9.1+dfsg-2+18.04+bionic+build4_amd64.ddeb | Bin 0 -> 972 bytes
 3 files changed, 42 insertions(+), 8 deletions(-)
 create mode 100644 system/changes/libqt5concurrent5-dbgsym_5.9.1+dfsg-2+18.04+bionic+build4_amd64.ddeb

diff --git a/deb/deb.go b/deb/deb.go
index 50c7b7c..757155f 100644
--- a/deb/deb.go
+++ b/deb/deb.go
@@ -29,21 +29,46 @@ func GetControlFileFromDeb(packageFile string) (Stanza, error) {
 	library := ar.NewReader(file)
 	for {
 		header, err := library.Next()
+
 		if err == io.EOF {
-			return nil, fmt.Errorf("unable to find control.tar.gz part in package %s", packageFile)
+			return nil, fmt.Errorf("unable to find control.tar.* part in package %s", packageFile)
 		}
 		if err != nil {
 			return nil, fmt.Errorf("unable to read .deb archive %s: %s", packageFile, err)
 		}
 
-		if header.Name == "control.tar.gz" {
-			ungzip, err := gzip.NewReader(library)
-			if err != nil {
-				return nil, fmt.Errorf("unable to ungzip control file from %s. Error: %s", packageFile, err)
+		// As per deb(5) version 1.19.0.4 the control file may be:
+		// - control.tar (since 1.17.6)
+		// - control.tar.gz
+		// - control.tar.xz (since 1.17.6)
+		// Look for all of the above and uncompress as necessary.
+		if strings.HasPrefix(header.Name, "control.tar") {
+			bufReader := bufio.NewReader(library)
+
+			var tarInput io.Reader
+
+			switch header.Name {
+			case "control.tar":
+				tarInput = bufReader
+			case "control.tar.gz":
+				ungzip, err := gzip.NewReader(bufReader)
+				if err != nil {
+					return nil, fmt.Errorf("unable to ungzip %s from %s", header.Name, packageFile)
+				}
+				defer ungzip.Close()
+				tarInput = ungzip
+			case "control.tar.xz":
+				unxz, err := xz.NewReader(bufReader)
+				if err != nil {
+					return nil, fmt.Errorf("unable to unxz %s from %s", header.Name, packageFile)
+				}
+				defer unxz.Close()
+				tarInput = unxz
+			default:
+				return nil, fmt.Errorf("unsupported tar compression in %s: %s", packageFile, header.Name)
 			}
-			defer ungzip.Close()
 
-			untar := tar.NewReader(ungzip)
+			untar := tar.NewReader(tarInput)
 			for {
 				tarHeader, err := untar.Next()
 				if err == io.EOF {
diff --git a/deb/deb_test.go b/deb/deb_test.go
index 0260044..bd4e680 100644
--- a/deb/deb_test.go
+++ b/deb/deb_test.go
@@ -10,7 +10,7 @@ import (
 )
 
 type DebSuite struct {
-	debFile, debFile2, dscFile, dscFileNoSign string
+	debFile, debFile2, debFileWithXzControl, dscFile, dscFileNoSign string
 }
 
 var _ = Suite(&DebSuite{})
@@ -19,6 +19,7 @@ func (s *DebSuite) SetUpSuite(c *C) {
 	_, _File, _, _ := runtime.Caller(0)
 	s.debFile = filepath.Join(filepath.Dir(_File), "../system/files/libboost-program-options-dev_1.49.0.1_i386.deb")
 	s.debFile2 = filepath.Join(filepath.Dir(_File), "../system/changes/hardlink_0.2.1_amd64.deb")
+	s.debFileWithXzControl = filepath.Join(filepath.Dir(_File), "../system/changes/libqt5concurrent5-dbgsym_5.9.1+dfsg-2+18.04+bionic+build4_amd64.ddeb")
 	s.dscFile = filepath.Join(filepath.Dir(_File), "../system/files/pyspi_0.6.1-1.3.dsc")
 	s.dscFileNoSign = filepath.Join(filepath.Dir(_File), "../system/files/pyspi-0.6.1-1.3.stripped.dsc")
 }
@@ -37,6 +38,14 @@ func (s *DebSuite) TestGetControlFileFromDeb(c *C) {
 	c.Check(st["Package"], Equals, "libboost-program-options-dev")
 }
 
+func (s *DebSuite) TestGetControlFileFromDebWithXzControl(c *C) {
+	// Has control.tar.xz archive inside.
+	st, err := GetControlFileFromDeb(s.debFileWithXzControl)
+	c.Check(err, IsNil)
+	c.Check(st["Version"], Equals, "5.9.1+dfsg-2+18.04+bionic+build4")
+	c.Check(st["Package"], Equals, "libqt5concurrent5-dbgsym")
+}
+
 func (s *DebSuite) TestGetControlFileFromDsc(c *C) {
 	verifier := &utils.GpgVerifier{}
 
diff --git a/system/changes/libqt5concurrent5-dbgsym_5.9.1+dfsg-2+18.04+bionic+build4_amd64.ddeb b/system/changes/libqt5concurrent5-dbgsym_5.9.1+dfsg-2+18.04+bionic+build4_amd64.ddeb
new file mode 100644
index 0000000..77d6946
--- /dev/null
+++ b/system/changes/libqt5concurrent5-dbgsym_5.9.1+dfsg-2+18.04+bionic+build4_amd64.ddeb
@@ -0,0 +1,6 @@
+!<arch>
+debian-binary   1509443940  0     0     100644  4         `
+2.0
+control.tar.xz  1509443940  0     0     100644  600       `
+7zXZִF!t/']}JF._!}ݯ͆DC2✗!ؿ1~&1]y)#ٖ1ϺH:N)H__&g!b-\; Kg%sFeێe2=)jL5?b,XT~Ivѕ|I3CLQ✈OŇ$lmJ"ml-E&&%PHV9q'֍:ȯ85(DVܓImTx|N%Z@~^Nuw%TNDlc-[U.U-e%RO%Gu+FV&[Ie1`B>zĖ8virL9BGJc
 (OٵōMxteޓ"+n6@u	iDyg*2	&&͔=ت,#/ T9R]јL"\~2c?߷B(;Ɠ5	:_7Bt̕+0KPF*fgYZdata.tar.xz     1509443940  0     0     100644  180       `
+7zXZִF!t/'r]}JF._!_P<rMxLpHUcMfSQlYMU}3`rF/WeOݕB=);y֜ZhI;
--%PNj[gYZ
\ No newline at end of file

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to