apps/rehash.c: avoid printf format warning [-Wformat]
authorMatthias St. Pierre <matthias.st.pierre@ncp-e.com>
Wed, 25 Oct 2023 09:05:58 +0000 (11:05 +0200)
committerTomas Mraz <tomas@openssl.org>
Wed, 8 Nov 2023 09:28:22 +0000 (10:28 +0100)
The `aarch64-linux-android33-clang` cross-compiler (v14.0.6)
complains twice about an unsupported '%n' format specifier,
preventing a successful `--strict-warnings` build:

    error: '%n' specifier not supported on this platform [-Werror,-Wformat]
                BIO_snprintf(buf, buflen, "%s%s%n%08x.%s%d",

This is a false positive, because BIO_snprintf() implements its
own format parsing (which is implemented in the _dopr() function).

This commit fixes the problem by rewriting the code to dispense with
the dubious '%n' format specifier. As a side-effect, the code becomes
a little bit more comprehensible and self-explaining.

Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22511)

apps/rehash.c

index dbd1389acdf4feddbe9d1395f6569a8d975733f1..1e5cf38a7fe47bc6bf020e6da24afa6b38e3e8b5 100644 (file)
@@ -355,9 +355,9 @@ static int do_dir(const char *dirname, enum Hash h)
     OPENSSL_DIR_CTX *d = NULL;
     struct stat st;
     unsigned char idmask[MAX_COLLISIONS / 8];
-    int n, numfiles, nextid, buflen, errs = 0;
+    int n, numfiles, nextid, dirlen, buflen, errs = 0;
     size_t i;
-    const char *pathsep;
+    const char *pathsep = "";
     const char *filename;
     char *buf, *copy = NULL;
     STACK_OF(OPENSSL_STRING) *files = NULL;
@@ -366,9 +366,12 @@ static int do_dir(const char *dirname, enum Hash h)
         BIO_printf(bio_err, "Skipping %s, can't write\n", dirname);
         return 1;
     }
-    buflen = strlen(dirname);
-    pathsep = (buflen && !ends_with_dirsep(dirname)) ? "/": "";
-    buflen += NAME_MAX + 1 + 1;
+    dirlen = strlen(dirname);
+    if (dirlen != 0 && !ends_with_dirsep(dirname)) {
+        pathsep = "/";
+        dirlen++;
+    }
+    buflen = dirlen + NAME_MAX + 1;
     buf = app_malloc(buflen, "filename buffer");
 
     if (verbose)
@@ -427,12 +430,12 @@ static int do_dir(const char *dirname, enum Hash h)
                     while (bit_isset(idmask, nextid))
                         nextid++;
 
-                    BIO_snprintf(buf, buflen, "%s%s%n%08x.%s%d",
-                                 dirname, pathsep, &n, bp->hash,
+                    BIO_snprintf(buf, buflen, "%s%s%08x.%s%d",
+                                 dirname, pathsep, bp->hash,
                                  suffixes[bp->type], nextid);
                     if (verbose)
                         BIO_printf(bio_out, "link %s -> %s\n",
-                                   ep->filename, &buf[n]);
+                                   ep->filename, &buf[dirlen]);
                     if (unlink(buf) < 0 && errno != ENOENT) {
                         BIO_printf(bio_err,
                                    "%s: Can't unlink %s, %s\n",
@@ -449,12 +452,12 @@ static int do_dir(const char *dirname, enum Hash h)
                     bit_set(idmask, nextid);
                 } else if (remove_links) {
                     /* Link to be deleted */
-                    BIO_snprintf(buf, buflen, "%s%s%n%08x.%s%d",
-                                 dirname, pathsep, &n, bp->hash,
+                    BIO_snprintf(buf, buflen, "%s%s%08x.%s%d",
+                                 dirname, pathsep, bp->hash,
                                  suffixes[bp->type], ep->old_id);
                     if (verbose)
                         BIO_printf(bio_out, "unlink %s\n",
-                                   &buf[n]);
+                                   &buf[dirlen]);
                     if (unlink(buf) < 0 && errno != ENOENT) {
                         BIO_printf(bio_err,
                                    "%s: Can't unlink %s, %s\n",