diff options
| author | Xin LI <delphij@FreeBSD.org> | 2026-06-03 04:37:29 +0000 |
|---|---|---|
| committer | Xin LI <delphij@FreeBSD.org> | 2026-06-03 04:37:29 +0000 |
| commit | 79746c47b95c50bfab9b70e86bafdfeb844d9118 (patch) | |
| tree | 3e1ea3960c21349604c2a4f3744f6da7c0ecad45 | |
| parent | 995a16e0c2eb64b0875bccf37e696bddf35c3846 (diff) | |
82 files changed, 2041 insertions, 594 deletions
diff --git a/ChangeLog b/ChangeLog index d2dfbc14b77f..e7ce3347eff4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2026-02-26 11:32 Christos Zoulas <christos@zoulas.com> + + * release 5.47 + +2026-02-04 09:54 Christos Zoulas <christos@zoulas.com> + * Better multi-compound document identification by following the + order of the directories entries. (Thomas Ledoux) + +2026-01-19 14:00 Christos Zoulas <christos@zoulas.com> + * if stat fails, don't attempt to restore times (Steven Grubb) + +2025-05-28 15:20 Christos Zoulas <christos@zoulas.com> + + PR/622: Odd_Bloke: Handle negative offsets in file_buffer(), + when fd is not available. + +2025-05-28 12:50 Christos Zoulas <christos@zoulas.com> + + * PR/655: jsummers: Obey str_flags in strings like we do for search + and regex + * PR/659: Pitzl: Apply MAGIC_CONTINUE to annotations; i.e. print + only the first, unless -k is specified. + +2024-12-19 14:44 Christos Zoulas <christos@zoulas.com> + + * PR/592: allow + in format strings + * PR/592: signed operations should be done in signed context + +2024-12-05 13:50 Christos Zoulas <christos@zoulas.com> + + * PR/578: jsummers: Don't crash on cygwin when tm_mon == -1 + * PR/579: net147: Fix stack overrun. + 2024-11-27 14:44 Christos Zoulas <christos@zoulas.com> * release 5.46 diff --git a/config.sub b/config.sub index f6564f2885d4..83c4149b2293 100755 --- a/config.sub +++ b/config.sub @@ -1724,7 +1724,7 @@ case $os in | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ | hiux* | abug | nacl* | netware* | windows* \ - | os9* | macos* | osx* | ios* \ + | os9* | macos* | osx* | ios* | illumos* \ | mpw* | magic* | mmixware* | mon960* | lnews* \ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* | twizzler* \ diff --git a/configure b/configure index cdcdd746f562..3b72db770082 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for file 5.46. +# Generated by GNU Autoconf 2.72 for file 5.47. # # Report bugs to <christos@astron.com>. # @@ -614,8 +614,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='file' PACKAGE_TARNAME='file' -PACKAGE_VERSION='5.46' -PACKAGE_STRING='file 5.46' +PACKAGE_VERSION='5.47' +PACKAGE_STRING='file 5.47' PACKAGE_BUGREPORT='christos@astron.com' PACKAGE_URL='' @@ -1370,7 +1370,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures file 5.46 to adapt to many kinds of systems. +'configure' configures file 5.47 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1441,7 +1441,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of file 5.46:";; + short | recursive ) echo "Configuration of file 5.47:";; esac cat <<\_ACEOF @@ -1567,7 +1567,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -file configure 5.46 +file configure 5.47 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -2153,7 +2153,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by file $as_me 5.46, which was +It was created by file $as_me 5.47, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -3452,7 +3452,7 @@ fi # Define the identity of the package. PACKAGE='file' - VERSION='5.46' + VERSION='5.47' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -16880,7 +16880,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by file $as_me 5.46, which was +This file was extended by file $as_me 5.47, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16948,7 +16948,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -file config.status 5.46 +file config.status 5.47 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 58a5f63657bb..f48ccc36a470 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([file],[5.46],[christos@astron.com]) +AC_INIT([file],[5.47],[christos@astron.com]) AM_INIT_AUTOMAKE([subdir-objects foreign]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) diff --git a/doc/file.man b/doc/file.man index 366e4c3ce847..eab3a1a0b547 100644 --- a/doc/file.man +++ b/doc/file.man @@ -1,5 +1,5 @@ -.\" $File: file.man,v 1.151 2024/04/07 21:27:35 christos Exp $ -.Dd April 7, 2024 +.\" $File: file.man,v 1.153 2025/07/23 18:52:08 christos Exp $ +.Dd June 17, 2025 .Dt FILE __CSECTION__ .Os .Sh NAME @@ -173,7 +173,7 @@ Causes the command to output the file type and creator code as used by older MacOS versions. The code consists of eight letters, -the first describing the file type, the latter the creator. +the first four describing the file type, the latter four the creator. This option works properly only for file formats that have the apple-style output defined. .It Fl b , Fl Fl brief @@ -348,7 +348,7 @@ Set various parameter limits. .It Li elf_shsize Ta 128MB Ta max ELF section size processed .It Li encoding Ta 65K Ta max number of bytes to determine encoding .It Li indir Ta 50 Ta recursion limit for indirect magic -.It Li name Ta 100 Ta use count limit for name/use magic +.It Li name Ta 150 Ta use count limit for name/use magic .It Li regex Ta 8K Ta length limit for regex searches .El .It Fl r , Fl Fl raw diff --git a/doc/magic.man b/doc/magic.man index 6916b7b211d7..b2ae54844606 100644 --- a/doc/magic.man +++ b/doc/magic.man @@ -1,5 +1,5 @@ -.\" $File: magic.man,v 1.110 2024/11/27 15:37:00 christos Exp $ -.Dd November 27, 2024 +.\" $File: magic.man,v 1.115 2025/11/24 15:45:00 christos Exp $ +.Dd November 24, 2025 .Dt MAGIC __FSECTION__ .Os .\" install as magic.4 on USG, magic.5 on V7, Berkeley and Linux systems. @@ -73,7 +73,8 @@ A 64-bit double precision IEEE floating point number in this machine's native by .It Dv string A string of bytes. The string type specification can be optionally followed by a /<width> -option and optionally followed by a set of flags /[bCcftTtWw]*. +option and optionally followed by a set of flags [bCcftTtWw]*. +Slash characters can be used to separate options for readability. The width limits the number of characters to be copied. Zero means all characters. The following flags are supported: @@ -85,24 +86,31 @@ Use upper case insensitive matching: upper case characters in the magic match both lower and upper case characters in the target, whereas lower case characters in the magic only match upper case characters in the target. +(not valid for regex) .It c Use lower case insensitive matching: lower case characters in the magic match both lower and upper case characters in the target, whereas upper case characters in the magic only match upper case characters in the target. +(not valid for regex) To do a complete case insensitive match, specify both .Dq c and .Dq C . .It f Require that the matched string is a full word, not a partial word match. +.It s +Don't include the match length in the offset computation. +(only valid for search and regex) .It T Trim the string, i.e. leading and trailing whitespace +is deleted before the string is printed. .It t Force text file test. .It W Compact whitespace in the target, which must contain at least one whitespace character. +(not valid for regex) If the magic has .Dv n consecutive blanks, the target needs at least @@ -110,7 +118,7 @@ consecutive blanks, the target needs at least consecutive blanks to match. .It w Treat every blank in the magic as an optional blank. -is deleted before the string is printed. +(not valid for regex) .El .It Dv pstring A Pascal-style string where the first byte/short/int is interpreted as the @@ -221,10 +229,10 @@ than UTC. An eight-byte value in little-endian byte order, interpreted as a Windows-style date. .It Dv lemsdosdate -A two-byte value in big-endian byte order, +A two-byte value in little-endian byte order, interpreted as FAT/DOS-style date. .It Dv lemsdostime -A two-byte value in big-endian byte order, +A two-byte value in little-endian byte order, interpreted as FAT/DOS-style time. .It Dv lestring16 A two-byte unicode (UCS16) string in little-endian byte order. @@ -253,7 +261,8 @@ magic entry, like a subroutine call. Named instance direct magic offsets are relative to the offset of the previous matched entry, but indirect offsets are relative to the beginning of the file as usual. -Named magic entries always match. +Named magic entries return true if there was a match in the evaluation +of the entry, or if there was a previous existing match. .It Dv use Recursively call the named magic starting from the current offset. If the name of the referenced begins with a @@ -459,11 +468,12 @@ matching a file, binary patterns are tried first; if no match is found, and the file looks like text, then its encoding is determined and the text patterns are tried. .Pp -The numeric types may optionally be followed by -.Dv \*[Am] +The numeric types may optionally be followed by an operand and a numeric value, -to specify that the value is to be AND'ed with the +to specify that the value is to be modified according to the operand and the numeric value before any comparisons are done. +The following operands are supported: +.Dv \*[Am], \*[Ba], \*[ua], +, -, \&*, /, %. Prepending a .Dv u to the type indicates that ordered comparisons should be unsigned. diff --git a/magic/Magdir/amigaos b/magic/Magdir/amigaos index fdd947fdf7f5..1b8cacaf08ec 100644 --- a/magic/Magdir/amigaos +++ b/magic/Magdir/amigaos @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: amigaos,v 1.20 2021/09/20 00:42:19 christos Exp $ +# $File: amigaos,v 1.23 2026/02/05 18:49:06 christos Exp $ # amigaos: file(1) magic for AmigaOS binary formats: # @@ -36,7 +36,6 @@ 0 string COSO\0 Hippel-COSO Module sound file # Too simple (short, pure ASCII, deep), MPi #26 string V.3 Brian Postma's Soundmon Module sound file v3 -#26 string BPSM Brian Postma's Soundmon Module sound file v3 #26 string V.2 Brian Postma's Soundmon Module sound file v2 # The following are from: "Stefan A. Haubenthal" <polluks@web.de> @@ -195,8 +194,7 @@ 0 string LZX LZX compressed archive (Amiga) # From: Przemek Kramarczyk <pkramarczyk@gmail.com> -0 string .KEY AmigaDOS script -0 string .key AmigaDOS script +0 string/c .key AmigaDOS script # AMOS Basic file formats # https://www.exotica.org.uk/wiki/AMOS_file_formats @@ -216,3 +214,7 @@ >12 regex .{8} \b, type %s 0 string AmBs AMOS Basic memory banks >4 beshort x \b, %d banks + + +# https://github.com/alb42/Leu/blob/master/TCDReaderUnit.pas +3 string TURBOCALC TurboCalc spreadsheet diff --git a/magic/Magdir/animation b/magic/Magdir/animation index 0df435290a3a..4a73e72d8557 100644 --- a/magic/Magdir/animation +++ b/magic/Magdir/animation @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: animation,v 1.98 2024/09/01 15:51:51 christos Exp $ +# $File: animation,v 1.101 2025/05/28 19:54:08 christos Exp $ # animation: file(1) magic for animation/movie formats # # animation formats @@ -542,20 +542,23 @@ >>2 byte&0xF0 !0xF0 MPEG ADTS, layer III, v1 !:strength +20 !:mime audio/mpeg ->>>2 byte&0xF0 0x10 \b, 32 kbps ->>>2 byte&0xF0 0x20 \b, 40 kbps ->>>2 byte&0xF0 0x30 \b, 48 kbps ->>>2 byte&0xF0 0x40 \b, 56 kbps ->>>2 byte&0xF0 0x50 \b, 64 kbps ->>>2 byte&0xF0 0x60 \b, 80 kbps ->>>2 byte&0xF0 0x70 \b, 96 kbps ->>>2 byte&0xF0 0x80 \b, 112 kbps ->>>2 byte&0xF0 0x90 \b, 128 kbps ->>>2 byte&0xF0 0xA0 \b, 160 kbps ->>>2 byte&0xF0 0xB0 \b, 192 kbps ->>>2 byte&0xF0 0xC0 \b, 224 kbps ->>>2 byte&0xF0 0xD0 \b, 256 kbps ->>>2 byte&0xF0 0xE0 \b, 320 kbps +>>>2 search/100 Xing \b, variable bitrate +>>>2 search/100 VBRI \b, variable bitrate +>>>2 default x +>>>>2 byte&0xF0 0x10 \b, 32 kbps +>>>>2 byte&0xF0 0x20 \b, 40 kbps +>>>>2 byte&0xF0 0x30 \b, 48 kbps +>>>>2 byte&0xF0 0x40 \b, 56 kbps +>>>>2 byte&0xF0 0x50 \b, 64 kbps +>>>>2 byte&0xF0 0x60 \b, 80 kbps +>>>>2 byte&0xF0 0x70 \b, 96 kbps +>>>>2 byte&0xF0 0x80 \b, 112 kbps +>>>>2 byte&0xF0 0x90 \b, 128 kbps +>>>>2 byte&0xF0 0xA0 \b, 160 kbps +>>>>2 byte&0xF0 0xB0 \b, 192 kbps +>>>>2 byte&0xF0 0xC0 \b, 224 kbps +>>>>2 byte&0xF0 0xD0 \b, 256 kbps +>>>>2 byte&0xF0 0xE0 \b, 320 kbps # timing >>>2 byte&0x0C 0x00 \b, 44.1 kHz >>>2 byte&0x0C 0x04 \b, 48 kHz diff --git a/magic/Magdir/apache b/magic/Magdir/apache index d896b5055127..099efb77da57 100755 --- a/magic/Magdir/apache +++ b/magic/Magdir/apache @@ -1,18 +1,28 @@ #------------------------------------------------------------------------------ -# $File: apache,v 1.1 2017/04/11 14:52:15 christos Exp $ +# $File: apache,v 1.3 2025/05/30 13:25:13 christos Exp $ # apache: file(1) magic for Apache Big Data formats # Avro files -0 string Obj Apache Avro ->3 byte x version %d +0 string Obj\001 Apache Avro, version 1 # ORC files # Important information is in file footer, which we can't index to :( 0 string ORC Apache ORC -# Parquet files -0 string PAR1 Apache Parquet +# Apache arrow file format +# MIME: https://www.iana.org/assignments/media-types/application/vnd.apache.arrow.stream +# Description: https://arrow.apache.org/docs/format/Columnar.html +0 string ARROW1 Apache Arrow columnar file +!:mime application/vnd.apache.arrow.file +!:ext arrow/feather + +# Apache parquet file format +# MIME: https://www.iana.org/assignments/media-types/application/vnd.apache.parquet +# Description: https://parquet.apache.org/docs/file-format/ +0 string PAR1 Apache Parquet file +!:mime application/vnd.apache.parquet +!:ext parquet # Hive RC files 0 string RCF Apache Hive RC file diff --git a/magic/Magdir/archive b/magic/Magdir/archive index b920f9930f41..3aba947078b5 100644 --- a/magic/Magdir/archive +++ b/magic/Magdir/archive @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: archive,v 1.207 2024/11/27 15:37:46 christos Exp $ +# $File: archive,v 1.218 2026/01/10 16:16:27 christos Exp $ # archive: file(1) magic for archive formats (see also "msdos" for self- # extracting compressed archives) # @@ -689,7 +689,7 @@ # TODO: idarc says "bytes 0-2 == bytes 3-5" # TTComp # URL: http://fileformats.archiveteam.org/wiki/TTComp_archive -# Update: Joerg Jenderek +# Update: Joerg Jenderek, A Iooss # GRR: line below is too general as it matches also Panorama database "TCDB 2003-10 demo.pan", others 0 string \0\6 # look for first keyword of Panorama database *.pan @@ -735,8 +735,27 @@ #>-4 ubelong x LAST_BYTES=%8.8x >-4 ubelong&0x00FFffFF !0 >>0 use ttcomp -# display information of TTComp archive +# match end of TTComp to reduce false positives +# see https://mark0.net/forum/index.php?topic=848 0 name ttcomp +>-2 string \x01\xff +>>+0 use ttcomp-display +>-2 string \x80\x7f +>>+0 use ttcomp-display +>-2 string \xc0\x3f +>>+0 use ttcomp-display +>-2 string \xe0\x1f +>>+0 use ttcomp-display +>-2 string \xf0\x0f +>>+0 use ttcomp-display +>-2 string \xf8\x07 +>>+0 use ttcomp-display +>-2 string \xfc\x03 +>>+0 use ttcomp-display +>-2 string \xfe\x01 +>>+0 use ttcomp-display +# display information of TTComp archive +0 name ttcomp-display # (version 5.25) labeled the entry as "TTComp archive data" >0 ubyte x TTComp archive data !:mime application/x-compress-ttcomp @@ -746,23 +765,10 @@ >0 ubyte 0 \b, binary >0 ubyte 1 \b, ASCII # size of the dictionary: 4~1024 bytes 5~2048 bytes 6~4096 bytes ->1 ubyte 4 \b, 1K ->1 ubyte 5 \b, 2K ->1 ubyte 6 \b, 4K ->1 ubyte x dictionary -# https://mark0.net/forum/index.php?topic=848 -# last 3 bytes probably have only 8 possible bit sequences -# xxxxxxxx 0000000x 11111111 ____FFh -# xxxxxxxx 10000000 01111111 __807Fh -# 0xxxxxxx 11000000 00111111 __C03Fh -# 00xxxxxx 11100000 00011111 __E01Fh -# 000xxxxx 11110000 00001111 __F00Fh -# 0000xxxx 11111000 00000111 __F807h -# 00000xxx 11111100 00000011 __FC03h -# 000000xx 11111110 00000001 __FE01h -# but for quickgif.__d 0A7DD4h -#>-3 ubyte x \b, last 3 bytes 0x%2.2x -#>-2 ubeshort x \b%4.4x +>1 ubyte 4 \b, 1K dictionary +>1 ubyte 5 \b, 2K dictionary +>1 ubyte 6 \b, 4K dictionary + # From: Joerg Jenderek # URL: https://en.wikipedia.org/wiki/Disk_Copy # reference: http://nulib.com/library/FTN.e00005.htm @@ -1231,6 +1237,8 @@ #>0x200 ubequad x \b, at 0x200 %#16.16llx # cab_descriptor_size like: 0 (*.cab) BD5 C8B DA5 E2A E36 116C 251D 4DA9 56F0 5CC2 6E4B 777D 779E 1F7C2 >16 ulelong !0 \b, descriptor size %#x +>(12.l+40) lelong x ]b, %u files + # TOP4 0 string T4\x1a TOP4 archive data # BatComp left out: sig looks like COM executable @@ -1491,22 +1499,18 @@ >>9 ubyte !2 \b, security version %u # file type; 2 in main header; 0~binary 1~7-bitText 2~comment 3~directory 4~VolumeLabel 5=ChapterLabel >0xA ubyte !2 \b, file type %u -# date+time when original archive was created in MS-DOS format via ./msdos ->0xC ulelong x \b, created ->0xC use dos-date -# or date and time by new internal function -#>0xE lemsdosdate x %s -#>0xC lemsdostime x %s +# date+time when original archive was created in MS-DOS format +>0xE lemsdosdate x \b, created %s +>0xC lemsdostime x %s +# Archive mod time, added in format v6 (ARJ 2.39c) +>5 ubyte >5 +>>0x10 ulelong >0 \b, modified +>>>0x12 lemsdosdate x %s +>>>0x10 lemsdostime x %s + # FOR DEBUGGING #>0x12 uleshort x RAW DATE %#4.4x #>0x10 uleshort x RAW TIME %#4.4x -# date+time when archive was last modified; sometimes nil or -# maybe wrong like in HP4DRVR.ARJ -#>0x10 ulelong >0 \b, modified -#>>0x10 use dos-date -# or date and time by new internal function -#>>0x12 lemsdosdate x %s -#>>0x10 lemsdostime x %s # archive size (currently used only for secured archives); MAYBE? #>0x14 ulelong !0 \b, file size %u # security envelope file position; MAYBE? @@ -1795,6 +1799,51 @@ !:ext zip/cbz +# Generic zip archives (Greg Roelofs, c/o zip-bugs@wkuvx1.wku.edu) +# Next line excludes specialized formats: +0 name zipgeneric +>4 beshort x Zip archive data, at least +!:mime application/zip +>4 use zipversion +>4 beshort x to extract +>8 beshort x \b, compression method= +>8 use zipcompression +>0x161 string WINZIP \b, WinZIP self-extracting + +# Zip archives that can be either APK or JAR. Checks for resources.arsc, classes.dex, etc. +0 name apk_or_jar +# Contains resources.arsc (near the end, in the central directory) +>-512 search resources.arsc Android package (APK), with MANIFEST.MF and resources.arsc +!:mime application/vnd.android.package-archive +!:ext apk +>>-22 string PK\005\006 +>>>(-6.l-16) string APK\x20Sig\x20Block\x2042 \b, with APK Signing Block +>-512 default x +# Contains classes.dex (near the end, in the central directory) +>>-512 search classes.dex Android package (APK), with MANIFEST.MF and classes.dex +!:mime application/vnd.android.package-archive +!:ext apk +>>>-22 string PK\005\006 +>>>>(-6.l-16) string APK\x20Sig\x20Block\x2042 \b, with APK Signing Block +>>-512 default x +# Contains lib/armeabi (near the end, in the central directory) +>>>-512 search lib/armeabi Android package (APK), with MANIFEST.MF and armeabi lib +!:mime application/vnd.android.package-archive +!:ext apk +>>>>-22 string PK\005\006 +>>>>>(-6.l-16) string APK\x20Sig\x20Block\x2042 \b, with APK Signing Block +>>>-512 default x +# Contains drawables (near the end, in the central directory) +>>>>-512 search res/drawable Android package (APK), with MANIFEST.MF and drawables +!:mime application/vnd.android.package-archive +!:ext apk +>>>>>-22 string PK\005\006 +>>>>>>(-6.l-16) string APK\x20Sig\x20Block\x2042 \b, with APK Signing Block +# It may or may not be an APK file, but it's definitely a Java JAR file +>>>>-512 default x Java archive data (JAR) +!:mime application/java-archive +!:ext jar + 0 string PK\003\004 !:strength +1 # IOS/IPadOS IPA file (Zip archive) @@ -1830,40 +1879,14 @@ >>>-22 string PK\005\006 >>>>(-6.l-16) string APK\x20Sig\x20Block\x2042 \b, with APK Signing Block # Starts with META-INF/MANIFEST.MF (file name length = 20) -# NB: checks for resources.arsc, classes.dex, etc. as well to avoid matching JAR files >26 uleshort 20 >>30 string META-INF/MANIFEST.MF -# Contains resources.arsc (near the end, in the central directory) ->>>-512 search resources.arsc Android package (APK), with MANIFEST.MF and resources.arsc -!:mime application/vnd.android.package-archive -!:ext apk ->>>>-22 string PK\005\006 ->>>>>(-6.l-16) string APK\x20Sig\x20Block\x2042 \b, with APK Signing Block ->>>-512 default x -# Contains classes.dex (near the end, in the central directory) ->>>>-512 search classes.dex Android package (APK), with MANIFEST.MF and classes.dex -!:mime application/vnd.android.package-archive -!:ext apk ->>>>>-22 string PK\005\006 ->>>>>>(-6.l-16) string APK\x20Sig\x20Block\x2042 \b, with APK Signing Block ->>>>-512 default x -# Contains lib/armeabi (near the end, in the central directory) ->>>>>-512 search lib/armeabi Android package (APK), with MANIFEST.MF and armeabi lib -!:mime application/vnd.android.package-archive -!:ext apk ->>>>>>-22 string PK\005\006 ->>>>>>>(-6.l-16) string APK\x20Sig\x20Block\x2042 \b, with APK Signing Block ->>>>>-512 default x -# Contains drawables (near the end, in the central directory) ->>>>>>-512 search res/drawable Android package (APK), with MANIFEST.MF and drawables -!:mime application/vnd.android.package-archive -!:ext apk ->>>>>>>-22 string PK\005\006 ->>>>>>>>(-6.l-16) string APK\x20Sig\x20Block\x2042 \b, with APK Signing Block -# It may or may not be an APK file, but it's definitely a Java JAR file ->>>>>>-512 default x Java archive data (JAR) -!:mime application/java-archive -!:ext jar +>>>0 use apk_or_jar +# Starts with META-INF/ folder (file name length = 9) +>26 uleshort 9 +>>30 string META-INF/ +>>>0 use apk_or_jar + # Starts with zipflinger virtual entry (28 + 104 = 132 bytes) # See https://github.com/obfusk/apksigcopier/blob/666f5b7/apksigcopier/__init__.py#L230 >4 string \x00\x00\x00\x00\x00\x00 @@ -2132,17 +2155,11 @@ >>>>>>(-6.l) search/9000 kmp.json Keyman Compiled Package File !:mime application/vnd.keyman.kmp+zip !:ext kmp +>>>>>+4 default x +>>>>>>0 use zipgeneric -# Generic zip archives (Greg Roelofs, c/o zip-bugs@wkuvx1.wku.edu) -# Next line excludes specialized formats: >>>>+4 default x ->>>>>4 beshort x Zip archive data, at least -!:mime application/zip ->>>>>4 use zipversion ->>>>>4 beshort x to extract ->>>>>8 beshort x \b, compression method= ->>>>>8 use zipcompression ->>>>>0x161 string WINZIP \b, WinZIP self-extracting +>>>>>0 use zipgeneric # Zip archives (Greg Roelofs, c/o zip-bugs@wkuvx1.wku.edu) 0 string PK\005\006 Zip archive data (empty) @@ -2810,3 +2827,55 @@ >>37 byte x \b:%02d >>38 byte x \b:%02d >>56 ulelong x \b, size: %u bytes + +# Stone archive file - Serpent OS moss package manager's native format +# https://github.com/serpent-os/tools, +# (Ikey Doherty) +0 string \0mos Stone archive +>28 belong 1 (format v%d) +>>27 byte 1 binary package +!:mime application/x-stone-binary +!:ext stone +>>27 byte 2 delta package +!:mime application/x-stone-delta +!:ext stone +>>27 byte 3 repository index +!:mime application/x-stone-repository +!:ext index +>>27 byte 4 build manifest +!:mime application/x-stone-manifest +!:ext bin + +# * VOS <file_name> <sequential|relative|fixed|stream> <record_size> , +# * [encapsulated|not_encapsulated] = +# * [encoded|not_encoded|seq_encoded|base64_encoded] +0 string VOS\040 Stratus OpenVOS EFV archive +>4 regex [^[:space:]]+ \b, (%s) +>>&0 regex [^[:space:]]+ \b, %s +>>>&0 regex [^[:space:]]+ \b, record_size=%s +>>>>&0 regex [^[:space:]]+ \b, %s +>>>>>&0 regex [^[:space:]]+ \b, %s + + +# https://www.vm.ibm.com/devpages/bkw/vmarc.html magic in EBCDIC +0 string \x7a\xc3\xc6\xc6\x40\x40\x40\x40 VM Archive + +# https://pbs.proxmox.com/docs/file-formats.html +0 string \x42\xab\x38\x07\xbe\x83\x70\xa1 Proxmox Backup Server unencrypted uncompressed blob + +0 string \x31\xb9\x58\x42\x6f\xb6\xa3\x7f Proxmox Backup Server unencrypted compressed blob + +0 string \x7b\x67\x85\xbe\x22\x2d\x4c\xf0 Proxmox Backup Server encrypted uncompressed blob + +0 string \xe6\x59\x1b\xbf\x0b\xbf\xd8\x0b Proxmox Backup Server encrypted compressed blob + +0 string \x2f\x7f\x41\xed\x91\xfd\x0f\xcd Proxmox Backup Server fixed index + +0 string \x1c\x91\x4e\xa5\x19\xba\xb3\xcd Proxmox Backup Server dynamic index + +0 string \xef\xac\x88\xe5\x74\x64\x95\xd5 Proxmox File Archive Format v1 / pxar + +0 string \x0d\xa4\x16\xdf\x75\x6c\x0f\x73\x18\x00\x00\x00\x00\x00\x00\x00\x02 Proxmox File Archive Format v2+ / mpxar + +0 string \xd2\x4e\x4a\x19\xc2\x68\x4c\x83\x10 Proxmox File Archive Format payload stream / ppxar + diff --git a/magic/Magdir/audio b/magic/Magdir/audio index 991b75999608..e630663af86a 100644 --- a/magic/Magdir/audio +++ b/magic/Magdir/audio @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: audio,v 1.133 2024/09/04 19:07:20 christos Exp $ +# $File: audio,v 1.136 2026/01/23 17:02:27 christos Exp $ # audio: file(1) magic for sound formats (see also "iff") # # Jan Nicolai Langfeldt (janl@ifi.uio.no), Dan Quinlan (quinlan@yggdrasil.com), @@ -957,7 +957,7 @@ >>3 byte 4 (With no LAME header) >>3 byte 5 Version 2.4 -0 string ADRVPACK AProSys module +0 string ADRVPACK AProSys module # ftp://ftp.modland.com/pub/documents/format_documentation/\ # Art%20Of%20Noise%20(.aon).txt @@ -1199,6 +1199,13 @@ >4 beshort 0xFEFF >>0 use \^nintendo-3ds-bcwav-fields + +# QOA Quite Okay Audio format +# https://qoaformat.org/qoa-specification.pdf +# added by alex myczko <tar@debian.org> +0 string qoaf QOA audio data +>4 belong x \b, %d samples per channel + # Philips DSDIFF audio format (Direct Stream Digital Interchange File Format) # Used for DSD audio recordings and Super Audio CD (SACD) mastering annotations # https://dsd-guide.com/sites/default/files/white-papers/DSDIFF_1.5_Spec.pdf @@ -1338,3 +1345,6 @@ >50 leshort x \b, scaleX %d >52 byte 0 \b, percussive >52 byte 1 \b, melodic + +# https://pbat.ch/proj/protrekkr/ +0 string PROTREKT Protrekkr Module diff --git a/magic/Magdir/bgcode b/magic/Magdir/bgcode new file mode 100644 index 000000000000..407827916df3 --- /dev/null +++ b/magic/Magdir/bgcode @@ -0,0 +1,9 @@ +#------------------------------------------------------------------------------ +# $File: bgcode,v 1.1 2025/03/10 21:02:05 christos Exp $ + +# BGCode +0 string GCDE Binary G-code +!:ext bgcode,bgc +>4 ulelong x Version %u +>>8 uleshort 0 \b, no checksum +>>8 uleshort 1 \b, CRC32 checksum diff --git a/magic/Magdir/blender b/magic/Magdir/blender index 5a897113e092..456e3f331134 100644 --- a/magic/Magdir/blender +++ b/magic/Magdir/blender @@ -1,6 +1,5 @@ - #------------------------------------------------------------------------------ -# $File: blender,v 1.9 2022/12/21 15:53:27 christos Exp $ +# $File: blender,v 1.10 2026/01/10 14:38:14 christos Exp $ # blender: file(1) magic for Blender 3D related files # # Native format rule v1.2. For questions use the developers list @@ -13,13 +12,13 @@ # http://formats.kaitai.io/blender_blend/index.html # Note: called "Blender 3D data" by TrID # and gzip compressed variant handled by ./compress -0 string =BLENDER Blender3D, +0 string =BLENDER Blender3D #!:mime application/octet-stream !:mime application/x-blender !:ext blend # no sample found with extension blender #!:ext blend/blender ->7 string =_ saved as 32-bits +>7 string =_ pre-v5, saved as 32-bits >>8 string =v little endian >>>9 byte x with version %c. >>>10 byte x \b%c @@ -32,7 +31,7 @@ >>>11 byte x \b%c >>>0x40 string =GLOB \b. >>>>0x58 beshort x \b%.4d ->7 string =- saved as 64-bits +>7 string =- pre-v5, saved as 64-bits >>8 string =v little endian >>9 byte x with version %c. >>10 byte x \b%c @@ -46,5 +45,15 @@ >>>0x44 string =GLOB \b. >>>>0x60 beshort x \b%.4d +# Blender 5.0+ +>7 string =17 v5+, +>>10 byte x format version %c +>>>11 byte x \b%c +>>>>13 byte x app version %c +>>>>>14 byte x \b%c +>>>>>>15 byte x \b%c +>>>>>>>16 byte x \b%c +# + # Scripts that run in the embedded Python interpreter 0 string #!BPY Blender3D BPython script diff --git a/magic/Magdir/bytecode b/magic/Magdir/bytecode index dca961c26431..263f27e09c6e 100644 --- a/magic/Magdir/bytecode +++ b/magic/Magdir/bytecode @@ -1,6 +1,6 @@ #------------------------------------------------------------ -# $File: bytecode,v 1.5 2023/02/20 16:25:05 christos Exp $ +# $File: bytecode,v 1.6 2026/02/16 14:39:53 christos Exp $ # magic for various bytecodes # From: Mikhail Gusarov <dottedmag@dottedmag.net> @@ -34,8 +34,15 @@ # https://racket-lang.org/ # https://github.com/racket/racket/blob/master/racket/src/expander/compile/write-linklet.rkt 0 string #~ ->&0 pstring x ->>&0 pstring racket +>&0 pstring x +>>&0 pstring racket >>>0 string #~ Racket bytecode ->>>>&0 pstring x (version %s) +>>>>&0 pstring x (version %s) + + +# From: Marc Chantreux <mc@unistra.fr> +# [MoarVM](https://www.moarvm.org/) bytecode file +0 string MOARVM\x0d\x0a MoarVM bytecode +!:ext mbc +>0x9 short >0 \b, version %u diff --git a/magic/Magdir/c-lang b/magic/Magdir/c-lang index 6e375a06a7e6..4b203e6fddd8 100644 --- a/magic/Magdir/c-lang +++ b/magic/Magdir/c-lang @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: c-lang,v 1.32 2023/06/16 19:57:19 christos Exp $ +# $File: c-lang,v 1.38 2025/05/30 13:36:08 christos Exp $ # c-lang: file(1) magic for C and related languages programs # # The strength is to beat standard HTML @@ -17,7 +17,7 @@ >>0 regex \^class[[:space:]]+ >>>&0 regex \\{[\.\*]\\}(;)?$ \b++ >>&0 clear x source text -!:strength + 15 +!:strength + 30 !:mime text/x-c 0 search/8192 pragma >0 regex \^#[[:space:]]*pragma C source text @@ -27,8 +27,7 @@ >>&0 regex \^#[[:space:]]*endif$ C source text !:mime text/x-c 0 search/8192 define ->0 regex \^#[[:space:]]*(if\|ifn)def ->>&0 regex \^#[[:space:]]*define C source text +>0 regex \^#[[:space:]]*define C source text !:mime text/x-c 0 search/8192 char >0 regex \^[[:space:]]*char(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$ C source text @@ -58,21 +57,21 @@ # C++ # The strength of these rules is increased so they beat the C rules above 0 search/8192 namespace ->0 regex \^namespace[[:space:]]+[_[:alpha:]]{1,30}[[:space:]]*\\{ C++ source text -!:strength + 30 +>0 regex \^namespace[[:space:]]+[_[:alpha:]]{1,20}[[:space:]]*\\{ C++ source text +!:strength + 45 !:mime text/x-c++ # using namespace [namespace] or using std::[lib] 0 search/8192 using >0 regex \^using[[:space:]]+(namespace\ )?std(::)?[[:alpha:]]*[[:space:]]*; C++ source text -!:strength + 30 +!:strength + 45 !:mime text/x-c++ 0 search/8192 template >0 regex \^[[:space:]]*template[[:space:]]*<.*>[[:space:]]*$ C++ source text -!:strength + 30 +!:strength + 45 !:mime text/x-c++ 0 search/8192 virtual >0 regex \^[[:space:]]*virtual[[:space:]]+.*[};][[:space:]]*$ C++ source text -!:strength + 30 +!:strength + 45 !:mime text/x-c++ # But class alone is reduced to avoid beating php (Jens Schleusener) 0 search/8192 class @@ -81,15 +80,15 @@ !:mime text/x-c++ 0 search/8192 public >0 regex \^[[:space:]]*public: C++ source text -!:strength + 30 +!:strength + 45 !:mime text/x-c++ 0 search/8192 private >0 regex \^[[:space:]]*private: C++ source text -!:strength + 30 +!:strength + 45 !:mime text/x-c++ 0 search/8192 protected >0 regex \^[[:space:]]*protected: C++ source text -!:strength + 30 +!:strength + 45 !:mime text/x-c++ # Objective-C @@ -98,13 +97,30 @@ !:strength + 25 !:mime text/x-objective-c + +# Typst +# https://github.com/typst/typst +0 regex \^[[:space:]]*#(import|include)[[:space:]]+"@[[:alnum:]-]+ Typst source text +!:strength + 45 +!:mime text/vnd.typst +!:ext typ +0 regex \^[[:space:]]*#(import|include)[[:space:]]+"[[:alnum:]]+.typ" Typst source text +!:strength + 45 +!:mime text/vnd.typst +!:ext typ +0 regex \^[[:space:]]*#(set|show|let) Typst source text +!:strength + 45 +!:mime text/vnd.typst +!:ext typ + + # From: Mikhail Teterin <mi@aldan.algebra.com> 0 string cscope cscope reference data >7 string x version %.2s # We skip the path here, because it is often long (so file will # truncate it) and mostly redundant. # The inverted index functionality was added some time between -# versions 11 and 15, so look for -q if version is above 14: +# versions 11 and 30, so look for -q if version is above 14: >7 string >14 >>10 search/100 \ -q\ with inverted index >10 search/100 \ -c\ text (non-compressed) diff --git a/magic/Magdir/cisco b/magic/Magdir/cisco index 0279bbb5b5af..e5ec85f5a2e6 100644 --- a/magic/Magdir/cisco +++ b/magic/Magdir/cisco @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: cisco,v 1.4 2009/09/19 16:28:08 christos Exp $ +# $File: cisco,v 1.5 2025/05/28 14:02:37 christos Exp $ # cisco: file(1) magic for cisco Systems routers # # Most cisco file-formats are covered by the generic elf code @@ -10,3 +10,8 @@ >7 string >\0 for '%s' 0 belong&0xffffff00 0x8501cb00 cisco IOS experimental microcode >7 string >\0 for '%s' + +0 string/b MZIP Cisco IOS mzip compressed data +>0x4 belong x \b, version %d +>0x8 belong x \b, entry point %#x +!:ext bin diff --git a/magic/Magdir/commands b/magic/Magdir/commands index 88aa6920be86..4ce9776697dd 100644 --- a/magic/Magdir/commands +++ b/magic/Magdir/commands @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: commands,v 1.77 2024/11/10 16:55:15 christos Exp $ +# $File: commands,v 1.82 2026/02/16 14:39:53 christos Exp $ # commands: file(1) magic for various shells and interpreters # #0 string/w : shell archive or script for antique kernel text @@ -20,13 +20,13 @@ 0 string/fwb #!\ /bin/ksh Korn shell script executable (binary data) !:mime text/x-shellscript -0 string/fwt #!\ /bin/tcsh Tenex C shell script text executable +0 string/fwt #!\ /bin/tcsh Tenex C shell script text executable !:mime text/x-shellscript 0 string/fwt #!\ /usr/bin/tcsh Tenex C shell script text executable !:mime text/x-shellscript -0 string/fwt #!\ /usr/local/tcsh Tenex C shell script text executable +0 string/fwt #!\ /usr/local/tcsh Tenex C shell script text executable !:mime text/x-shellscript -0 string/fwt #!\ /usr/local/bin/tcsh Tenex C shell script text executable +0 string/fwt #!\ /usr/local/bin/tcsh Tenex C shell script text executable !:mime text/x-shellscript # @@ -52,13 +52,13 @@ !:mime text/x-nawk 0 string/fwt #!\ /usr/bin/nawk new awk script text executable !:mime text/x-nawk -0 string/fwt #!\ /usr/local/bin/nawk new awk script text executable +0 string/fwt #!\ /usr/local/bin/nawk new awk script text executable !:mime text/x-nawk 0 string/fwt #!\ /bin/gawk GNU awk script text executable !:mime text/x-gawk 0 string/wt #!\ /usr/bin/gawk GNU awk script text executable !:mime text/x-gawk -0 string/fwt #!\ /usr/local/bin/gawk GNU awk script text executable +0 string/fwt #!\ /usr/local/bin/gawk GNU awk script text executable !:mime text/x-gawk # 0 string/fwt #!\ /bin/awk awk script text executable @@ -67,6 +67,15 @@ !:mime text/x-awk 0 regex/4096 =^[\040\t\f\r\n]{0,100}BEGIN[\040\t\f\r\n]{0,100}[{] awk or perl script text +0 string/fwt #!\ /bin/lua Lua script text executable +!:mime text/x-lua +0 string/fwt #!\ /usr/bin/lua Lua script text executable +!:mime text/x-lua +0 string/fwt #!\ /usr/bin/env\ lua Lua script text executable +!:mime text/x-lua +0 string/fwt #!\ /bin/env\ lua Lua script text executable +!:mime text/x-lua + # AT&T Bell Labs' Plan 9 shell 0 string/fwt #!\ /bin/rc Plan 9 rc shell script text executable @@ -83,9 +92,9 @@ !:mime text/x-shellscript 0 string/fwb #!\ /usr/local/bash Bourne-Again shell script executable (binary data) !:mime text/x-shellscript -0 string/fwt #!\ /usr/local/bin/bash Bourne-Again shell script text executable +0 string/fwt #!\ /usr/local/bin/bash Bourne-Again shell script text executable !:mime text/x-shellscript -0 string/fwb #!\ /usr/local/bin/bash Bourne-Again shell script executable (binary data) +0 string/fwb #!\ /usr/local/bin/bash Bourne-Again shell script executable (binary data) !:mime text/x-shellscript 0 string/fwt #!\ /usr/bin/env\ bash Bourne-Again shell script text executable !:mime text/x-shellscript @@ -107,22 +116,33 @@ !:mime text/x-shellscript 0 search/1/fwt #!\ /usr/bin/tclsh Tcl/Tk script text executable -!:mime text/x-tcl +!:mime text/x-tcl 0 search/1/fwt #!\ /usr/bin/texlua LuaTex script text executable !:mime text/x-luatex +0 search/1/fwt #!\ /usr/bin/env\ texlua LuaTex script text executable +!:mime text/x-luatex +0 search/1/fwt #!\ /bin/env\ texlua LuaTex script text executable +!:mime text/x-luatex 0 search/1/fwt #!\ /usr/bin/luatex LuaTex script text executable !:mime text/x-luatex 0 search/1/fwt #!\ /usr/bin/stap Systemtap script text executable -!:mime text/x-systemtap +!:mime text/x-systemtap 0 search/1/fwt #!\ /sbin/openrc-run OpenRC script text executable -!:mime text/x-shellscript +!:mime text/x-shellscript + +# From: Marc Chantreux <mc@unistra.fr> +# [Raku](https://raku.org/) script +0 string/fwt #!\ /bin/raku Raku (http://raku.org) script +!:mime text/x-raku +0 string/fwt #!\ /usr/bin/raku Raku (http://raku.org) script +!:mime text/x-raku # From: Kylie McClain <kylie@somas.is> # Type: execline scripts -# URL: https://skarnet.org/software/execline/ +# URL: https://skarnet.org/software/execline/ 0 string/fwt #!\ /command/execlineb execline script text executable !:mime text/x-execline 0 string/fwt #!\ /bin/execlineb execline script text executable @@ -142,17 +162,17 @@ # PHP scripts # Ulf Harnhammar <ulfh@update.uu.se> 0 search/1/c =<?php PHP script text -!:strength + 30 +!:strength + 55 !:mime text/x-php 0 search/1 =<?\n PHP script text !:mime text/x-php 0 search/1 =<?\r PHP script text !:mime text/x-php 0 search/1/w #!\ /usr/local/bin/php PHP script text executable -!:strength + 10 +!:strength + 55 !:mime text/x-php 0 search/1/w #!\ /usr/bin/php PHP script text executable -!:strength + 10 +!:strength + 55 !:mime text/x-php # Smarty compiled template, https://www.smarty.net/ # Elan Ruusamae <glen@delfi.ee> @@ -193,21 +213,21 @@ 0 string/t $! DCL command file # Type: Pdmenu -# URL: https://packages.debian.org/pdmenu +# URL: https://packages.debian.org/pdmenu # From: Edward Betts <edward@debian.org> 0 string #!/usr/bin/pdmenu Pdmenu configuration file text # From Danny Weldon 0 string \x0b\x13\x08\x00 ->0x04 uleshort <4 ksh byte-code version %d +>0x04 uleshort <4 ksh byte-code version %d # From: arno <arenevier@fdn.fr> # mozilla xpconnect typelib # see https://www.mozilla.org/scriptable/typelib_file.html -0 string XPCOM\nTypeLib\r\n\032 XPConnect Typelib ->0x10 byte x version %d ->>0x11 byte x \b.%d +0 string XPCOM\nTypeLib\r\n\032 XPConnect Typelib +>0x10 byte x version %d +>>0x11 byte x \b.%d 0 string/fwt #!\ /usr/bin/env\ runghc GHC script executable 0 string/fwt #!\ /usr/bin/env\ runhaskell Haskell script executable -0 string/fwt #!\ /usr/bin/env\ julia Julia script executable +0 string/fwt #!\ /usr/bin/env\ julia Julia script executable diff --git a/magic/Magdir/console b/magic/Magdir/console index 8fef21f73ab8..a4357b3e7acb 100644 --- a/magic/Magdir/console +++ b/magic/Magdir/console @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: console,v 1.80 2024/11/09 23:55:02 christos Exp $ +# $File: console,v 1.81 2026/01/31 15:44:17 christos Exp $ # Console game magic # Toby Deshane <hac@shoelace.digivill.net> @@ -1376,3 +1376,93 @@ >0x20 ubelong 1 PowerPC >>0xA4 ubelong 0x11 \b, Wii U mode >>0xA4 ubelong 0x12 \b, Wii mode + +# Type: WonderSwan raw ROM format +# (Also covers the WonderSwan WSR sound format, which is an extension thereof) +# From: Adrian Siekierka <kontakt@asie.pl> +# Reference: https://ws.nesdev.org/wiki/ROM_header +0 name wonderswan-maintenance +>0 ubyte&0x80 =128 \b, custom splash screen bypassed + +0 name wonderswan-version +>0 ubyte&0x7F x \b, rev. %d +>0 ubyte&0x80 =128 \b, internal EEPROM unlocked + +0 name wonderswan-rom-size +>0 byte 0x00 \b, ROM: 1Mbit +>0 byte 0x01 \b, ROM: 2Mbit +>0 byte 0x02 \b, ROM: 4Mbit +>0 byte 0x03 \b, ROM: 8Mbit +>0 byte 0x04 \b, ROM: 16Mbit +>0 byte 0x05 \b, ROM: 24Mbit +>0 byte 0x06 \b, ROM: 32Mbit +>0 byte 0x07 \b, ROM: 48Mbit +>0 byte 0x08 \b, ROM: 64Mbit +>0 byte 0x09 \b, ROM: 128Mbit +>0 byte 0x0A \b, ROM: 256Mbit +>0 byte 0x0B \b, ROM: 512Mbit + +0 name wonderswan-save-type +>0 ubyte&0x0F =1 \b, RAM: 256Kbit +>0 ubyte&0x0F =2 \b, RAM: 256Kbit +>0 ubyte&0x0F =3 \b, RAM: 1Mbit +>0 ubyte&0x0F =4 \b, RAM: 2Mbit +>0 ubyte&0x0F =5 \b, RAM: 4Mbit +>0 ubyte&0xF0 =16 \b, EEPROM: 1Kbit +>0 ubyte&0xF0 =32 \b, EEPROM: 16Kbit +>0 ubyte&0xF0 =80 \b, EEPROM: 8Kbit + +0 name wonderswan-flags +>0 ubyte&0x01 =0 \b, orientation: horizontal +>0 ubyte&0x01 =1 \b, orientation: vertical + +0 name wonderswan-rom-flags +>0 ubyte&0x04 =0 \b, bus: 8-bit +>0 ubyte&0x04 =4 \b, bus: 16-bit +>0 ubyte&0x08 =8 \b, slow + +0 name wonderswan-mapper +>0 ubyte&0x0F =0 \b, mapper: 2001 +>0 ubyte&0x0F =1 \b, mapper: 2003 + +-16 ubyte 0xEA +>-32 string WSRF\x00 WonderSwan WSR sound file, based on +>-11 ubyte&0x0F =0 +>>-9 ubyte&0x01 =0 WonderSwan ROM image +!:ext ws/pc2 +>>-9 ubyte&0x01 =1 WonderSwan Color ROM image +!:ext wsc +>>-11 use wonderswan-maintenance +>>-7 use wonderswan-version +>>-7 use wonderswan-rom-size +>>-4 use wonderswan-rom-flags +>>-7 use wonderswan-save-type +>>-4 use wonderswan-flags +>>-3 use wonderswan-mapper + +# Type: WonderWitch transfer file +# From: Adrian Siekierka <kontakt@asie.pl> +# Reference: https://ws.nesdev.org/wiki/WonderWitch_.fx_files +0 string #!ws\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff WonderWitch transfer file +!:ext fx/il +>64 string/16 x \b, name "%s" +>80 string/24 x \b, info "%s" +>108 ulelong x \b, %u bytes +>112 uleshort x \b (%d blocks) +>114 uleshort >0 \b, mode " +>>114 uleshort&0x80 >0 \bd +>>114 uleshort&0x40 >0 \bl +>>114 uleshort&0x20 >0 \bi +>>114 uleshort&0x10 >0 \bs +>>114 uleshort&0x08 >0 \bm +>>114 uleshort&0x04 >0 \br +>>114 uleshort&0x02 >0 \bw +>>114 uleshort&0x01 >0 \bx +>>114 uleshort >0 \b" +>124 lelong >0 \b, resource data after %d bytes + +# Type: Aquaplus P/ECE executable format +# From: Adrian Siekierka <kontakt@asie.pl> +0 uleshort 0x0258 P/ECE executable +>(0x04.s) string x \b: "%s" +!:ext pex diff --git a/magic/Magdir/creativeassembly b/magic/Magdir/creativeassembly new file mode 100644 index 000000000000..4183d58c60bb --- /dev/null +++ b/magic/Magdir/creativeassembly @@ -0,0 +1,26 @@ + +#-------------------------------------------------------------- +# $File: creativeassembly,v 1.1 2026/02/01 16:25:09 christos Exp $ +# creativeassembly: file(1) magic for various Creative Assembly files +# +# Community file formats documentation: +# <https://github.com/TotalWar-Modding/docs> + +# Benedikt Radtke <benediktradtke@gmail.com> +# PFH4 Archive +0 lelong 0x34484650 Creative Assembly Archive version 4 + +# Benedikt Radtke <benediktradtke@gmail.com> +# PFH5 Archive +0 lelong 0x35484650 Creative Assembly Archive version 5 +>&0 lelong&0xf 0x00 \b, boot archive +>&0 lelong&0xf 0x01 \b, release archive +>&0 lelong&0xf 0x02 \b, patch archive +>&0 lelong&0xf 0x03 \b, mod archive +>&0 lelong&0xf 0x04 \b, movie archive +>&0 lelong&0x10 0x10 \b, data encrypted +>&0 lelong&0x40 0x40 \b, timestamped files +>&0 lelong&0x80 0x80 \b, index encrypted +>&0 lelong&0x100 0x100 \b, big header +>&0x0c lelong x \b, %d files +#>0x14 ledate x \b, created on %s diff --git a/magic/Magdir/database b/magic/Magdir/database index c4462f96675e..788916f8d321 100644 --- a/magic/Magdir/database +++ b/magic/Magdir/database @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: database,v 1.73 2024/11/09 19:54:36 christos Exp $ +# $File: database,v 1.75 2025/11/10 16:06:19 christos Exp $ # database: file(1) magic for various databases # # extracted from header/code files by Graeme Wilford (eep2gw@ee.surrey.ac.uk) @@ -909,3 +909,103 @@ # so we check both to detect them also on hosts with differnet endianess 16 lelong 0xED0CDAED BoltDB database 16 belong 0xED0CDAED BoltDB database, big-endian + +# https://en.wikipedia.org/wiki/HCL_Notes +0 string \x1A\x00\x00\x03\x00\x00 Notes Storage Facility database + +# PostgreSQL WAL segment +# repo: https://git.postgresql.org/gitweb/?p=postgresql.git;a=summary +# file: src/include/access/xlog_internal.h +# header structure is XLogPageHeaderData+XLogLongPageHeaderData +# magic header numbers are defined in XLOG_PAGE_MAGIC +# The magic number is too short to safely identify a file; but since the +# WAL log pages repeat in a file, we can test the magic number on the +# headers of more than one page to make a safer match. Two is ok for now. + +0 short 0xd118 +(0x24.l) short 0xd118 PostgreSQL 18 +>0 use pgwal + +0 short 0xd116 +(0x24.l) short 0xd116 PostgreSQL 17 +>0 use pgwal + +0 short 0xd113 +(0x24.l) short 0xd113 PostgreSQL 16 +>0 use pgwal + +0 short 0xd110 +(0x24.l) short 0xd110 PostgreSQL 15 +>0 use pgwal + +0 short 0xd10d +(0x24.l) short 0xd10d PostgreSQL 14 +>0 use pgwal + +0 short 0xd106 +(0x24.l) short 0xd106 PostgreSQL 13 +>0 use pgwal + +0 short 0xd101 +(0x24.l) short 0xd101 PostgreSQL 12 +>0 use pgwal + +0 short 0xd098 +(0x24.l) short 0xd098 PostgreSQL 11 +>0 use pgwal + +0 short 0xd097 +(0x24.l) short 0xd097 PostgreSQL 10 +>0 use pgwal + +0 short 0xd093 +(0x24.l) short 0xd093 PostgreSQL 9.6 +>0 use pgwal + +0 short 0xd087 +(0x24.l) short 0xd087 PostgreSQL 9.5 +>0 use pgwal + +0 short 0xd07e +(0x24.l) short 0xd07e PostgreSQL 9.4 +>0 use pgwal + +0 short 0xd075 +(0x24.l) short 0xd075 PostgreSQL 9.3 +>0 use pgwal + +0 short 0xd071 +(0x24.l) short 0xd071 PostgreSQL 9.2 +>0 use pgwal + +0 short 0xd066 +(0x24.l) short 0xd066 PostgreSQL 9.1 +>0 use pgwal + +0 short 0xd064 +(0x24.l) short 0xd064 PostgreSQL 9.0 +>0 use pgwal + +0 short 0xd063 +(0x24.l) short 0xd063 PostgreSQL 8.4 +>0 use pgwal + +0 short 0xd062 +(0x24.l) short 0xd062 PostgreSQL 8.3 +>0 use pgwal + +0 short 0xd05e +(0x24.l) short 0xd05e PostgreSQL 8.2 +>0 use pgwal + +0 short 0xd05d +(0x24.l) short 0xd05d PostgreSQL 8.1 +>0 use pgwal + +0 short 0xd05c +(0x24.l) short 0xd05c PostgreSQL 8.0 +>0 use pgwal + +0 name pgwal WAL segment file +>0x18 quad x (System ID %lld, +>0x04 long x Timeline %d) diff --git a/magic/Magdir/filesystems b/magic/Magdir/filesystems index a15e5e74d971..427011f1598d 100644 --- a/magic/Magdir/filesystems +++ b/magic/Magdir/filesystems @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: filesystems,v 1.165 2024/09/01 15:51:51 christos Exp $ +# $File: filesystems,v 1.169 2025/12/27 15:29:44 christos Exp $ # filesystems: file(1) magic for different filesystems # 0 name partid @@ -1950,8 +1950,23 @@ >36865 string BEA01 + >>36864 use extendedarea -37633 string CD001 ISO 9660 CD-ROM filesystem data (raw 2352 byte sectors) -!:mime application/x-iso9660-image +# ISO 9660 as part of various raw CD-ROM image formats. +# Usually the BIN file of a CUE/BIN pair or the IMG of a CCD/IMG/SUB triplet. + +# MODE1/2352 (2352*16 + 16 + 1) +37649 string CD001 ISO 9660 CD-ROM filesystem data +>0 default x (CD-ROM Mode 1 image, 2352 byte sectors) +!:ext bin/img + +# MODE2/2352 (2352*16 + 24 + 1) +37657 string CD001 ISO 9660 CD-ROM filesystem data +>0 default x (CD-ROM XA Mode 2 image, 2352 byte sectors) +!:ext bin/img + +# MODE2/2336 (2336*16 + 8 + 1) +37385 string CD001 ISO 9660 CD-ROM filesystem data +>0 default x (CD-ROM XA Mode 2 image, 2336 byte sectors) +!:ext bin # URL: http://fileformats.archiveteam.org/wiki/High_Sierra # Update: Joerg Jenderek @@ -2607,7 +2622,7 @@ >12 use next # bcachefs -# From: Thomas Weißschuh <thomas@t-8ch.de> +# From: Thomas Weissschuh <thomas@t-8ch.de> 0 name bcachefs-uuid >0 ubelong x \b%08x @@ -2654,7 +2669,8 @@ #>1060 lelong x \b, blocks=%d #>1064 lelong x \b, metadata@%#x #>1068 lelong x \b, xattr@%#x ->1072 guid x \b, uuid=%s +>1072 guid x \b, uuid= +>1072 use bcachefs-uuid >1088 string >0 \b, name=%s >1104 lelong >0 \b, incompat: >>1104 lelong &1 LZ4_0PADDING @@ -2763,3 +2779,8 @@ 0x0 string \x10\x00\x4e\x57\x20 >0x10000 string \x4e\x57\x00\x00\x01 >0x100A2 string \x4C\x00\x40 EldOS Corporation SolidFS, 64KiB page size + +# YBLOB mini object storage +# PIN-protected storage format based on the PIV application +# https://github.com/douzebis/yb +0 lelong 0xF2ED5F0B yblob object store image data diff --git a/magic/Magdir/firmware b/magic/Magdir/firmware index 21ba1ed591b6..75a131138aa6 100644 --- a/magic/Magdir/firmware +++ b/magic/Magdir/firmware @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: firmware,v 1.13 2024/09/04 19:04:03 christos Exp $ +# $File: firmware,v 1.17 2025/04/06 18:37:40 christos Exp $ # firmware: file(1) magic for firmware files # @@ -110,7 +110,7 @@ >>28 ulelong&0x1 1 \b, encrypted # ESP-IDF application image -# From: Alexandre Iooss <erdnaxe@crans.org> +# From: A. Iooss <aiooss@crans.org> # Update: Joerg Jenderek # URL: https://github.com/espressif/esp-idf/blob/v5.0/components/bootloader_support/include/esp_app_format.h # Reference: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/app_image_format.html @@ -134,13 +134,34 @@ >>12 uleshort 0x000D for ESP32-C6 >>12 uleshort 0x000E for ESP32-H2 Beta2 >>12 uleshort 0x0010 for ESP32-H2 ->>80 string/32 x \b, project name: "%s" ->>48 string/32 x \b, version %s +>>80 byte !0 +>>>80 string/32 x \b, project name: "%s" +>>48 byte !0 +>>>48 string/32 x \b, version %s >>128 string/16 x \b, compiled on %s >>>112 string/16 x %s >>144 string/32 x \b, IDF version: %s >>4 ulelong x \b, entry address: 0x%08X +# ESP8266/ESP32 firmware image +# Note: contain partition table entries and ESP-IDF application image +# From: A. Iooss <aiooss@crans.org> +# Reference: https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/firmware-image-format.html +0 byte 0xE9 +>2 byte <4 +>>7 byte 0x40 ESP firmware image +# ESP8266 does not have Extended File Header +>>>12 uleshort 0x0000 for ESP32 +>>>12 uleshort 0x0002 for ESP32-S2 +>>>12 uleshort 0x0005 for ESP32-C3 +>>>12 uleshort 0x0009 for ESP32-S3 +>>>12 uleshort 0x000A for ESP32-H2 Beta1 +>>>12 uleshort 0x000C for ESP32-C2 +>>>12 uleshort 0x000D for ESP32-C6 +>>>12 uleshort 0x000E for ESP32-H2 Beta2 +>>>12 uleshort 0x0010 for ESP32-H2 +>>>4 ulelong x \b, entry point 0x%08X + # AVR firmware # From: Alexandre Iooss <erdnaxe@crans.org> # URL: https://microchipdeveloper.com/8avr:int @@ -174,7 +195,7 @@ # Reference: http://www.piclist.com/techref/fileext/hex/intel.htm # http://mark0.net/download/triddefs_xml.7z/defs/h/hex-intel.trid.xml # From: Joerg Jenderek -# Note: called "Intel Hexadecimal object format" by TrID, "Intel® hexadecimal object file" on Linux +# Note: called "Intel Hexadecimal object format" by TrID, "Intel(R) hexadecimal object file" on Linux # and "Intel HEX binary data" by Notepad++ # look for start code; 1 character, an ASCII colon ':'; all characters preceding this symbol should be ignored 0 ubyte 0x3A @@ -275,3 +296,117 @@ >-10 string \x1A\x01UFD >>-12 uleshort x \b, for device %04X: >>-14 uleshort x \b%04X + +# Allwinner eGON Boot Image +# Reference: https://linux-sunxi.org/EGON + +0 name egon-details +# ARM b instruction +>0 ulelong&0xff000000 0xea000000 (ARM) +# RISC-V jal instruction +>0 ulelong&0x00000fff 0x0000006f (RISC-V) +>16 ulelong x \b, size %u + +4 string eGON.BT0 Allwinner eGON.BT0 Boot Image +>0 use egon-details + +4 string eGON.BT1 Allwinner eGON.BT1 Boot Image +>0 use egon-details + +# Allwinner TOC0 Boot Image +# Reference: https://linux-sunxi.org/TOC0 +0 name toc0-item +>0 ulelong 0x010101 certificate +>0 ulelong 0x010202 firmware +>0 ulelong 0x010303 key +>4 ulelong x (offset 0x%x +>8 ulelong x \b, size 0x%x) + +8 ulelong 0x89119800 Allwinner TOC0 Boot Image +>24 ulelong x with %u items +# each item is 32 bytes +# item 0 +>24 ulelong >0 \b: +>>48 use toc0-item +# item 1 +>24 ulelong >1 \b, +>>80 use toc0-item +# item 2 +>24 ulelong >2 \b, +>>112 use toc0-item +# item 3 +>24 ulelong >3 \b, +>>144 use toc0-item +# item 4 +>24 ulelong >4 \b, +>>176 use toc0-item +# item 5+ +>24 ulelong >5 \b, ... + +# Allwinner TOC1 Boot Image +# Reference: https://lore.kernel.org/all/20211015040811.56856-2-samuel@sholland.org/T/ +0 name toc1-item +>0 string/64/T x %s +>64 ulelong x (offset 0x%x +>68 ulelong x \b, size 0x%x) + +16 ulelong 0x89119800 Allwinner TOC1 Boot Image +>0 string/16/T >\0 (name "%s") +>32 ulelong x with %u items +# each item is 368 bytes +# item 0 +>32 ulelong >0 \b: +>>64 use toc1-item +# item 1 +>32 ulelong >1 \b, +>>432 use toc1-item +# item 2 +>32 ulelong >2 \b, +>>800 use toc1-item +# item 3 +>32 ulelong >3 \b, +>>1168 use toc1-item +# item 4 +>32 ulelong >4 \b, +>>1536 use toc1-item +# item 5+ +>32 ulelong >5 \b, ... + +# https://github.com/o-gs/dji-firmware-tools/blob/master/dji_imah_fwsig.py#L404 +0 string IM*H DJI firmware update +>40 string/4 >\0 (auth %s, +>44 string/4 >\0 enc %s) +>44 string/4 =\0 no enc) + +# NXP i.MX RT firmware image +# From: A. Iooss <aiooss@crans.org> +# Reference: Table 8-2 in MCU_Flashloader_Reference_Manual.pdf +# URL: https://github.com/tock/tock/blob/master/boards/teensy40/layout.ld +# Image starts with a NOR FlexSPI Configuration Block (FCB) of 3kB or 4kB +0 string FCFB +>7 string V NXP i.MX RT bootable image +!:ext bin +>>6 byte x \b, version %d +>>5 byte x \b.%d +>>4 byte x \b.%d +# then a Image Vector Table of 4kB +>>3072 ulelong&0xFCFFFFFF 0x402000D1 +>>>7168 use flexspi-fw +>>4096 ulelong&0xFDFFFFFF 0x402000D1 +>>>5120 use flexspi-fw +>>4096 ulelong&0xFDFFFFFF 0x412000D1 +>>>8192 use flexspi-fw +# then maybe a ARM Cortex-M program, but with vector table pointing to peripheral memory +0 name flexspi-fw +>3 byte 0x20 +>>4 ulelong&1 1 +>>>8 ulelong&1 1 +>>>>12 ulelong&1 1 +>>>>>44 ulelong&1 1 +>>>>>>56 ulelong&1 1 \b, ARM Cortex-M +>>>>>>>0 ulelong >0 \b, initial SP at 0x%08x +>>>>>>>4 ulelong^1 x \b, reset at 0x%08x +>>>>>>>8 ulelong^1 x \b, NMI at 0x%08x +>>>>>>>12 ulelong^1 x \b, HardFault at 0x%08x +>>>>>>>44 ulelong^1 x \b, SVCall at 0x%08x +>>>>>>>56 ulelong^1 x \b, PendSV at 0x%08x diff --git a/magic/Magdir/fonts b/magic/Magdir/fonts index e059ba563317..54b8c499dfd1 100644 --- a/magic/Magdir/fonts +++ b/magic/Magdir/fonts @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: fonts,v 1.52 2024/11/09 23:52:53 christos Exp $ +# $File: fonts,v 1.54 2025/02/10 22:01:36 rrt Exp $ # fonts: file(1) magic for font data # 0 search/1 FONT ASCII vfont text @@ -276,14 +276,14 @@ # maximal 27 tables found like in Skia.ttf # 46 different table names mentioned on Apple specification # skip 1st sequence of DOS 2 backup with path separator (\~92 or /~47) misinterpreted as table number ->4 ubeshort <47 +>4 ubeshort <48 # skip bad examples with garbage table names like in a5.show HYPERC MAC # tag names consist of up to four characters padded with spaces at end like -# BASE DSIG OS/2 Zapf acnt glyf cvt vmtx xref ... ->>12 regex/4l \^[A-Za-z][A-Za-z][A-Za-z/][A-Za-z2\ ] +# BASE C2PA DSIG OS/2 Zapf acnt glyf cvt vmtx xref ... +>>12 regex/4l \^[A-Za-z][A-Za-z2][A-Za-z/][A-Za-z2\ ] #>>>0 ubelong x \b, sfnt version %#x >>>0 ubelong !0x4f54544f TrueType -!:mime font/sfnt +!:mime font/ttf !:apple ????tfil # .ttf for TrueType font # EUDC.tte created by privat character editor %WINDIR%\system32\eudcedit.exe @@ -295,8 +295,8 @@ !:ext otf >>>0 ubelong x Font data # DSIG=44454947h table name implies a digitally signed font -# search range = number of tables * 16 =< maximal number of tables * 16 = 27 * 16 = 432 ->>>12 search/432 DSIG \b, digitally signed +# search range = number of tables * 16 =< maximal number of tables * 16 = 28 * 16 = 432 +>>>12 search/448 DSIG \b, digitally signed >>>4 ubeshort x \b, %d tables # minimal 9 tables found like in NISC18030.ttf #>>>4 ubeshort <10 TMIN diff --git a/magic/Magdir/games b/magic/Magdir/games index b8ead41b1dba..2520b937f74c 100644 --- a/magic/Magdir/games +++ b/magic/Magdir/games @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: games,v 1.35 2024/11/09 23:04:46 christos Exp $ +# $File: games,v 1.38 2025/05/31 15:42:06 christos Exp $ # games: file(1) for games # Fabio Bonelli <fabiobonelli@libero.it> @@ -245,14 +245,14 @@ # Type: SGF Smart Game Format # URL: https://www.red-bean.com/sgf/ # From: Eduardo Sabbatella <eduardo_sabbatella@yahoo.com.ar> -2 regex/c \\(;.*GM\\[[0-9]{1,2}\\] Smart Game Format ->2 regex/c GM\\[1\\] - Go Game ->2 regex/c GM\\[6\\] - BackGammon Game ->2 regex/c GM\\[11\\] - Hex Game ->2 regex/c GM\\[18\\] - Amazons Game ->2 regex/c GM\\[19\\] - Octi Game ->2 regex/c GM\\[20\\] - Gess Game ->2 regex/c GM\\[21\\] - twix Game +2 regex \\(;.*GM\\[[0-9]{1,2}\\] Smart Game Format +>2 regex GM\\[1\\] - Go Game +>2 regex GM\\[6\\] - BackGammon Game +>2 regex GM\\[11\\] - Hex Game +>2 regex GM\\[18\\] - Amazons Game +>2 regex GM\\[19\\] - Octi Game +>2 regex GM\\[20\\] - Gess Game +>2 regex GM\\[21\\] - twix Game # Epic Games/Unreal Engine Package # URL: https://docs.unrealengine.com/udk/Three/ContentCooking.html @@ -436,7 +436,7 @@ 0 uleshort 0x0469 GTA2 binary mission script (SCR), Industrial area (bil) 0 string v9.6\0\0 GTA2 replay file (REP), ->8 regex/30c [a-z0-9:\ ]+\0\0 created on %s +>8 regex/30 [a-z0-9:\ ]+\0\0 created on %s # GTA 3D-Era (III/VC/SA/LCS/VCS) - used by the RenderWare engine by Criterion Games @@ -664,3 +664,47 @@ >122 ubyte 0x01 pcxLib archive >>144 uleshort 0 \b, uncompressed >>144 uleshort !0 \b, compressed + +# RGSSAD asset archive used in RPG Maker XP, VX and VX Ace +0 string RGSSAD\0 +>7 byte x RPG Maker RGSSAD asset archive. version %u +!:ext rgssad/rgss2a/rgss3a + +# Panda3D BAM model format +# From: Derzsi Daniel <daniel@tohka.us> +# URL: https://gist.github.com/rdb/13cb936f41e0339a9a9cf9651ea2b09f +0 string pbj\0\n\r Panda3D BAM file +>10 ubyte x version %u +>12 ubyte x \b.%u +# Version >= 5.0 has little-endian and big-endian formats +>10 ubyte >4 +>>14 ubyte 0 \b, big-endian vertex data +>>14 ubyte 1 \b, little-endian vertex data +>10 ubyte <5 \b, little-endian vertex data +# Version >= 6.27 has single-precision and double-precision floats +>10 ubyte =6 +>>12 ubyte >26 +>>>15 ubyte 0 \b, single-precision floats +>>>15 ubyte 1 \b, double-precision floats +>>12 ubyte <27 \b, single-precision floats +>10 ubyte >6 +>>15 ubyte 0 \b, single-precision floats +>>15 ubyte 1 \b, double-precision floats +>10 ubyte <6 \b, single-precision floats + +# Panda3D Multifile archive format +# From: Derzsi Daniel <daniel@tohka.us> +# URL: https://tohka.us/p/exploring-encrypted-multifiles-a-technical-overview +0 string pmf\0\n\r Panda3D Multifile archive +>6 uleshort x version %u +>8 uleshort x \b.%u +# Version >= 1.1 has creation date information, missing if set to zero +>6 uleshort =1 +>>8 uleshort >0 +>>>14 uledate =0 \b, unknown creation date +>>>14 uledate !0 \b, created: %s +>>8 uleshort <1 \b, unknown creation date +>6 uleshort >1 +>>14 uledate =0 \b, unknown creation date +>>14 uledate !0 \b, created: %s +>6 uleshort <1 \b, unknown creation date diff --git a/magic/Magdir/gguf b/magic/Magdir/gguf new file mode 100644 index 000000000000..4becd6e114dc --- /dev/null +++ b/magic/Magdir/gguf @@ -0,0 +1,23 @@ + +#------------------------------------------------------------------------------ +# $File: gguf,v 1.2 2025/03/10 20:50:40 christos Exp $ +# +# +# GGUF: magic file for GGUF-models +# URL: https://github.com/ggml-org/ggml/ +# From: Noah Peterson <noahbpeterson1997@gmail.com> + +0 string GGUF GGUF file format +>4 byte x version %d +>8 quad x \b, %llu tensors +>16 quad >0 \b, %llu metadata entries +>&8 search/256 general.architecture +>>&12 regex ([A-Za-z0-9-]+) \b, Architecture: %s +>&8 search/256 general.name +>>&12 regex ([A-Za-z0-9\ -]+) \b, Name: %s +>&0 search/512 .block_count +>>&4 long x \b, Block Count: %u +>&0 search/512 context_length +>>&4 long x \b, Context Length: %u +>&0 search/512 embedding_length +>>&4 long x \b, Embedding Length: %u diff --git a/magic/Magdir/ibm370 b/magic/Magdir/ibm370 index 95f737128c97..bac449e04ef9 100644 --- a/magic/Magdir/ibm370 +++ b/magic/Magdir/ibm370 @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: ibm370,v 1.13 2024/06/19 16:52:57 christos Exp $ +# $File: ibm370,v 1.14 2026/01/10 15:49:11 christos Exp $ # ibm370: file(1) magic for IBM 370 and compatibles. # # "ibm370" said that 0x15d == 0535 was "ibm 370 pure executable". @@ -56,3 +56,9 @@ # to 8 bytes. According to https://www.ibm.com/support/pages/apar/PK91585 # IEWPLMH is eyecatcher for "Binder Program Load Module Header" control block 0 string \xc9\xc5\xe6\xd7\xd3\xd4\xc8\x40 z/OS Program Object executable + + +# https://www.cbttape.org/awstape.htm +0 leshort >0 +>2 leshort 0x0000 +>>4 leshort 0x00a0 IBM AWS file diff --git a/magic/Magdir/images b/magic/Magdir/images index a3b972fb1ee1..ecc3fb5ae475 100644 --- a/magic/Magdir/images +++ b/magic/Magdir/images @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: images,v 1.263 2024/11/10 20:44:30 christos Exp $ +# $File: images,v 1.267 2025/11/24 14:22:31 christos Exp $ # images: file(1) magic for image formats (see also "iff", and "c-lang" for # XPM bitmaps) # @@ -644,7 +644,8 @@ # GRR: with --keep-going option the line above gives duplicate messages 0 search/1/ts #FIG >&0 use image-xfig -# binary data variant with non ASCII text characters like Control-A or °C in thermostat.fig +# o +# binary data variant with non ASCII text characters like Control-A or C in thermostat.fig 0 search/1/bs #FIG >&0 use image-xfig # display XFIG image describing text, mime type, file name extension and version @@ -4565,6 +4566,7 @@ >24 ulelong 0 >>4 uleshort 0xA5E0 Aseprite asset file !:ext aseprite +!:mime image/x-aseprite >>>0 ulelong x \b, size %u >>>6 uleshort x \b, frames %u >>>8 uleshort x \b, size %ux @@ -4582,3 +4584,44 @@ >>>38 leshort x \b%d) >>>40 uleshort x \b, grid size %dx >>>42 uleshort x \b%d + +# Type: CIS/COD Bitmaps +# Documentation: https://cod.igada.de/ and http://fileformats.archiveteam.org/wiki/Lightning_Strike +# From: Robert Jäschke <robert.jaeschke at hu-berlin.de> +0 string/b CIS +>4 ubyte 0x2e +>>3 ubyte >0x31 +>>>3 ubyte <0x34 CIS/COD image data +!:mime image/cis-cod +!:ext cod + +# versions 2.3 to 2.5 are different to version 3.0 +>>>>3 regex/4 2\\.[345] \b, version %s +>>>>>16 uleshort x \b, %u x +>>>>>18 uleshort x %u + +# so far we know more about version 3.0 +>>>>3 string/3 3.0 \b, version %s +# width and height +>>>>>16 uleshort x \b, %u x +>>>>>18 uleshort x %u x +>>>>>20 ubyte x %u + +# gray vs. color +>>>>>21 byte 0 \b, gray +>>>>>21 byte 1 \b, color +# encoder type +>>>>>24 byte 1 \b, lossy arithmetic encoder +>>>>>24 byte 2 \b, lossless arithmetic encoder +# compression type +>>>>>25 byte 1 \b, bi-wavelet compression +# quantizer type +>>>>>26 byte 1 \b, table quantization +# scb +>>>>>27 byte 1 \b, SISD +# color space +>>>>>28 byte 1 \b, YIQ RGB +>>>>>28 byte 2 \b, YUV RGB +>>>>>28 byte 3 \b, YCbCr RGB +# wavelet levels +>>>>>29 ubyte x \b, %u wavelet levels diff --git a/magic/Magdir/intel b/magic/Magdir/intel index 5177fea45785..fb32cac5f943 100644 --- a/magic/Magdir/intel +++ b/magic/Magdir/intel @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: intel,v 1.23 2022/10/31 13:22:26 christos Exp $ +# $File: intel,v 1.24 2025/01/30 19:02:08 christos Exp $ # intel: file(1) magic for x86 Unix # # Various flavors of x86 UNIX executable/object (other than Xenix, which @@ -308,3 +308,7 @@ # revision number of the ASL Compiler like: 20051117 20140724 20190703 20200110 ... >>>32 ulelong x %x +# data that can be parsed by dmidecode(8) from a dump +# or extracted from a bios image +0 string _SM3_ +>0x5 byte <0x3 SMBIOS 3.x file diff --git a/magic/Magdir/linux b/magic/Magdir/linux index 16aadca87d1a..eb29069d566a 100644 --- a/magic/Magdir/linux +++ b/magic/Magdir/linux @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: linux,v 1.91 2024/11/09 21:15:48 christos Exp $ +# $File: linux,v 1.95 2025/07/12 14:30:14 christos Exp $ # linux: file(1) magic for Linux files # # Values for Linux/i386 binaries, from Daniel Quinlan <quinlan@yggdrasil.com> @@ -456,6 +456,8 @@ ############################################################################ # Linux S390 kernel image # Created by: Jan Kaluza <jkaluza@redhat.com> +# Update: Jens Remus <jremus@linux.ibm.com> based on Vasily Gorbik <gor@linux.ibm.com> +# Linux kernel: arch/s390/boot/head.S and arch/s390/include/asm/setup.h 8 string \x02\x00\x00\x18\x60\x00\x00\x50\x02\x00\x00\x68\x60\x00\x00\x50\x40\x40\x40\x40\x40\x40\x40\x40 Linux S390 >0x00010000 search/b/4096 \x00\x0a\x00\x00\x8b\xad\xcc\xcc # 64bit @@ -468,6 +470,12 @@ >>&0 string \x81\x00\xc8\x80\x00\x00\x00\x00 Z9-109 32bit kernel >>&0 string \x80\x00\x20\x00\x00\x00\x00\x00 Z990 32bit kernel >>&0 string \x80\x00\x00\x00\x00\x00\x00\x00 Z900 32bit kernel +# Linux kernel v3.2+ +>0x10008 string S390EP +# Linux kernel v5.3+ +>>0x10428 ubequad >0 +>>>(0x10428.Q) string >\0 \b, version %s + ############################################################################ # Linux ARM compressed kernel image @@ -522,6 +530,17 @@ >0x18 lelong &6 \b, 32K pages ############################################################################ +# Linux kernel (arm64/riscv/loongarch) EFI executable (zstd/gzip) compressed zboot Image +# from: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/firmware/efi/libstub/zboot-header.S +0 string MZ\0\0zimg +>0x40 string PE\0\0 Linux kernel +>>&0 leshort 0xAA64 ARM64 EFI executable +>>&0 leshort 0x5032 RISC-V32 EFI executable +>>&0 leshort 0x5064 RISC-V64 EFI executable +>>&0 leshort 0x6264 LoongArch64 EFI executable +>>0x18 string >0 %s compressed zboot Image + +############################################################################ # Linux RISC-V kernel image 0x38 string RSC\05 Linux kernel RISC-V boot executable Image >0x18 lelong ^1 \b, little-endian @@ -968,3 +987,14 @@ 0 lequad 0x32454c4946524550 Linux perf recording, version 2. little endian 0 bequad 0x32454c4946524550 Linux perf recording, version 2. big endian + +# perf(1) (Performance analysis tools) command +# +# For file format details, see: +# +# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/\ +# tools/perf/Documentation/perf.data-file-format.txt + +# The file is normally called 'perf.data' but can take any name, +# so only check the eye catcher value. +0 string PERFILE2 perf(1) data diff --git a/magic/Magdir/lua b/magic/Magdir/lua index ab17374534de..859862a351f4 100644 --- a/magic/Magdir/lua +++ b/magic/Magdir/lua @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: lua,v 1.8 2020/10/08 23:23:56 christos Exp $ +# $File: lua,v 1.9 2026/01/25 16:07:06 christos Exp $ # lua: file(1) magic for Lua scripting language # URL: https://www.lua.org/ # From: Reuben Thomas <rrt@sc3d.org>, Seo Sanghyeon <tinuviel@sparcs.kaist.ac.kr> @@ -29,3 +29,4 @@ >4 byte 0x52 version 5.2 >4 byte 0x53 version 5.3 >4 byte 0x54 version 5.4 +>4 byte 0x55 version 5.5 diff --git a/magic/Magdir/mail.news b/magic/Magdir/mail.news index 94f30898d5de..1cd1dffeab53 100644 --- a/magic/Magdir/mail.news +++ b/magic/Magdir/mail.news @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: mail.news,v 1.32 2024/11/10 16:59:38 christos Exp $ +# $File: mail.news,v 1.33 2025/02/28 19:28:01 christos Exp $ # mail.news: file(1) magic for mail and news # # Unfortunately, saved netnews also has From line added in some news software. @@ -32,7 +32,7 @@ !:mime message/rfc822 0 string/t To: news or mail text !:mime message/rfc822 -0 string/t Article saved news text +0 regex/t Article:[[:space:]]+[0-9]+ saved news text !:mime message/news # Reference: http://quimby.gnus.org/notes/BABYL # Update: Joerg Jenderek diff --git a/magic/Magdir/measure b/magic/Magdir/measure index 42e7186484c8..a36547213c7c 100644 --- a/magic/Magdir/measure +++ b/magic/Magdir/measure @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: measure,v 1.3 2021/03/25 17:30:10 christos Exp $ +# $File: measure,v 1.4 2026/01/23 16:41:32 christos Exp $ # measure: file(1) magic for measurement data # DIY-Thermocam raw data @@ -42,3 +42,10 @@ (0x02.l) string *IDENTIFICATION Becker & Hickl PMS Data File >0x12 short x (%d data blocks) !:ext sdt + +# https://www.asam.net/standards/detail/mdf/ +0 string MDF\x20\x20\x20\x20\x20 ASAM/MDF measurement file Version +>8 regex .\\... %s +>12 string \x20\x20\x20\x20 +>62 byte !0 (unfinalized) +>64 string ##HD diff --git a/magic/Magdir/msdos b/magic/Magdir/msdos index 925901694c30..3e748eb1d6bc 100644 --- a/magic/Magdir/msdos +++ b/magic/Magdir/msdos @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: msdos,v 1.208 2024/08/27 18:50:57 christos Exp $ +# $File: msdos,v 1.214 2025/09/06 17:00:32 christos Exp $ # msdos: file(1) magic for MS-DOS files # @@ -24,9 +24,9 @@ # OS/2 batch files are REXX. the second regex is a bit generic, oh well # the matched commands seem to be common in REXX and uncommon elsewhere 100 search/0xffff rxfuncadd ->100 regex/c =^[\ \t]{0,10}call[\ \t]{1,10}rxfunc OS/2 REXX batch file text +>100 regex =^[\ \t]{0,10}call[\ \t]{1,10}rxfunc OS/2 REXX batch file text 100 search/0xffff say ->100 regex/c =^[\ \t]{0,10}say\ ['"] OS/2 REXX batch file text +>100 regex/ =^[\ \t]{0,10}say\ ['"] OS/2 REXX batch file text # Tests for various EXE types. @@ -510,7 +510,7 @@ >>>>>>>(0x3c.l+0x2a) default x # Binaries with KERNEL, USER or GDI import library are for Windows # FIXME: names are prefixed by its length, but regex type does not support binary bytes ->>>>>>>>&(&0.s-0x29) regex/512/C KERNEL|USER|GDI for MS Windows 1.x/2.x +>>>>>>>>&(&0.s-0x29) regex/512 KERNEL|USER|GDI for MS Windows 1.x/2.x >>>>>>>>>(0x3c.l+0x37) byte&0x04 0 (real mode only) >>>>>>>>>(0x3c.l+0x37) byte&0x04 !0 (real+protected mode) # Binaries without any of those import library can be for any OS @@ -772,7 +772,13 @@ >>>0x40 search/0x80 STUB/32C \b, DOS/32A DOS extender (configurable stub) >>>0x40 search/0x80 DOS/32A \b, DOS/32A DOS extender (embedded) -# PX\0\0 signature for 32bit DOS Applications in DOS-PE Format (https://www.japheth.de/HX.html) +# PL\0\0 signature for 32-bit DOS Applications in Phar Lap TNT PE/PL Format +# Binaries can be created by TNT MARKPHAR.EXE or by 386LINK.EXE -markphar switch +# FULLSCR.EXE, GDEMO.EXE, MOUSE.EXE from MSVC32s SDK and from Phar Lap TNT SDK +>(0x3c.l) string PL\0\0 \b, PE32 executable for MS-DOS +>>(8.s*16) search/0x50 Phar\ Lap\ Software,\ Inc. \b, Phar Lap TNT DOS extender + +# PX\0\0 signature for 32/64-bit DOS Applications in DOS-PE Format (https://www.japheth.de/HX.html) # SHDPMI.EXE, DOSTEST.EXE, GETVMODE.EXE, RMINT.EXE >(0x3c.l) string PX\0\0 \b, PE32 >>(0x3c.l+24) leshort 0x020b \b+ @@ -793,6 +799,7 @@ # Skip already parsed binary types # If magic in the branch is not parsed then always jumps to mz-unrecognized >(0x3c.l) string PE\0\0 +>(0x3c.l) string PL\0\0 >(0x3c.l) string PX\0\0 >(0x3c.l) string LX >(0x3c.l) string NE @@ -2108,9 +2115,9 @@ # display shared information of cursor or icon entry 0 name cur-ico-entry >0 byte =0 \b, 256x ->0 byte !0 \b, %dx +>0 ubyte !0 \b, %dx >1 byte =0 \b256 ->1 byte !0 \b%d +>1 ubyte !0 \b%d # number of colors in palette >2 ubyte !0 \b, %d colors # reserved 0 FFh @@ -2516,7 +2523,7 @@ # URL: https://en.wikipedia.org/wiki/Microsoft_OneNote#File_format # http://fileformats.archiveteam.org/wiki/OneNote # Reference: https://mark0.net/download/triddefs_xml.7z/defs/o/onepkg.trid.xml -# 1st member name like: "Class Notes.one" "test-onenote.one" "Open Notebook.onetoc2" "Editor Öffnen.onetoc2" +# 1st member name like: "Class Notes.one" "test-onenote.one" "Open Notebook.onetoc2" "Editor offnen.onetoc2" >>>>>&0 string/c one \b, OneNote Package !:mime application/msonenote !:ext onepkg @@ -2681,12 +2688,6 @@ # next archive member name if more files #>>&17 string >\0 \b, NEXT NAME %-.50s -# InstallShield Cabinet files -0 string/b ISc( InstallShield Cabinet archive data ->5 byte&0xf0 =0x60 version 6, ->5 byte&0xf0 !0x60 version 4/5, ->(12.l+40) lelong x %u files - # Windows CE package files 0 string/b MSCE\0\0\0\0 Microsoft WinCE install header >20 lelong 0 \b, architecture-independent @@ -2821,40 +2822,6 @@ # NB: The BACKUP.nnn files consist of the files backed up, # concatenated. -# From: Joerg Jenderek -# URL: http://fileformats.archiveteam.org/wiki/MS-DOS_date/time -# Reference: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-dosdatetimetofiletime -# Note: DOS date+time format is different from formats such as Unix epoch -# bit encoded; uses year values relative to 1980 and 2 second precision -0 name dos-date -# HHHHHMMMMMMSSSSS bit encoded Hour (0-23) Minute (0-59) SecondPart (*2) -#>0 uleshort x RAW TIME [%#4.4x] -# hour part -#>0 uleshort/2048 x hour [%u] -# YYYYYMMMMDDDDD bit encoded YearPart (+1980) Month (1-12) Day (1-31) -#>2 uleshort x RAW DATE [%#4.4x] -# day part ->2 uleshort&0x001F x %u -#>2 uleshort/16 x MONTH PART [%#x] -# GRR: not working -#>2 uleshort/16 &0x000F MONTH [%u] -#>2 uleshort&0x01E0 x MONTH PART [%#4.4x] ->2 uleshort&0x01E0 =0x0020 jan ->2 uleshort&0x01E0 =0x0040 feb ->2 uleshort&0x01E0 =0x0060 mar ->2 uleshort&0x01E0 =0x0080 apr ->2 uleshort&0x01E0 =0x00A0 may ->2 uleshort&0x01E0 =0x00C0 jun ->2 uleshort&0x01E0 =0x00E0 jul ->2 uleshort&0x01E0 =0x0100 aug ->2 uleshort&0x01E0 =0x0120 sep ->2 uleshort&0x01E0 =0x0140 oct ->2 uleshort&0x01E0 =0x0160 nov ->2 uleshort&0x01E0 =0x0180 dec -# year part ->2 uleshort/512 x 1980+%u -# - # ExcelBIFF2-8BOF.magic - Excel Binary Interchange File Format versions 2-8 # Beginning of File records # See https://www.gaia-gis.it/gaia-sins/freexl-1.0.6-doxy-doc/html/Format.html diff --git a/magic/Magdir/msooxml b/magic/Magdir/msooxml index 4dfb3a9fb623..274ce238df9e 100644 --- a/magic/Magdir/msooxml +++ b/magic/Magdir/msooxml @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: msooxml,v 1.23 2024/07/19 18:48:23 christos Exp $ +# $File: msooxml,v 1.24 2025/05/29 15:03:04 christos Exp $ # msooxml: file(1) magic for Microsoft Office XML # From: Ralf Brown <ralf.brown@gmail.com> @@ -26,6 +26,8 @@ !:mime application/vnd.ms-visio.drawing.main+xml >0 string AppManifest.xaml Microsoft Silverlight Application !:mime application/x-silverlight-app +>0 search/100 .nuspec NuGet package +!:mime application/vnd.nuget.package # start by checking for ZIP local file header signature 0 string PK\003\004 @@ -33,30 +35,30 @@ # make sure the first file is correct >0x1E use msooxml >0x1E default x ->>0x1E regex \\[Content_Types\\]\\.xml|_rels/\\.rels|docProps|customXml +>>0x1E regex \\[Content_Types\\]\\.xml|_rels/\\.rels|docProps|customXml|.*\\.md|.*\\.png # skip to the second local file header # since some documents include a 520-byte extra field following the file # header, we need to scan for the next header ->>>(18.l+49) search/6000 PK\003\004 +>>>&26 search/10000 PK\003\004 >>>>&26 use msooxml >>>>&26 default x # now skip to the *third* local file header; again, we need to scan due to a # 520-byte extra field following the file header ->>>>>&26 search/6000 PK\003\004 +>>>>>&26 search/10000 PK\003\004 # and check the subdirectory name to determine which type of OOXML # file we have. Correct the mimetype with the registered ones: # https://technet.microsoft.com/en-us/library/cc179224.aspx >>>>>>&26 use msooxml >>>>>>&26 default x # OpenOffice/Libreoffice orders ZIP entry differently, so check the 4th file ->>>>>>>&26 search/6000 PK\003\004 +>>>>>>>&26 search/10000 PK\003\004 >>>>>>>>&26 use msooxml # Some OOXML generators add an extra customXml directory. Check another file. >>>>>>>>&26 default x ->>>>>>>>>&26 search/6000 PK\003\004 +>>>>>>>>>&26 search/10000 PK\003\004 >>>>>>>>>>&26 use msooxml >>>>>>>>>>&26 default x ->>>>>>>>>>>&26 search/6000 PK\003\004 +>>>>>>>>>>>&26 search/10000 PK\003\004 >>>>>>>>>>>>&26 use msooxml >>>>>>>>>>>>&26 default x Microsoft OOXML >>>>>>>>>>>&26 default x Microsoft OOXML @@ -66,11 +68,11 @@ >>>>>>>&26 default x Microsoft OOXML >>>>>>&26 default x Microsoft OOXML >>0x1E regex \\[trash\\] ->>>&26 search/6000 PK\003\004 ->>>>&26 search/6000 PK\003\004 +>>>&26 search/10000 PK\003\004 +>>>>&26 search/10000 PK\003\004 >>>>>&26 use msooxml >>>>>&26 default x ->>>>>>&26 search/6000 PK\003\004 +>>>>>>&26 search/10000 PK\003\004 >>>>>>>&26 use msooxml >>>>>>>&26 default x Microsoft OOXML >>>>>>&26 default x Microsoft OOXML diff --git a/magic/Magdir/music b/magic/Magdir/music index f87fc12ef8b2..045a62ae81e0 100644 --- a/magic/Magdir/music +++ b/magic/Magdir/music @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: music,v 1.2 2024/06/10 23:09:52 christos Exp $ +# $File: music,v 1.4 2026/02/07 21:56:41 rrt Exp $ # music: file(1) magic for music formats # BWW format used by Bagpipe Music Writer Gold by Robert MacNeil Musicworks @@ -15,3 +15,46 @@ >>>25 string : >>>>26 string >\0 (version %.3s) +# Bars & Pipes Professional +# https://wiki.amigaos.net/wiki/Bars_and_Pipes_Professional +# +0 string BRPP Bars & Pipes Professional + +# Sibelius music notation software (published by Sibelius Software, then Avid) +# http://fileformats.archiveteam.org/wiki/Sibelius +# +# These patterns cover the Windows and macOS versions of the software, not +# the older (confusingly-named) Sibelius 6 & 7 for Acorn RISC PC. +0 string \x0fSIBELIUS Sibelius +!:mime application/x-sibelius-score +>10 string \x00\x00\x00\x0e (version 1.2) +>10 string \x00\x08 (version 2.x) +>10 string \x00\x0a (version 3.x) +>10 string \x00\x1b (version 4.x) +>10 string \x00\x2d\x00\x03 (version 5.0) +>10 string \x00\x2d\x00\x0d (version 5.1) +>10 string \x00\x2d\x00\x10 (version 5.2) +>10 string \x00\x36\x00\x01 (version 6.0) +>10 string \x00\x36\x00\x17 (version 6.1) +>10 string \x00\x36\x00\x1e (version 6.2) +>10 string \x00\x39\x00\x0c (version 7.0) +>10 string \x00\x39\x00\x0e (version 7.0.1-7.0.2) +>10 string \x00\x39\x00\x13 (version 7.0.3) +>10 string \x00\x39\x00\x15 (version 7.1.0) +>10 string \x00\x39\x00\x16 (version 7.1.2-7.1.3) +>10 string \x00\x3d\x00\x0e (version 7.5) +>10 string \x00\x3d\x00\x10 (version 8.0) +>10 string \x00\x3e\x00\x00 (version 8.1) +>10 string \x00\x3e\x00\x01 (version 8.2) +>10 string \x00\x3e\x00\x02 (version 8.3) +>10 string \x00\x3e\x00\x06 (version 8.4) +>10 string \x00\x3e\x00\x07 (version 8.5) +>10 string \x00\x3f\x00\x00 (version 8.6-8.7.1) +>10 string \x00\x3f\x00\x01 (version 8.7.2) +>10 string \x00\x3f\x00 (version 8.8-2019.12) +>10 string \x00\x3f\x00\x0b (version 2020.1) +>10 string \x00\x40\x00 (version 2020.3-2022.5) +>10 string \x00\x41\x00 (version 2022.7-2022.11) +>10 string \x00\x42\x00 (version 2022.12-2023.3) +>10 string \x00\x43\x00 (version 2023.5-2023.8) +>10 string \x00\x44\x00 (version 2024) diff --git a/magic/Magdir/os2 b/magic/Magdir/os2 index cb43e999f6f6..9705a28b9e37 100644 --- a/magic/Magdir/os2 +++ b/magic/Magdir/os2 @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: os2,v 1.14 2022/03/21 21:25:50 christos Exp $ +# $File: os2,v 1.16 2024/12/26 19:34:28 christos Exp $ # os2: file(1) magic for OS/2 files # @@ -167,20 +167,40 @@ !:mime application/x-os2-ini !:ext ini +# archive for the OS/2 WarpIN package manager # From: Joerg Jenderek # URL: http://warpin.netlabs.org/ # Reference: http://mark0.net/download/triddefs_xml.7z/defs/a/ark-wpi.trid.xml # Note: called by TrID "WarpIN Installer" -# probably magic at the beginning -0 ubelong =0x770402BE WarpIN Installer +# Revised by: Anton Monroe December 2024 +# Reference: http://trac.netlabs.org/warpin/browser/trunk/include/wiarchive/wiarchive.h +# magic is 4 bytes at the beginning +0 ubelong =0x770402BE OS/2 WarpIN Archive #>4 ubelong =0x03000000 #!:mime application/octet-stream !:mime application/x-os2-wpi !:ext wpi -# creator program name like: "reserved" or "WIC x.y.z" ->0x106 string x \b, created by %s +# The compiler that created the archive: "WicPM" or "WIC <version>". +# A few early archives say "reserved" or "Test application" +>0x106 string x \b, created with %s # name like: "reserved" or "OS/2 Netlabs" >0x146 string x \b, '%s' # name like: "N/A" "http://warpin.netlabs.org" >0x186 string x \b, URL %s +# self-extracting archive for the OS/2 WarpIN package manager +# From: Anton Monroe December 2024 +# Reference: http://trac.netlabs.org/warpin/browser/trunk/include/wiarchive/wiarchive.h +# look for "WarpIN self-extracting archive EXE stub" which is +# usually somewhere between offset 40000 and 45000, but one was at 62000 +0 string/b MZ +>40000 search/25000 WarpIN\ self-extracting\ archive\ EXE\ stub +>>&3 ubelong =0x770402BE OS/2 WarpIN self-extracting archive +!:ext exe +>>>&0x102 string x \b, created with %s + +# EXTPROC script +# "extproc" is the OS/2 version of Unix "#!" +0 string/tc extproc\x20 EXTPROC script +>&0 string x executed by %s +!:ext cmd diff --git a/magic/Magdir/pdf b/magic/Magdir/pdf index 7a99d8d3cf3d..9e39a9b011fc 100644 --- a/magic/Magdir/pdf +++ b/magic/Magdir/pdf @@ -1,12 +1,12 @@ #------------------------------------------------------------------------------ -# $File: pdf,v 1.18 2023/07/17 15:57:18 christos Exp $ +# $File: pdf,v 1.20 2025/11/22 20:59:37 christos Exp $ # pdf: file(1) magic for Portable Document Format # 0 name pdf >8 search /Count ->>&0 regex [0-9]+ \b, %s page(s) +>>&0 regex [1-9]([0-9]+)? \b, %s page(s) >8 search/512 /Filter/FlateDecode/ (zip deflate encoded) 0 string %PDF- PDF document diff --git a/magic/Magdir/pgp b/magic/Magdir/pgp index d7d3ae95d850..f0a98f3dbaa1 100644 --- a/magic/Magdir/pgp +++ b/magic/Magdir/pgp @@ -1,8 +1,15 @@ #------------------------------------------------------------------------------ -# $File: pgp,v 1.26 2024/09/01 15:51:51 christos Exp $ +# $File: pgp,v 1.27 2025/12/18 18:33:33 christos Exp $ # pgp: file(1) magic for Pretty Good Privacy +# Reference: https://www.iana.org/assignments/openpgp/openpgp.xhtml + +# PGP compressed data packet (RFC 4880, section 5.6) +0 beshort 0xa301 PGP compressed data (ZIP) +0 beshort 0xa302 PGP compressed data (ZLIB) +0 beshort 0xa303 PGP compressed data (BZIP2) + # Handling of binary PGP keys is in pgp-binary-keys. # see https://lists.gnupg.org/pipermail/gnupg-devel/1999-September/016052.html # @@ -101,6 +108,54 @@ # - symmetric encrypted packet header # - RSA (e=65537) secret (sub-)keys +# PGP ECC encrypted data +0 byte 0x84 +>2 byte 3 +>>11 byte 18 PGP ECDH Public-Key Encrypted Session Key - +>>>3 belong x keyid: %08X +>>>7 belong x %08X +>>11 byte 19 PGP ECDSA Public-Key Encrypted Session Key - +>>>3 belong x keyid: %08X +>>>7 belong x %08X +>>11 byte 22 PGP EdDSALegacy Public-Key Encrypted Session Key - +>>>3 belong x keyid: %08X +>>>7 belong x %08X +>>11 byte 25 PGP X25519 Public-Key Encrypted Session Key - +>>>3 belong x keyid: %08X +>>>7 belong x %08X +>>11 byte 26 PGP X448 Public-Key Encrypted Session Key - +>>>3 belong x keyid: %08X +>>>7 belong x %08X +>>11 byte 27 PGP Ed25519 Public-Key Encrypted Session Key - +>>>3 belong x keyid: %08X +>>>7 belong x %08X +>>11 byte 28 PGP Ed448 Public-Key Encrypted Session Key - +>>>3 belong x keyid: %08X +>>>7 belong x %08X +0 byte 0x85 +>3 byte 3 +>>12 byte 18 PGP ECDH Public-Key Encrypted Session Key - +>>>4 belong x keyid: %08X +>>>8 belong x %08X +>>12 byte 19 PGP ECDSA Public-Key Encrypted Session Key - +>>>4 belong x keyid: %08X +>>>8 belong x %08X +>>12 byte 22 PGP EdDSALegacy Public-Key Encrypted Session Key - +>>>4 belong x keyid: %08X +>>>8 belong x %08X +>>12 byte 25 PGP X25519 Public-Key Encrypted Session Key - +>>>4 belong x keyid: %08X +>>>8 belong x %08X +>>12 byte 26 PGP X448 Public-Key Encrypted Session Key - +>>>4 belong x keyid: %08X +>>>8 belong x %08X +>>12 byte 27 PGP Ed25519 Public-Key Encrypted Session Key - +>>>4 belong x keyid: %08X +>>>8 belong x %08X +>>12 byte 28 PGP Ed448 Public-Key Encrypted Session Key - +>>>4 belong x keyid: %08X +>>>8 belong x %08X + # 1024b RSA encrypted data 0 string \x84\x8c\x03 PGP RSA encrypted session key - @@ -243,6 +298,9 @@ >0 byte 0x08 AES with 192-bit key >0 byte 0x09 AES with 256-bit key >0 byte 0x0a Twofish with 256-bit key +>0 byte 0x0b Camellia with 128-bit key +>0 byte 0x0c Camellia with 192-bit key +>0 byte 0x0d Camellia with 256-bit key # hash algo mapper @@ -254,6 +312,8 @@ >0 byte 0x09 SHA384 >0 byte 0x0a SHA512 >0 byte 0x0b SHA224 +>0 byte 0x0c SHA3-256 +>0 byte 0x0e SHA3-512 # display public key algorithms as human readable text 0 name key_algo @@ -263,14 +323,19 @@ >0 byte 0x03 RSA (Sign-Only) >0 byte 16 ElGamal (Encrypt-Only) >0 byte 17 DSA ->0 byte 18 Elliptic Curve +>0 byte 18 ECDH >0 byte 19 ECDSA >0 byte 20 ElGamal (Encrypt or Sign) >0 byte 21 Diffie-Hellman +>0 byte 22 EdDSALegacy +>0 byte 25 X25519 +>0 byte 26 X448 +>0 byte 27 Ed25519 +>0 byte 28 Ed448 >0 default x ->>0 ubyte <22 unknown (pub %d) +>>0 ubyte <29 unknown (pub %d) # this should never happen ->>0 ubyte >21 invalid (%d) +>>0 ubyte >28 invalid (%d) # pgp symmetric encrypted data diff --git a/magic/Magdir/python b/magic/Magdir/python index e00a087d8bec..ede1b5baa1a2 100644 --- a/magic/Magdir/python +++ b/magic/Magdir/python @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: python,v 1.47 2024/08/27 18:50:57 christos Exp $ +# $File: python,v 1.49 2025/06/17 21:14:40 christos Exp $ # python: file(1) magic for python # # Outlook puts """ too for urgent messages @@ -205,7 +205,7 @@ 2 string \x0d\x0a # extra check: only two bits of flag field are currently used >4 ulelong <0x4 -# \x0d as part of magic should suffice till Python 3.14 (magic 3600) +# \x0d as part of magic suffices up to Python 3.13 >>1 ubyte 0x0d Byte-compiled Python module for !:mime application/x-bytecode.python # now look at the magic number to determine the version @@ -220,10 +220,17 @@ >>>>>>>0 uleshort <3500 CPython 3.11 >>>>>>>0 default x >>>>>>>>0 uleshort <3550 CPython 3.12 ->>>>>>>>0 default x ->>>>>>>>>0 uleshort <3600 CPython 3.13 ->>>>>>>>>0 default x CPython 3.14 or newer +>>>>>>>>0 default x CPython 3.13 >>>0 use pyc-pep552 +# \x0e means Python 3.14 or newer +>>1 ubyte 0x0e Byte-compiled Python module for +!:mime application/x-bytecode.python +>>>0 uleshort <3650 CPython 3.14 +>>>0 default x +>>>>0 uleshort <3700 CPython 3.15 +>>>>0 default x CPython 3.16 or newer +>>>0 use pyc-pep552 +# PyPy magic numbers >>0 uleshort 240 Byte-compiled Python module for PyPy3.7 !:mime application/x-bytecode.python >>>0 use pyc-pep552 @@ -233,15 +240,21 @@ >>0 uleshort 336 Byte-compiled Python module for PyPy3.9 !:mime application/x-bytecode.python >>>0 use pyc-pep552 +>>0 uleshort 384 Byte-compiled Python module for PyPy3.10 +!:mime application/x-bytecode.python +>>>0 use pyc-pep552 +>>0 uleshort 416 Byte-compiled Python module for PyPy3.11 +!:mime application/x-bytecode.python +>>>0 use pyc-pep552 0 search/1/w #!\040/usr/bin/python Python script text executable -!:strength + 15 +!:strength + 30 !:mime text/x-script.python 0 search/1/w #!\040/usr/local/bin/python Python script text executable -!:strength + 15 +!:strength + 30 !:mime text/x-script.python 0 search/10/w #!\040/usr/bin/env\040python Python script text executable -!:strength + 15 +!:strength + 30 !:mime text/x-script.python diff --git a/magic/Magdir/r b/magic/Magdir/r new file mode 100644 index 000000000000..3c393f70ab0b --- /dev/null +++ b/magic/Magdir/r @@ -0,0 +1,86 @@ + +#------------------------------------------------------------------------------ +# $File: r,v 1.1 2025/02/10 17:48:42 christos Exp $ +# file(1) magic for R's RDS and RData file formats +# Copyright (C) 2025 Gert Hulselmans <hulselmansgert@gmail.com> +# +# URLS: +# https://cran.r-project.org/doc/manuals/r-release/R-ints.html#Serialization-Formats +# https://rdata.readthedocs.io/en/latest/_modules/rdata/parser/_parser.html +# +# Example files: +# https://github.com/vnmabus/rdata/tree/develop/rdata/tests/data +# +############################################################################### + + +############################################################################### +# RDS format +############################################################################### + +0 name RDS +# Check for RDS ASCII formats. +>0 string A\n2\n R RDS (ASCII format v2) +>0 string A\n3\n R RDS (ASCII format v3) +>0 string A\r\n2\r\n R RDS (ASCII CRLF format v2) +>0 string A\r\n3\r\n R RDS (ASCII CRLF format v3) +# Check for RDS binary formats with native word order. +>0 string B\n\0\0\0 R RDS (Native (big-endian) word order format +>>0 use RDS_binary_version_info +>0 string B\n\2\0\0 R RDS (Native (little-endian) word order format +>>0 use ^RDS_binary_version_info +>0 string B\n\3\0\0 R RDS (Native (little-endian) word order format +>>0 use ^RDS_binary_version_info +# Check for RDS XDR binary save format. +>0 string X\n\0\0\0 R RDS (XDR binary save format +>>0 use RDS_binary_version_info + + +# Parse version numbers from RDS if it was one of the binary versions. +0 name RDS_binary_version_info +>2 belong >-1 v%d) +>6 beshort >-1 \b, written by R v%d. +>8 byte >-1 \b%d. +>9 byte >-1 \b%d +>10 beshort >-1 \b, readable from R v%d. +>12 byte >-1 \b%d. +>13 byte >-1 \b%d +>2 belong >2 +>>14 pstring/L x \b, %s encoded + + +# Check if file is one of the RDS ASCII formats. +0 string A +>0 use RDS not_printed +!:ext rds + +# Check if file is RDS binary native format. +0 string B +>0 use RDS not_printed +!:ext rds + +# Check if file is RDS XDR binary save format. +0 string X +>0 use RDS not_printed +!:ext rds + + +############################################################################### +# RData file formats: magic bytes followed by RDS container. +############################################################################### + +0 string RDA2\n R RData version 2 (ASCII), +!:ext rda/rdata +>5 use RDS + +0 string RDA3\n R RData version 3 (ASCII), +!:ext rda/rdata +>5 use RDS + +0 string RDX2\n R RData version 2 (binary), +!:ext rda/rdata +>5 use RDS + +0 string RDX3\n R RData version 3 (binary), +!:ext rda/rdata +>5 use RDS diff --git a/magic/Magdir/riff b/magic/Magdir/riff index 664fef24d5e9..0c6e066861cb 100644 --- a/magic/Magdir/riff +++ b/magic/Magdir/riff @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: riff,v 1.50 2024/04/13 16:40:48 christos Exp $ +# $File: riff,v 1.52 2025/09/08 12:48:15 christos Exp $ # riff: file(1) magic for RIFF format # See # @@ -171,8 +171,13 @@ >>>8 byte &0x20 \b, ICC profile # TODO: These two values are off-by-one, for a 64x64 WebP they contain # 63x63 as there can be no 0x0 file. ->>>12 lelong&0xffffff x \b, %d+1 ->>>15 lelong&0xffffff x \bx%d+1 +# we only handle < 65536 so we don't have do print %d+1: +#>>>12 ulelong&0xffffff x \b, %d+1 +#>>>15 ulelong&0xffffff x \bx%d+1 +>>>12 ulelong&0xffffff <65536 +>>>>15 ulelong&0xffffff <65536 +>>>>>12 uleshort+1 x \b, %u +>>>>>15 uleshort+1 x \bx%u #>0 string x we got %s #>>&(4.l+4) use riff-walk @@ -237,6 +242,7 @@ # AVI section extended by Patrik Radman <patrik+file-magic@iki.fi> # 0 string RIFF RIFF (little-endian) data +!:strength +50 # RIFF Palette format # Update: Joerg Jenderek # URL: https://en.wikipedia.org/wiki/Resource_Interchange_File_Format diff --git a/magic/Magdir/rtf b/magic/Magdir/rtf index 48a1f28af467..e49c565d3dc0 100644 --- a/magic/Magdir/rtf +++ b/magic/Magdir/rtf @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: rtf,v 1.9 2020/12/12 20:01:47 christos Exp $ +# $File: rtf,v 1.10 2025/03/21 17:11:56 christos Exp $ # rtf: file(1) magic for Rich Text Format (RTF) # # Duncan P. Simpson, D.P.Simpson@dcs.warwick.ac.uk @@ -92,3 +92,8 @@ !:ext pwd/psw/pwt >0 use rtf-info +# https://en.wikipedia.org/wiki/Rich_Text_Format_Directory +# https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/rtfd +0 string rtfd\0\0\0\0 Rich Text Format Directory +!:ext rtfd + diff --git a/magic/Magdir/sf3 b/magic/Magdir/sf3 new file mode 100644 index 000000000000..10a49d5b7a77 --- /dev/null +++ b/magic/Magdir/sf3 @@ -0,0 +1,112 @@ + +#------------------------------------------------------------------------------ +# $File: sf3,v 1.1 2025/06/27 15:13:53 christos Exp $ +# sfr: SF3 [Simple File Format Family] files +# (Yukari Hafner, shinmera@tymoon.eu) +# +# Reference: https://shirakumo.org/docs/sf3 +# Samples: https://shirakumo.org/projects/sf3/tree/master/samples/ + +0 name SF3-archive +>0 ulequad x \b, %llu files +!:mime application/x.sf3-archive + +0 name SF3-audio +>0 ulelong >1 \b, %dHz +>4 ubyte >0 \b, %d channels +>5 byte 0x01 \b, A-law +>5 byte 0x02 \b, 16-bit signed PCM +>5 byte 0x04 \b, 32-bit signed PCM +>5 byte 0x08 \b, 64-bit signed PCM +>5 byte 0x11 \b, u-law +>5 byte 0x12 \b, 16-bit unsigned PCM +>5 byte 0x14 \b, 32-bit unsigned PCM +>5 byte 0x18 \b, 64-bit unsigned PCM +>5 byte 0x22 \b, half-float PCM +>5 byte 0x24 \b, single-float PCM +>5 byte 0x28 \b, double-float PCM +!:mime audio/x.sf3 + +0 name SF3-image +>0 ulelong >0 \b, %d +>4 ulelong >0 \bx%d +>8 ulelong >0 \bx%d +>12 byte 0x01 \b, grayscale +>12 byte 0x02 \b, grayscale-alpha +>12 byte 0x03 \b, RGB +>12 byte 0x04 \b, RGBA +>12 byte 0x12 \b, grayscale-alpha +>12 byte 0x13 \b, BGR +>12 byte 0x14 \b, ABGR +>12 byte 0x24 \b, ARGB +>12 byte 0x34 \b, BGRA +>12 byte 0x44 \b, CMYK +>12 byte 0x54 \b, KYMC +>13 byte 0x01 \b, 8-bit signed +>13 byte 0x02 \b, 16-bit signed +>13 byte 0x04 \b, 32-bit signed +>13 byte 0x08 \b, 64-bit signed +>13 byte 0x11 \b, 8-bit unsigned +>13 byte 0x12 \b, 16-bit unsigned +>13 byte 0x14 \b, 32-bit unsigned +>13 byte 0x18 \b, 64-bit unsigned +>13 byte 0x22 \b, half-float +>13 byte 0x24 \b, single-float +>13 byte 0x28 \b, double-float +!:mime image/x.sf3 + +0 name SF3-log +>0 leqdate x \b, from %s +>8 leqdate x \b, to %s +>16 uleshort x \b, %d chunks +!:mime application/x.sf3-log + +0 name SF3-model +>(2.l+22) ulelong x \b, %d face indices +>>&(&-20.l*4) ulelong x \b, %d vertex attributes +!:mime model/x.sf3 + +0 name SF3-physics-model +>0 lefloat x \b, %f kg +>40 uleshort x \b, %d shapes +!:mime model/x.sf3-physics + +0 name SF3-table +>0 uleshort x \b, %d columns +>10 ulequad x \b, %llu rows +!:mime application/x.sf3-table + +0 name SF3-text +>8 ulelong x \b, %d markup options +>(0.q+28) ulequad x \b, %llu bytes of text +!:mime application/x.sf3-text + +0 name SF3-vector-graphic +>0 ulelong >0 \b, %d +>4 ulelong >0 \bx%d +>8 ulelong x \b, %d instructions +!:mime image/x.sf3-vector + +# Generic SF3 Header +0 string \x81SF3\x00\xE0\xD0\x0D\x0A\x0A SF3 +>10 byte 0x01 archive +>>16 use SF3-archive +>10 byte 0x02 audio file +>>16 use SF3-audio +>10 byte 0x03 image file +>>16 use SF3-image +>10 byte 0x04 log file +>>16 use SF3-log +>10 byte 0x05 3D model +>>16 use SF3-model +>10 byte 0x06 physics model +>>16 use SF3-physics-model +>10 byte 0x07 table +>>16 use SF3-table +>10 byte 0x08 text file +>>16 use SF3-text +>10 byte 0x09 vector graphic +>>16 use SF3-vector-graphic +>10 byte >9 file of unknown type (%d) +!:mime application/x.sf3 +!:ext sf3 diff --git a/magic/Magdir/sgml b/magic/Magdir/sgml index f7327b45961a..bb6d2adf975a 100644 --- a/magic/Magdir/sgml +++ b/magic/Magdir/sgml @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: sgml,v 1.53 2024/11/10 14:48:55 christos Exp $ +# $File: sgml,v 1.55 2025/04/06 20:34:30 christos Exp $ # Type: SVG Vectorial Graphics # From: Noel Torres <tecnico@ejerciciosresueltos.com> 0 string/bt \<?xml\ version= @@ -11,11 +11,17 @@ !:ext svg >>19 search/4096 \<gnc-v2 GnuCash file !:mime application/x-gnucash +>>19 search/4096 application/x-qtskin QuickTime5 skinned movie +!:mime application/x-qtskin + 0 string/bt \<svg SVG Scalable Vector Graphics image !:mime image/svg+xml !:ext svg +0 string/t \<?xml\ version= +!:strength +40 >14 regex ['"\ \t]*[0-9.]+['"\ \t]* + # Sitemap file >>19 search/4096 \<urlset XML Sitemap document text !:mime application/xml-sitemap @@ -26,8 +32,8 @@ # http://files.pef-format.org/specifications/pef-2008-1/pef-specification.html # # Simon Aittamaa <simon.aittamaa@gmail.com> ->>19 search/4096 \<pef Portable Embosser Format -!:mime application/x-pef+xml +>>19 search/4096 \<pef Portable Embosser Format +!:mime application/x-pef+xml # OpenStreetMap XML (.osm) # https://wiki.openstreetmap.org/wiki/OSM_XML @@ -37,9 +43,7 @@ # xhtml >19 search/4096/cWbt \<!doctype\ html XHTML document text >>15 string >\0 (version %.3s) -!:strength + 15 !:mime application/xhtml+xml - >19 search/4096/cWbt \<html\ xmlns= XHTML document text >>15 string >\0 (version %.3s) !:mime application/xhtml+xml @@ -57,14 +61,11 @@ # avoid misdetection as JavaScript 0 string/cWt \<!doctype\ html HTML document text !:mime text/html -!:strength + 30 0 string/ct \<html> HTML document text !:mime text/html -!:strength + 30 0 string/ct \<!-- >&0 search/4096/cWt \<!doctype\ html HTML document text !:mime text/html -!:strength + 30 >&0 search/4096/ct \<html> HTML document text !:mime text/html @@ -127,13 +128,21 @@ 0 search/1/cwt \<?xml XML document text !:mime text/xml !:strength + 30 +0 string/t \<?xml\ version\ " XML +!:mime text/xml +!:strength + 30 0 string/t \<?xml\ version=" XML !:mime text/xml !:strength + 30 >15 string/t >\0 %.3s document text >>23 search/1 \<xsl:stylesheet (XSL stylesheet) >>24 search/1 \<xsl:stylesheet (XSL stylesheet) - +0 string/t \<?xml\ version=' XML +!:mime text/xml +!:strength + 30 +>15 string/t >\0 %.3s document text +>>23 search/1 \<xsl:stylesheet (XSL stylesheet) +>>24 search/1 \<xsl:stylesheet (XSL stylesheet) 0 search/1/wt \<?XML broken XML document text !:mime text/xml !:strength - 10 diff --git a/magic/Magdir/sniffer b/magic/Magdir/sniffer index d5cf63d509e6..e477a8aa444a 100644 --- a/magic/Magdir/sniffer +++ b/magic/Magdir/sniffer @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: sniffer,v 1.36 2024/06/16 15:09:26 christos Exp $ +# $File: sniffer,v 1.39 2025/07/02 17:35:12 christos Exp $ # sniffer: file(1) magic for packet capture files # # From: guy@alum.mit.edu (Guy Harris) @@ -240,7 +240,7 @@ >20 belong&0x03FFFFFF 255 (Bluetooth Basic Rate/Enhanced Data Rate baseband packets >20 belong&0x03FFFFFF 256 (Bluetooth Low Energy air interface with pseudo-header >20 belong&0x03FFFFFF 257 (PROFIBUS data link layer ->20 belong&0x03FFFFFF 258 (Apple DLT_PKTAP +>20 belong&0x03FFFFFF 258 (Apple PKTAP >20 belong&0x03FFFFFF 259 (Ethernet with 802.3 Clause 65 EPON preamble >20 belong&0x03FFFFFF 260 (IPMI trace packets >20 belong&0x03FFFFFF 261 (Z-Wave RF profile R1 and R2 packets @@ -249,7 +249,7 @@ >20 belong&0x03FFFFFF 264 (ISO 14443 messages >20 belong&0x03FFFFFF 265 (IEC 62106 Radio Data System groups >20 belong&0x03FFFFFF 266 (USB with Darwin header ->20 belong&0x03FFFFFF 267 (OpenBSD DLT_OPENFLOW +>20 belong&0x03FFFFFF 267 (OpenBSD OpenFlow >20 belong&0x03FFFFFF 268 (IBM SDLC frames >20 belong&0x03FFFFFF 269 (TI LLN sniffer frames >20 belong&0x03FFFFFF 271 (Linux vsock @@ -312,13 +312,16 @@ # 0 ubelong 0x0a0d0d0a >8 ubelong 0x1a2b3c4d pcapng capture file +!:mime application/x-pcapng >>12 beshort x - version %d >>14 beshort x \b.%d 0 ulelong 0x0a0d0d0a >8 ulelong 0x1a2b3c4d pcapng capture file +!:mime application/x-pcapng >>12 leshort x - version %d >>14 leshort x \b.%d + # # AIX "iptrace" capture files. # diff --git a/magic/Magdir/sql b/magic/Magdir/sql index d8cdfbf165b3..1f48b14ac0d7 100644 --- a/magic/Magdir/sql +++ b/magic/Magdir/sql @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: sql,v 1.27 2023/08/19 15:33:04 christos Exp $ +# $File: sql,v 1.38 2024/12/26 19:14:32 christos Exp $ # sql: file(1) magic for SQL files # # From: "Marty Leisner" <mleisner@eng.mc.xerox.com> @@ -106,7 +106,7 @@ # at offset 68 that is preferred over "user version" for indicating the # associated application. # -0 string SQLite\ format\ 3 +0 string SQLite\040format\0403\0 # skip DROID fmt-729-signature-id-1053.sqlite by checking for valid page size >16 ubeshort >0 SQLite 3.x # deprecated @@ -220,9 +220,26 @@ # AUDY Audacity Project File >>>68 belong =0x41554459 (Audacity Project) >>>68 belong =0x6A035744 (TeXnicard card database) +>>>68 belong =0x43455745 (Cewe Fotobuch) +>>>68 belong =0x5E96730E (Corsair iCue package registry) +>>>68 belong =0xF9BEB4D9 (Bitcoin wallet) +>>>68 belong =0x56333500 (Vector35 Binary Ninja) +>>>68 belong =0x4163726E (FlyingMeat Acorn) +>>>68 belong =0x544f4952 (Riot Games patcher) +>>>68 belong =0x544d5052 (Twinmotion project) +>>>68 belong =0x43484557 (Chewing IME) # unknown application ID >>>68 default x >>>>68 belong !0 \b, application id %u +>>>>68 belong 0 +>>>>>0xC70 search/0x9000 CREATE\040TABLE\040s3api_per_key_metadata\n \b, Archive Metadata +>>>>>0x2A0 search/0x10 CREATE\040TABLE\040version_table\040(\040version\040INTEGER\040NOT\040NULL\040PRIMARY\040KEY\040) \b, Adobe SDE +>>>>>0xEA0 search/0x10 CREATE\040TABLE\040version_table\040(\040version\040INTEGER\040NOT\040NULL\040PRIMARY\040KEY\040) \b, Adobe SDE +>>>>>0xA0 search/0x100 CREATE\040TABLE\040IPMMessage\040( \b, Adobe IPM DB +>>>>>0xC00 search/0x100 CREATE\040TABLE\040IPMMessage\040( \b, Adobe IPM DB +>>>>>0x200 search/0xFFFF C\0R\0E\0A\0T\0E\0\040\0T\0A\0B\0L\0E\0\040\0A\0C\0T\0I\0O\0N\0R\0E\0C\0O\0R\0D\0S\0\040\0( \b, Microsoft Store Database + + # The "user version" as read and set by the user_version pragma like: # 1 2 4 5 7 9 10 25 36 43 53 400 416 131073 131074 131075 50331648 >>60 belong !0 \b, user version %d diff --git a/magic/Magdir/syd b/magic/Magdir/syd new file mode 100644 index 000000000000..37114ba7e0ed --- /dev/null +++ b/magic/Magdir/syd @@ -0,0 +1,37 @@ + +#------------------------------------------------------------------------------ +# $File: syd,v 1.1 2025/09/11 01:49:40 christos Exp $ +# syd: file(1) magic for syd(1) encrypted files +# +# From: Ali Polatel <alip@chesswob.org> +# Documentation: https://man.exherbo.org/syd.7.html#Crypt_Sandboxing +# No defined extension yet; files are recognized by magic header only. +# +# Layout: +# 0..3 : "\x7fSYD" +# 4 : version byte (current API: 3) +# 5..36 : HMAC (32 bytes, SHA256) +# 37..52 : IV (16 bytes) +# 53.. : ciphertext (AES-256-CTR) +#------------------------------------------------------------------------------ + +# Header and version +0 string \x7fSYD SYD encrypted file +>4 ubyte x \b, version %u +# Version 3: algorithm + HMAC/IV as hex blobs + ciphertext size +>>4 ubyte =3 \b, AES-256-CTR; HMAC-SHA256: +>>>5 belong x \b%08x +>>>9 belong x \b%08x +>>>13 belong x \b%08x +>>>17 belong x \b%08x +>>>21 belong x \b%08x +>>>25 belong x \b%08x +>>>29 belong x \b%08x +>>>33 belong x \b%08x +>>>37 belong x \b, IV:%08x +>>>41 belong x \b%08x +>>>45 belong x \b%08x +>>>49 belong x \b%08x +>>>-0 offset-53 x \b, ciphertext %llu bytes + +# End of syd diff --git a/magic/Magdir/tapebackup b/magic/Magdir/tapebackup new file mode 100644 index 000000000000..ca46f3fd1919 --- /dev/null +++ b/magic/Magdir/tapebackup @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------ +# $File: tapebackup,v 1.1 2026/01/10 15:45:02 christos Exp $ +# Dmitry Brant, 2026 +# tapebackup: file(1) magic for different tape backup formats + +# QIC-80 tapes +# https://www.qic.org/html/standards/8x.x/qic80n.pdf +0 string VTBL QIC-80 tape volume header +>8 string/44 x \b, Volume label: %s + +0 lelong 0xaa55aa55 +>4 lelong 0x00000002 Colorado tape backup +>>146 string/88 x \b, Volume label: %s + +56 string \<\<NoVaStOr\>\> NovaStor tape backup + +0 lelong 0xdddddddd +>512 lelong 0xabbaabba ArcServe tape backup + +# IBM AS/400 +# https://www.ibm.com/docs/en/i/7.4.0?topic=ssw_ibm_i_74/cl/savlib.html +0 belong 0xffffffff +>4 belong 0xd8e2d9c4 AS/400 SAVLIB backup + +0 lelong 0x3a3a3a3a +>12 lelong 0x3a3a3a20 TXPLUS tape backup + +0 lelong 0x55aa0004 Mountain FileSafe tape backup +>93 string x \b, Volume label: %s diff --git a/magic/Magdir/tex b/magic/Magdir/tex index e66f8ffdcecb..a8ff1c7a7e32 100644 --- a/magic/Magdir/tex +++ b/magic/Magdir/tex @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: tex,v 1.22 2022/12/21 16:50:04 christos Exp $ +# $File: tex,v 1.24 2026/02/01 16:17:53 christos Exp $ # tex: file(1) magic for TeX files # # XXX - needs byte-endian stuff (big-endian and little-endian DVI?) @@ -20,6 +20,17 @@ 0 string \367\312 >(2.b+11) string \363 TeX virtual font data 0 search/1 This\ is\ TeX, TeX transcript text +0 search/1 This\ is\ pdfTeX, pdfTeX transcript text +0 search/1 This\ is\ XeTeX, XeTeX transcript text +0 search/1 This\ is\ LuaTeX, LuaTeX transcript text +0 search/1 This\ is\ LuaHBTeX, LuaTeX transcript text +0 search/1 This\ is\ LuajitTeX, LuaTeX transcript text +0 search/1 This\ is\ LuajitHBTeX, LuaTeX transcript text +0 search/1 This\ is\ pTeX, pTeX transcript text +0 search/1 This\ is\ e-pTeX, e-pTeX transcript text +0 search/1 This\ is\ upTeX, upTeX transcript text +0 search/1 This\ is\ e-upTeX, e-upTeX transcript text +0 search/1 This\ is\ HiTeX, HiTeX transcript text 0 search/1 This\ is\ METAFONT, METAFONT transcript text # There is no way to detect TeX Font Metric (*.tfm) files without @@ -38,6 +49,10 @@ 0 search/1 This\ is\ Info\ file GNU Info text !:mime text/x-info +0 string %!TEX\040root TeX Document text +!:mime text/x-tex +!:strength + 15 + # TeX documents, from Daniel Quinlan (quinlan@yggdrasil.com) 0 search/4096 \\input TeX document text !:mime text/x-tex diff --git a/magic/Magdir/ti-8x b/magic/Magdir/ti-8x index b05c5c9c3f25..8bcb0302384c 100644 --- a/magic/Magdir/ti-8x +++ b/magic/Magdir/ti-8x @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: ti-8x,v 1.8 2020/02/12 22:13:01 christos Exp $ +# $File: ti-8x,v 1.9 2025/05/28 16:49:05 christos Exp $ # ti-8x: file(1) magic for the TI-8x and TI-9x Graphing Calculators. # # From: Ryan McGuire (rmcguire@freenet.columbus.oh.us). @@ -237,3 +237,8 @@ >>7 byte >0 \b %c >>9 byte x \b.%c >>10 byte x \b%c + +# Magic Numbers for the TI-99 +# https://www.ninerpedia.org/wiki/File_systems#Floppy_Disk_File_System +# +13 string DSK TI-99/4 image diff --git a/magic/Magdir/varied.script b/magic/Magdir/varied.script index e6090b49f43f..a6e2d95e9d0e 100644 --- a/magic/Magdir/varied.script +++ b/magic/Magdir/varied.script @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: varied.script,v 1.16 2024/02/04 19:26:02 christos Exp $ +# $File: varied.script,v 1.17 2025/03/10 20:41:09 christos Exp $ # varied.script: file(1) magic for various interpreter scripts 0 string #![ Rust Source file @@ -15,10 +15,19 @@ # using env -0 string/wt #!\ /usr/bin/env a ->15 string/T >\0 %s script text executable -!:strength / 6 +0 regex/t #![[:space:]]*/usr/bin/env[[:space:]]* a +>&0 string/T >\0 %s script text executable +!:strength / 2 -0 string/wb #!\ /usr/bin/env a ->15 string/T >\0 %s script executable (binary data) -!:strength / 6 +0 regex/b #![[:space:]]*/usr/bin/env[[:space:]]* a +>&0 string/T >\0 %s script executable (binary data) +!:strength / 2 + +# using env +0 regex/t #![[:space:]]*/usr/bin/env[[:space:]]*-[Si0] a +>&0 string/T >\0 %s script text executable +!:strength / 2 + +0 regex/b #![[:space:]]*/usr/bin/env[[:space:]]*-[Si0] a +>&0 string/T >\0 %s script executable (binary data) +!:strength / 2 diff --git a/magic/Magdir/virtual b/magic/Magdir/virtual index 295dbd025d52..e6a30ef1afb4 100644 --- a/magic/Magdir/virtual +++ b/magic/Magdir/virtual @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: virtual,v 1.21 2024/09/04 19:09:00 christos Exp $ +# $File: virtual,v 1.22 2026/02/05 18:51:36 christos Exp $ # From: James Nobis <quel@quelrod.net> # Microsoft hard disk images for: # Virtual Server @@ -337,3 +337,7 @@ >>>>3 byte 9 (QEMU 5.0) >>>>3 byte 10 (QEMU 5.1-7.0) >>>>3 byte 12 (QEMU 7.1+) + +# Parallels disk image +0 string WithoutFreeSpace Parallels disk image +0 string WithouFreSpacExt Parallels disk image (extended) diff --git a/magic/Magdir/webassembly b/magic/Magdir/webassembly index 469b45e22b8e..c3dff64c4572 100644 --- a/magic/Magdir/webassembly +++ b/magic/Magdir/webassembly @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: webassembly,v 1.4 2022/08/16 11:16:39 christos Exp $ +# $File: webassembly,v 1.5 2025/06/08 15:37:23 christos Exp $ # webassembly: file(1) magic for WebAssembly modules # # WebAssembly is a virtual architecture developed by a W3C Community @@ -10,8 +10,9 @@ # document describing the binary format. # From: Pip Cet <pipcet@gmail.com> and Joel Martin -0 string \0asm WebAssembly (wasm) binary module ->4 lelong =1 version %#x (MVP) +0 string \0asm WebAssembly (wasm) binary +>4 lelong >0 version %#x +>4 lelong =1 (MVP module) +>4 lelong =0x1000d (component) !:mime application/wasm !:ext wasm ->4 lelong >1 version %#x diff --git a/magic/Magdir/windows b/magic/Magdir/windows index 2614e57f96be..ef2b64840113 100644 --- a/magic/Magdir/windows +++ b/magic/Magdir/windows @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: windows,v 1.67 2024/11/09 22:43:01 christos Exp $ +# $File: windows,v 1.69 2025/09/06 16:58:00 christos Exp $ # windows: file(1) magic for Microsoft Windows # # This file is mainly reserved for files where programs @@ -663,7 +663,7 @@ # skip space at beginning >0 string \040 # name without extension and greater character or name with hlp extension ->>1 regex/c \^([^\xd>]*|.*\\.hlp) MS Windows help file Content, based "%s" +>>1 regex \^([^\xd>]*|.*\\.hlp) MS Windows help file Content, based "%s" !:mime text/plain !:apple ????TEXT !:ext cnt @@ -1106,7 +1106,7 @@ # space after right bracket # or AutoRun.Amd64 for 64 bit systems # or only NL separator ->>&0 regex/c \^autorun +>>&0 regex \^autorun # but sometimes total commander directory tree file "treeinfo.wc" with lines like # [AUTORUN] # [boot] @@ -1120,56 +1120,56 @@ !:ext inf # https://msdn.microsoft.com/en-us/library/windows/hardware/ff549520(v=vs.85).aspx # version strings ASCII coded case-independent for Windows setup information script file ->>&0 regex/c \^(version|strings)] Windows setup INFormation +>>&0 regex \^(version|strings)] Windows setup INFormation !:mime application/x-setupscript #!:mime application/x-wine-extension-inf !:ext inf # NETCRC.INF OEMCPL.INF ->>&0 regex/c \^(WinsockCRCList|OEMCPL)] Windows setup INFormation +>>&0 regex \^(WinsockCRCList|OEMCPL)] Windows setup INFormation !:mime application/x-setupscript !:ext inf # http://www.winfaq.de/faq_html/Content/tip2500/onlinefaq.php?h=tip2653.htm # https://msdn.microsoft.com/en-us/library/windows/desktop/cc144102.aspx # .ShellClassInfo DeleteOnCopy LocalizedFileNames ASCII coded case-independent ->>&0 regex/1024c \^(\\.ShellClassInfo|DeleteOnCopy|LocalizedFileNames)] Windows desktop.ini +>>&0 regex/1024 \^(\\.ShellClassInfo|DeleteOnCopy|LocalizedFileNames)] Windows desktop.ini !:mime application/x-wine-extension-ini #!:mime text/plain # https://support.microsoft.com/kb/84709/ ->>&0 regex/c \^don't\ load] Windows CONTROL.INI +>>&0 regex \^don't\ load] Windows CONTROL.INI !:mime application/x-wine-extension-ini !:ext ini ->>&0 regex/c \^(ndishlp\\$|protman\\$|NETBEUI\\$)] Windows PROTOCOL.INI +>>&0 regex \^(ndishlp\\$|protman\\$|NETBEUI\\$)] Windows PROTOCOL.INI !:mime application/x-wine-extension-ini !:ext ini # https://technet.microsoft.com/en-us/library/cc722567.aspx # http://www.winfaq.de/faq_html/Content/tip0000/onlinefaq.php?h=tip0137.htm ->>&0 regex/c \^(windows|Compatibility|embedding)] Windows WIN.INI +>>&0 regex \^(windows|Compatibility|embedding)] Windows WIN.INI !:mime application/x-wine-extension-ini !:ext ini # https://en.wikipedia.org/wiki/SYSTEM.INI ->>&0 regex/c \^(boot|386enh|drivers)] Windows SYSTEM.INI +>>&0 regex \^(boot|386enh|drivers)] Windows SYSTEM.INI !:mime application/x-wine-extension-ini !:ext ini # http://www.mdgx.com/newtip6.htm ->>&0 regex/c \^SafeList] Windows IOS.INI +>>&0 regex \^SafeList] Windows IOS.INI !:mime application/x-wine-extension-ini !:ext ini # https://en.wikipedia.org/wiki/NTLDR Windows Boot Loader information ->>&0 regex/c \^boot\x20loader] Windows boot.ini +>>&0 regex \^boot\x20loader] Windows boot.ini !:mime application/x-wine-extension-ini !:ext ini # https://en.wikipedia.org/wiki/CONFIG.SYS ->>&0 regex/c \^menu] MS-DOS CONFIG.SYS +>>&0 regex \^menu] MS-DOS CONFIG.SYS # @CONFIG.UI configuration file of previous DOS version saved by Caldera OPENDOS INSTALL.EXE # CONFIG.PSS saved version of file CONFIG.SYS created by %WINDIR%\SYSTEM\MSCONFIG.EXE # CONFIG.TSH renamed file CONFIG.SYS.BAT by %WINDIR%\SYSTEM\MSCONFIG.EXE # dos and w40 used in dual booting scene !:ext sys/dos/w40 # https://support.microsoft.com/kb/118579/ ->>&0 regex/c \^Paths]\r\n MS-DOS MSDOS.SYS +>>&0 regex \^Paths]\r\n MS-DOS MSDOS.SYS !:ext sys/dos # http://chmspec.nongnu.org/latest/INI.html#HHP ->>&0 regex/c \^options]\r\n Microsoft HTML Help Project +>>&0 regex \^options]\r\n Microsoft HTML Help Project !:mime text/plain !:ext hhp # From: Joerg Jenderek @@ -1178,7 +1178,7 @@ # http://mark0.net/download/triddefs_xml.7z/defs/c/cpx.trid.xml # Note: stored in directory %WINDIR%\SysWOW64 or %WINDIR%\system # second word often Latin but sometimes Cyrillic like in 12510866.CPX ->>&0 regex/c \^Windows\ (Latin|Cyrillic) Windows codepage translator +>>&0 regex \^Windows\ (Latin|Cyrillic) Windows codepage translator #!:mime text/plain !:mime text/x-ms-cpx # like: 12510866.CPX @@ -1187,7 +1187,7 @@ # URL: https://en.wikipedia.org/wiki/File_Explorer # Reference: http://mark0.net/download/triddefs_xml.7z/defs/s/scf-exp.trid.xml,scf-exp-old.trid.xml # Note: called "Windows Explorer Command Shell File" by TrID and "File Explorer Command" by Windows via SHCmdFile ->>&0 regex/c \^Shell]\r\n Windows Explorer Shell Command File +>>&0 regex \^Shell]\r\n Windows Explorer Shell Command File #!:mime text/plain !:mime text/x-ms-scf # like: channels.scf desktop.scf explorer.scf "Desktop anzeigen.scf" @@ -1199,7 +1199,7 @@ # URL: http://en.wikipedia.org/wiki/VIA_Technologies # Reference: http://mark0.net/download/triddefs_xml.7z/defs/s/scf-via.trid.xml # Note: called "VIA setup configuration file" by TrID ->>&0 regex/c \^SCF]\r\n VIA setup configuration +>>&0 regex \^SCF]\r\n VIA setup configuration #!:mime text/plain !:mime text/x-via-scf # like: SETUP.SCF @@ -1208,7 +1208,7 @@ # URL: https://en.wikipedia.org/wiki/InstallShield # Reference: http://mark0.net/download/triddefs_xml.7z/defs/l/lid-is.trid.xml # Note: contain also 3 keywords like: count Default key0 ->>&0 regex/c \^Languages] InstallShield Language Identifier +>>&0 regex \^Languages] InstallShield Language Identifier #!:mime text/plain !:mime text/x-installshield-lid # like: SETUP.LID @@ -1217,7 +1217,7 @@ # URL: https://www.file-extensions.org/tag-file-extension # Reference: http://mark0.net/download/triddefs_xml.7z/defs/t/taginfo.trid.xml # Note: contain also keywords like: Application Category Company Misc Version ->>&0 regex/c \^TagInfo] TagInfo +>>&0 regex \^TagInfo] TagInfo #!:mime text/plain #!:mime text/prs.lines.tag !:mime text/x-ms-tag @@ -1260,7 +1260,7 @@ >>>>>&0 ubyte x # characters, digits, underscore and white space followed by right bracket # terminated by CR implies section line to skip BOOTLOG.TXT DETLOG.TXT ->>>>>>&-1 regex/T \^([A-Za-z0-9_\(\)\ ]+)\]\r Generic INItialization configuration [%-.40s +>>>>>>&-1 regex/T \^([A-Za-z0-9_\(\)\ ]+)\][\r\n] Generic INItialization configuration [%-.40s # NETDEF.INF multiarc.ini #!:mime application/x-setupscript !:mime application/x-wine-extension-ini diff --git a/magic/Magdir/xilinx b/magic/Magdir/xilinx index 3476e5181236..9475ac2308e1 100644 --- a/magic/Magdir/xilinx +++ b/magic/Magdir/xilinx @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: xilinx,v 1.12 2024/09/04 19:06:12 christos Exp $ +# $File: xilinx,v 1.13 2025/03/30 20:29:30 christos Exp $ # This is Aaron's attempt at a MAGIC file for Xilinx .bit files. # Xilinx-Magic@RevRagnarok.com # Got the info from FPGA-FAQ 0026 @@ -14,26 +14,26 @@ >2 belong =0x0ff00ff0 >>&0 belong =0x0ff00ff0 >>>&0 byte =0x00 ->>>>&1 beshort =0x0001 ->>>>>&3 string a Xilinx BIT data +>>>&1 beshort =0x0001 +>>>&3 string a Xilinx BIT data # Next is a Pascal-style string with the NCD name. We want to capture that. ->>>>>>&0 pstring/H x - from %s +>>>>&0 pstring/H x - from %s # And then 'b' ->>>>>>>&1 string b +>>>>>&1 string b # Then the model / part number: ->>>>>>>>&0 pstring/H x - for %s +>>>>>>&0 pstring/H x - for %s # Then 'c' ->>>>>>>>>&1 string c +>>>>>>>&1 string c # Then the build-date ->>>>>>>>>>&0 pstring/H x - built %s +>>>>>>>>&0 pstring/H x - built %s # Then 'd' ->>>>>>>>>>>&1 string d +>>>>>>>>>&1 string d # Then the build-time ->>>>>>>>>>>>&0 pstring/H x \b(%s) +>>>>>>>>>>&0 pstring/H x \b(%s) # Then 'e' ->>>>>>>>>>>>>&1 string e +>>>>>>>>>>>&1 string e # And length of data ->>>>>>>>>>>>>>&0 belong x - data length %#x +>>>>>>>>>>>>&0 belong x - data length %#x # Raw bitstream files 0 long 0xffffffff diff --git a/magic/Magdir/xwindows b/magic/Magdir/xwindows index d8c08c8702e7..7acbe5f7796a 100644 --- a/magic/Magdir/xwindows +++ b/magic/Magdir/xwindows @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# $File: xwindows,v 1.13 2022/03/24 15:48:58 christos Exp $ +# $File: xwindows,v 1.14 2025/04/06 19:18:03 christos Exp $ # xwindows: file(1) magic for various X/Window system file formats. # Compiled X Keymap @@ -29,10 +29,11 @@ # X11 mouse cursor format defined in libXcursor, see # https://www.x.org/archive/X11R6.8.1/doc/Xcursor.3.html # https://cgit.freedesktop.org/xorg/lib/libXcursor/tree/include/X11/Xcursor/Xcursor.h -0 string Xcur Xcursor data +0 string Xcur +>4 lelong <64 Xcursor data !:mime image/x-xcursor ->10 leshort x version %d ->>8 leshort x \b.%d +>>10 leshort x version %d +>>>8 leshort x \b.%d # X bitmap https://en.wikipedia.org/wiki/X_BitMap 0 search/2048 #define\040 diff --git a/magic/Magdir/zip b/magic/Magdir/zip index abf5284776d4..acfb1b7a8b02 100644 --- a/magic/Magdir/zip +++ b/magic/Magdir/zip @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# $File: zip,v 1.8 2021/10/24 15:53:56 christos Exp $ +# $File: zip,v 1.10 2025/10/22 19:31:31 christos Exp $ # zip: file(1) magic for zip files; this is not use # Note the version of magic in archive is currently stronger, this is # just an example until negative offsets are supported better @@ -17,7 +17,6 @@ >>6 leshort x \b, extract using at least >>6 use zipversion # This is DOS date like: ledate 21:00:48 19 Dec 2001 != DOS 00:00 1 Jan 2010 ~ 0000213C ->>12 ulelong x \b, last modified >>14 lemsdosdate x \b, last modified %s >>12 lemsdostime x %s # uncompressed size of 1st entry; FFffFFff means real value stored in ZIP64 record @@ -124,3 +123,9 @@ #>>20 uleshort >0 \b, comment length %u # archive comment >>20 pstring/l >0 \b, %s + +# The end directory record does not work for piped input +# so try one that looks from the beginning of the file. +0 string PK\003\004 +>0 search/1024 PK\001\002 +>>&-4 use zipcd diff --git a/magic/Makefile.am b/magic/Makefile.am index e0f90343fc89..21e57bea4ede 100644 --- a/magic/Makefile.am +++ b/magic/Makefile.am @@ -1,5 +1,5 @@ # -# $File: Makefile.am,v 1.192 2024/10/02 01:45:32 christos Exp $ +# $File: Makefile.am,v 1.201 2026/02/01 16:25:09 christos Exp $ # MAGIC_FRAGMENT_BASE = Magdir MAGIC_DIR = $(top_srcdir)/magic @@ -41,6 +41,7 @@ $(MAGIC_FRAGMENT_DIR)/basis \ $(MAGIC_FRAGMENT_DIR)/beetle \ $(MAGIC_FRAGMENT_DIR)/ber \ $(MAGIC_FRAGMENT_DIR)/bflt \ +$(MAGIC_FRAGMENT_DIR)/bgcode \ $(MAGIC_FRAGMENT_DIR)/bhl \ $(MAGIC_FRAGMENT_DIR)/bioinformatics \ $(MAGIC_FRAGMENT_DIR)/biosig \ @@ -77,6 +78,7 @@ $(MAGIC_FRAGMENT_DIR)/console \ $(MAGIC_FRAGMENT_DIR)/convex \ $(MAGIC_FRAGMENT_DIR)/coverage \ $(MAGIC_FRAGMENT_DIR)/cracklib \ +$(MAGIC_FRAGMENT_DIR)/creativeassembly \ $(MAGIC_FRAGMENT_DIR)/crypto \ $(MAGIC_FRAGMENT_DIR)/ctags \ $(MAGIC_FRAGMENT_DIR)/ctf \ @@ -124,6 +126,7 @@ $(MAGIC_FRAGMENT_DIR)/gconv \ $(MAGIC_FRAGMENT_DIR)/gentoo \ $(MAGIC_FRAGMENT_DIR)/geo \ $(MAGIC_FRAGMENT_DIR)/geos \ +$(MAGIC_FRAGMENT_DIR)/gguf \ $(MAGIC_FRAGMENT_DIR)/gimp \ $(MAGIC_FRAGMENT_DIR)/git \ $(MAGIC_FRAGMENT_DIR)/glibc \ @@ -262,6 +265,7 @@ $(MAGIC_FRAGMENT_DIR)/pwsafe \ $(MAGIC_FRAGMENT_DIR)/pyramid \ $(MAGIC_FRAGMENT_DIR)/python \ $(MAGIC_FRAGMENT_DIR)/qt \ +$(MAGIC_FRAGMENT_DIR)/r \ $(MAGIC_FRAGMENT_DIR)/revision \ $(MAGIC_FRAGMENT_DIR)/ringdove \ $(MAGIC_FRAGMENT_DIR)/riff \ @@ -280,6 +284,7 @@ $(MAGIC_FRAGMENT_DIR)/selinux \ $(MAGIC_FRAGMENT_DIR)/sendmail \ $(MAGIC_FRAGMENT_DIR)/sequent \ $(MAGIC_FRAGMENT_DIR)/sereal \ +$(MAGIC_FRAGMENT_DIR)/sf3 \ $(MAGIC_FRAGMENT_DIR)/sgi \ $(MAGIC_FRAGMENT_DIR)/sgml \ $(MAGIC_FRAGMENT_DIR)/sharc \ @@ -300,9 +305,11 @@ $(MAGIC_FRAGMENT_DIR)/statistics \ $(MAGIC_FRAGMENT_DIR)/subtitle \ $(MAGIC_FRAGMENT_DIR)/sun \ $(MAGIC_FRAGMENT_DIR)/svf \ +$(MAGIC_FRAGMENT_DIR)/syd \ $(MAGIC_FRAGMENT_DIR)/sylk \ $(MAGIC_FRAGMENT_DIR)/symbos \ $(MAGIC_FRAGMENT_DIR)/sysex \ +$(MAGIC_FRAGMENT_DIR)/tapebackup \ $(MAGIC_FRAGMENT_DIR)/tcl \ $(MAGIC_FRAGMENT_DIR)/teapot \ $(MAGIC_FRAGMENT_DIR)/terminfo \ diff --git a/magic/Makefile.in b/magic/Makefile.in index 5774badc4bbf..f91aceea1c1d 100644 --- a/magic/Makefile.in +++ b/magic/Makefile.in @@ -279,7 +279,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # -# $File: Makefile.am,v 1.192 2024/10/02 01:45:32 christos Exp $ +# $File: Makefile.am,v 1.201 2026/02/01 16:25:09 christos Exp $ # MAGIC_FRAGMENT_BASE = Magdir MAGIC_DIR = $(top_srcdir)/magic @@ -319,6 +319,7 @@ $(MAGIC_FRAGMENT_DIR)/basis \ $(MAGIC_FRAGMENT_DIR)/beetle \ $(MAGIC_FRAGMENT_DIR)/ber \ $(MAGIC_FRAGMENT_DIR)/bflt \ +$(MAGIC_FRAGMENT_DIR)/bgcode \ $(MAGIC_FRAGMENT_DIR)/bhl \ $(MAGIC_FRAGMENT_DIR)/bioinformatics \ $(MAGIC_FRAGMENT_DIR)/biosig \ @@ -355,6 +356,7 @@ $(MAGIC_FRAGMENT_DIR)/console \ $(MAGIC_FRAGMENT_DIR)/convex \ $(MAGIC_FRAGMENT_DIR)/coverage \ $(MAGIC_FRAGMENT_DIR)/cracklib \ +$(MAGIC_FRAGMENT_DIR)/creativeassembly \ $(MAGIC_FRAGMENT_DIR)/crypto \ $(MAGIC_FRAGMENT_DIR)/ctags \ $(MAGIC_FRAGMENT_DIR)/ctf \ @@ -402,6 +404,7 @@ $(MAGIC_FRAGMENT_DIR)/gconv \ $(MAGIC_FRAGMENT_DIR)/gentoo \ $(MAGIC_FRAGMENT_DIR)/geo \ $(MAGIC_FRAGMENT_DIR)/geos \ +$(MAGIC_FRAGMENT_DIR)/gguf \ $(MAGIC_FRAGMENT_DIR)/gimp \ $(MAGIC_FRAGMENT_DIR)/git \ $(MAGIC_FRAGMENT_DIR)/glibc \ @@ -540,6 +543,7 @@ $(MAGIC_FRAGMENT_DIR)/pwsafe \ $(MAGIC_FRAGMENT_DIR)/pyramid \ $(MAGIC_FRAGMENT_DIR)/python \ $(MAGIC_FRAGMENT_DIR)/qt \ +$(MAGIC_FRAGMENT_DIR)/r \ $(MAGIC_FRAGMENT_DIR)/revision \ $(MAGIC_FRAGMENT_DIR)/ringdove \ $(MAGIC_FRAGMENT_DIR)/riff \ @@ -558,6 +562,7 @@ $(MAGIC_FRAGMENT_DIR)/selinux \ $(MAGIC_FRAGMENT_DIR)/sendmail \ $(MAGIC_FRAGMENT_DIR)/sequent \ $(MAGIC_FRAGMENT_DIR)/sereal \ +$(MAGIC_FRAGMENT_DIR)/sf3 \ $(MAGIC_FRAGMENT_DIR)/sgi \ $(MAGIC_FRAGMENT_DIR)/sgml \ $(MAGIC_FRAGMENT_DIR)/sharc \ @@ -578,9 +583,11 @@ $(MAGIC_FRAGMENT_DIR)/statistics \ $(MAGIC_FRAGMENT_DIR)/subtitle \ $(MAGIC_FRAGMENT_DIR)/sun \ $(MAGIC_FRAGMENT_DIR)/svf \ +$(MAGIC_FRAGMENT_DIR)/syd \ $(MAGIC_FRAGMENT_DIR)/sylk \ $(MAGIC_FRAGMENT_DIR)/symbos \ $(MAGIC_FRAGMENT_DIR)/sysex \ +$(MAGIC_FRAGMENT_DIR)/tapebackup \ $(MAGIC_FRAGMENT_DIR)/tcl \ $(MAGIC_FRAGMENT_DIR)/teapot \ $(MAGIC_FRAGMENT_DIR)/terminfo \ diff --git a/python/magic.py b/python/magic.py index 4300ee0719a9..14938281c659 100644 --- a/python/magic.py +++ b/python/magic.py @@ -127,12 +127,14 @@ _setparam.argtypes = [magic_t, c_int, c_void_p] class Magic(object): def __init__(self, ms): self._magic_t = ms + self._close = _close def close(self): """ Closes the magic database and deallocates any resources used. """ - _close(self._magic_t) + if _close: + _close(self._magic_t) @staticmethod def __tostr(s): diff --git a/src/apprentice.c b/src/apprentice.c index cf040cddd9e0..7b6f7f0c399b 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: apprentice.c,v 1.356 2024/11/27 15:37:00 christos Exp $") +FILE_RCSID("@(#)$File: apprentice.c,v 1.369 2025/10/08 16:40:52 christos Exp $") #endif /* lint */ #include "magic.h" @@ -58,7 +58,7 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.356 2024/11/27 15:37:00 christos Exp $") #endif -#define EATAB {while (isascii(CAST(unsigned char, *l)) && \ +#define EATAB {while (*l && isascii(CAST(unsigned char, *l)) && \ isspace(CAST(unsigned char, *l))) ++l;} #define LOWCASE(l) (isupper(CAST(unsigned char, l)) ? \ tolower(CAST(unsigned char, l)) : (l)) @@ -341,7 +341,11 @@ get_standard_integer_type(const char *l, const char **t) { int type; - if (isalpha(CAST(unsigned char, l[1]))) { + if (l[0] == '\0') + return FILE_INVALID; + if (l[1] == '\0') + return FILE_INVALID; + else if (isalpha(CAST(unsigned char, l[1]))) { switch (l[1]) { case 'C': /* "dC" and "uC" */ @@ -749,6 +753,7 @@ file_apprentice(struct magic_set *ms, const char *fn, int action) init_file_tables(); free(ms->fnamebuf); + ms->file = NULL; if ((ms->fnamebuf = strdup(fn)) == NULL) { file_oomem(ms, strlen(fn)); return -1; @@ -1148,8 +1153,10 @@ apprentice_sort(const void *a, const void *b) return 0; file_magwarn1("Duplicate magic entry `%s'", ma->mp->desc); +#ifndef COMPILE_ONLY file_mdump(ma->mp); file_mdump(mb->mp); +#endif return 0; } return x > 0 ? -1 : 1; @@ -1258,12 +1265,6 @@ set_test_type(struct magic *mstart, struct magic *m) case FILE_PSTRING: case FILE_BESTRING16: case FILE_LESTRING16: - /* Allow text overrides */ - if (mstart->str_flags & STRING_TEXTTEST) - mstart->flag |= TEXTTEST; - else - mstart->flag |= BINTEST; - break; case FILE_REGEX: case FILE_SEARCH: /* Check for override */ @@ -1275,6 +1276,16 @@ set_test_type(struct magic *mstart, struct magic *m) if (mstart->flag & (TEXTTEST|BINTEST)) break; + /* + * XXX: Compatibility: For string types assume binary match + * in reality it is better in the long term to change all + * the magic to be string/b where appropriate + */ + if (m->type != FILE_REGEX && m->type != FILE_SEARCH) { + mstart->flag |= BINTEST; + break; + } + /* binary test if pattern is not text */ if (file_looks_utf8(m->value.us, CAST(size_t, m->vallen), NULL, NULL) <= 0) @@ -1778,6 +1789,16 @@ string_modifier_check(struct magic_set *ms, struct magic *m) CHAR_COMPACT_OPTIONAL_WHITESPACE); return -1; } + if ((m->str_flags & STRING_IGNORE_LOWERCASE) != 0) { + file_magwarn(ms, "'/%c' not allowed on regex\n", + CHAR_IGNORE_LOWERCASE); + return -1; + } + if ((m->str_flags & STRING_IGNORE_UPPERCASE) != 0) { + file_magwarn(ms, "'/%c' not allowed on regex\n", + CHAR_IGNORE_UPPERCASE); + return -1; + } break; default: file_magwarn(ms, "coding error: m->type=%d\n", @@ -2391,11 +2412,19 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *file, } break; } + + /* * Grab the value part, except for an 'x' reln. */ - if (m->reln != 'x' && getvalue(ms, m, &l, action)) + if (m->reln != 'x') { + if (*l == '\0') { + file_magwarn(ms, "incomplete magic `%s'", line); + return -1; + } + if (getvalue(ms, m, &l, action)) return -1; + } /* * TODO finish this macro and start using it! @@ -2415,7 +2444,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *file, ++l; m->flag |= NOSPACE; } - for (i = 0; (m->desc[i++] = *l++) != '\0' && i < sizeof(m->desc); ) + for (i = 0; i < sizeof(m->desc) && (m->desc[i++] = *l++) != '\0';) continue; if (m->desc[0] == '\0') { // Tuck in the filename for debugging. @@ -2647,7 +2676,7 @@ check_format_type(const char *ptr, int type, const char **estr) } } else h = 0; - while (*ptr && strchr("-.#", *ptr) != NULL) + while (*ptr && strchr("+-.#", *ptr) != NULL) ptr++; #define CHECKLEN() do { \ for (len = cnt = 0; isdigit(CAST(unsigned char, *ptr)); ptr++, cnt++) \ @@ -2856,7 +2885,7 @@ check_format(struct magic_set *ms, struct magic *m) * pointer, according to the magic type. Update the string pointer to point * just after the number read. Return 0 for success, non-zero for failure. */ -file_private int +file_no_overflow file_private int getvalue(struct magic_set *ms, struct magic *m, const char **p, int action) { char *ep; @@ -2919,8 +2948,10 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action) *p = ep; return 0; case FILE_GUID: - if (file_parse_guid(*p, m->value.guid) == -1) + if (file_parse_guid(*p, m->value.guid) == -1) { + file_magwarn(ms, "Error parsing guid `%s'", *p); return -1; + } *p += FILE_GUID_SIZE - 1; return 0; default: @@ -3377,7 +3408,7 @@ check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname) int i, needsbyteswap; entries = CAST(uint32_t, map->len / sizeof(struct magic)); - if (entries < MAGIC_SETS + 1) { + if (entries < MAGIC_SETS) { file_error(ms, 0, "Too few magic entries %u in `%s'", entries, dbname); return -1; @@ -3644,15 +3675,14 @@ file_varint2uintmax_t(const unsigned char *us, int t, size_t *l) file_private void bs1(struct magic *m) { - m->cont_level = swap2(m->cont_level); + 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)); if (IS_STRING(m->type)) { m->str_range = swap4(m->str_range); m->str_flags = swap4(m->str_flags); - } - else { + } else { m->value.q = swap8(m->value.q); m->num_mask = swap8(m->num_mask); } diff --git a/src/apptype.c b/src/apptype.c index 9473627567f7..6366f0f19ca9 100644 --- a/src/apptype.c +++ b/src/apptype.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: apptype.c,v 1.17 2022/12/26 17:31:14 christos Exp $") +FILE_RCSID("@(#)$File: apptype.c,v 1.18 2024/12/08 18:59:04 christos Exp $") #endif /* lint */ #include <stdlib.h> @@ -42,8 +42,7 @@ FILE_RCSID("@(#)$File: apptype.c,v 1.17 2022/12/26 17:31:14 christos Exp $") typedef ULONG APPTYPE; file_protected int -file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf, - size_t nb) +file_os2_apptype(struct magic_set *ms, const char *fn, const struct buffer *b) { APPTYPE rc, type; char path[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR], @@ -69,7 +68,7 @@ file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf, file_error(ms, errno, "cannot open tmp file `%s'", path); return -1; } - if (fwrite(buf, 1, nb, fp) != nb) { + if (fwrite(b->fbuf, 1, b->flen, fp) != b->flen) { file_error(ms, errno, "cannot write tmp file `%s'", path); (void)fclose(fp); @@ -129,7 +128,7 @@ file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf, * ".com". */ if (stricmp(ext, ".com") == 0) - if (strncmp((const char *)buf, "MZ", 2)) + if (strncmp((const char *)b->fbuf, "MZ", 2)) return (0); if (file_printf(ms, "DOS executable") == -1) return -1; diff --git a/src/buffer.c b/src/buffer.c index 598db1471dd5..058fbadd2a55 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: buffer.c,v 1.13 2023/07/02 12:48:39 christos Exp $") +FILE_RCSID("@(#)$File: buffer.c,v 1.14 2025/05/28 19:22:22 christos Exp $") #endif /* lint */ #include "magic.h" @@ -68,6 +68,10 @@ buffer_fill(const struct buffer *bb) if (b->elen != 0) return b->elen == FILE_BADSIZE ? -1 : 0; + // Nothing to refill, everything is in memory + if (b->fd == -1) + return 0; + if (!S_ISREG(b->st.st_mode)) goto out; diff --git a/src/cdf.c b/src/cdf.c index 0c9c3743a075..c35833e18a9b 100644 --- a/src/cdf.c +++ b/src/cdf.c @@ -35,7 +35,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: cdf.c,v 1.124 2024/11/25 21:24:59 christos Exp $") +FILE_RCSID("@(#)$File: cdf.c,v 1.126 2026/02/09 17:10:42 christos Exp $") #endif #include <assert.h> @@ -830,7 +830,7 @@ out: return 0; } -file_private int +file_protected int cdf_namecmp(const char *d, const uint16_t *s, size_t l) { for (; l--; d++, s++) @@ -880,12 +880,12 @@ cdf_find_stream(const cdf_dir_t *dir, const char *name, int type) { size_t i, name_len = strlen(name) + 1; - for (i = dir->dir_len; i > 0; i--) - if (dir->dir_tab[i - 1].d_type == type && - cdf_namecmp(name, dir->dir_tab[i - 1].d_name, name_len) + for (i = 1; i <= dir->dir_len; i++) + if (dir->dir_tab[i-1].d_type == type && + cdf_namecmp(name, dir->dir_tab[i-1].d_name, name_len) == 0) break; - if (i > 0) + if (i <= dir->dir_len) return CAST(int, i); DPRINTF(("Cannot find type %d `%s'\n", type, name)); diff --git a/src/cdf.h b/src/cdf.h index 4a4c35554cdf..6dddb3d65af0 100644 --- a/src/cdf.h +++ b/src/cdf.h @@ -323,6 +323,7 @@ file_protected int cdf_read_user_stream(const cdf_info_t *, const cdf_stream_t *, const cdf_dir_t *, const char *, cdf_stream_t *); file_protected int cdf_find_stream(const cdf_dir_t *, const char *, int); file_protected int cdf_zero_stream(cdf_stream_t *); +file_protected int cdf_namecmp(const char *, const uint16_t *, size_t); file_protected int cdf_read_doc_summary_info(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *, const cdf_dir_t *, cdf_stream_t *); diff --git a/src/encoding.c b/src/encoding.c index 4b0d45e29db1..706e3315e56b 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -35,7 +35,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: encoding.c,v 1.43 2024/10/29 20:56:48 christos Exp $") +FILE_RCSID("@(#)$File: encoding.c,v 1.44 2024/12/26 18:41:27 christos Exp $") #endif /* lint */ #include "magic.h" @@ -237,11 +237,15 @@ file_encoding(struct magic_set *ms, const struct buffer *b, #define I 2 /* character appears in ISO-8859 text */ #define X 3 /* character appears in non-ISO extended ASCII (Mac, IBM PC) */ +/* + * SUB (substitute character ^Z) was used as EOF in DOS and early Windows + * NEL (next line 0x85) is considered in ECMAScript as whitespace + */ file_private char text_chars[256] = { /* BEL BS HT LF VT FF CR */ F, F, F, F, F, F, F, T, T, T, T, T, T, T, F, F, /* 0x0X */ - /* ESC */ - F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F, /* 0x1X */ + /* SUB ESC */ + F, F, F, F, F, F, F, F, F, F, T, T, F, F, F, F, /* 0x1X */ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x2X */ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x3X */ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x4X */ diff --git a/src/file.h b/src/file.h index 99226327d7e3..06cf91d1ddf2 100644 --- a/src/file.h +++ b/src/file.h @@ -27,7 +27,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$File: file.h,v 1.258 2024/11/27 15:37:00 christos Exp $ + * @(#)$File: file.h,v 1.262 2025/07/23 18:52:08 christos Exp $ */ #ifndef __file_h__ @@ -202,6 +202,10 @@ struct buffer { }; union VALUETYPE { + int8_t sb; + int16_t sh; + int32_t sl; + int64_t sq; uint8_t b; uint16_t h; uint32_t l; @@ -513,7 +517,7 @@ struct magic_set { #define FILE_ELF_SHNUM_MAX 32768 #define FILE_ELF_SHSIZE_MAX (128 * 1024 * 1024) #define FILE_INDIR_MAX 50 -#define FILE_NAME_MAX 100 +#define FILE_NAME_MAX 150 #define FILE_REGEX_MAX 8192 #define FILE_ENCODING_MAX (64 * 1024) #define FILE_MAGWARN_MAX 64 @@ -616,7 +620,7 @@ file_protected char * file_printable(struct magic_set *, char *, size_t, const char *, size_t); #ifdef __EMX__ file_protected int file_os2_apptype(struct magic_set *, const char *, - const void *, size_t); + const struct buffer *); #endif /* __EMX__ */ file_protected int file_pipe_closexec(int *); file_protected int file_clear_closexec(int); @@ -735,4 +739,7 @@ static const char *rcsid(const char *p) { \ #define __RCSID(a) #endif +#define file_no_overflow \ + __attribute__((__no_sanitize__("signed-integer-overflow"))) + #endif /* __file_h__ */ diff --git a/src/funcs.c b/src/funcs.c index e7e8cb0fc184..fa62b26d853c 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: funcs.c,v 1.142 2023/07/30 14:41:14 christos Exp $") +FILE_RCSID("@(#)$File: funcs.c,v 1.148 2026/01/10 16:18:18 christos Exp $") #endif /* lint */ #include "magic.h" @@ -99,8 +99,13 @@ file_checkfmt(char *msg, size_t mlen, const char *fmt) continue; if (*++p == '%') continue; + if (*p == '\0') { + if (msg) + snprintf(msg, mlen, "incomplete %% format"); + return -1; + } // Skip uninteresting. - while (strchr("#0.'+- ", *p) != NULL) + while (*p != '\0' && strchr("#0.'+- ", *p) != NULL) p++; if (*p == '*') { if (msg) @@ -300,6 +305,7 @@ file_default(struct magic_set *ms, size_t nb) return 1; } if (ms->flags & MAGIC_APPLE) { + // This is not a typo: Type: UNKN Creator: UNKN if (file_printf(ms, "UNKNUNKN") == -1) return -1; return 1; @@ -674,25 +680,31 @@ check_regex(struct magic_set *ms, const char *pat) unsigned char oc = '\0'; const char *p; unsigned long l; + static const char wild[] = "?*+{"; for (p = pat; *p; p++) { unsigned char c = *p; - // Avoid repetition - if (c == oc && strchr("?*+{", c) != NULL) { + // Avoid repetition of wild characters + if (strchr(wild, oc) != NULL && strchr(wild, c) != NULL) { size_t len = strlen(pat); file_magwarn(ms, - "repetition-operator operand `%c' " - "invalid in regex `%s'", c, + "repetition-operator operand `%c%c' " + "invalid in regex `%s'", oc, c, file_printable(ms, sbuf, sizeof(sbuf), pat, len)); return -1; } if (c == '{') { char *ep, *eep; + + if (oc == '}') { + file_magwarn(ms, "cascading repetition " + "operators in regex `%s'", pat); + return -1; + } errno = 0; l = strtoul(p + 1, &ep, 10); if (ep != p + 1 && l > 1000) goto bounds; - if (*ep == ',') { l = strtoul(ep + 1, &eep, 10); if (eep != ep + 1 && l > 1000) @@ -858,29 +870,68 @@ struct guid { uint8_t data4[8]; }; +static char XDIGIT[] = "0123456789abcdef"; +static int +atox(const uint8_t c) +{ + uint8_t d = isupper(c) ? tolower(c) : c; + const char *q = d ? strchr(XDIGIT, isupper(c) ? tolower(c) : c) : NULL; + if (q == NULL) + return -1; + return q - XDIGIT; +} + +static int +getxvalue(void *p, const char *s, size_t n) +{ + uint64_t v = 0; + for (size_t i = 0; i < n; i++) { + int x = atox(s[i]); + if (x == -1) + return 0; + v = (v << 4) | x; + } + switch (n) { + case 8: + *(uint32_t *)p = v; + return 1; + case 4: + *(uint16_t *)p = v; + return 1; + case 2: + *(uint8_t *)p = v; + return 1; + default: + return 0; + } +} + file_protected int file_parse_guid(const char *s, uint64_t *guid) { struct guid *g = CAST(struct guid *, CAST(void *, guid)); -#ifndef WIN32 - return sscanf(s, - "%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx", - &g->data1, &g->data2, &g->data3, &g->data4[0], &g->data4[1], - &g->data4[2], &g->data4[3], &g->data4[4], &g->data4[5], - &g->data4[6], &g->data4[7]) == 11 ? 0 : -1; -#else - /* MS-Windows runtime doesn't support %hhx, except under - non-default __USE_MINGW_ANSI_STDIO. */ - uint16_t data16[8]; - int rv = sscanf(s, "%8x-%4hx-%4hx-%2hx%2hx-%2hx%2hx%2hx%2hx%2hx%2hx", - &g->data1, &g->data2, &g->data3, &data16[0], &data16[1], - &data16[2], &data16[3], &data16[4], &data16[5], - &data16[6], &data16[7]) == 11 ? 0 : -1; - int i; - for (i = 0; i < 8; i++) - g->data4[i] = data16[i]; - return rv; -#endif + + if (!getxvalue(&g->data1, s, 8) || s[8] != '-') + return -1; + s += 9; + if (!getxvalue(&g->data2, s, 4) || s[4] != '-') + return -1; + s += 5; + if (!getxvalue(&g->data3, s, 4) || s[4] != '-') + return -1; + s += 5; + if (!getxvalue(&g->data4[0], s, 2) || + !getxvalue(&g->data4[1], s + 2, 2) || s[4] != '-') + return -1; + s += 5; + if (!getxvalue(&g->data4[2], s, 2) || + !getxvalue(&g->data4[3], s + 2, 2) || + !getxvalue(&g->data4[4], s + 4, 2) || + !getxvalue(&g->data4[5], s + 6, 2) || + !getxvalue(&g->data4[6], s + 8, 2) || + !getxvalue(&g->data4[7], s + 10, 2)) + return -1; + return 0; } file_protected int diff --git a/src/is_simh.c b/src/is_simh.c index 4e78173fc44c..ac6297ad9681 100644 --- a/src/is_simh.c +++ b/src/is_simh.c @@ -33,7 +33,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: is_simh.c,v 1.10 2023/07/27 19:39:55 christos Exp $") +FILE_RCSID("@(#)$File: is_simh.c,v 1.11 2025/05/31 23:31:45 christos Exp $") #endif #include <string.h> @@ -91,15 +91,18 @@ swap4(uint32_t sv) static uint32_t -getlen(const unsigned char **uc) +getlen(const unsigned char **uc, int *err) { uint32_t n; memcpy(&n, *uc, sizeof(n)); + *err = 0; *uc += sizeof(n); if (NEED_SWAP) n = swap4(n); if (n == 0xffffffff) /* check for End of Medium */ return n; + /* Check bits 25 to 28 are not used */ + *err = ((n & 0x00ffffff) != (n & 0x0fffffff)); n &= 0x00ffffff; /* keep only the record len */ if (n & 1) n++; @@ -112,11 +115,14 @@ simh_parse(const unsigned char *uc, const unsigned char *ue) uint32_t nbytes, cbytes; const unsigned char *orig_uc = uc; size_t nt = 0, nr = 0; + int err = 0; (void)memcpy(simh_bo.s, "\01\02\03\04", 4); while (ue - uc >= CAST(ptrdiff_t, sizeof(nbytes))) { - nbytes = getlen(&uc); + nbytes = getlen(&uc, &err); + if (err) + return 0; if ((nt > 0 || nr > 0) && nbytes == 0xFFFFFFFF) /* EOM after at least one record or tapemark */ break; @@ -132,7 +138,9 @@ simh_parse(const unsigned char *uc, const unsigned char *ue) uc += nbytes; if (ue - uc < CAST(ptrdiff_t, sizeof(nbytes))) break; - cbytes = getlen(&uc); + cbytes = getlen(&uc, &err); + if (err) + return 0; if (nbytes != cbytes) return 0; nr++; diff --git a/src/magic.c b/src/magic.c index def46fa39f89..653b91523657 100644 --- a/src/magic.c +++ b/src/magic.c @@ -33,7 +33,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: magic.c,v 1.123 2023/12/29 18:04:48 christos Exp $") +FILE_RCSID("@(#)$File: magic.c,v 1.125 2026/01/19 18:53:58 christos Exp $") #endif /* lint */ #include "magic.h" @@ -205,7 +205,7 @@ get_default_magic(void) } } - if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0) + if (asprintf(&default_magic, "%s%c%s", hmagicpath, PATHSEP, MAGIC) < 0) goto out; free(hmagicpath); return default_magic; @@ -368,29 +368,30 @@ close_and_restore(const struct magic_set *ms, const char *name, int fd, return; (void) close(fd); - if ((ms->flags & MAGIC_PRESERVE_ATIME) != 0) { - /* - * Try to restore access, modification times if read it. - * This is really *bad* because it will modify the status - * time of the file... And of course this will affect - * backup programs - */ + if (sb == NULL || (ms->flags & MAGIC_PRESERVE_ATIME) == 0) + return; + + /* + * Try to restore access, modification times if read it. + * This is really *bad* because it will modify the status + * time of the file... And of course this will affect + * backup programs + */ #ifdef HAVE_UTIMES - struct timeval utsbuf[2]; - (void)memset(utsbuf, 0, sizeof(utsbuf)); - utsbuf[0].tv_sec = sb->st_atime; - utsbuf[1].tv_sec = sb->st_mtime; + struct timeval utsbuf[2]; + (void)memset(utsbuf, 0, sizeof(utsbuf)); + utsbuf[0].tv_sec = sb->st_atime; + utsbuf[1].tv_sec = sb->st_mtime; - (void) utimes(name, utsbuf); /* don't care if loses */ + (void) utimes(name, utsbuf); /* don't care if loses */ #elif defined(HAVE_UTIME_H) || defined(HAVE_SYS_UTIME_H) - struct utimbuf utbuf; + struct utimbuf utbuf; - (void)memset(&utbuf, 0, sizeof(utbuf)); - utbuf.actime = sb->st_atime; - utbuf.modtime = sb->st_mtime; - (void) utime(name, &utbuf); /* don't care if loses */ + (void)memset(&utbuf, 0, sizeof(utbuf)); + utbuf.actime = sb->st_atime; + utbuf.modtime = sb->st_mtime; + (void) utime(name, &utbuf); /* don't care if loses */ #endif - } } #ifndef COMPILE_ONLY @@ -530,7 +531,8 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd) } (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */ - if (file_buffer(ms, fd, okstat ? &sb : NULL, inname, buf, CAST(size_t, nbytes)) == -1) + if (file_buffer(ms, fd, okstat ? &sb : NULL, inname, buf, + CAST(size_t, nbytes)) == -1) goto done; rv = 0; done: @@ -538,7 +540,7 @@ done: if (fd != -1) { if (pos != CAST(off_t, -1)) (void)lseek(fd, pos, SEEK_SET); - close_and_restore(ms, inname, fd, &sb); + close_and_restore(ms, inname, fd, okstat ? &sb : NULL); } out: return rv == 0 ? file_getbuffer(ms) : NULL; diff --git a/src/print.c b/src/print.c index 361e73be7740..0740fd67e213 100644 --- a/src/print.c +++ b/src/print.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: print.c,v 1.106 2024/09/01 13:50:01 christos Exp $") +FILE_RCSID("@(#)$File: print.c,v 1.110 2025/03/20 17:46:50 christos Exp $") #endif /* lint */ #include <string.h> @@ -352,9 +352,13 @@ file_fmtdate(char *buf, size_t bsize, uint16_t v) memset(&tm, 0, sizeof(tm)); tm.tm_mday = v & 0x1f; tm.tm_mon = ((v >> 5) & 0xf) - 1; + // Sanity check because some OS's coredump with invalid values. + // Yes, Cygwin I am looking at you! + if (tm.tm_mon < 0 || tm.tm_mon > 11) + tm.tm_mon = 0; tm.tm_year = (v >> 9) + 80; - if (strftime(buf, bsize, "%a, %b %d %Y", &tm) == 0) + if (strftime(buf, bsize, "%b %d %Y", &tm) == 0) goto out; return buf; diff --git a/src/readcdf.c b/src/readcdf.c index 30c3d24667cd..27dd34629235 100644 --- a/src/readcdf.c +++ b/src/readcdf.c @@ -26,7 +26,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: readcdf.c,v 1.80 2023/01/24 20:13:40 christos Exp $") +FILE_RCSID("@(#)$File: readcdf.c,v 1.81 2026/02/04 14:56:28 christos Exp $") #endif #include <assert.h> @@ -220,6 +220,11 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, } else if (str == NULL && info[i].pi_id == CDF_PROPERTY_NAME_OF_APPLICATION) { str = cdf_app_to_mime(vbuf, app2mime); +#ifdef CDF_DEBUG + fprintf(stderr, "Found property " + "application name = \"%s\" " + "(mime=%s)\n", vbuf, str); +#endif } } break; @@ -487,7 +492,7 @@ file_private struct sinfo { }, { "Microsoft PowerPoint", "vnd.ms-powerpoint", { - "PowerPoint", NULL, NULL, NULL, NULL, + "PowerPoint Document", NULL, NULL, NULL, NULL, }, { CDF_DIR_TYPE_USER_STREAM, @@ -511,28 +516,43 @@ file_private struct sinfo { file_private int cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir) { - size_t sd, j; + size_t sd, i, j; + uint16_t *dir_name; + int dir_type; + const char* section_name; + + for (i = 0; i < dir->dir_len; i++) { + dir_name = dir->dir_tab[i].d_name; + dir_type = dir->dir_tab[i].d_type; - for (sd = 0; sd < __arraycount(sectioninfo); sd++) { - const struct sinfo *si = §ioninfo[sd]; - for (j = 0; si->sections[j]; j++) { - if (cdf_find_stream(dir, si->sections[j], si->types[j]) - > 0) - break; + for (sd = 0; sd < __arraycount(sectioninfo); sd++) { + const struct sinfo *si = §ioninfo[sd]; + for (j = 0; si->sections[j]; j++) { + if (si->sections[j] == NULL) + continue; + section_name = si->sections[j]; + if (si->types[j] != dir_type || + cdf_namecmp(section_name, dir_name, + strlen(section_name) + 1) != 0) + continue; #ifdef CDF_DEBUG - fprintf(stderr, "Can't read %s\n", si->sections[j]); + fprintf(stderr, "Matching directory %" + SIZE_T_FORMAT + "u with expected name \"%s\"\n", + i, section_name); #endif + if (NOTMIME(ms)) { + if (file_printf(ms, "CDFV2 %s", + si->name) == -1) + return -1; + } else if (ms->flags & MAGIC_MIME_TYPE) { + if (file_printf(ms, "application/%s", + si->mime) == -1) + return -1; + } + return 1; + } } - if (si->sections[j] == NULL) - continue; - if (NOTMIME(ms)) { - if (file_printf(ms, "CDFV2 %s", si->name) == -1) - return -1; - } else if (ms->flags & MAGIC_MIME_TYPE) { - if (file_printf(ms, "application/%s", si->mime) == -1) - return -1; - } - return 1; } return -1; } diff --git a/src/readelf.c b/src/readelf.c index fe4cf5413895..8454f4db4159 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -27,13 +27,14 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: readelf.c,v 1.196 2024/11/11 15:49:11 christos Exp $") +FILE_RCSID("@(#)$File: readelf.c,v 1.204 2025/06/27 16:57:44 christos Exp $") #endif #ifdef BUILTIN_ELF #include <string.h> #include <ctype.h> #include <stdlib.h> +#include <stdarg.h> #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -65,12 +66,25 @@ file_private uint64_t getu64(int, uint64_t); #define NAMEEQUALS(n, v) \ (namesz == sizeof(v) && memcmp(n, v, namesz) == 0) +__attribute__((__format__(__printf__, 2, 3))) file_private int -toomany(struct magic_set *ms, const char *name, uint16_t num) +elf_printf(struct magic_set *ms, const char *fmt, ...) { + va_list ap; + int rv; + if (ms->flags & MAGIC_MIME) return 1; - if (file_printf(ms, ", too many %s (%u)", name, num) == -1) + + va_start(ap, fmt); + rv = file_vprintf(ms, fmt, ap); + va_end(ap); + return rv; +} +file_private int +toomany(struct magic_set *ms, const char *name, uint16_t num) +{ + if (elf_printf(ms, ", too many %s (%u)", name, num) == -1) return -1; return 1; } @@ -363,12 +377,12 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, return 0; if (num == 0) { - if (file_printf(ms, ", no program header") == -1) + if (elf_printf(ms, ", no program header") == -1) return -1; return 0; } if (size != xph_sizeof) { - if (file_printf(ms, ", corrupted program header size") == -1) + if (elf_printf(ms, ", corrupted program header size") == -1) return -1; return 0; } @@ -379,7 +393,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, for ( ; num; num--) { if (pread(fd, xph_addr, xph_sizeof, off) < CAST(ssize_t, xph_sizeof)) { - if (file_printf(ms, + if (elf_printf(ms, ", can't read elf program headers at %jd", (intmax_t)off) == -1) return -1; @@ -402,7 +416,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, len = xph_filesz < sizeof(nbuf) ? xph_filesz : sizeof(nbuf); offs = xph_offset; if ((bufsize = pread(fd, nbuf, len, offs)) == -1) { - if (file_printf(ms, " can't read note section at %jd", + if (elf_printf(ms, " can't read note section at %jd", (intmax_t)offs) == -1) return -1; return 0; @@ -430,7 +444,7 @@ do_note_netbsd_version(struct magic_set *ms, int swap, void *v) memcpy(&desc, v, sizeof(desc)); desc = elf_getu32(swap, desc); - if (file_printf(ms, ", for NetBSD") == -1) + if (elf_printf(ms, ", for NetBSD") == -1) return -1; /* * The version number used to be stuck as 199905, and was thus @@ -450,22 +464,22 @@ do_note_netbsd_version(struct magic_set *ms, int swap, void *v) uint32_t ver_min = (desc / 1000000) % 100; uint32_t ver_maj = desc / 100000000; - if (file_printf(ms, " %u.%u", ver_maj, ver_min) == -1) + if (elf_printf(ms, " %u.%u", ver_maj, ver_min) == -1) return -1; if (ver_maj >= 9) { ver_patch += 100 * ver_rel; ver_rel = 0; } if (ver_rel == 0 && ver_patch != 0) { - if (file_printf(ms, ".%u", ver_patch) == -1) + if (elf_printf(ms, ".%u", ver_patch) == -1) return -1; } else if (ver_rel != 0) { while (ver_rel > 26) { - if (file_printf(ms, "Z") == -1) + if (elf_printf(ms, "Z") == -1) return -1; ver_rel -= 26; } - if (file_printf(ms, "%c", 'A' + ver_rel - 1) == -1) + if (elf_printf(ms, "%c", 'A' + ver_rel - 1) == -1) return -1; } } @@ -479,7 +493,7 @@ do_note_freebsd_version(struct magic_set *ms, int swap, void *v) memcpy(&desc, v, sizeof(desc)); desc = elf_getu32(swap, desc); - if (file_printf(ms, ", for FreeBSD") == -1) + if (elf_printf(ms, ", for FreeBSD") == -1) return -1; /* @@ -509,39 +523,39 @@ do_note_freebsd_version(struct magic_set *ms, int swap, void *v) * was version 3.0. */ if (desc == 460002) { - if (file_printf(ms, " 4.6.2") == -1) + if (elf_printf(ms, " 4.6.2") == -1) return -1; } else if (desc < 460100) { - if (file_printf(ms, " %d.%d", desc / 100000, + if (elf_printf(ms, " %d.%d", desc / 100000, desc / 10000 % 10) == -1) return -1; if (desc / 1000 % 10 > 0) - if (file_printf(ms, ".%d", desc / 1000 % 10) == -1) + if (elf_printf(ms, ".%d", desc / 1000 % 10) == -1) return -1; if ((desc % 1000 > 0) || (desc % 100000 == 0)) - if (file_printf(ms, " (%d)", desc) == -1) + if (elf_printf(ms, " (%d)", desc) == -1) return -1; } else if (desc < 500000) { - if (file_printf(ms, " %d.%d", desc / 100000, + if (elf_printf(ms, " %d.%d", desc / 100000, desc / 10000 % 10 + desc / 1000 % 10) == -1) return -1; if (desc / 100 % 10 > 0) { - if (file_printf(ms, " (%d)", desc) == -1) + if (elf_printf(ms, " (%d)", desc) == -1) return -1; } else if (desc / 10 % 10 > 0) { - if (file_printf(ms, ".%d", desc / 10 % 10) == -1) + if (elf_printf(ms, ".%d", desc / 10 % 10) == -1) return -1; } } else { - if (file_printf(ms, " %d.%d", desc / 100000, + if (elf_printf(ms, " %d.%d", desc / 100000, desc / 1000 % 100) == -1) return -1; if ((desc / 100 % 10 > 0) || (desc % 100000 / 100 == 0)) { - if (file_printf(ms, " (%d)", desc) == -1) + if (elf_printf(ms, " (%d)", desc) == -1) return -1; } else if (desc / 10 % 10 > 0) { - if (file_printf(ms, ".%d", desc / 10 % 10) == -1) + if (elf_printf(ms, ".%d", desc / 10 % 10) == -1) return -1; } } @@ -574,18 +588,18 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, btype = "unknown"; break; } - if (file_printf(ms, ", BuildID[%s]=", btype) == -1) + if (elf_printf(ms, ", BuildID[%s]=", btype) == -1) return -1; memcpy(desc, &nbuf[doff], descsz); for (i = 0; i < descsz; i++) - if (file_printf(ms, "%02x", desc[i]) == -1) + if (elf_printf(ms, "%02x", desc[i]) == -1) return -1; return 1; } if (namesz == 4 && memcmp(RCAST(char *, &nbuf[noff]), "Go", 3) == 0 && type == NT_GO_BUILD_ID && descsz < 128) { char buf[256]; - if (file_printf(ms, ", Go BuildID=%s", + if (elf_printf(ms, ", Go BuildID=%s", file_copystr(buf, sizeof(buf), descsz, RCAST(const char *, &nbuf[doff]))) == -1) return -1; @@ -603,7 +617,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, if (NAMEEQUALS(name, "SuSE") && type == NT_GNU_VERSION && descsz == 2) { *flags |= FLAGS_DID_OS_NOTE; - if (file_printf(ms, ", for SuSE %d.%d", nbuf[doff], + if (elf_printf(ms, ", for SuSE %d.%d", nbuf[doff], nbuf[doff + 1]) == -1) return -1; return 1; @@ -614,34 +628,34 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, memcpy(desc, &nbuf[doff], sizeof(desc)); *flags |= FLAGS_DID_OS_NOTE; - if (file_printf(ms, ", for GNU/") == -1) + if (elf_printf(ms, ", for GNU/") == -1) return -1; switch (elf_getu32(swap, desc[0])) { case GNU_OS_LINUX: - if (file_printf(ms, "Linux") == -1) + if (elf_printf(ms, "Linux") == -1) return -1; break; case GNU_OS_HURD: - if (file_printf(ms, "Hurd") == -1) + if (elf_printf(ms, "Hurd") == -1) return -1; break; case GNU_OS_SOLARIS: - if (file_printf(ms, "Solaris") == -1) + if (elf_printf(ms, "Solaris") == -1) return -1; break; case GNU_OS_KFREEBSD: - if (file_printf(ms, "kFreeBSD") == -1) + if (elf_printf(ms, "kFreeBSD") == -1) return -1; break; case GNU_OS_KNETBSD: - if (file_printf(ms, "kNetBSD") == -1) + if (elf_printf(ms, "kNetBSD") == -1) return -1; break; default: - if (file_printf(ms, "<unknown>") == -1) + if (elf_printf(ms, "<unknown>") == -1) return -1; } - if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]), + if (elf_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]), elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1) return -1; return 1; @@ -667,7 +681,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, if (NAMEEQUALS(name, "OpenBSD") && type == NT_OPENBSD_VERSION && descsz == 4) { *flags |= FLAGS_DID_OS_NOTE; - if (file_printf(ms, ", for OpenBSD") == -1) + if (elf_printf(ms, ", for OpenBSD") == -1) return -1; /* Content of note is always 0 */ return 1; @@ -677,11 +691,11 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, type == NT_DRAGONFLY_VERSION && descsz == 4) { uint32_t desc; *flags |= FLAGS_DID_OS_NOTE; - if (file_printf(ms, ", for DragonFly") == -1) + if (elf_printf(ms, ", for DragonFly") == -1) return -1; memcpy(&desc, &nbuf[doff], sizeof(desc)); desc = elf_getu32(swap, desc); - if (file_printf(ms, " %d.%d.%d", desc / 100000, + if (elf_printf(ms, " %d.%d.%d", desc / 100000, desc / 10000 % 10, desc % 10000) == -1) return -1; return 1; @@ -693,7 +707,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, *flags |= FLAGS_DID_OS_NOTE; memcpy(&api_level, &nbuf[doff], sizeof(api_level)); api_level = elf_getu32(swap, api_level); - if (file_printf(ms, ", for Android %d", api_level) == -1) + if (elf_printf(ms, ", for Android %d", api_level) == -1) return -1; /* * NDK r14 and later also include details of the NDK that @@ -702,7 +716,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, * are both 64-byte strings. */ if (descsz >= 4 + 64 + 64) { - if (file_printf(ms, ", built by NDK %.64s (%.64s)", + if (elf_printf(ms, ", built by NDK %.64s (%.64s)", &nbuf[doff + 4], &nbuf[doff + 4 + 64]) == -1) return -1; } @@ -735,13 +749,13 @@ do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, memcpy(&desc, &nbuf[doff], sizeof(desc)); desc = elf_getu32(swap, desc); - if (desc && file_printf(ms, ", PaX: ") == -1) + if (desc && elf_printf(ms, ", PaX: ") == -1) return -1; for (i = 0; i < __arraycount(pax); i++) { if (((1 << CAST(int, i)) & desc) == 0) continue; - if (file_printf(ms, "%s%s", did++ ? "," : "", + if (elf_printf(ms, "%s%s", did++ ? "," : "", pax[i]) == -1) return -1; } @@ -774,13 +788,13 @@ do_memtag_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, memcpy(&desc, &nbuf[doff], sizeof(desc)); desc = elf_getu32(swap, desc); - if (desc && file_printf(ms, ", Android Memtag: ") == -1) + if (desc && elf_printf(ms, ", Android Memtag: ") == -1) return -1; for (i = 0; i < __arraycount(memtag); i++) { if (((1 << CAST(int, i)) & desc) == 0) continue; - if (file_printf(ms, "%s%s", did++ ? "," : "", + if (elf_printf(ms, "%s%s", did++ ? "," : "", memtag[i]) == -1) return -1; } @@ -827,7 +841,7 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, } if (os_style != -1 && (*flags & FLAGS_DID_CORE_STYLE) == 0) { - if (file_printf(ms, ", %s-style", os_style_names[os_style]) + if (elf_printf(ms, ", %s-style", os_style_names[os_style]) == -1) return -1; *flags |= FLAGS_DID_CORE_STYLE; @@ -842,7 +856,7 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, memset(&pi, 0, sizeof(pi)); memcpy(&pi, nbuf + doff, MIN(descsz, sizeof(pi))); - if (file_printf(ms, ", from '%.31s', pid=%u, uid=%u, " + if (elf_printf(ms, ", from '%.31s', pid=%u, uid=%u, " "gid=%u, nlwps=%u, lwp=%u (signal %u/code %u)", file_printable(ms, sbuf, sizeof(sbuf), RCAST(char *, pi.cpi_name), sizeof(pi.cpi_name)), @@ -868,12 +882,12 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, argoff = 4 + 4 + 17; else argoff = 4 + 4 + 8 + 17; - if (file_printf(ms, ", from '%.80s'", nbuf + doff + + if (elf_printf(ms, ", from '%.80s'", nbuf + doff + argoff) == -1) return -1; pidoff = argoff + 81 + 2; if (doff + pidoff + 4 <= size) { - if (file_printf(ms, ", pid=%u", + if (elf_printf(ms, ", pid=%u", elf_getu32(swap, *RCAST(uint32_t *, (nbuf + doff + pidoff)))) == -1) return -1; @@ -982,7 +996,7 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, */ while (cp > cname && isspace(cp[-1])) cp--; - if (file_printf(ms, ", from '%s'", + if (elf_printf(ms, ", from '%s'", file_copystr(buf, sizeof(buf), CAST(size_t, cp - cname), RCAST(char *, cname))) == -1) @@ -1014,7 +1028,7 @@ get_offset_from_virtaddr(struct magic_set *ms, int swap, int clazz, int fd, for ( ; num; num--) { if (pread(fd, xph_addr, xph_sizeof, off) < CAST(ssize_t, xph_sizeof)) { - if (file_printf(ms, + if (elf_printf(ms, ", can't read elf program header at %jd", (intmax_t)off) == -1) return -1; @@ -1049,7 +1063,7 @@ get_string_on_virtaddr(struct magic_set *ms, fsize, virtaddr); if (offset < 0 || (buflen = pread(fd, buf, CAST(size_t, buflen), offset)) <= 0) { - (void)file_printf(ms, ", can't read elf string at %jd", + (void)elf_printf(ms, ", can't read elf string at %jd", (intmax_t)offset); return 0; } @@ -1161,10 +1175,10 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, if (buflen == 0) continue; - if (file_printf(ms, ", %s: '%s'", tag, buf) == -1) + if (elf_printf(ms, ", %s: '%s'", tag, buf) == -1) return -1; } else { - if (file_printf(ms, ", %s: %d", tag, + if (elf_printf(ms, ", %s: %d", tag, CAST(int, xauxv_val)) == -1) return -1; } @@ -1251,13 +1265,13 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, } if (namesz & 0x80000000) { - (void)file_printf(ms, ", bad note name size %#lx", + (void)elf_printf(ms, ", bad note name size %#lx", CAST(unsigned long, namesz)); return 0; } if (descsz & 0x80000000) { - (void)file_printf(ms, ", bad note description size %#lx", + (void)elf_printf(ms, ", bad note description size %#lx", CAST(unsigned long, descsz)); return 0; } @@ -1341,7 +1355,7 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, if (*flags & FLAGS_DID_NETBSD_UNKNOWN) return offset; *flags |= FLAGS_DID_NETBSD_UNKNOWN; - if (file_printf(ms, ", note=%u", xnh_type) == -1) + if (elf_printf(ms, ", note=%u", xnh_type) == -1) return offset; return offset; } @@ -1351,7 +1365,7 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, str = RCAST(const char *, &nbuf[doff]); descw = CAST(int, descsz); *flags |= flag; - file_printf(ms, ", %s: %s", tag, + elf_printf(ms, ", %s: %s", tag, file_copystr(buf, sizeof(buf), descw, str)); return offset; } @@ -1429,12 +1443,12 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, return 0; if (num == 0) { - if (file_printf(ms, ", no section header") == -1) + if (elf_printf(ms, ", no section header") == -1) return -1; return 0; } if (size != xsh_sizeof) { - if (file_printf(ms, ", corrupted section header size") == -1) + if (elf_printf(ms, ", corrupted section header size") == -1) return -1; return 0; } @@ -1442,7 +1456,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, /* Read offset of name section to be able to read section names later */ offs = CAST(off_t, (off + size * strtab)); if (pread(fd, xsh_addr, xsh_sizeof, offs) < CAST(ssize_t, xsh_sizeof)) { - if (file_printf(ms, ", missing section headers at %jd", + if (elf_printf(ms, ", missing section headers at %jd", (intmax_t)offs) == -1) return -1; return 0; @@ -1450,7 +1464,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, name_off = xsh_offset; if (fsize != SIZE_UNKNOWN && fsize < name_off) { - if (file_printf(ms, ", too large section header offset %jd", + if (elf_printf(ms, ", too large section header offset %jd", (intmax_t)name_off) == -1) return -1; return 0; @@ -1461,7 +1475,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, offs = name_off + xsh_name; if ((namesize = pread(fd, name, sizeof(name) - 1, offs)) == -1) { - if (file_printf(ms, + if (elf_printf(ms, ", can't read name of elf section at %jd", (intmax_t)offs) == -1) return -1; @@ -1475,7 +1489,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, if (pread(fd, xsh_addr, xsh_sizeof, off) < CAST(ssize_t, xsh_sizeof)) { - if (file_printf(ms, ", can't read elf section at %jd", + if (elf_printf(ms, ", can't read elf section at %jd", (intmax_t)off) == -1) return -1; return 0; @@ -1504,7 +1518,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, case SHT_NOTE: if (CAST(uintmax_t, (xsh_size + xsh_offset)) > CAST(uintmax_t, fsize)) { - if (file_printf(ms, + if (elf_printf(ms, ", note offset/size %#" INTMAX_T_FORMAT "x+%#" INTMAX_T_FORMAT "x exceeds" " file size %#" INTMAX_T_FORMAT "x", @@ -1529,7 +1543,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, if (pread(fd, nbuf, xsh_size, offs) < CAST(ssize_t, xsh_size)) { free(nbuf); - if (file_printf(ms, + if (elf_printf(ms, ", can't read elf note at %jd", (intmax_t)offs) == -1) return -1; @@ -1591,7 +1605,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, p += 4; len = getu32(swap, len); if (memcmp("gnu", p, 3) != 0) { - if (file_printf(ms, + if (elf_printf(ms, ", unknown capability %.3s", p) == -1) return -1; @@ -1603,7 +1617,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, p += 4; len = getu32(swap, len); if (tag != 1) { - if (file_printf(ms, ", unknown gnu" + if (elf_printf(ms, ", unknown gnu" " capability tag %d", tag) == -1) return -1; @@ -1624,7 +1638,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, cap_sf1 |= xcap_val; break; default: - if (file_printf(ms, + if (elf_printf(ms, ", with unknown capability " "%#" INT64_T_FORMAT "x = %#" INT64_T_FORMAT "x", @@ -1633,7 +1647,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, == -1) return -1; if (nbadcap++ > 2) - coff = xsh_size; + goto skip; break; } } @@ -1645,10 +1659,10 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, } if (has_debug_info) { - if (file_printf(ms, ", with debug_info") == -1) + if (elf_printf(ms, ", with debug_info") == -1) return -1; } - if (file_printf(ms, ", %sstripped", stripped ? "" : "not ") == -1) + if (elf_printf(ms, ", %sstripped", stripped ? "" : "not ") == -1) return -1; if (cap_hw1) { const cap_desc_t *cdp; @@ -1667,12 +1681,12 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, cdp = NULL; break; } - if (file_printf(ms, ", uses") == -1) + if (elf_printf(ms, ", uses") == -1) return -1; if (cdp) { while (cdp->cd_name) { if (cap_hw1 & cdp->cd_mask) { - if (file_printf(ms, + if (elf_printf(ms, " %s", cdp->cd_name) == -1) return -1; cap_hw1 &= ~cdp->cd_mask; @@ -1680,13 +1694,13 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, ++cdp; } if (cap_hw1) - if (file_printf(ms, + if (elf_printf(ms, " unknown hardware capability %#" INT64_T_FORMAT "x", CAST(unsigned long long, cap_hw1)) == -1) return -1; } else { - if (file_printf(ms, + if (elf_printf(ms, " hardware capability %#" INT64_T_FORMAT "x", CAST(unsigned long long, cap_hw1)) == -1) return -1; @@ -1694,7 +1708,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, } if (cap_sf1) { if (cap_sf1 & SF1_SUNW_FPUSED) { - if (file_printf(ms, + if (elf_printf(ms, (cap_sf1 & SF1_SUNW_FPKNWN) ? ", uses frame pointer" : ", not known to use frame pointer") == -1) @@ -1702,7 +1716,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, } cap_sf1 &= ~SF1_SUNW_MASK; if (cap_sf1) - if (file_printf(ms, + if (elf_printf(ms, ", with unknown software capability %#" INT64_T_FORMAT "x", CAST(unsigned long long, cap_sf1)) == -1) @@ -1724,20 +1738,20 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, { Elf32_Phdr ph32; Elf64_Phdr ph64; - const char *linking_style; + const char *str; unsigned char nbuf[NBUFSIZE]; - char interp[128]; + char interp[NBUFSIZE]; ssize_t bufsize; size_t offset, align, need = 0; int pie = 0, dynamic = 0; if (num == 0) { - if (file_printf(ms, ", no program header") == -1) + if (elf_printf(ms, ", no program header") == -1) return -1; return 0; } if (size != xph_sizeof) { - if (file_printf(ms, ", corrupted program header size") == -1) + if (elf_printf(ms, ", corrupted program header size") == -1) return -1; return 0; } @@ -1747,7 +1761,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int doread; if (pread(fd, xph_addr, xph_sizeof, off) < CAST(ssize_t, xph_sizeof)) { - if (file_printf(ms, + if (elf_printf(ms, ", can't read elf program headers at %jd", (intmax_t)off) == -1) return -1; @@ -1768,7 +1782,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, continue; if (((align = xph_align) & 0x80000000UL) != 0 || align < 4) { - if (file_printf(ms, + if (elf_printf(ms, ", invalid note alignment %#lx", CAST(unsigned long, align)) == -1) return -1; @@ -1793,7 +1807,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, off_t offs = xph_offset; bufsize = pread(fd, nbuf, len, offs); if (bufsize == -1) { - if (file_printf(ms, + if (elf_printf(ms, ", can't read section at %jd", (intmax_t)offs) == -1) return -1; @@ -1817,8 +1831,6 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, if (offset == 0) break; } - if (ms->flags & MAGIC_MIME) - continue; break; case PT_INTERP: @@ -1827,9 +1839,10 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, continue; if (bufsize && nbuf[0]) { nbuf[bufsize - 1] = '\0'; - memcpy(interp, nbuf, CAST(size_t, bufsize)); + str = CAST(const char *, nbuf); } else - strlcpy(interp, "*empty*", sizeof(interp)); + str = "*empty*"; + strlcpy(interp, str, sizeof(interp)); break; case PT_NOTE: if (ms->flags & MAGIC_MIME) @@ -1859,17 +1872,17 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, return 0; if (dynamic) { if (pie && need == 0) - linking_style = "static-pie"; + str = "static-pie"; else - linking_style = "dynamically"; + str = "dynamically"; } else { - linking_style = "statically"; + str = "statically"; } - if (file_printf(ms, ", %s linked", linking_style) == -1) + if (elf_printf(ms, ", %s linked", str) == -1) return -1; if (interp[0]) - if (file_printf(ms, ", interpreter %s", file_printable(ms, - CAST(char *, nbuf), sizeof(nbuf), + if (elf_printf(ms, ", interpreter %s", file_printable(ms, + RCAST(char *, nbuf), sizeof(nbuf), interp, sizeof(interp))) == -1) return -1; return 0; @@ -1956,7 +1969,7 @@ file_tryelf(struct magic_set *ms, const struct buffer *b) #define elfhdr elf64hdr #include "elfclass.h" default: - if (file_printf(ms, ", unknown class %d", clazz) == -1) + if (elf_printf(ms, ", unknown class %d", clazz) == -1) return -1; break; } diff --git a/src/seccomp.c b/src/seccomp.c index ce8243300095..e80b18ccec77 100644 --- a/src/seccomp.c +++ b/src/seccomp.c @@ -27,15 +27,16 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: seccomp.c,v 1.29 2024/09/29 16:49:25 christos Exp $") +FILE_RCSID("@(#)$File: seccomp.c,v 1.36 2026/02/06 14:04:20 christos Exp $") #endif /* lint */ #if HAVE_LIBSECCOMP #include <seccomp.h> /* libseccomp */ #include <sys/prctl.h> /* prctl */ -#include <sys/ioctl.h> #include <sys/socket.h> -#include <termios.h> +// See: https://sourceware.org/bugzilla/show_bug.cgi?id=32806 +#include <asm/termbits.h> +#include <sys/ioctl.h> #include <fcntl.h> #include <stdlib.h> #include <errno.h> @@ -103,6 +104,11 @@ enable_sandbox(void) #ifdef __NR_getdents64 ALLOW_RULE(getdents64); #endif + ALLOW_RULE(getpid); // Used by glibc in file_pipe2file() + ALLOW_RULE(getrandom); // Used by glibc in file_pipe2file() +#ifdef __NR_getcwd + ALLOW_RULE(getcwd); // GCONV_PATH= +#endif #ifdef FIONREAD // called in src/compress.c under sread ALLOW_IOCTL_RULE(FIONREAD); @@ -115,6 +121,10 @@ enable_sandbox(void) // glibc may call ioctl TCGETS on stdout on physical terminal ALLOW_IOCTL_RULE(TCGETS); #endif +#ifdef TCGETS2 + // glibc may call ioctl TCGETS2 on stdout on physical terminal + ALLOW_IOCTL_RULE(TCGETS2); +#endif ALLOW_RULE(lseek); ALLOW_RULE(_llseek); ALLOW_RULE(lstat); @@ -136,6 +146,7 @@ enable_sandbox(void) #ifdef __NR_readlinkat ALLOW_RULE(readlinkat); #endif + ALLOW_RULE(rseq); // Used by glibc to randomize malloc ALLOW_RULE(rt_sigaction); ALLOW_RULE(rt_sigprocmask); ALLOW_RULE(rt_sigreturn); @@ -145,8 +156,6 @@ enable_sandbox(void) ALLOW_RULE(stat64); ALLOW_RULE(sysinfo); ALLOW_RULE(umask); // Used in file_pipe2file() - ALLOW_RULE(getpid); // Used by glibc in file_pipe2file() - ALLOW_RULE(getrandom); // Used by glibc in file_pipe2file() ALLOW_RULE(unlink); ALLOW_RULE(utimes); ALLOW_RULE(write); diff --git a/src/softmagic.c b/src/softmagic.c index 59300a699140..54ebcde36af6 100644 --- a/src/softmagic.c +++ b/src/softmagic.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: softmagic.c,v 1.350 2024/11/27 15:37:00 christos Exp $") +FILE_RCSID("@(#)$File: softmagic.c,v 1.359 2025/06/08 14:42:11 christos Exp $") #endif /* lint */ #include "magic.h" @@ -414,6 +414,7 @@ flush: *need_separator = 1; *printed_something = 1; *returnval = 1; + *firstline = 0; return e; } if (*m->desc) { @@ -1042,11 +1043,28 @@ cvt_flip(int type, int flip) return FILE_LEDOUBLE; case FILE_LEDOUBLE: return FILE_BEDOUBLE; + case FILE_BEMSDOSDATE: + return FILE_LEMSDOSDATE; + case FILE_LEMSDOSDATE: + return FILE_BEMSDOSDATE; + case FILE_BEMSDOSTIME: + return FILE_LEMSDOSTIME; + case FILE_LEMSDOSTIME: + return FILE_BEMSDOSTIME; default: return type; } } -#define DO_CVT(fld, type) \ + +/* X86 INT_MIN / -1 traps */ +#define CHECKOVFL(type, a, b, size, sign) \ + if (size == 32 && sign && CAST(type, a) == CAST(type, 0x80000000) \ + && CAST(type, b) == CAST(type, -1)) \ + return -1; \ + if (size == 64 && sign && CAST(type, a) == CAST(type, 0x8000000000000000LL) \ + && CAST(type, b) == CAST(type, -1)) \ + return -1 +#define DO_CVT1(fld, type, size, sign) \ if (m->num_mask) \ switch (m->mask_op & FILE_OPS_MASK) { \ case FILE_OPAND: \ @@ -1068,11 +1086,13 @@ cvt_flip(int type, int flip) p->fld *= CAST(type, m->num_mask); \ break; \ case FILE_OPDIVIDE: \ + CHECKOVFL(type, p->fld, m->num_mask, size, sign); \ if (CAST(type, m->num_mask) == 0) \ return -1; \ p->fld /= CAST(type, m->num_mask); \ break; \ case FILE_OPMODULO: \ + CHECKOVFL(type, p->fld, m->num_mask, size, sign); \ if (CAST(type, m->num_mask) == 0) \ return -1; \ p->fld %= CAST(type, m->num_mask); \ @@ -1081,31 +1101,38 @@ cvt_flip(int type, int flip) if (m->mask_op & FILE_OPINVERSE) \ p->fld = ~p->fld \ -file_private int +#define DO_CVT(m, fld, size) \ + if ((m)->flag & UNSIGNED) { \ + DO_CVT1(fld, uint##size##_t, size, 0); \ + } else { \ + DO_CVT1(s##fld, int##size##_t, size, 1); \ + } + +file_no_overflow file_private int cvt_8(union VALUETYPE *p, const struct magic *m) { - DO_CVT(b, uint8_t); + DO_CVT(m, b, 8); return 0; } -file_private int +file_no_overflow file_private int cvt_16(union VALUETYPE *p, const struct magic *m) { - DO_CVT(h, uint16_t); + DO_CVT(m, h, 16); return 0; } -file_private int +file_no_overflow file_private int cvt_32(union VALUETYPE *p, const struct magic *m) { - DO_CVT(l, uint32_t); + DO_CVT(m, l, 32); return 0; } -file_private int +file_no_overflow file_private int cvt_64(union VALUETYPE *p, const struct magic *m) { - DO_CVT(q, uint64_t); + DO_CVT(m, q, 64); return 0; } @@ -1159,11 +1186,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) return 1; case FILE_SHORT: case FILE_MSDOSDATE: - case FILE_LEMSDOSDATE: - case FILE_BEMSDOSDATE: case FILE_MSDOSTIME: - case FILE_LEMSDOSTIME: - case FILE_BEMSDOSTIME: if (cvt_16(p, m) == -1) goto out; return 1; @@ -1217,6 +1240,8 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) return 1; } case FILE_BESHORT: + case FILE_BEMSDOSDATE: + case FILE_BEMSDOSTIME: p->h = CAST(short, BE16(p->hs)); if (cvt_16(p, m) == -1) goto out; @@ -1237,6 +1262,8 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) goto out; return 1; case FILE_LESHORT: + case FILE_LEMSDOSDATE: + case FILE_LEMSDOSTIME: p->h = CAST(short, LE16(p->hs)); if (cvt_16(p, m) == -1) goto out; @@ -1305,7 +1332,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) return 0; } out: - file_magerror(ms, "zerodivide in mconvert()"); + file_magerror(ms, "zerodivide/overflow/underflow in mconvert()"); return 0; } @@ -1534,10 +1561,16 @@ msetoffset(struct magic_set *ms, struct magic *m, struct buffer *bb, "u at level %u", o, cont_level); return -1; } - if (CAST(size_t, m->offset) > b->elen) - return -1; - buffer_init(bb, -1, NULL, b->ebuf, b->elen); - ms->eoffset = ms->offset = CAST(int32_t, b->elen - m->offset); + if (b->fd == -1) { + ms->eoffset = ms->offset = + CAST(int32_t, b->flen - m->offset); + } else { + if (CAST(size_t, m->offset) > b->elen) + return -1; + buffer_init(bb, -1, NULL, b->ebuf, b->elen); + ms->eoffset = ms->offset = + CAST(int32_t, b->elen - m->offset); + } } else { offset = m->offset; if ((m->flag & OFFPOSITIVE) || cont_level == 0) { @@ -1547,7 +1580,8 @@ normal: ms->offset = offset; ms->eoffset = 0; } else { - ms->offset = ms->eoffset + offset; + if (b->fd != -1) + ms->offset = ms->eoffset + offset; } } if ((ms->flags & MAGIC_DEBUG) != 0) { @@ -1966,7 +2000,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b, *need_separator = oneed_separator; ms->offset = offset; ms->eoffset = eoffset; - return rv || *found_match; + return rv ? rv : *found_match; case FILE_NAME: if (ms->flags & MAGIC_NODESC) @@ -2484,6 +2518,8 @@ file_private int handle_annotation(struct magic_set *ms, struct magic *m, int firstline) { if ((ms->flags & MAGIC_APPLE) && m->apple[0]) { + if (!firstline && !(ms->flags & MAGIC_CONTINUE)) + return 1; if (print_sep(ms, firstline) == -1) return -1; if (file_printf(ms, "%.8s", m->apple) == -1) @@ -2491,6 +2527,8 @@ handle_annotation(struct magic_set *ms, struct magic *m, int firstline) return 1; } if ((ms->flags & MAGIC_EXTENSION) && m->ext[0]) { + if (!firstline && !(ms->flags & MAGIC_CONTINUE)) + return 1; if (print_sep(ms, firstline) == -1) return -1; if (file_printf(ms, "%s", m->ext) == -1) @@ -2500,6 +2538,8 @@ handle_annotation(struct magic_set *ms, struct magic *m, int firstline) if ((ms->flags & MAGIC_MIME_TYPE) && m->mimetype[0]) { char buf[1024]; const char *p; + if (!firstline && !(ms->flags & MAGIC_CONTINUE)) + return 1; if (print_sep(ms, firstline) == -1) return -1; if (varexpand(ms, buf, sizeof(buf), m->mimetype) == -1) diff --git a/tests/Makefile.am b/tests/Makefile.am index 6e45949af223..32b35c1c1d64 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -13,6 +13,31 @@ bcachefs.result \ bcachefs.testfile \ bcachefs2.result \ bcachefs2.testfile \ +bgcode.result \ +bgcode.testfile \ +cl8m8ocofedso.result \ +cl8m8ocofedso.testfile \ +cmd1.result \ +cmd1.testfile \ +cmd2.result \ +cmd2.testfile \ +cmd3.result \ +cmd3.testfile \ +cmd4.result \ +cmd4.testfile \ +CVE-2014-1943.result \ +CVE-2014-1943.testfile \ +dsd64-dff.result \ +dsd64-dff.testfile \ +dsd64-dsf.result \ +dsd64-dsf.testfile \ +efi-signature-list-sha256.result \ +efi-signature-list-sha256.testfile \ +escapevel.result \ +escapevel.testfile \ +ext4.result \ +ext4.testfile \ +fit-map-data.result \ cl8m8ocofedso.result \ cl8m8ocofedso.testfile \ cmd1.result \ @@ -193,7 +218,7 @@ check-local: if [ -z "$$m" ]; then \ m=$$j; \ else \ - m=$$m:$$j; \ + m=$$m${PATH_SEPARATOR}$$j; \ fi \ fi \ done; \ diff --git a/tests/Makefile.in b/tests/Makefile.in index 4f583bf540a7..4c5ead125c2b 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -307,6 +307,31 @@ bcachefs.result \ bcachefs.testfile \ bcachefs2.result \ bcachefs2.testfile \ +bgcode.result \ +bgcode.testfile \ +cl8m8ocofedso.result \ +cl8m8ocofedso.testfile \ +cmd1.result \ +cmd1.testfile \ +cmd2.result \ +cmd2.testfile \ +cmd3.result \ +cmd3.testfile \ +cmd4.result \ +cmd4.testfile \ +CVE-2014-1943.result \ +CVE-2014-1943.testfile \ +dsd64-dff.result \ +dsd64-dff.testfile \ +dsd64-dsf.result \ +dsd64-dsf.testfile \ +efi-signature-list-sha256.result \ +efi-signature-list-sha256.testfile \ +escapevel.result \ +escapevel.testfile \ +ext4.result \ +ext4.testfile \ +fit-map-data.result \ cl8m8ocofedso.result \ cl8m8ocofedso.testfile \ cmd1.result \ @@ -801,7 +826,7 @@ check-local: if [ -z "$$m" ]; then \ m=$$j; \ else \ - m=$$m:$$j; \ + m=$$m${PATH_SEPARATOR}$$j; \ fi \ fi \ done; \ diff --git a/tests/arj.result b/tests/arj.result index 7198be22bb3b..654694586f0b 100644 --- a/tests/arj.result +++ b/tests/arj.result @@ -1 +1 @@ -ARJ archive data, v11, slash-switched, created 5 1980+48, original name: example_m0.arj, os: Unix +ARJ archive data, v11, slash-switched, created Jan 05 2028 07:31:08, modified Jan 05 2028 07:31:08, original name: example_m0.arj, os: Unix diff --git a/tests/bgcode.result b/tests/bgcode.result new file mode 100644 index 000000000000..87bfa0037b9c --- /dev/null +++ b/tests/bgcode.result @@ -0,0 +1 @@ +Binary G-code Version 1, CRC32 checksum
\ No newline at end of file diff --git a/tests/bgcode.testfile b/tests/bgcode.testfile Binary files differnew file mode 100644 index 000000000000..bc2a37f75499 --- /dev/null +++ b/tests/bgcode.testfile diff --git a/tests/efi-signature-list-sha256.result b/tests/efi-signature-list-sha256.result new file mode 100644 index 000000000000..04c597e372f5 --- /dev/null +++ b/tests/efi-signature-list-sha256.result @@ -0,0 +1 @@ +EFI Signature List, SHA256, total size: 76 bytes
\ No newline at end of file diff --git a/tests/efi-signature-list-sha256.testfile b/tests/efi-signature-list-sha256.testfile Binary files differnew file mode 100755 index 000000000000..9faf68ee8af0 --- /dev/null +++ b/tests/efi-signature-list-sha256.testfile |
