The following commit has been merged in the master branch:
commit c13a013fd8778f9f558bedfb532c011dcb304394
Author: Guillem Jover <guil...@debian.org>
Date:   Mon Mar 26 05:47:43 2012 +0200

    Switch deb format version handling to use the new deb-version module
    
    This simplifies the parsing and checking and avoids having to treat the
    format versions as floats, which can cause parse errors depending on the
    locale (this only affected the old deb format).

diff --git a/TODO b/TODO
index 419e2cb..38b82dc 100644
--- a/TODO
+++ b/TODO
@@ -40,7 +40,6 @@ TODO
    - Add needed includes to all header files.
    - Get rid of unuseful "unsigned" modifiers.
    - Use internerr instead of assert, and print more meaninful messages.
-   - Make deb build version a version instead of doing checks over a string.
    - Use enums for currently hardcoded literals (replacingfilesandsaid,
      saidread, rok, filetriggers_edited, etc).
    - Do not use nfmalloc (and friends) for non in-core db memory.
diff --git a/debian/changelog b/debian/changelog
index 8f1d795..3f785d8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -22,6 +22,9 @@ dpkg (1.16.3) UNRELEASED; urgency=low
   * Change start-stop-daemon --name on GNU/Hurd to check the process' argv[1]
     in addition to argv[0], to handle both binaries and interpreted scripts.
     Reported by Mats Erik Andersson <mats.anders...@gisladisker.se>.
+  * Handle deb format versions as major.minor integers instead of strings or
+    floats, the latter being susceptible to parsing errors depending on the
+    current locale (although this was only affecting the old deb format).
 
   [ Helge Kreutzmann ]
   * Fix a typo in man/dpkg-buildflags.1.
diff --git a/dpkg-deb/extract.c b/dpkg-deb/extract.c
index d0b04a1..08b0664 100644
--- a/dpkg-deb/extract.c
+++ b/dpkg-deb/extract.c
@@ -3,6 +3,7 @@
  * extract.c - extracting archives
  *
  * Copyright © 1994,1995 Ian Jackson <i...@chiark.greenend.org.uk>
+ * Copyright © 2006-2012 Guillem Jover <guil...@debian.org>
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -47,6 +48,7 @@
 #include <dpkg/command.h>
 #include <dpkg/compress.h>
 #include <dpkg/ar.h>
+#include <dpkg/deb-version.h>
 #include <dpkg/options.h>
 
 #include "dpkg-deb.h"
@@ -105,8 +107,9 @@ void
 extracthalf(const char *debar, const char *dir, const char *taroption,
             int admininfo)
 {
+  const char *err;
   char versionbuf[40];
-  float versionnum;
+  struct deb_version version;
   off_t ctrllennum, memberlen = 0;
   ssize_t r;
   int dummy;
@@ -117,7 +120,7 @@ extracthalf(const char *debar, const char *dir, const char 
*taroption,
   struct stat stab;
   char nlc;
   int adminmember;
-  bool oldformat, header_done;
+  bool header_done;
   enum compressor_type decompressor = compressor_type_gzip;
 
   arfd = open(debar, O_RDONLY);
@@ -131,8 +134,6 @@ extracthalf(const char *debar, const char *dir, const char 
*taroption,
     read_fail(r, debar, _("archive magic version number"));
 
   if (strcmp(versionbuf, DPKG_AR_MAGIC) == 0) {
-    oldformat = false;
-
     ctrllennum= 0;
     header_done = false;
     for (;;) {
@@ -149,7 +150,6 @@ extracthalf(const char *debar, const char *dir, const char 
*taroption,
       memberlen = dpkg_ar_member_get_size(debar, &arh);
       if (!header_done) {
         char *infobuf;
-        char *cur;
 
         if (strncmp(arh.ar_name, DEBMAGIC, sizeof(arh.ar_name)) != 0)
           ohshit(_("file `%.250s' is not a debian binary archive (try 
dpkg-split?)"),debar);
@@ -158,17 +158,16 @@ extracthalf(const char *debar, const char *dir, const 
char *taroption,
         if (r != (memberlen + (memberlen & 1)))
           read_fail(r, debar, _("archive information header member"));
         infobuf[memberlen] = '\0';
-        cur= strchr(infobuf,'\n');
-        if (!cur) ohshit(_("archive has no newlines in header"));
-        *cur = '\0';
-        cur= strchr(infobuf,'.');
-        if (!cur) ohshit(_("archive has no dot in version number"));
-        *cur = '\0';
-        if (strcmp(infobuf,"2"))
-          ohshit(_("archive version %.250s not understood, get newer 
dpkg-deb"), infobuf);
-        *cur= '.';
-        strncpy(versionbuf,infobuf,sizeof(versionbuf));
-        versionbuf[sizeof(versionbuf) - 1] = '\0';
+
+        if (strchr(infobuf, '\n') == NULL)
+          ohshit(_("archive has no newlines in header"));
+        err = deb_version_parse(&version, infobuf);
+        if (err)
+          ohshit(_("archive has invalid format version: %s"), err);
+        if (version.major != 2)
+          ohshit(_("archive is format version %d.%d; get a newer dpkg-deb"),
+                 version.major, version.minor);
+
         free(infobuf);
 
         header_done = true;
@@ -211,21 +210,23 @@ extracthalf(const char *debar, const char *dir, const 
char *taroption,
     }
 
     if (admininfo >= 2) {
-      printf(_(" new debian package, version %s.\n"
-               " size %jd bytes: control archive= %jd bytes.\n"),
-             versionbuf, (intmax_t)stab.st_size, (intmax_t)ctrllennum);
+      printf(_(" new debian package, version %d.%d.\n"
+               " size %jd bytes: control archive=%jd bytes.\n"),
+             version.major, version.minor,
+             (intmax_t)stab.st_size, (intmax_t)ctrllennum);
       m_output(stdout, _("<standard output>"));
     }
-  } else if (strncmp(versionbuf, "0.93", 4) == 0 &&
-             sscanf(versionbuf,"%f%c%d",&versionnum,&nlc,&dummy) == 2 &&
-             nlc == '\n') {
+  } else if (strncmp(versionbuf, "0.93", 4) == 0) {
     char ctrllenbuf[40];
     int l = 0;
 
-    oldformat = true;
     l = strlen(versionbuf);
-    if (l && versionbuf[l - 1] == '\n')
-      versionbuf[l - 1] = '\0';
+
+    if (strchr(versionbuf, '\n') == NULL)
+      ohshit(_("archive has no newlines in header"));
+    err = deb_version_parse(&version, versionbuf);
+    if (err)
+      ohshit(_("archive has invalid format version: %s"), err);
 
     r = read_line(arfd, ctrllenbuf, 1, sizeof(ctrllenbuf));
     if (r < 0)
@@ -243,9 +244,10 @@ extracthalf(const char *debar, const char *dir, const char 
*taroption,
     }
 
     if (admininfo >= 2) {
-      printf(_(" old debian package, version %s.\n"
-               " size %jd bytes: control archive= %jd, main archive= %jd.\n"),
-             versionbuf, (intmax_t)stab.st_size, (intmax_t)ctrllennum,
+      printf(_(" old debian package, version %d.%d.\n"
+               " size %jd bytes: control archive=%jd, main archive=%jd.\n"),
+             version.major, version.minor,
+             (intmax_t)stab.st_size, (intmax_t)ctrllennum,
              (intmax_t)(stab.st_size - ctrllennum - strlen(ctrllenbuf) - l));
       m_output(stdout, _("<standard output>"));
     }
@@ -323,12 +325,17 @@ extracthalf(const char *debar, const char *dir, const 
char *taroption,
   subproc_wait_check(c2, _("<decompress>"), PROCPIPE);
   if (c1 != -1)
     subproc_wait_check(c1, _("paste"), 0);
-  if (oldformat && admininfo) {
-    if (versionnum == 0.931F) {
+  if (version.major == 0 && admininfo) {
+    /* Handle the version as a float to preserve the behaviour of old code,
+     * because even if the format is defined to be padded by 0's that might
+     * not have been always true for really ancient versions... */
+    while (version.minor && (version.minor % 10) == 0)
+      version.minor /= 10;
+
+    if (version.minor ==  931)
       movecontrolfiles(OLDOLDDEBDIR);
-    } else if (versionnum == 0.932F || versionnum == 0.933F) {
+    else if (version.minor == 932 || version.minor == 933)
       movecontrolfiles(OLDDEBDIR);
-    }
   }
 }
 
diff --git a/dpkg-split/dpkg-split.h b/dpkg-split/dpkg-split.h
index ceb9be9..88c2e15 100644
--- a/dpkg-split/dpkg-split.h
+++ b/dpkg-split/dpkg-split.h
@@ -3,6 +3,7 @@
  * dpkg-split.h - external definitions for this program
  *
  * Copyright © 1995 Ian Jackson <i...@chiark.greenend.org.uk>
+ * Copyright © 2008-2012 Guillem Jover <guil...@debian.org>
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,6 +22,8 @@
 #ifndef DPKG_SPLIT_H
 #define DPKG_SPLIT_H
 
+#include <dpkg/deb-version.h>
+
 action_func do_split;
 action_func do_join;
 action_func do_info;
@@ -29,8 +32,8 @@ action_func do_queue;
 action_func do_discard;
 
 struct partinfo {
+  struct deb_version fmtversion;
   const char *filename;
-  const char *fmtversion;
   const char *package;
   const char *version;
   const char *arch;
diff --git a/dpkg-split/info.c b/dpkg-split/info.c
index ea51b2e..b2f12d5 100644
--- a/dpkg-split/info.c
+++ b/dpkg-split/info.c
@@ -3,6 +3,7 @@
  * info.c - information about split archives
  *
  * Copyright © 1995 Ian Jackson <i...@chiark.greenend.org.uk>
+ * Copyright © 2008-2012 Guillem Jover <guil...@debian.org>
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -80,6 +81,7 @@ struct partinfo *read_info(FILE *partfile, const char *fn, 
struct partinfo *ir)
   size_t thisilen;
   intmax_t templong;
   char magicbuf[sizeof(DPKG_AR_MAGIC) - 1], *rip, *partnums, *slash;
+  const char *err;
   struct ar_hdr arh;
   int c;
   struct stat stab;
@@ -119,10 +121,13 @@ struct partinfo *read_info(FILE *partfile, const char 
*fn, struct partinfo *ir)
   ir->filename= fn;
 
   rip= readinfobuf;
-  ir->fmtversion = nfstrsave(nextline(&rip, fn, _("format version number")));
-  if (strcmp(ir->fmtversion,SPLITVERSION))
-    ohshit(_("file `%.250s' is format version `%.250s' - you need a newer 
dpkg-split"),
-           fn,ir->fmtversion);
+  err = deb_version_parse(&ir->fmtversion,
+                          nextline(&rip, fn, _("format version number")));
+  if (err)
+    ohshit(_("file '%.250s' has invalid format version: %s"), fn, err);
+  if (ir->fmtversion.major != 2 || ir->fmtversion.minor != 1)
+    ohshit(_("file '%.250s' is format version %d.%d; get a newer dpkg-split"),
+           fn, ir->fmtversion.major, ir->fmtversion.minor);
 
   ir->package = nfstrsave(nextline(&rip, fn, _("package name")));
   ir->version = nfstrsave(nextline(&rip, fn, _("package version number")));
@@ -207,7 +212,7 @@ void mustgetpartinfo(const char *filename, struct partinfo 
*ri) {
 
 void print_info(const struct partinfo *pi) {
   printf(_("%s:\n"
-         "    Part format version:            %s\n"
+         "    Part format version:            %d.%d\n"
          "    Part of package:                %s\n"
          "        ... version:                %s\n"
          "        ... architecture:           %s\n"
@@ -219,7 +224,7 @@ void print_info(const struct partinfo *pi) {
          "    Part offset:                    %jd bytes\n"
          "    Part file size (used portion):  %jd bytes\n\n"),
          pi->filename,
-         pi->fmtversion,
+         pi->fmtversion.major, pi->fmtversion.minor,
          pi->package,
          pi->version,
          pi->arch ? pi->arch : C_("architecture", "<unknown>"),
diff --git a/dpkg-split/queue.c b/dpkg-split/queue.c
index 2ed2866..0a8c5d7 100644
--- a/dpkg-split/queue.c
+++ b/dpkg-split/queue.c
@@ -3,6 +3,7 @@
  * queue.c - queue management
  *
  * Copyright © 1995 Ian Jackson <i...@chiark.greenend.org.uk>
+ * Copyright © 2008-2012 Guillem Jover <guil...@debian.org>
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -94,7 +95,10 @@ void scandepot(void) {
 
     if (de->d_name[0] == '.') continue;
     pq= nfmalloc(sizeof(struct partqueue));
-    pq->info.fmtversion= pq->info.package= pq->info.version= NULL;
+    pq->info.fmtversion.major = 0;
+    pq->info.fmtversion.minor = 0;
+    pq->info.package = NULL;
+    pq->info.version = NULL;
     pq->info.arch = NULL;
     pq->info.orglength= pq->info.thispartoffset= pq->info.thispartlen= 0;
     pq->info.headerlen= 0;

-- 
dpkg's main repository


-- 
To UNSUBSCRIBE, email to debian-dpkg-cvs-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to