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