This is an automated email from the git hooks/post-receive script.

guillem pushed a commit to branch master
in repository dpkg.

commit 2a6d9275c0bdd44f306adf816cfcec95204d0e54
Author: Guillem Jover <[email protected]>
Date:   Sun Feb 15 23:58:34 2015 +0100

    libdpkg: Simplify namevalue parsing code
    
    This removes the special fallback value from the name/value table,
    so that we cannot accidentally parse it as a valid value.
---
 dselect/pkgdisplay.cc    |  1 -
 lib/dpkg/fields.c        | 87 ++++++++++++++++++++++++++++++------------------
 lib/dpkg/namevalue.c     |  8 ++---
 lib/dpkg/namevalue.h     |  2 --
 lib/dpkg/pkg-namevalue.c |  1 -
 5 files changed, 56 insertions(+), 43 deletions(-)

diff --git a/dselect/pkgdisplay.cc b/dselect/pkgdisplay.cc
index 7b9b017..e264a9e 100644
--- a/dselect/pkgdisplay.cc
+++ b/dselect/pkgdisplay.cc
@@ -63,7 +63,6 @@ const char
                               N_("Standard"),
                               N_("Optional"),
                               N_("Extra"),
-                              N_("!Bug!"),
                               N_("Unclassified"),
                               nullptr },
 
diff --git a/lib/dpkg/fields.c b/lib/dpkg/fields.c
index abbf23e..831b53d 100644
--- a/lib/dpkg/fields.c
+++ b/lib/dpkg/fields.c
@@ -40,45 +40,57 @@
 #include <dpkg/pkg-spec.h>
 #include <dpkg/triglib.h>
 
+/**
+ * Flags to parse a name associated to a value.
+ */
+enum parse_nv_flags {
+  /** Expect no more words (default). */
+  PARSE_NV_LAST                = 0,
+  /** Expect another word after the parsed name. */
+  PARSE_NV_NEXT                = DPKG_BIT(0),
+  /** Do not fail if there is no name with an associated value found. */
+  PARSE_NV_FALLBACK    = DPKG_BIT(1),
+};
+
+/**
+ * Parses a name and returns its associated value.
+ *
+ * Gets a pointer to the string to parse in @a strp, and modifies the pointer
+ * to the string to point to the end of the parsed text. If no value is found
+ * for the name and #PARSE_NV_FALLBACK is set in @a flags then @a strp is set
+ * to NULL and returns -1, otherwise a parse error is emitted.
+ */
 static int
-parse_nv_next(struct parsedb_state *ps,
-              const char *what, const struct namevalue *nv_head,
-              const char **strp)
+parse_nv(struct parsedb_state *ps, enum parse_nv_flags flags,
+         const char **strp, const struct namevalue *nv_head, const char *what)
 {
   const char *str_start = *strp, *str_end;
   const struct namevalue *nv;
+  int value;
 
   if (str_start[0] == '\0')
     parse_error(ps, _("%s is missing"), what);
 
   nv = namevalue_find_by_name(nv_head, str_start);
-  if (nv == NULL)
-    parse_error(ps, _("'%.50s' is not allowed for %s"), str_start, what);
+  if (nv == NULL) {
+    /* We got no match, skip further string validation. */
+    if (!(flags & PARSE_NV_FALLBACK))
+      parse_error(ps, _("'%.50s' is not allowed for %s"), str_start, what);
 
-  /* We got the fallback value, skip further string validation. */
-  if (nv->length == 0) {
     str_end = NULL;
+    value = -1;
   } else {
     str_end = str_start + nv->length;
     while (c_isspace(str_end[0]))
       str_end++;
+    value = nv->value;
   }
-  *strp = str_end;
-
-  return nv->value;
-}
-
-static int
-parse_nv_last(struct parsedb_state *ps,
-              const char *what, const struct namevalue *nv_head,
-              const char *str)
-{
-  int value;
 
-  value = parse_nv_next(ps, what, nv_head, &str);
-  if (str_is_set(str))
+  if (!(flags & PARSE_NV_NEXT) && str_is_set(str_end))
     parse_error(ps, _("junk after %s"), what);
 
+  *strp = str_end;
+
   return value;
 }
 
@@ -162,8 +174,8 @@ f_boolean(struct pkginfo *pkg, struct pkgbin *pkgbin,
   if (!*value)
     return;
 
-  boolean = parse_nv_last(ps, _("yes/no in boolean field"),
-                          booleaninfos, value);
+  boolean = parse_nv(ps, PARSE_NV_LAST, &value, booleaninfos,
+                     _("yes/no in boolean field"));
   STRUCTFIELD(pkgbin, fip->integer, bool) = boolean;
 }
 
@@ -177,8 +189,8 @@ f_multiarch(struct pkginfo *pkg, struct pkgbin *pkgbin,
   if (!*value)
     return;
 
-  multiarch = parse_nv_last(ps, _("foreign/allowed/same/no in quadstate 
field"),
-                            multiarchinfos, value);
+  multiarch = parse_nv(ps, PARSE_NV_LAST, &value, multiarchinfos,
+                       _("foreign/allowed/same/no in quadstate field"));
   STRUCTFIELD(pkgbin, fip->integer, int) = multiarch;
 }
 
@@ -207,11 +219,20 @@ f_priority(struct pkginfo *pkg, struct pkgbin *pkgbin,
            struct parsedb_state *ps,
            const char *value, const struct fieldinfo *fip)
 {
+  const char *str = value;
+  int priority;
+
   if (!*value) return;
-  pkg->priority = parse_nv_last(ps, _("word in 'Priority' field"),
-                                priorityinfos, value);
-  if (pkg->priority == PKG_PRIO_OTHER)
+
+  priority = parse_nv(ps, PARSE_NV_LAST | PARSE_NV_FALLBACK, &str,
+                      priorityinfos, _("word in 'Priority' field"));
+
+  if (str == NULL) {
+    pkg->priority = PKG_PRIO_OTHER;
     pkg->otherpriority = nfstrsave(value);
+  } else {
+    pkg->priority = priority;
+  }
 }
 
 void
@@ -226,12 +247,12 @@ f_status(struct pkginfo *pkg, struct pkgbin *pkgbin,
   if (ps->flags & pdb_recordavailable)
     return;
 
-  pkg->want = parse_nv_next(ps, _("first (want) word in 'Status' field"),
-                            wantinfos, &value);
-  pkg->eflag = parse_nv_next(ps, _("second (error) word in 'Status' field"),
-                             eflaginfos, &value);
-  pkg->status = parse_nv_last(ps, _("third (status) word in 'Status' field"),
-                              statusinfos, value);
+  pkg->want = parse_nv(ps, PARSE_NV_NEXT, &value, wantinfos,
+                       _("first (want) word in 'Status' field"));
+  pkg->eflag = parse_nv(ps, PARSE_NV_NEXT, &value, eflaginfos,
+                        _("second (error) word in 'Status' field"));
+  pkg->status = parse_nv(ps, PARSE_NV_LAST, &value, statusinfos,
+                         _("third (status) word in 'Status' field"));
 }
 
 void
diff --git a/lib/dpkg/namevalue.c b/lib/dpkg/namevalue.c
index f3536a6..f585446 100644
--- a/lib/dpkg/namevalue.c
+++ b/lib/dpkg/namevalue.c
@@ -29,16 +29,12 @@
 const struct namevalue *
 namevalue_find_by_name(const struct namevalue *head, const char *str)
 {
-       const struct namevalue *nv, *nv_fallback = NULL;
+       const struct namevalue *nv;
 
        for (nv = head; nv->name; nv++) {
-               if (nv->length == 0) {
-                       nv_fallback = nv;
-                       continue;
-               }
                if (strncasecmp(str, nv->name, nv->length) == 0)
                        return nv;
        }
 
-       return nv_fallback;
+       return NULL;
 }
diff --git a/lib/dpkg/namevalue.h b/lib/dpkg/namevalue.h
index 65f8bd8..0bcbe93 100644
--- a/lib/dpkg/namevalue.h
+++ b/lib/dpkg/namevalue.h
@@ -40,8 +40,6 @@ struct namevalue {
 
 #define NAMEVALUE_DEF(n, v) \
        [v] = { .name = n, .value = v, .length = sizeof(n) - 1 }
-#define NAMEVALUE_FALLBACK_DEF(n, v) \
-       [v] = { .name = n, .value = v, .length = 0 }
 
 const struct namevalue *namevalue_find_by_name(const struct namevalue *head,
                                                const char *str);
diff --git a/lib/dpkg/pkg-namevalue.c b/lib/dpkg/pkg-namevalue.c
index 6304ed5..be30332 100644
--- a/lib/dpkg/pkg-namevalue.c
+++ b/lib/dpkg/pkg-namevalue.c
@@ -45,7 +45,6 @@ const struct namevalue priorityinfos[] = {
        NAMEVALUE_DEF("standard",               PKG_PRIO_STANDARD),
        NAMEVALUE_DEF("optional",               PKG_PRIO_OPTIONAL),
        NAMEVALUE_DEF("extra",                  PKG_PRIO_EXTRA),
-       NAMEVALUE_FALLBACK_DEF("this is a bug - please report", PKG_PRIO_OTHER),
        NAMEVALUE_DEF("unknown",                PKG_PRIO_UNKNOWN),
        { .name = NULL }
 };

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/dpkg/dpkg.git


-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to