diff options
author | Guillem Jover <guillem@debian.org> | 2014-07-01 03:55:37 +0200 |
---|---|---|
committer | Guillem Jover <guillem@debian.org> | 2014-08-09 22:47:52 +0200 |
commit | 589602c7802ab927d7f3e4ed026601d9ca701012 (patch) | |
tree | 6ae97dcd1ec314d2564e982f5a096a5abfa16a8c | |
parent | bdfc98f46c81b56b895e436e3652b553fa106ce9 (diff) | |
download | dpkg-589602c7802ab927d7f3e4ed026601d9ca701012.tar.gz |
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.
-rw-r--r-- | debian/changelog | 3 | ||||
-rw-r--r-- | dpkg-deb/dpkg-deb.h | 1 | ||||
-rw-r--r-- | dpkg-deb/info.c | 82 |
3 files changed, 33 insertions, 53 deletions
diff --git a/debian/changelog b/debian/changelog index b0d62e4b9..a789f7602 100644 --- a/debian/changelog +++ b/debian/changelog @@ -38,6 +38,9 @@ dpkg (1.17.11) UNRELEASED; urgency=low and derivatives, enabled by default. It will fallback to stackprotector when the former is not functional or disabled by the user. 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 ] * Danish (Joe Dalton). Closes: #754127 diff --git a/dpkg-deb/dpkg-deb.h b/dpkg-deb/dpkg-deb.h index d89c5ab22..2233c96df 100644 --- a/dpkg-deb/dpkg-deb.h +++ b/dpkg-deb/dpkg-deb.h @@ -75,7 +75,6 @@ extern struct compress_params compress_params; #define DATAMEMBER "data.tar" #define MAXFILENAME 2048 -#define MAXFIELDNAME 200 #ifdef PATH_MAX # define INTERPRETER_MAX PATH_MAX diff --git a/dpkg-deb/info.c b/dpkg-deb/info.c index 9915117a0..f7b2ea537 100644 --- a/dpkg-deb/info.c +++ b/dpkg-deb/info.c @@ -40,6 +40,7 @@ #include <dpkg/i18n.h> #include <dpkg/dpkg.h> #include <dpkg/dpkg-db.h> +#include <dpkg/parsedump.h> #include <dpkg/pkg-format.h> #include <dpkg/buffer.h> #include <dpkg/path.h> @@ -208,64 +209,41 @@ info_list(const char *debar, const char *dir) static void info_field(const char *debar, const char *dir, const char *const *fields, - bool showfieldname) + enum fwriteflags fieldflags) { - FILE *cc; 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); - 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>")); - free(controlfile); + + varbuf_destroy(&str); } int @@ -315,7 +293,7 @@ do_field(const char *const *argv) info_prepare(&argv, &debar, &dir, 1); if (*argv) { - info_field(debar, dir, argv, argv[1] != NULL); + info_field(debar, dir, argv, argv[1] != NULL ? fw_printheader : 0); } else { static const char *const controlonly[] = { CONTROLFILE, NULL }; info_spew(debar, dir, controlonly); |