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);