Browse Source

libdpkg: Use our own dpkg_ar_hdr instead of relying on the system one

The ar format is not standardized and some systems might provide a
different format than the one used by dpkg. For example on AIX.
Guillem Jover 7 years ago
parent
commit
534510ae79
6 changed files with 30 additions and 14 deletions
  1. 3 0
      debian/changelog
  2. 1 1
      dpkg-deb/extract.c
  3. 1 1
      dpkg-split/info.c
  4. 6 6
      lib/dpkg/ar.c
  5. 16 3
      lib/dpkg/ar.h
  6. 3 3
      lib/dpkg/t/t-ar.c

+ 3 - 0
debian/changelog

@@ -53,6 +53,9 @@ dpkg (1.18.11) UNRELEASED; urgency=medium
       derivatives, by using perl's $Config{cf_by} variable to key on. The
       Debian-specific --rsyncable option should have never been accepted for
       use in dpkg to begin with.
+    - Use our own dpkg_ar_hdr struct instead of relying on the system
+      ar_hdr struct, as the ar format is not standardized and does vary
+      across systems, for example on AIX.
   * Perl modules:
     - Obsolete Source-Version substvar in Dpkg::Substvars by emitting errors.
     - Rework keyring hooks in Dpkg::Vendor. Deprecate the keyrings hook, and

+ 1 - 1
dpkg-deb/extract.c

@@ -131,7 +131,7 @@ extracthalf(const char *debar, const char *dir,
     ctrllennum= 0;
     header_done = false;
     for (;;) {
-      struct ar_hdr arh;
+      struct dpkg_ar_hdr arh;
 
       r = fd_read(ar->fd, &arh, sizeof(arh));
       if (r != sizeof(arh))

+ 1 - 1
dpkg-split/info.c

@@ -93,7 +93,7 @@ read_info(struct dpkg_ar *ar, struct partinfo *ir)
   intmax_t templong;
   char magicbuf[sizeof(DPKG_AR_MAGIC) - 1], *rip, *partnums, *slash;
   const char *err;
-  struct ar_hdr arh;
+  struct dpkg_ar_hdr arh;
   ssize_t rc;
 
   rc = fd_read(ar->fd, magicbuf, sizeof(magicbuf));

+ 6 - 6
lib/dpkg/ar.c

@@ -110,7 +110,7 @@ dpkg_ar_member_init(struct dpkg_ar *ar, struct dpkg_ar_member *member,
 }
 
 void
-dpkg_ar_normalize_name(struct ar_hdr *arh)
+dpkg_ar_normalize_name(struct dpkg_ar_hdr *arh)
 {
 	char *name = arh->ar_name;
 	int i;
@@ -125,7 +125,7 @@ dpkg_ar_normalize_name(struct ar_hdr *arh)
 }
 
 off_t
-dpkg_ar_member_get_size(struct dpkg_ar *ar, struct ar_hdr *arh)
+dpkg_ar_member_get_size(struct dpkg_ar *ar, struct dpkg_ar_hdr *arh)
 {
 	const char *str = arh->ar_size;
 	int len = sizeof(arh->ar_size);
@@ -150,9 +150,9 @@ dpkg_ar_member_get_size(struct dpkg_ar *ar, struct ar_hdr *arh)
 }
 
 bool
-dpkg_ar_member_is_illegal(struct ar_hdr *arh)
+dpkg_ar_member_is_illegal(struct dpkg_ar_hdr *arh)
 {
-	return memcmp(arh->ar_fmag, ARFMAG, sizeof(arh->ar_fmag)) != 0;
+	return memcmp(arh->ar_fmag, DPKG_AR_FMAG, sizeof(arh->ar_fmag)) != 0;
 }
 
 void
@@ -165,7 +165,7 @@ dpkg_ar_put_magic(struct dpkg_ar *ar)
 void
 dpkg_ar_member_put_header(struct dpkg_ar *ar, struct dpkg_ar_member *member)
 {
-	char header[sizeof(struct ar_hdr) + 1];
+	char header[sizeof(struct dpkg_ar_hdr) + 1];
 	int n;
 
 	if (strlen(member->name) > 15)
@@ -177,7 +177,7 @@ dpkg_ar_member_put_header(struct dpkg_ar *ar, struct dpkg_ar_member *member)
 	            member->name, (unsigned long)member->time,
 	            (unsigned long)member->uid, (unsigned long)member->gid,
 	            (unsigned long)member->mode, (intmax_t)member->size);
-	if (n != sizeof(struct ar_hdr))
+	if (n != sizeof(struct dpkg_ar_hdr))
 		ohshit(_("generated corrupt ar header for '%s'"), ar->name);
 
 	if (fd_write(ar->fd, header, n) < 0)

+ 16 - 3
lib/dpkg/ar.h

@@ -37,6 +37,19 @@ DPKG_BEGIN_DECLS
  */
 
 #define DPKG_AR_MAGIC "!<arch>\n"
+#define DPKG_AR_FMAG  "`\n"
+
+/**
+ * An on-disk archive header.
+ */
+struct dpkg_ar_hdr {
+	char ar_name[16];	   /* Member file name, sometimes / terminated. */
+	char ar_date[12];	   /* File date, decimal seconds since Epoch.  */
+	char ar_uid[6], ar_gid[6]; /* User and group IDs, in ASCII decimal.  */
+	char ar_mode[8];	   /* File mode, in ASCII octal.  */
+	char ar_size[10];	   /* File size, in ASCII decimal.  */
+	char ar_fmag[2];
+};
 
 /**
  * An archive (Unix ar) file.
@@ -70,8 +83,8 @@ struct dpkg_ar *dpkg_ar_create(const char *filename, mode_t mode);
 void dpkg_ar_set_mtime(struct dpkg_ar *ar, time_t mtime);
 void dpkg_ar_close(struct dpkg_ar *ar);
 
-void dpkg_ar_normalize_name(struct ar_hdr *arh);
-bool dpkg_ar_member_is_illegal(struct ar_hdr *arh);
+void dpkg_ar_normalize_name(struct dpkg_ar_hdr *arh);
+bool dpkg_ar_member_is_illegal(struct dpkg_ar_hdr *arh);
 
 void dpkg_ar_put_magic(struct dpkg_ar *ar);
 void dpkg_ar_member_put_header(struct dpkg_ar *ar,
@@ -80,7 +93,7 @@ void dpkg_ar_member_put_file(struct dpkg_ar *ar, const char *name,
                              int fd, off_t size);
 void dpkg_ar_member_put_mem(struct dpkg_ar *ar, const char *name,
                             const void *data, size_t size);
-off_t dpkg_ar_member_get_size(struct dpkg_ar *ar, struct ar_hdr *arh);
+off_t dpkg_ar_member_get_size(struct dpkg_ar *ar, struct dpkg_ar_hdr *arh);
 
 /** @} */
 

+ 3 - 3
lib/dpkg/t/t-ar.c

@@ -27,7 +27,7 @@
 static void
 test_ar_normalize_name(void)
 {
-	struct ar_hdr arh;
+	struct dpkg_ar_hdr arh;
 
 	strncpy(arh.ar_name, "member-name/    ", sizeof(arh.ar_name));
 	dpkg_ar_normalize_name(&arh);
@@ -41,12 +41,12 @@ test_ar_normalize_name(void)
 static void
 test_ar_member_is_illegal(void)
 {
-	struct ar_hdr arh;
+	struct dpkg_ar_hdr arh;
 
 	memset(&arh, ' ', sizeof(arh));
 	test_pass(dpkg_ar_member_is_illegal(&arh));
 
-	memcpy(arh.ar_fmag, ARFMAG, sizeof(arh.ar_fmag));
+	memcpy(arh.ar_fmag, DPKG_AR_FMAG, sizeof(arh.ar_fmag));
 	test_fail(dpkg_ar_member_is_illegal(&arh));
 }