Ted Unangst wrote:
> MarcusMüller wrote:
> > I've just stumbled across a malfunction in signify: It cannot handle
> > file names that contain a `)` character, when checking a list of hashes
> > generated by `sha256` command line utilities (`sha256sum --tags` on
> > Linux). 
> 
> This fix is unfortunately rather complicated for the problem. Files with ) are
> not used within openbsd, for instance. It may possible to simplify it a bit? 

Not much simpler, but maybe this is easier to follow. Keeps the hair in a
separate function.


Index: signify.c
===================================================================
RCS file: /home/cvs/src/usr.bin/signify/signify.c,v
retrieving revision 1.134
diff -u -p -r1.134 signify.c
--- signify.c   22 Dec 2019 06:37:25 -0000      1.134
+++ signify.c   21 Jan 2020 22:20:55 -0000
@@ -651,6 +651,37 @@ verifychecksum(struct checksum *c, int q
 }
 
 static void
+scanchecksum(const char *input, struct checksum *c)
+{
+       char *p, *algo, *file, *hash;
+       char line[2 * PATH_MAX];
+
+       if (strlcpy(line, input, sizeof(line)) >= sizeof(line))
+           goto fail;
+
+       /* algo (filename) = hash */
+       algo = line;
+       p = strchr(algo, ' ');
+       if (p == NULL || strncmp(p, " (", 2) != 0)
+               goto fail;
+       *p = 0;
+       file = p + 2;
+       p = strrchr(file, ')');
+       if (p == NULL || strncmp(p, ") = ", 4) != 0)
+               goto fail;
+       *p = 0;
+       hash = p + 4;
+
+       if (strlcpy(c->algo, algo, sizeof(c->algo)) >= sizeof(c->algo) ||
+           strlcpy(c->file, file, sizeof(c->file)) >= sizeof(c->file) ||
+           strlcpy(c->hash, hash, sizeof(c->hash)) >= sizeof(c->hash))
+               goto fail;
+       return;
+fail:
+       errx(1, "unable to parse checksum line %s", input);
+}
+
+static void
 verifychecksums(char *msg, int argc, char **argv, int quiet)
 {
        struct ohash_info info = { 0, NULL, ecalloc, efree, NULL };
@@ -658,7 +689,7 @@ verifychecksums(char *msg, int argc, cha
        struct checksum c;
        char *e, *line, *endline;
        int hasfailed = 0;
-       int i, rv;
+       int i;
        unsigned int slot;
 
        ohash_init(&myh, 6, &info);
@@ -675,13 +706,8 @@ verifychecksums(char *msg, int argc, cha
        while (line && *line) {
                if ((endline = strchr(line, '\n')))
                        *endline++ = '\0';
-#if PATH_MAX < 1024 || HASHBUFSIZE < 224
-#error sizes are wrong
-#endif
-               rv = sscanf(line, "%31s (%1023[^)]) = %223s",
-                   c.algo, c.file, c.hash);
-               if (rv != 3)
-                       errx(1, "unable to parse checksum line %s", line);
+
+               scanchecksum(line, &c);
                line = endline;
                if (argc) {
                        slot = ohash_qlookup(&myh, c.file);

Reply via email to