Pārlūkot izejas kodu

libdpkg: Ensure parsed packages have a usable arch member

In case the package didn't have an Architecture field, warn and
initialize it to an empty string, so that it can be safely used for
string comparisons, printing, etc.

This fixes a potential segfault when setting the environment variable
DPKG_MAINTSCRIPT_ARCH from a package w/o an Architecture field, which
are a thing from the distant past, but still should be supported.
Guillem Jover 15 gadi atpakaļ
vecāks
revīzija
58e7276b69
4 mainītis faili ar 10 papildinājumiem un 7 dzēšanām
  1. 2 0
      debian/changelog
  2. 3 3
      dpkg-deb/build.c
  3. 4 2
      lib/dpkg/parse.c
  4. 1 2
      src/processarc.c

+ 2 - 0
debian/changelog

@@ -25,6 +25,8 @@ dpkg (1.16.0) UNRELEASED; urgency=low
   * Do not fail when trying to remove the root directory. This will only
   * Do not fail when trying to remove the root directory. This will only
     happen either on distributions where dpkg is a foreign package manager,
     happen either on distributions where dpkg is a foreign package manager,
     or on artificial dpkg databases.
     or on artificial dpkg databases.
+  * Always warn when parsing any package control data which does not have
+    an Architecture field.
 
 
   [ Raphaël Hertzog ]
   [ Raphaël Hertzog ]
   * Fail properly when debian/source/format is empty. Closes: #600854
   * Fail properly when debian/source/format is empty. Closes: #600854

+ 3 - 3
dpkg-deb/build.c

@@ -368,12 +368,12 @@ static char *
 pkg_get_pathname(const char *dir, struct pkginfo *pkg)
 pkg_get_pathname(const char *dir, struct pkginfo *pkg)
 {
 {
   char *path;
   char *path;
-  const char *versionstring, *arch;
+  const char *versionstring, *arch_sep;
 
 
   versionstring = versiondescribe(&pkg->available.version, vdew_never);
   versionstring = versiondescribe(&pkg->available.version, vdew_never);
-  arch = pkg->available.arch;
+  arch_sep = pkg->available.arch[0] == '\0' ? "" : "_";
   m_asprintf(&path, "%s/%s_%s%s%s%s", dir, pkg->name, versionstring,
   m_asprintf(&path, "%s/%s_%s%s%s%s", dir, pkg->name, versionstring,
-             arch ? "_" : "", arch ? arch : "", DEBEXT);
+             arch_sep, pkg->available.arch, DEBEXT);
 
 
   return path;
   return path;
 }
 }

+ 4 - 2
lib/dpkg/parse.c

@@ -168,8 +168,10 @@ pkg_parse_verify(struct parsedb_state *ps,
     parse_ensure_have_field(ps, pkg, &pkgbin->maintainer, "maintainer");
     parse_ensure_have_field(ps, pkg, &pkgbin->maintainer, "maintainer");
     parse_must_have_field(ps, pkg, pkgbin->version.version, "version");
     parse_must_have_field(ps, pkg, pkgbin->version.version, "version");
   }
   }
-  if (ps->flags & pdb_recordavailable)
-    parse_ensure_have_field(ps, pkg, &pkgbin->arch, "architecture");
+
+  /* We always want usable architecture information, so that it can be used
+   * safely on string comparisons and the like. */
+  parse_ensure_have_field(ps, pkg, &pkgbin->arch, "architecture");
 
 
   /* Check the Config-Version information:
   /* Check the Config-Version information:
    * If there is a Config-Version it is definitely to be used, but
    * If there is a Config-Version it is definitely to be used, but

+ 1 - 2
src/processarc.c

@@ -282,8 +282,7 @@ void process_archive(const char *filename) {
     return;
     return;
   }
   }
 
 
-  if (pkg->available.arch && *pkg->available.arch &&
-      strcmp(pkg->available.arch, "all") &&
+  if (strcmp(pkg->available.arch, "all") &&
       strcmp(pkg->available.arch, native_arch))
       strcmp(pkg->available.arch, native_arch))
     forcibleerr(fc_architecture,
     forcibleerr(fc_architecture,
                 _("package architecture (%s) does not match system (%s)"),
                 _("package architecture (%s) does not match system (%s)"),