[File] [PATCH] Avoid cast of address constant to integer constant in initalizer

Michael Forney mforney at mforney.org
Fri Dec 20 23:49:34 UTC 2019


RCAST converts an address constant to an integer, and then to pointer. An
integer constant cast to a pointer type is a valid address constant,
however, a pointer cast to a integer is not an integer constant:

> Cast operators in an integer constant expression shall only convert
> arithmetic types to integer types, except as part of an operand to the
> sizeof operator.

So the result of RCAST(const void *, zlibcmp) is not technically a
constant expression, and might be rejected by some compilers when it is
used in an initializer for an object with static storage.

Instead, just use a union so no casts are necessary.
---
Initializing the second member of a union requires C99 initialization
syntax. I couldn't figure out if file is strictly ANSI C, but if so,
the union could be replaced with two struct members instead.

 src/compress.c | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/src/compress.c b/src/compress.c
index 33ce2bc9..569c87e8 100644
--- a/src/compress.c
+++ b/src/compress.c
@@ -161,7 +161,10 @@ static const char *zstd_args[] = {
 #define	do_bzlib	NULL
 
 private const struct {
-	const void *magic;
+	union {
+		const void *magic;
+		int (*func)(const unsigned char *);
+	} u;
 	int maglen;
 	const char **argv;
 	void *unused;
@@ -171,26 +174,26 @@ private const struct {
 #define METH_XZ		9
 #define METH_LZMA	13
 #define METH_ZLIB	14
-	{ "\037\235",	2, gzip_args, NULL },		/* 0, compressed */
+	{ { "\037\235" },	2, gzip_args, NULL },		/* 0, compressed */
 	/* Uncompress can get stuck; so use gzip first if we have it
 	 * Idea from Damien Clark, thanks! */
-	{ "\037\235",	2, uncompress_args, NULL },	/* 1, compressed */
-	{ "\037\213",	2, gzip_args, do_zlib },	/* 2, gzipped */
-	{ "\037\236",	2, gzip_args, NULL },		/* 3, frozen */
-	{ "\037\240",	2, gzip_args, NULL },		/* 4, SCO LZH */
+	{ { "\037\235" },	2, uncompress_args, NULL },	/* 1, compressed */
+	{ { "\037\213" },	2, gzip_args, do_zlib },	/* 2, gzipped */
+	{ { "\037\236" },	2, gzip_args, NULL },		/* 3, frozen */
+	{ { "\037\240" },	2, gzip_args, NULL },		/* 4, SCO LZH */
 	/* the standard pack utilities do not accept standard input */
-	{ "\037\036",	2, gzip_args, NULL },		/* 5, packed */
-	{ "PK\3\4",	4, gzip_args, NULL },		/* 6, pkzipped, */
+	{ { "\037\036" },	2, gzip_args, NULL },		/* 5, packed */
+	{ { "PK\3\4" },		4, gzip_args, NULL },		/* 6, pkzipped, */
 	/* ...only first file examined */
-	{ "BZh",	3, bzip2_args, do_bzlib },	/* 7, bzip2-ed */
-	{ "LZIP",	4, lzip_args, NULL },		/* 8, lzip-ed */
- 	{ "\3757zXZ\0",	6, xz_args, NULL },		/* 9, XZ Utils */
- 	{ "LRZI",	4, lrzip_args, NULL },	/* 10, LRZIP */
- 	{ "\004\"M\030",4, lz4_args, NULL },		/* 11, LZ4 */
- 	{ "\x28\xB5\x2F\xFD", 4, zstd_args, NULL },	/* 12, zstd */
-	{ RCAST(const void *, lzmacmp),	-13, xz_args, NULL },	/* 13, lzma */
+	{ { "BZh" },		3, bzip2_args, do_bzlib },	/* 7, bzip2-ed */
+	{ { "LZIP" },		4, lzip_args, NULL },		/* 8, lzip-ed */
+	{ { "\3757zXZ\0" },	6, xz_args, NULL },		/* 9, XZ Utils */
+	{ { "LRZI" },		4, lrzip_args, NULL },		/* 10, LRZIP */
+	{ { "\004\"M\030" },	4, lz4_args, NULL },		/* 11, LZ4 */
+	{ { "\x28\xB5\x2F\xFD" }, 4, zstd_args, NULL },		/* 12, zstd */
+	{ { .func = lzmacmp },	-13, xz_args, NULL },		/* 13, lzma */
 #ifdef ZLIBSUPPORT
-	{ RCAST(const void *, zlibcmp),	-2, zlib_args, NULL },	/* 14, zlib */
+	{ { .func = zlibcmp },	-2, zlib_args, NULL },		/* 14, zlib */
 #endif
 };
 
@@ -262,10 +265,9 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
 		if (nbytes < CAST(size_t, abs(compr[i].maglen)))
 			continue;
 		if (compr[i].maglen < 0) {
-			zm = (RCAST(int (*)(const unsigned char *),
-			    CCAST(void *, compr[i].magic)))(buf);
+			zm = compr[i].u.func(buf);
 		} else {
-			zm = memcmp(buf, compr[i].magic,
+			zm = memcmp(buf, compr[i].u.magic,
 			    CAST(size_t, compr[i].maglen)) == 0;
 		}
 
-- 
2.24.1



More information about the File mailing list