diff --git a/pkgs/tools/misc/file/0003-Add-LE-BE-GUID.patch b/pkgs/tools/misc/file/0003-Add-LE-BE-GUID.patch new file mode 100644 index 000000000000..69e52586b5f6 --- /dev/null +++ b/pkgs/tools/misc/file/0003-Add-LE-BE-GUID.patch @@ -0,0 +1,631 @@ +From 797a275514c80303accbd821df9692b04f6020e6 Mon Sep 17 00:00:00 2001 +From: Christos Zoulas +Date: Sun, 19 Apr 2026 19:56:49 +0000 +Subject: [PATCH] Add LE/BE GUID + +(OPNA2608: removed hunks that change file modification dates, as they +make it more difficult to apply the patch) + +(OPNA2608: merge typo fix 2866af2e51beb40afe35d2ff5e765991ac459237) + +--- + doc/magic.man | 8 ++-- + src/Makefile.am | 3 +- + src/apprentice.c | 121 ++++++++++------------------------------------- + src/file.h | 31 ++++++------ + src/funcs.c | 30 +++++++++--- + src/print.c | 11 +++-- + src/softmagic.c | 18 ++++++- + src/swap.c | 101 +++++++++++++++++++++++++++++++++++++++ + src/swap.h | 48 +++++++++++++++++++ + 9 files changed, 247 insertions(+), 124 deletions(-) + create mode 100644 src/swap.c + create mode 100644 src/swap.h + +diff --git a/doc/magic.man b/doc/magic.man +index aa9f8da247..bad8111b28 100644 +--- a/doc/magic.man ++++ b/doc/magic.man +@@ -373,7 +373,9 @@ The DER types are: + .Dv rel-oid-iri . + These types can be followed by an optional numeric size, which indicates + the field width in bytes. +-.It Dv guid ++.It Dv guid , ++.It Dv leguid , ++.It Dv beguid + A Globally Unique Identifier, parsed and printed as + XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. + Its format is a string. +diff --git a/src/Makefile.am b/src/Makefile.am +index 64c0414367..10cf6fcb23 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -10,7 +10,8 @@ AM_CFLAGS = $(CFLAG_VISIBILITY) @WARNINGS@ + libmagic_la_SOURCES = buffer.c magic.c apprentice.c softmagic.c ascmagic.c \ + encoding.c compress.c is_csv.c is_json.c is_simh.c is_tar.c readelf.c \ + print.c fsmagic.c funcs.c file.h readelf.h tar.h apptype.c der.c der.h \ +- file_opts.h elfclass.h mygetopt.h cdf.c cdf_time.c readcdf.c cdf.h ++ file_opts.h elfclass.h mygetopt.h cdf.c cdf_time.c readcdf.c cdf.h \ ++ swap.c swap.h + libmagic_la_LDFLAGS = -no-undefined -version-info 1:0:0 + if MINGW + MINGWLIBS = -lgnurx -lshlwapi +diff --git a/src/apprentice.c b/src/apprentice.c +index a6ab9e7c30..b67897b45a 100644 +--- a/src/apprentice.c ++++ b/src/apprentice.c +@@ -32,6 +32,7 @@ + #endif /* lint */ + + #include "magic.h" ++#include "swap.h" + #include + #ifdef HAVE_UNISTD_H + #include +@@ -50,12 +51,6 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.373 2026/04/17 14:58:57 christos Exp $") + #endif + #include + #include +-#ifdef HAVE_BYTESWAP_H +-#include +-#endif +-#ifdef HAVE_SYS_BSWAP_H +-#include +-#endif + + + #define EATAB {while (*l && isascii(CAST(unsigned char, *l)) && \ +@@ -131,20 +126,6 @@ file_private void mlist_free(struct mlist *); + file_private void byteswap(struct magic *, uint32_t); + file_private void bs1(struct magic *); + +-#if defined(HAVE_BYTESWAP_H) +-#define swap2(x) bswap_16(x) +-#define swap4(x) bswap_32(x) +-#define swap8(x) bswap_64(x) +-#elif defined(HAVE_SYS_BSWAP_H) +-#define swap2(x) bswap16(x) +-#define swap4(x) bswap32(x) +-#define swap8(x) bswap64(x) +-#else +-file_private uint16_t swap2(uint16_t); +-file_private uint32_t swap4(uint32_t); +-file_private uint64_t swap8(uint64_t); +-#endif +- + file_private char *mkdbname(struct magic_set *, const char *, int); + file_private struct magic_map *apprentice_buf(struct magic_set *, struct magic *, + size_t); +@@ -285,6 +266,8 @@ static const struct type_tbl_s type_tbl[] = { + { XX("clear"), FILE_CLEAR, FILE_FMT_NONE }, + { XX("der"), FILE_DER, FILE_FMT_STR }, + { XX("guid"), FILE_GUID, FILE_FMT_STR }, ++ { XX("leguid"), FILE_LEGUID, FILE_FMT_STR }, ++ { XX("beguid"), FILE_BEGUID, FILE_FMT_STR }, + { XX("offset"), FILE_OFFSET, FILE_FMT_QUAD }, + { XX("bevarint"), FILE_BEVARINT, FILE_FMT_STR }, + { XX("levarint"), FILE_LEVARINT, FILE_FMT_STR }, +@@ -926,6 +909,8 @@ typesize(int type) + case FILE_LEVARINT: + return 8; + ++ case FILE_LEGUID: ++ case FILE_BEGUID: + case FILE_GUID: + return 16; + +@@ -989,6 +974,8 @@ apprentice_magic_strength_1(const struct magic *m) + case FILE_BEVARINT: + case FILE_LEVARINT: + case FILE_GUID: ++ case FILE_LEGUID: ++ case FILE_BEGUID: + case FILE_BEID3: + case FILE_LEID3: + case FILE_OFFSET: +@@ -1251,6 +1238,8 @@ set_test_type(struct magic *mstart, struct magic *m) + case FILE_LEVARINT: + case FILE_DER: + case FILE_GUID: ++ case FILE_LEGUID: ++ case FILE_BEGUID: + case FILE_OFFSET: + case FILE_MSDOSDATE: + case FILE_BEMSDOSDATE: +@@ -1733,6 +1722,8 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v) + case FILE_CLEAR: + case FILE_DER: + case FILE_GUID: ++ case FILE_LEGUID: ++ case FILE_BEGUID: + case FILE_OCTAL: + break; + default: +@@ -2943,6 +2934,8 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action) + if (errno == 0) + *p = ep; + return 0; ++ case FILE_BEGUID: ++ case FILE_LEGUID: + case FILE_GUID: + if (file_parse_guid(*p, m->value.guid) == -1) { + file_magwarn(ms, "Error parsing guid `%s'", *p); +@@ -3418,7 +3411,7 @@ check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname) + + ptr = CAST(uint32_t *, map->p); + if (*ptr != MAGICNO) { +- if (swap4(*ptr) != MAGICNO) { ++ if (file_swap4(*ptr) != MAGICNO) { + file_error(ms, 0, "bad magic in `%s'", dbname); + return -1; + } +@@ -3426,7 +3419,7 @@ check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname) + } else + needsbyteswap = 0; + if (needsbyteswap) +- version = swap4(ptr[1]); ++ version = file_swap4(ptr[1]); + else + version = ptr[1]; + if (version != VERSIONNO) { +@@ -3439,7 +3432,7 @@ check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname) + nentries = 0; + for (i = 0; i < MAGIC_SETS; i++) { + if (needsbyteswap) +- map->nmagic[i] = swap4(ptr[i + 2]); ++ map->nmagic[i] = file_swap4(ptr[i + 2]); + else + map->nmagic[i] = ptr[i + 2]; + if (map->nmagic[i] > entries) { +@@ -3577,69 +3570,6 @@ byteswap(struct magic *magic, uint32_t nmagic) + bs1(&magic[i]); + } + +-#if !defined(HAVE_BYTESWAP_H) && !defined(HAVE_SYS_BSWAP_H) +-/* +- * swap a short +- */ +-file_private uint16_t +-swap2(uint16_t sv) +-{ +- uint16_t rv; +- uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv)); +- uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv)); +- d[0] = s[1]; +- d[1] = s[0]; +- return rv; +-} +- +-/* +- * swap an int +- */ +-file_private uint32_t +-swap4(uint32_t sv) +-{ +- uint32_t rv; +- uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv)); +- uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv)); +- d[0] = s[3]; +- d[1] = s[2]; +- d[2] = s[1]; +- d[3] = s[0]; +- return rv; +-} +- +-/* +- * swap a quad +- */ +-file_private uint64_t +-swap8(uint64_t sv) +-{ +- uint64_t rv; +- uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv)); +- uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv)); +-# if 0 +- d[0] = s[3]; +- d[1] = s[2]; +- d[2] = s[1]; +- d[3] = s[0]; +- d[4] = s[7]; +- d[5] = s[6]; +- d[6] = s[5]; +- d[7] = s[4]; +-# else +- d[0] = s[7]; +- d[1] = s[6]; +- d[2] = s[5]; +- d[3] = s[4]; +- d[4] = s[3]; +- d[5] = s[2]; +- d[6] = s[1]; +- d[7] = s[0]; +-# endif +- return rv; +-} +-#endif +- + file_protected uintmax_t + file_varint2uintmax_t(const unsigned char *us, int t, size_t *l) + { +@@ -3676,16 +3606,16 @@ file_varint2uintmax_t(const unsigned char *us, int t, size_t *l) + file_private void + bs1(struct magic *m) + { +- m->flag = swap2(m->flag); +- m->offset = swap4(CAST(uint32_t, m->offset)); +- m->in_offset = swap4(CAST(uint32_t, m->in_offset)); +- m->lineno = swap4(CAST(uint32_t, m->lineno)); ++ m->flag = file_swap2(m->flag); ++ m->offset = file_swap4(CAST(uint32_t, m->offset)); ++ m->in_offset = file_swap4(CAST(uint32_t, m->in_offset)); ++ m->lineno = file_swap4(CAST(uint32_t, m->lineno)); + if (IS_STRING(m->type)) { +- m->str_range = swap4(m->str_range); +- m->str_flags = swap4(m->str_flags); ++ m->str_range = file_swap4(m->str_range); ++ m->str_flags = file_swap4(m->str_flags); + } else { +- m->value.q = swap8(m->value.q); +- m->num_mask = swap8(m->num_mask); ++ m->value.q = file_swap8(m->value.q); ++ m->num_mask = file_swap8(m->num_mask); + } + } + +@@ -3708,6 +3638,7 @@ file_pstring_length_size(struct magic_set *ms, const struct magic *m) + return FILE_BADSIZE; + } + } ++ + file_protected size_t + file_pstring_get_length(struct magic_set *ms, const struct magic *m, + const char *ss) +diff --git a/src/file.h b/src/file.h +index 258b776976..25e365351d 100644 +--- a/src/file.h ++++ b/src/file.h +@@ -179,7 +179,7 @@ + #define MAXstring 128 /* max len of "string" types */ + + #define MAGICNO 0xF11E041C +-#define VERSIONNO 20 ++#define VERSIONNO 21 + #define FILE_MAGICSIZE 432 + + #define FILE_GUID_SIZE sizeof("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX") +@@ -292,17 +292,19 @@ struct magic { + #define FILE_CLEAR 47 + #define FILE_DER 48 + #define FILE_GUID 49 +-#define FILE_OFFSET 50 +-#define FILE_BEVARINT 51 +-#define FILE_LEVARINT 52 +-#define FILE_MSDOSDATE 53 +-#define FILE_LEMSDOSDATE 54 +-#define FILE_BEMSDOSDATE 55 +-#define FILE_MSDOSTIME 56 +-#define FILE_LEMSDOSTIME 57 +-#define FILE_BEMSDOSTIME 58 +-#define FILE_OCTAL 59 +-#define FILE_NAMES_SIZE 60 /* size of array to contain all names */ ++#define FILE_LEGUID 50 ++#define FILE_BEGUID 51 ++#define FILE_OFFSET 52 ++#define FILE_BEVARINT 53 ++#define FILE_LEVARINT 54 ++#define FILE_MSDOSDATE 55 ++#define FILE_LEMSDOSDATE 56 ++#define FILE_BEMSDOSDATE 57 ++#define FILE_MSDOSTIME 58 ++#define FILE_LEMSDOSTIME 59 ++#define FILE_BEMSDOSTIME 60 ++#define FILE_OCTAL 61 ++#define FILE_NAMES_SIZE 62 /* size of array to contain all names */ + + #define IS_STRING(t) \ + ((t) == FILE_STRING || \ +@@ -558,7 +560,8 @@ file_protected int file_separator(struct magic_set *); + file_protected char *file_copystr(char *, size_t, size_t, const char *); + file_protected int file_checkfmt(char *, size_t, const char *); + file_protected size_t file_printedlen(const struct magic_set *); +-file_protected int file_print_guid(char *, size_t, const uint64_t *); ++file_protected int file_print_leguid(char *, size_t, const uint64_t *); ++file_protected int file_print_beguid(char *, size_t, const uint64_t *); + file_protected int file_parse_guid(const char *, uint64_t *); + file_protected int file_replace(struct magic_set *, const char *, const char *); + file_protected int file_printf(struct magic_set *, const char *, ...) +diff --git a/src/funcs.c b/src/funcs.c +index dd80198f36..e5782bf2e8 100644 +--- a/src/funcs.c ++++ b/src/funcs.c +@@ -27,6 +27,7 @@ + #endif /* lint */ + + #include "magic.h" ++#include "swap.h" + #include + #include + #include +@@ -934,12 +935,9 @@ file_parse_guid(const char *s, uint64_t *guid) + return 0; + } + +-file_protected int +-file_print_guid(char *str, size_t len, const uint64_t *guid) ++file_private int ++file_print_guid(char *str, size_t len, const struct guid *g) + { +- const struct guid *g = CAST(const struct guid *, +- CAST(const void *, guid)); +- + #ifndef WIN32 + return snprintf(str, len, "%.8X-%.4hX-%.4hX-%.2hhX%.2hhX-" + "%.2hhX%.2hhX%.2hhX%.2hhX%.2hhX%.2hhX", +@@ -955,6 +953,26 @@ file_print_guid(char *str, size_t len, const uint64_t *guid) + #endif + } + ++file_protected int ++file_print_leguid(char *str, size_t len, const uint64_t *guid) ++{ ++ const struct guid *g = CAST(const struct guid *, ++ CAST(const void *, guid)); ++ return file_print_guid(str, len, g); ++} ++ ++file_protected int ++file_print_beguid(char *str, size_t len, const uint64_t *guid) ++{ ++ const struct guid *g = CAST(const struct guid *, ++ CAST(const void *, guid)); ++ struct guid gg = *g; ++ gg.data1 = file_swap4(gg.data1); ++ gg.data2 = file_swap2(gg.data2); ++ gg.data3 = file_swap2(gg.data3); ++ return file_print_guid(str, len, &gg); ++} ++ + file_protected int + file_pipe_closexec(int *fds) + { +diff --git a/src/print.c b/src/print.c +index 0740fd67e2..ac0802f309 100644 +--- a/src/print.c ++++ b/src/print.c +@@ -227,12 +227,17 @@ file_mdump(struct magic *m) + case FILE_DER: + (void) fprintf(stderr, "'%s'", m->value.s); + break; ++ case FILE_LEGUID: + case FILE_GUID: +- (void) file_print_guid(tbuf, sizeof(tbuf), ++ (void) file_print_leguid(tbuf, sizeof(tbuf), ++ m->value.guid); ++ (void) fprintf(stderr, "%s", tbuf); ++ break; ++ case FILE_BEGUID: ++ (void) file_print_beguid(tbuf, sizeof(tbuf), + m->value.guid); + (void) fprintf(stderr, "%s", tbuf); + break; +- + default: + (void) fprintf(stderr, "*bad type %d*", m->type); + break; +diff --git a/src/softmagic.c b/src/softmagic.c +index 370be0a54d..2f04b5ce6c 100644 +--- a/src/softmagic.c ++++ b/src/softmagic.c +@@ -812,7 +812,13 @@ mprint(struct magic_set *ms, struct magic *m) + return -1; + break; + case FILE_GUID: +- (void) file_print_guid(buf, sizeof(buf), ms->ms_value.guid); ++ case FILE_LEGUID: ++ (void) file_print_leguid(buf, sizeof(buf), ms->ms_value.guid); ++ if (file_printf(ms, F(ms, desc, "%s"), buf) == -1) ++ return -1; ++ break; ++ case FILE_BEGUID: ++ (void) file_print_beguid(buf, sizeof(buf), ms->ms_value.guid); + if (file_printf(ms, F(ms, desc, "%s"), buf) == -1) + return -1; + break; +@@ -972,6 +978,8 @@ moffset(struct magic_set *ms, struct magic *m, size_t nbytes, + } + break; + ++ case FILE_BEGUID: ++ case FILE_LEGUID: + case FILE_GUID: + o = CAST(int32_t, (ms->offset + 2 * sizeof(uint64_t))); + break; +@@ -1333,6 +1341,8 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) + case FILE_USE: + case FILE_DER: + case FILE_GUID: ++ case FILE_LEGUID: ++ case FILE_BEGUID: + return 1; + default: + file_magerror(ms, "invalid type %d in mconvert()", m->type); +@@ -1903,6 +1913,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b, + return 0; + break; + ++ case FILE_LEGUID: ++ case FILE_BEGUID: + case FILE_GUID: + if (OFFSET_OOB(nbytes, offset, 16)) + return 0; +@@ -2416,6 +2428,8 @@ magiccheck(struct magic_set *ms, struct magic *m, file_regex_t **m_cache) + return 0; + } + return matched; ++ case FILE_BEGUID: ++ case FILE_LEGUID: + case FILE_GUID: + l = 0; + v = memcmp(m->value.guid, p->guid, sizeof(p->guid)); +diff --git a/src/swap.c b/src/swap.c +new file mode 100644 +index 0000000000..f20e354237 +--- /dev/null ++++ b/src/swap.c +@@ -0,0 +1,101 @@ ++/* ++ * Copyright (c) Ian F. Darwin 1986-1995. ++ * Software written by Ian F. Darwin and others; ++ * maintained 1995-present by Christos Zoulas and others. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice immediately at the beginning of the file, without modification, ++ * this list of conditions, and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ++ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ */ ++/* ++ * apprentice - make one pass through /etc/magic, learning its secrets. ++ */ ++ ++#include "file.h" ++ ++#ifndef lint ++FILE_RCSID("@(#)$File: swap.c,v 1.1 2026/04/19 19:56:49 christos Exp $") ++#endif /* lint */ ++ ++#include "swap.h" ++ ++#if !defined(HAVE_BYTESWAP_H) && !defined(HAVE_SYS_BSWAP_H) ++/* ++ * swap a short ++ */ ++file_protected uint16_t ++file_swap2(uint16_t sv) ++{ ++ uint16_t rv; ++ uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv)); ++ uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv)); ++ d[0] = s[1]; ++ d[1] = s[0]; ++ return rv; ++} ++ ++/* ++ * swap an int ++ */ ++file_protected uint32_t ++file_swap4(uint32_t sv) ++{ ++ uint32_t rv; ++ uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv)); ++ uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv)); ++ d[0] = s[3]; ++ d[1] = s[2]; ++ d[2] = s[1]; ++ d[3] = s[0]; ++ return rv; ++} ++ ++/* ++ * swap a quad ++ */ ++file_protected uint64_t ++file_swap8(uint64_t sv) ++{ ++ uint64_t rv; ++ uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv)); ++ uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv)); ++# if 0 ++ d[0] = s[3]; ++ d[1] = s[2]; ++ d[2] = s[1]; ++ d[3] = s[0]; ++ d[4] = s[7]; ++ d[5] = s[6]; ++ d[6] = s[5]; ++ d[7] = s[4]; ++# else ++ d[0] = s[7]; ++ d[1] = s[6]; ++ d[2] = s[5]; ++ d[3] = s[4]; ++ d[4] = s[3]; ++ d[5] = s[2]; ++ d[6] = s[1]; ++ d[7] = s[0]; ++# endif ++ return rv; ++} ++#endif +diff --git a/src/swap.h b/src/swap.h +new file mode 100644 +index 0000000000..9fc6428d7d +--- /dev/null ++++ b/src/swap.h +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (c) Ian F. Darwin 1986-1995. ++ * Software written by Ian F. Darwin and others; ++ * maintained 1995-present by Christos Zoulas and others. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice immediately at the beginning of the file, without modification, ++ * this list of conditions, and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ++ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ */ ++ ++#ifdef HAVE_BYTESWAP_H ++#include ++#endif ++#ifdef HAVE_SYS_BSWAP_H ++#include ++#endif ++ ++#if defined(HAVE_BYTESWAP_H) ++#define file_swap2(x) bswap_16(x) ++#define file_swap4(x) bswap_32(x) ++#define file_swap8(x) bswap_64(x) ++#elif defined(HAVE_SYS_BSWAP_H) ++#define file_swap2(x) bswap16(x) ++#define file_swap4(x) bswap32(x) ++#define file_swap8(x) bswap64(x) ++#else ++file_protected uint16_t file_swap2(uint16_t); ++file_protected uint32_t file_swap4(uint32_t); ++file_protected uint64_t file_swap8(uint64_t); ++#endif diff --git a/pkgs/tools/misc/file/0004-Handle-parsing-guids-in-big-endian-machines.patch b/pkgs/tools/misc/file/0004-Handle-parsing-guids-in-big-endian-machines.patch new file mode 100644 index 000000000000..ede424aaba7c --- /dev/null +++ b/pkgs/tools/misc/file/0004-Handle-parsing-guids-in-big-endian-machines.patch @@ -0,0 +1,82 @@ +From 7a2b2a4b6e0f9de8682e6098c514155f2198cc8e Mon Sep 17 00:00:00 2001 +From: Christos Zoulas +Date: Sun, 17 May 2026 17:10:25 +0000 +Subject: [PATCH] Handle parsing guids in big endian machines (Christoph Biedl) + +(OPNA2608: removed hunks that change file modification dates, as they +make it more difficult to apply the patch) + +--- + src/compress.c | 7 +++---- + src/file.h | 3 ++- + src/funcs.c | 21 ++++++++++++++++++++- + 3 files changed, 25 insertions(+), 6 deletions(-) + +diff --git a/src/compress.c b/src/compress.c +index 76b7aad18..7f1d584d0 100644 +--- a/src/compress.c ++++ b/src/compress.c +@@ -125,12 +125,11 @@ static const char *zlib_args[] = { "python", "-c", zlibcode, NULL }; + static int + zlibcmp(const unsigned char *buf) + { +- unsigned short x = 1; +- unsigned char *s = CAST(unsigned char *, CAST(void *, &x)); ++ unsigned short x; + + if ((buf[0] & 0xf) != 8 || (buf[0] & 0x80) != 0) + return 0; +- if (s[0] != 1) /* endianness test */ ++ if (file_bigendian()) /* endianness test */ + x = buf[0] | (buf[1] << 8); + else + x = buf[1] | (buf[0] << 8); +diff --git a/src/file.h b/src/file.h +index 497de9b91..6a39801e4 100644 +--- a/src/file.h ++++ b/src/file.h +@@ -597,6 +597,7 @@ file_protected uint64_t file_signextend(struct magic_set *, struct magic *, + file_protected uintmax_t file_varint2uintmax_t(const unsigned char *, int, + size_t *); + ++file_protected int file_bigendian(void); + file_protected void file_badread(struct magic_set *); + file_protected void file_badseek(struct magic_set *); + file_protected void file_oomem(struct magic_set *, size_t); +diff --git a/src/funcs.c b/src/funcs.c +index 8698f3312..0f2e6942b 100644 +--- a/src/funcs.c ++++ b/src/funcs.c +@@ -52,6 +52,18 @@ FILE_RCSID("@(#)$File: funcs.c,v 1.151 2026/05/16 15:21:40 christos Exp $") + #define SIZE_MAX ((size_t)~0) + #endif + ++file_protected int ++file_bigendian(void) ++{ ++ union { ++ unsigned short x; ++ unsigned char s[sizeof(unsigned short)]; ++ } u; ++ ++ u.x = 1; ++ return u.s[0] != 1; ++} ++ + file_protected char * + file_copystr(char *buf, size_t blen, size_t width, const char *str) + { +@@ -931,6 +943,13 @@ file_parse_guid(const char *s, uint64_t *guid) + !getxvalue(&g->data4[6], s + 8, 2) || + !getxvalue(&g->data4[7], s + 10, 2)) + return -1; ++ ++ if (file_bigendian()) { ++ g->data1 = file_swap4(g->data1); ++ g->data2 = file_swap2(g->data2); ++ g->data3 = file_swap2(g->data3); ++ ++ } + return 0; + } + diff --git a/pkgs/tools/misc/file/default.nix b/pkgs/tools/misc/file/default.nix index ae27a481b38f..4bd56f4dcfb3 100644 --- a/pkgs/tools/misc/file/default.nix +++ b/pkgs/tools/misc/file/default.nix @@ -3,6 +3,8 @@ stdenv, fetchurl, buildPackages, + autoconf, + automake, zlib, libgnurx, updateAutotoolsGnuConfigScriptsHook, @@ -41,16 +43,37 @@ stdenv.mkDerivation (finalAttrs: { ./0001-PR-745-streamout-Don-t-flush-when-trying-to-set-nega.patch # Fixes breakage of python3Packages.python-magic and xdg-utils ./0002-PR-725-inliniac-Revert-previous-and-always-set-offse.patch + + # Splits byteswapping functions into a separate file & reuses them across the codebase + # (needed for GUID parsing fix below) + # https://github.com/file/file/commit/797a275514c80303accbd821df9692b04f6020e6 + # https://github.com/file/file/commit/2866af2e51beb40afe35d2ff5e765991ac459237 + ./0003-Add-LE-BE-GUID.patch + + # Fixes GUID parsing on big-endian + # https://github.com/file/file/commit/7a2b2a4b6e0f9de8682e6098c514155f2198cc8e + ./0004-Handle-parsing-guids-in-big-endian-machines.patch ]; strictDeps = true; enableParallelBuilding = true; nativeBuildInputs = [ + # 0003-Add-LE-BE-GUID.patch touches automake file, need to regenerate files + # autoreconfHook would cause inf rec (hook -> libtool -> file -> hook), adding the individual components we need + autoconf + automake + updateAutotoolsGnuConfigScriptsHook ]; buildInputs = [ zlib ] ++ lib.optional stdenv.hostPlatform.isMinGW libgnurx; + # 0003-Add-LE-BE-GUID.patch touches automake file, need to regenerate files + # autoreconfHook would cause inf rec (hook -> libtool -> file -> hook), manually calling autoreconf + preConfigure = '' + autoreconf + ''; + # https://bugs.astron.com/view.php?id=382 doCheck = !stdenv.buildPlatform.isMusl;