Browse Source

dpkg-deb: Use parsedb() instead of an ad-hoc deb822 parser

This makes sure any field fixup and sanity check is performed on
the input, and gets reflected on the output.
Guillem Jover 12 years ago
parent
commit
589602c780
3 changed files with 33 additions and 53 deletions
  1. 3 0
      debian/changelog
  2. 0 1
      dpkg-deb/dpkg-deb.h
  3. 30 52
      dpkg-deb/info.c

+ 3 - 0
debian/changelog

@@ -38,6 +38,9 @@ dpkg (1.17.11) UNRELEASED; urgency=low
     and derivatives, enabled by default. It will fallback to stackprotector
     and derivatives, enabled by default. It will fallback to stackprotector
     when the former is not functional or disabled by the user.
     when the former is not functional or disabled by the user.
     Thanks to Romain Francoise <rfrancoise@debian.org>.
     Thanks to Romain Francoise <rfrancoise@debian.org>.
+  * Change «dpkg-deb --field» code to use the libdpkg deb822 parser instead
+    of an ad-hoc one. This makes sure any field fixup and sanity check is
+    performed on the input, and gets reflected on the output.
 
 
   [ Updated programs translations ]
   [ Updated programs translations ]
   * Danish (Joe Dalton). Closes: #754127
   * Danish (Joe Dalton). Closes: #754127

+ 0 - 1
dpkg-deb/dpkg-deb.h

@@ -75,7 +75,6 @@ extern struct compress_params compress_params;
 #define DATAMEMBER		"data.tar"
 #define DATAMEMBER		"data.tar"
 
 
 #define MAXFILENAME 2048
 #define MAXFILENAME 2048
-#define MAXFIELDNAME 200
 
 
 #ifdef PATH_MAX
 #ifdef PATH_MAX
 # define INTERPRETER_MAX PATH_MAX
 # define INTERPRETER_MAX PATH_MAX

+ 30 - 52
dpkg-deb/info.c

@@ -40,6 +40,7 @@
 #include <dpkg/i18n.h>
 #include <dpkg/i18n.h>
 #include <dpkg/dpkg.h>
 #include <dpkg/dpkg.h>
 #include <dpkg/dpkg-db.h>
 #include <dpkg/dpkg-db.h>
+#include <dpkg/parsedump.h>
 #include <dpkg/pkg-format.h>
 #include <dpkg/pkg-format.h>
 #include <dpkg/buffer.h>
 #include <dpkg/buffer.h>
 #include <dpkg/path.h>
 #include <dpkg/path.h>
@@ -208,64 +209,41 @@ info_list(const char *debar, const char *dir)
 
 
 static void
 static void
 info_field(const char *debar, const char *dir, const char *const *fields,
 info_field(const char *debar, const char *dir, const char *const *fields,
-           bool showfieldname)
+           enum fwriteflags fieldflags)
 {
 {
-  FILE *cc;
   char *controlfile;
   char *controlfile;
-  char fieldname[MAXFIELDNAME+1];
-  char *pf;
-  const char *const *fp;
-  int c, lno, fnl;
-  bool doing;
+  struct varbuf str = VARBUF_INIT;
+  struct pkginfo *pkg;
+  int i;
 
 
   m_asprintf(&controlfile, "%s/%s", dir, CONTROLFILE);
   m_asprintf(&controlfile, "%s/%s", dir, CONTROLFILE);
-  cc = fopen(controlfile, "r");
-  if (!cc)
-    ohshite(_("could not open the `control' component"));
-  doing = true;
-  lno = 1;
-  for (;;) {
-    c = getc(cc);
-    if (c == EOF) {
-      doing = false;
-      break;
-    }
-    if (c == '\n') {
-      lno++;
-      doing = true;
-      continue;
-    }
-    if (!isspace(c)) {
-      for (pf=fieldname, fnl=0;
-           fnl <= MAXFIELDNAME && c!=EOF && !isspace(c) && c!=':';
-           c= getc(cc)) { *pf++= c; fnl++; }
-      *pf = '\0';
-      doing= fnl >= MAXFIELDNAME || c=='\n' || c==EOF;
-      for (fp=fields; !doing && *fp; fp++)
-        if (strcasecmp(*fp, fieldname) == 0)
-          doing = true;
-      if (showfieldname) {
-        if (doing)
-          fputs(fieldname,stdout);
-      } else {
-        if (c==':') c= getc(cc);
-        while (c != '\n' && isspace(c)) c= getc(cc);
-      }
-    }
-    for(;;) {
-      if (c == EOF) break;
-      if (doing) putc(c,stdout);
-      if (c == '\n') { lno++; break; }
-      c= getc(cc);
+  parsedb(controlfile, pdb_parse_binary | pdb_ignorefiles, &pkg);
+  free(controlfile);
+
+  for (i = 0; fields[i]; i++) {
+    const struct fieldinfo *field;
+    const struct arbitraryfield *arbfield;
+
+    varbuf_reset(&str);
+    field = find_field_info(fieldinfos, fields[i]);
+    if (field) {
+      field->wcall(&str, pkg, &pkg->available, fieldflags, field);
+    } else {
+      arbfield = find_arbfield_info(pkg->available.arbs, fields[i]);
+      if (arbfield)
+        varbuf_add_arbfield(&str, arbfield, fieldflags);
     }
     }
-    if (c == EOF) break;
+    varbuf_end_str(&str);
+
+    if (fieldflags & fw_printheader)
+      printf("%s", str.buf);
+    else
+      printf("%s\n", str.buf);
   }
   }
-  if (ferror(cc)) ohshite(_("failed during read of `control' component"));
-  if (fclose(cc))
-    ohshite(_("error closing the '%s' component"), CONTROLFILE);
-  if (doing) putc('\n',stdout);
+
   m_output(stdout, _("<standard output>"));
   m_output(stdout, _("<standard output>"));
-  free(controlfile);
+
+  varbuf_destroy(&str);
 }
 }
 
 
 int
 int
@@ -315,7 +293,7 @@ do_field(const char *const *argv)
 
 
   info_prepare(&argv, &debar, &dir, 1);
   info_prepare(&argv, &debar, &dir, 1);
   if (*argv) {
   if (*argv) {
-    info_field(debar, dir, argv, argv[1] != NULL);
+    info_field(debar, dir, argv, argv[1] != NULL ? fw_printheader : 0);
   } else {
   } else {
     static const char *const controlonly[] = { CONTROLFILE, NULL };
     static const char *const controlonly[] = { CONTROLFILE, NULL };
     info_spew(debar, dir, controlonly);
     info_spew(debar, dir, controlonly);