summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillem Jover <guillem@debian.org>2014-07-01 03:55:37 +0200
committerGuillem Jover <guillem@debian.org>2014-08-09 22:47:52 +0200
commit589602c7802ab927d7f3e4ed026601d9ca701012 (patch)
tree6ae97dcd1ec314d2564e982f5a096a5abfa16a8c
parentbdfc98f46c81b56b895e436e3652b553fa106ce9 (diff)
downloaddpkg-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/changelog3
-rw-r--r--dpkg-deb/dpkg-deb.h1
-rw-r--r--dpkg-deb/info.c82
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);