Imported Upstream version 5.36 upstream/5.36
authorHyunjee Kim <hj0426.kim@samsung.com>
Wed, 13 Mar 2019 05:02:15 +0000 (14:02 +0900)
committerHyunjee Kim <hj0426.kim@samsung.com>
Wed, 13 Mar 2019 05:02:15 +0000 (14:02 +0900)
50 files changed:
ChangeLog
README
configure.ac
doc/file.man
doc/magic.man
magic/Magdir/algol68
magic/Magdir/android
magic/Magdir/archive
magic/Magdir/audio
magic/Magdir/clojure [new file with mode: 0644]
magic/Magdir/elf
magic/Magdir/espressif [new file with mode: 0644]
magic/Magdir/filesystems
magic/Magdir/fonts
magic/Magdir/fsav
magic/Magdir/hp
magic/Magdir/images
magic/Magdir/java
magic/Magdir/map
magic/Magdir/mozilla
magic/Magdir/msdos
magic/Magdir/msooxml
magic/Magdir/netbsd
magic/Magdir/pgp
magic/Magdir/sniffer
magic/Magdir/tplink
magic/Magdir/unicode
magic/Magdir/virtual
magic/Magdir/windows
magic/Makefile.am
src/apprentice.c
src/ascmagic.c
src/buffer.c
src/cdf.c
src/cdf.h
src/cdf_time.c
src/compress.c
src/der.c
src/elfclass.h
src/encoding.c
src/file.c
src/file.h
src/funcs.c
src/is_json.c
src/is_tar.c
src/magic.c
src/print.c
src/readcdf.c
src/readelf.c
src/softmagic.c

index 249a910..3b7feb2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2019-02-20  10:16  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.36
+
+2019-02-19  15:30  Christos Zoulas <christos@zoulas.com>
+
+       * Fix cast to use cast macros
+       * Add UCS-32 builtin detection (PR/61) reported by tmc
+
+2019-02-18  18:24  Christos Zoulas <christos@zoulas.com>
+
+       * Fix stack read (PR/62) and write (PR/64) stack overflows
+         reported by spinpx 
+
 2018-10-18  19:32  Christos Zoulas <christos@zoulas.com>
 
        * release 5.35
diff --git a/README b/README
index 5ff359f..bb29a46 100644 (file)
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
-## README for file(1) Command ##
+## README for file(1) Command and the libmagic(3) library ##
 
-    @(#) $File: README,v 1.56 2018/09/09 20:33:28 christos Exp $
+    @(#) $File: README,v 1.57 2019/02/06 00:20:56 christos Exp $
 
 Mailing List: file@astron.com
 Mailing List archives: http://mailman.astron.com/pipermail/file/
index 17505e3..ec296aa 100644 (file)
@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_INIT([file],[5.35],[christos@astron.com])
+AC_INIT([file],[5.36],[christos@astron.com])
 AM_INIT_AUTOMAKE([subdir-objects foreign])
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
index 978a4b5..070a2e4 100644 (file)
@@ -1,5 +1,5 @@
-.\" $File: file.man,v 1.133 2018/10/01 18:51:39 christos Exp $
-.Dd October 1, 2018
+.\" $File: file.man,v 1.134 2019/02/18 18:59:25 christos Exp $
+.Dd February 18, 2019
 .Dt FILE __CSECTION__
 .Os
 .Sh NAME
@@ -171,6 +171,9 @@ Causes the file 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 describing the file type, the latter the creator.
+This option works properly only for file formats that have the
+apple-style output defined.
 .It Fl b , Fl Fl brief
 Do not prepend filenames to output lines (brief mode).
 .It Fl C , Fl Fl compile
index a1b3596..bc69604 100644 (file)
@@ -1,5 +1,5 @@
-.\" $File: magic.man,v 1.95 2018/10/01 19:59:53 christos Exp $
-.Dd October 1, 2018
+.\" $File: magic.man,v 1.96 2019/01/21 14:56:53 christos Exp $
+.Dd January 21, 2019
 .Dt MAGIC __FSECTION__
 .Os
 .\" install as magic.4 on USG, magic.5 on V7, Berkeley and Linux systems.
@@ -116,13 +116,13 @@ The following modifiers are supported:
 .It B
 A byte length (default).
 .It H
-A 4 byte big endian length.
+A 2 byte big endian length.
 .It h
 A 2 byte little endian length.
 .It L
 A 4 byte big endian length.
 .It l
-A 2 byte little endian length.
+A 4 byte little endian length.
 .It J
 The length includes itself in its count.
 .El
index 68583df..3675b84 100644 (file)
@@ -1,17 +1,17 @@
 
 #------------------------------------------------------------------------------
-# $File: algol68,v 1.1 2016/08/02 16:53:28 christos Exp $
+# $File: algol68,v 1.3 2018/10/19 01:04:21 christos Exp $
 # algol68:  file(1) magic for Algol 68 source
 #
 0      search/8192     (input,                 Algol 68 source text
 !:mime text/x-Algol68
-0      regex           \^PROC                  Algol 68 source text
+0      regex/1024      \^PROC                  Algol 68 source text
 !:mime text/x-Algol68
-0      regex           MODE[\t\ ]              Algol 68 source text
+0      regex/1024      \bMODE[\t\ ]            Algol 68 source text
 !:mime text/x-Algol68
-0      regex           REF[\t\ ]               Algol 68 source text
+0      regex/1024      \bREF[\t\ ]             Algol 68 source text
 !:mime text/x-Algol68
-0      regex           FLEX[\t\ ]\*\\[         Algol 68 source text
+0      regex/1024      \bFLEX[\t\ ]\*\\[       Algol 68 source text
 !:mime text/x-Algol68
 #0     regex           [\t\ ]OD                Algol 68 source text
 #!:mime        text/x-Algol68
index dca5c33..3ec41c5 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------
-# $File: android,v 1.10 2017/03/17 21:35:28 christos Exp $
+# $File: android,v 1.11 2018/12/04 14:24:01 christos Exp $
 # Various android related magic entries
 #------------------------------------------------------------
 
 
 # Android Backup archive
 # From: Ariel Shkedi
-# File extension: .ab
-# No mime-type defined
+# Update: Joerg Jenderek 
 # URL: https://github.com/android/platform_frameworks_base/blob/\
 # 0bacfd2ba68d21a68a3df345b830bc2a1e515b5a/services/java/com/\
 # android/server/BackupManagerService.java#L2367
+# Reference: http://sourceforge.net/projects/adbextractor/
+#            android-backup-extractor/perl/backupencrypt.pl 
+# Note:        only unix line feeds "\n" found
 # After the header comes a tar file
 # If compressed, the entire tar file is compressed with JAVA deflate
 #
 # Include the version number hardcoded with the magic string to avoid
 # false positives
-0      string/b        ANDROID\ BACKUP\n1\n    Android Backup
+0      string/b        ANDROID\ BACKUP\n       Android Backup
+# maybe look for some more characteristics like linefeed '\n' or version
+#>16   string          \n                      
+# No mime-type defined offically
+!:mime application/x-google-ab
+!:ext  ab
+# on 2nd line version (often 1, 2 on kitkat 4.4.3+, 4 on 7.1.2)
+>15    string          >\0                     \b, version %s
+# "1" on 3rd line means compressed
 >17    string          0\n                     \b, Not-Compressed
 >17    string          1\n                     \b, Compressed
+# The 4th line is encryption "none" or "AES-256"
 # any string as long as it's not the word none (which is matched below)
+>19    string          none\n                  \b, Not-Encrypted
+# look for backup content after line with encryption info
+#>>19  search/7        \n
+# data part after header for not encrypted Android Backup 
+#>>>&0 ubequad         x       \b, content 0x%16.16llx...
+# look for zlib compressed by ./compress after message with 1 space at end
+#>>>&0 indirect        x       \b; contains 
+# look for tar archive block by ./archive for package name manifest
+>>288  string          ustar   \b; contains
+>>>31  use     tar-file
+# look for zip/jar archive by ./archive ./zip after message with 1 space at end
+#>>2079        search/1025/s   PK\003\004      \b; contains 
+#>>>&0 indirect        x
+>19    string          !none                   
 >>19    regex/1l       \^([^n\n]|n[^o]|no[^n]|non[^e]|none.+).*        \b, Encrypted (%s)
->>19   string          none\n                  \b, Not-Encrypted
 # Commented out because they don't seem useful to print
 # (but they are part of the header - the tar file comes after them):
+# The 5th line is User Password Salt (128 Hex)
+# string length too high with standard src configuration
+#>>>&1         string  >\0     \b, PASSWORD salt: "%-128.128s"
 #>>>&1         regex/1l .*     \b, Password salt: %s
+# The 6th line is Master Key Checksum Salt (128 Hex)
 #>>>>&1                regex/1l .*     \b, Master salt: %s
+# The 7th line is Number of PBDKF2 Rounds (10000)
 #>>>>>&1       regex/1l .*     \b, PBKDF2 rounds: %s
+# The 8th line is User key Initialization Vector (IV) (32 Hex)
 #>>>>>>&1      regex/1l .*     \b, IV: %s
+#>>>>>>&1      regex/1l .*     \b, IV: %s
+# The 9th line is Master IV+Key+Checksum (192 Hex)
 #>>>>>>>&1     regex/1l .*     \b, Key: %s
+# look for new line separator char after line number 9
+#>>>0x204      ubyte   0x0a    NL found
+#>>>>&1                ubequad x       \b, Content magic %16.16llx
 
 # *.pit files by Joerg Jenderek
 # http://forum.xda-developers.com/showthread.php?p=9122369
index f8cf3a2..edbab37 100644 (file)
@@ -1,5 +1,5 @@
 #------------------------------------------------------------------------------
-# $File: archive,v 1.119 2018/04/24 23:19:45 christos Exp $
+# $File: archive,v 1.124 2019/02/20 15:07:44 christos Exp $
 # archive:  file(1) magic for archive formats (see also "msdos" for self-
 #           extracting compressed archives)
 #
 >19    string  B                       and an EB hash table
 >22    string  X                       -- out of date
 
-0      search/1        -h-             Software Tools format archive text
-
 #
 # BSD/SVR2-and-later portable archive formats.
 #
+# Update: Joerg Jenderek
+# URL:         http://fileformats.archiveteam.org/wiki/AR
+# Reference:   https://www.unix.com/man-page/opensolaris/3HEAD/ar.h/
+# Note:                Mach-O universal binary in ./cafebabe is dependent
+# TODO:                unify current ar archive, MIPS archive, Debian package
+#              distinguish BSD, SVR; 32, 64 bit; HP from other 32-bit SVR;
+#              *.ar packages from *.a libraries. handle empty archive
 0      string          =!<arch>\n              current ar archive
+# print first and possibly second ar_name[16] for debugging purpose
+#>8                    string  x       \b, 1st "%.16s"
+#>68                   string  x       \b, 2nd "%.16s"
 !:mime application/x-archive
+# a in most case for libraries; lib for Microsoft libraries; ar else cases
+!:ext  a/lib/ar
 >8     string          __.SYMDEF       random library
+# first member with long marked name __.SYMDEF SORTED implies BSD library
 >68    string          __.SYMDEF\ SORTED       random library
+# Reference: https://parisc.wiki.kernel.org/images-parisc/b/b2/Rad_11_0_32.pdf
+# "archive file" entry moved from ./hp
+# LST header system_id 0210h~PA-RISC 1.1,... identifies the target architecture
+# LST header a_magic 0619h~relocatable library
+>68    belong          0x020b0619      - PA-RISC1.0 relocatable library
+>68    belong          0x02100619      - PA-RISC1.1 relocatable library
+>68    belong          0x02110619      - PA-RISC1.2 relocatable library
+>68    belong          0x02140619      - PA-RISC2.0 relocatable library
+#EOF for common ar archives
 
 #
 # "Thin" archive, as can be produced by GNU ar.
 >68    belong          1               %d symbol entry
 >68    belong          >1              %d symbol entries
 
+0      search/1        -h-             Software Tools format archive text
+
 # ARC archiver, from Daniel Quinlan (quinlan@yggdrasil.com)
 #
 # The first byte is the magic (0x1a), byte 2 is the compression type for
 0      string          PK\005\006      Zip archive data (empty)
 !:mime application/zip
 !:ext zip/cbz
+!:strength +1
 0      string          PK\003\004
 
 # Specialised zip formats which start with a member named 'mimetype'
 >5     byte    x               \b.%d
 >6     belong  x               (%d bytes)
 
+# From:                Joerg Jenderek
+# URL:         https://help.foxitsoftware.com/kb/install-fzip-file.php
+# reference:   http://mark0.net/download/triddefs_xml.7z/
+#              defs/f/fzip.trid.xml
+# Note: unknown compression; No "PK" zip magic; normally in directory like
+#      "%APPDATA%\Foxit Software\Addon\Foxit Reader\Install"
+0      ubequad 0x2506781901010000      Foxit add-on/update
+!:mime application/x-fzip
+!:ext  fzip
+
 # From: "Robert Dale" <robdale@gmail.com>
 0      belong  123             dar archive,
 >4     belong  x               label "%.8x
 
 # LyNX archive
 56     string  USE\040LYNX\040TO\040DISSOLVE\040THIS\040FILE    LyNX archive
+
+# From: Joerg Jenderek
+# URL: http://www.acronis.com/
+# Reference: http://en.wikipedia.org/wiki/TIB_(file_format)
+# Note: only tested with True Image 2013 Build 5962 and 2019 Build 14110
+0      ubequad         0xce24b9a220000000      Acronis True Image backup
+!:mime application/x-acronis-tib
+!:ext  tib
+# 01000000
+#>20   ubelong         x                       \b, at 20 0x%x
+# 20000000
+#>28   ubelong         x                       \b, at 28 0x%x
+# strings like "Generic- SD/MMC 1.00" "Unknown Disk" "Msft Virtual Disk 1.0"
+# ???
+# strings like "\Device\0000011e" "\Device\0000015a"
+#>0    search/0x6852300/cs     \\Device\\
+#>>&-1 pstring         x                       \b, %s
+# "\Device\HarddiskVolume30" "\Device\HarddiskVolume39"
+#>>>&1 search/180/cs   \\Device\\
+#>>>>&-1       pstring         x                       \b, %s
+#>>>>>&0       search/29/cs    \0\0\xc8\0
+# disk label
+#>>>>>>&10     lestring16      x               \b, disk label %11.11s
+#>>>>>>&9      plestring16     x               \b, disk label "%11.11s"
+#>>>>>>&10     ubequad x                       %16.16llx
+
+
+# Gentoo XPAK binary package
+# by Michal Gorny <mgorny@gentoo.org>
+# https://gitweb.gentoo.org/proj/portage.git/tree/man/xpak.5
+-4     string  STOP
+>-16   string  XPAKSTOP        Gentoo binary package (XPAK)
index 82c04fd..e5aea03 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: audio,v 1.93 2018/10/18 23:35:42 christos Exp $
+# $File: audio,v 1.96 2019/01/16 19:35:21 christos Exp $
 # audio:  file(1) magic for sound formats (see also "iff")
 #
 # Jan Nicolai Langfeldt (janl@ifi.uio.no), Dan Quinlan (quinlan@yggdrasil.com),
 
 # adlib sound files
 # From: Alex Myczko <alex@aiei.ch>
+
+# https://github.com/rerrahkr/BambooTracker
+0      string          BambooTrackerMod        BambooTracker
+
 0      string          RAWADATA        RdosPlay RAW
 
 1068   string          RoR             AMUSIC Adlib Tracker
 # Summary:     Garmin Voice Processing Module (WAVE audios)
 # From:                Joerg Jenderek
 # URL:         http://www.garmin.com/
-# Reference:   http://turboccc.wikispaces.com/share/view/28622555
+# Reference:   http://www.poi-factory.com/node/19580
 # NOTE:                there exist 2 other Garmin VPM formats
 0              string  AUDIMG
 # skip text files starting with string "AUDIMG"
 # if you select a language like german on your garmin device
 # you can only select voice modules with corresponding language byte ID like 1
 >>18           ubyte           x       \b, language ID %d
+# structure for phrases/sentences?
+# number of voice sample in the 1st phrase?
+#>>19          uleshort                x       \b, 0x%x samples
+#>>>21         uleshort                >0      \b, at 0x%4.4x
+#>>>(21.s)     ubequad                 x       0x%llx
+# 2nd phrase?
+#>>23          uleshort                x       \b, 0x%x samples
+#>>>25         uleshort                >0      \b, at 0x%4.4x
+#>>>(25.s)     ubequad                 x       0x%llx
 # pointer to 1st audio WAV sample
 >>16           uleshort        >0
->>>(16.s)      ulelong         >0      \b, at offset 0x%x
+>>>(16.s)      ulelong         >0      \b, at 0x%x
 # WAV length
->>>>(16.s+4)   ulelong         >0      %d Bytes
+# 1 space char after "bytes" to get phrase "bytes RIFF"
+>>>>(16.s+4)   ulelong         >0      %u bytes 
 # look for magic
 >>>>>(&-8.l)   string          RIFF
 # determine type by ./riff
->>>>>>&-4      indirect        x       \b
+>>>>>>&-4      indirect        x
 # 2 - ~ 131 WAV samples following same way
+#
+# Summary:     encrypted Garmin Voice Processing Module
+# From:                Joerg Jenderek
+# URL:         https://www.garmin.com/us/products/ontheroad/voicestudio
+# NOTE:                Encrypted variant used in voices like DrNightmare, Elfred, Yeti.
+#              There exist 2 other Garmin VPM formats
+0      ubequad         0xa141190fecc8ced6      Garmin Voice Processing Module (encrypted)
+!:mime audio/x-vpm-garmin
+!:ext  vpm
 
 # From Martin Mueller Skarbiniks Pedersen
 0              string          GDM
diff --git a/magic/Magdir/clojure b/magic/Magdir/clojure
new file mode 100644 (file)
index 0000000..1f1cddf
--- /dev/null
@@ -0,0 +1,30 @@
+#------------------------------------------------------------------------------
+# file:  file(1) magic for Clojure
+# URL:  https://clojure.org/
+# From: Jason Felice <jason.m.felice@gmail.com>
+
+0      string/w        #!\ /usr/bin/clj        Clojure script text executable
+!:mime text/x-clojure
+0      string/w        #!\ /usr/local/bin/clj  Clojure script text executable
+!:mime text/x-clojure
+0      string/w        #!\ /usr/bin/clojure    Clojure script text executable
+!:mime text/x-clojure
+0      string/w        #!\ /usr/local/bin/clojure      Clojure script text executable
+!:mime text/x-clojure
+0      string/W        #!/usr/bin/env\ clj     Clojure script text executable
+!:mime text/x-clojure
+0      string/W        #!/usr/bin/env\ clojure Clojure script text executable
+!:mime text/x-clojure
+0      string/W        #!\ /usr/bin/env\ clj   Clojure script text executable
+!:mime text/x-clojure
+0      string/W        #!\ /usr/bin/env\ clojure       Clojure script text executable
+!:mime text/x-clojure
+
+0      regex   \^\\\(ns[[:space:]]+[a-z]       Clojure module source text
+!:mime text/x-clojure
+
+0      regex   \^\\\(ns[[:space:]]+\\\^\\{:    Clojure module source text
+!:mime text/x-clojure
+
+0      regex   \^\\\(defn-?[[:space:]] Clojure module source text
+!:mime text/x-clojure
index 133bd1f..85eda78 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: elf,v 1.74 2018/06/23 16:39:53 christos Exp $
+# $File: elf,v 1.77 2019/01/16 19:33:35 christos Exp $
 # elf:  file(1) magic for ELF executables
 #
 # We have to check the byte order flag to see what byte order all the
@@ -38,6 +38,8 @@
 >0     lelong&0x3              2               relaxed memory ordering,
 
 0      name            elf-pa-risc
+>2     leshort         0x0208          1.0
+>2     leshort         0x0210          1.1
 >2     leshort         0x0214          2.0
 >0     leshort         &0x0008         (LP64)
 
 >18    leshort         217             iCelero CoolEngine,
 >18    leshort         218             Nanoradio Optimized RISC,
 >18    leshort         243             UCB RISC-V,
+>18    leshort         247             eBPF,
+>18    leshort         251             NEC VE,
 >18    leshort         0x1057          AVR (unofficial),
 >18    leshort         0x1059          MSP430 (unofficial),
 >18    leshort         0x1223          Adapteva Epiphany (unofficial),
diff --git a/magic/Magdir/espressif b/magic/Magdir/espressif
new file mode 100644 (file)
index 0000000..72a0ec9
--- /dev/null
@@ -0,0 +1,57 @@
+
+# $File: espressif,v 1.1 2018/11/20 18:57:17 christos Exp $
+# configuration dump of Tasmota firmware for ESP8266 based devices by Espressif
+# URL: https://github.com/arendst/Sonoff-Tasmota/
+# Reference: https://codeload.github.com/arendst/Sonoff-Tasmota/zip/release-6.2/
+# Sonoff-Tasmota-release-6.2.zip/Sonoff-Tasmota-release-6.2/sonoff/settings.h 
+# From: Joerg Jenderek
+#
+# cfg_holder=4617=0x1209
+0              uleshort        4617
+# remainig settings normally 0x5A+offset XORed; free_1D5[20] empty since 5.12.0e
+>0x1D5         ubequad         0x2f30313233343536      configuration of Tasmota firmware (ESP8266)
+!:mime application/x-tasmota-dmp
+!:ext  dmp
+# version like 6.2.1.0 ~ 0x06020100 XORed to 0x63666262
+>>11           ubyte^0x65      x                       \b, version %u
+>>10           ubyte^0x64      x                       \b.%u
+>>9            ubyte^0x63      x                       \b.%u
+>>8            ubyte^0x62      x                       \b.%u
+#>8            ubelong         x                       (0x%x)
+# hostname[33] XORed
+>>0x165                ubyte^0x1BF     x                       \b, hostname %c
+>>0x166                ubyte^0x1C0     >037                    \b%c
+>>0x167                ubyte^0x1C1     >037                    \b%c
+>>0x168                ubyte^0x1C2     >037                    \b%c
+>>0x169                ubyte^0x1C3     >037                    \b%c
+>>0x16A                ubyte^0x1C4     >037                    \b%c
+>>0x16B                ubyte^0x1C5     >037                    \b%c
+>>0x16C                ubyte^0x1C6     >037                    \b%c
+>>0x16D                ubyte^0x1C7     >037                    \b%c
+>>0x16E                ubyte^0x1C8     >037                    \b%c
+>>0x16F                ubyte^0x1C9     >037                    \b%c
+>>0x170                ubyte^0x1CA     >037                    \b%c
+>>0x171                ubyte^0x1CB     >037                    \b%c
+>>0x172                ubyte^0x1CC     >037                    \b%c
+>>0x173                ubyte^0x1CD     >037                    \b%c
+>>0x174                ubyte^0x1CE     >037                    \b%c
+>>0x175                ubyte^0x1CF     >037                    \b%c
+>>0x176                ubyte^0x1D0     >037                    \b%c
+>>0x177                ubyte^0x1D1     >037                    \b%c
+>>0x178                ubyte^0x1D2     >037                    \b%c
+>>0x179                ubyte^0x1D3     >037                    \b%c
+>>0x17A                ubyte^0x1D4     >037                    \b%c
+>>0x17B                ubyte^0x1D5     >037                    \b%c
+>>0x17C                ubyte^0x1D6     >037                    \b%c
+>>0x17D                ubyte^0x1D7     >037                    \b%c
+>>0x17E                ubyte^0x1D8     >037                    \b%c
+>>0x17F                ubyte^0x1D9     >037                    \b%c
+>>0x180                ubyte^0x1DA     >037                    \b%c
+>>0x181                ubyte^0x1DB     >037                    \b%c
+>>0x182                ubyte^0x1DC     >037                    \b%c
+>>0x183                ubyte^0x1DD     >037                    \b%c
+>>0x184                ubyte^0x1DE     >037                    \b%c
+>>0x185                ubyte^0x1DF     >037                    \b%c
+#>>0x165               string          x                       (%.33s)
+
+
index eb41868..bf1775c 100644 (file)
@@ -1,5 +1,5 @@
 #------------------------------------------------------------------------------
-# $File: filesystems,v 1.124 2018/01/12 12:35:30 christos Exp $
+# $File: filesystems,v 1.125 2018/12/10 21:06:53 christos Exp $
 # filesystems:  file(1) magic for different filesystems
 #
 0      name    partid
 # Other fields are used to determine what type of CISO this is:
 # - 0x04 == 0x00200000: GameCube/Wii CISO (block_size)
 # - 0x10 == 0x00000800: PSP CISO (ISO-9660 sector size)
+# - 0x10 == 0x00004000: For >2GB files using maxcso...
+#                      https://github.com/unknownbrackets/maxcso/issues/26
 # - None of the above: Compact ISO.
 >4     lelong  !0
 >>4    lelong  !0x200000
->>>0x10        lelong  !0x800          Compressed ISO CD image
+>>>16  lelong  !0x800
+>>>>16 lelong  !0x4000         Compressed ISO CD image
 
 # cramfs filesystem - russell@coker.com.au
 0       lelong    0x28cd3d45      Linux Compressed ROM File System data, little endian
index cf9d588..9ca50cb 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: fonts,v 1.38 2017/11/14 15:48:36 christos Exp $
+# $File: fonts,v 1.39 2018/12/10 20:58:34 christos Exp $
 # fonts:  file(1) magic for font data
 #
 0      search/1        FONT            ASCII vfont text
 >>12   regex/4l        \^[A-Za-z][A-Za-z][A-Za-z/][A-Za-z2\ ]  
 #>>>0  ubelong x       \b, sfnt version 0x%x
 >>>0   ubelong !0x4f54544f     TrueType
-!:mime application/font-sfnt
-#!:mime        font/ttf
+!:mime font/sfnt
 !:apple        ????tfil
 # .ttf for TrueType font
 # EUDC.tte created by privat character editor %WINDIR%\system32\eudcedit.exe
 !:ext  ttf/tte
 # sfnt version 4F54544Fh~OTTO
 >>>0   ubelong =0x4f54544f     OpenType
-!:mime application/font-sfnt
-#!:mime        font/otf
+!:mime font/otf
 !:apple        ????OTTO
 !:ext  otf
 >>>0   ubelong x               Font data
 >4     ubyte           0               
 # sfnt version often 0x00010000 of 1st table is TrueType
 >>(12.L)       ubelong !0x4f54544f     TrueType
-#!:mime        font/ttf
+!:mime font/ttf
 !:apple        ????tfil
 !:ext  ttc
 # sfnt version 4F54544Fh~OTTO of 1st table is OpenType font 
 >>(12.L)       ubelong =0x4f54544f     OpenType
-#!:mime        font/otf
+!:mime font/otf
 !:apple        ????OTTO
 # no example found for otc
 !:ext  ttc/otc
 >>4    ubyte           x               font collection data
-!:mime application/font-sfnt
 #!:mime        font/collection
 # TCC version
 >>4    belong          0x00010000      \b, 1.0
index d260157..8661983 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: fsav,v 1.15 2018/07/16 12:30:41 christos Exp $
+# $File: fsav,v 1.18 2018/12/10 20:57:41 christos Exp $
 # fsav:  file(1) magic for datafellows fsav virus definition files
 # Anthon van der Neut (anthon@mnt.org)
 
 #>>>>>>13      ubyte   x               \b%02x bytes
 
 # Joerg Jenderek: joerg dot jenderek at web dot de
-# http://www.clamav.net/doc/latest/html/node45.html
-# .cvd files start with a 512 bytes colon separated header
+# clamav-0.100.2\docs\html\node60.html 
+# https://github.com/vrtadmin/clamav-faq/raw/master/manual/clamdoc.pdf
+# ClamAV virus database files start with a 512 bytes colon separated header
 # ClamAV-VDB:buildDate:version:signaturesNumbers:functionalityLevelRequired:MD5:Signature:builder:buildTime
-# + gzipped tarball files
-0      string          ClamAV-VDB:
->11    string          >\0             Clam AntiVirus database %-.23s
->>34   string          :
->>>35          string          !:      \b, version
->>>>35         string          x       \b %-.1s
->>>>>36                string          !:
->>>>>>36       string          x       \b%-.1s
->>>>>>>37      string          !:
->>>>>>>>37     string          x       \b%-.1s
->>>>>>>>>38    string          !:
->>>>>>>>>>38   string          x       \b%-.1s
->>>>>>>>>>>39  string          !:
->>>>>>>>>>>>39 string          x       \b%-.1s
->512   string          \037\213        \b, gzipped
->769   string          ustar\0         \b, tarred
+# + gzipped (optional) tarball files
+# output can often be verified by `sigtool --info=FILE`
+0      string          ClamAV-VDB:     Clam AntiVirus
+# padding spaces implies database
+>511   ubyte           =0x20           database
+!:mime application/x-clamav-database
+# empty build time
+>>10   string          =::             (unsigned)
+# sigtool(1) man page
+!:ext  cud
+# display some text to avoid error like:
+# Magdir/fsav, 78: Warning: Current entry does not yet have a description for adding a EXTENSION type
+# file: could not find any valid magic files! (No error)
+>>10   default         x               (with buildtime)
+#>>10  default         x
+# clamtmp is used for temporily database like update process
+# for pure tar database only cld extension found
+!:ext  cld/cvd/clamtmp/cud
+>511   default         x               file
+!:mime application/x-clamav
+!:ext  info
+>11    string          >\0
+# buildDate empty or like "22 Mar 2017 12-57 -0400"; verified by `sigtool -i FILE`
+>>11   regex           \^[^:]{0,23}    \b, %s
+# version like 25170
+>>>&1  regex           \^[^:]{1,6}     \b, version %s
+# signaturesNumbers like 4566249
+>>>>&1 regex           \^[^:]{1,10}    \b, %s signatures
+# functionalityLevelRequired like 60
+>>>>>&1        regex           \^[^:]{1,4}     \b, level %s
+# X for nothing or MD5
+#>>>>>>&1      regex   \^[^:]{1,32}    \b, MD5 "%s"
+>>>>>>&1       regex   \^[^:]{1,32}
+# X for nothing or digital signature starting like AIzk/LYbX
+#>>>>>>>&1     regex   \^[^:]{1,255}   \b, signature "%s"
+>>>>>>>&1      regex   \^[^:]{1,255}
+# builder like neo
+>>>>>>>>&1     regex   \^[^:]{1,32}    \b, builder %s
+# buildTime like 1506611558
+#>>>>>>>>>&1   regex   \^[^:]{1,10}    \b, %s
+>>>>>>>>>&1    regex   \^[^:]{1,10}    
+# padding with spaces
+#>>>>>>>>>>&1  ubequad x               \b, padding 0x%16.16llx
+>510   ubyte           =0x20
+# inspect real database content
+#>>512 ubeshort        x               \b, database MAGIC 0x%x
+# ./archive handle pure tar archives
+>>1012 quad            =0              \b, with
+>>>512 use             tar-file
+# not pure tar
+>>1012 quad            !0
+# one space at the end of text and then handles gziped archives by ./compress
+>>>512 string          \037\213        \b, with 
+>>>>512        indirect        x
 
 # Type: Grisoft AVG AntiVirus
 # From: David Newgas <david@newgas.net>
 
 0      string  X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR
 >33    string  -STANDARD-ANTIVIRUS-TEST-FILE!$H+H*     EICAR virus test files
+
+# From: Joerg Jenderek
+# URL: http://www.avira.com/
+# Note: found in directory %ProgramData%\Avira\Antivirus\INFECTED (Windows)
+# tested with version 15.0.43.23 at November 2019
+0      string          AntiVir\ Qua    Avira AntiVir quarantined
+!:mime application/x-avira-qua
+#!:mime        application/octet-stream
+!:ext  qua
+>156   string          SUSPICIOUS_FILE
+# file path of suspicious file
+>>220  lestring16      x               %s
+>156   string          !SUSPICIOUS_FILE
+# file path of virus file
+>>228  lestring16      x               %s
+# quarantined date
+>60    ldate           x               at %s
+# virus/danger name
+>156   string          !SUSPICIOUS_FILE
+>>156  string          x               \b, category "%s"
+
index df2c89b..d57169e 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: hp,v 1.23 2009/09/19 16:28:09 christos Exp $
+# $File: hp,v 1.25 2019/01/13 00:32:38 christos Exp $
 # hp:  file(1) magic for Hewlett Packard machines (see also "printer")
 #
 # XXX - somebody should figure out whether any byte order needs to be
 0      belong          0x020b010d      PA-RISC1.0 dynamic load library
 >96    belong          >0              - not stripped
 
-0      belong          0x213c6172      archive file
->68    belong          0x020b0619      - PA-RISC1.0 relocatable library
->68    belong          0x02100619      - PA-RISC1.1 relocatable library
->68    belong          0x02110619      - PA-RISC1.2 relocatable library
->68    belong          0x02140619      - PA-RISC2.0 relocatable library
-
 #### 500
 0      long            0x02080106      HP s500 relocatable executable
 >16    long            >0              - version %d
index 5cd9fab..099bd55 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: images,v 1.152 2018/10/01 19:10:56 christos Exp $
+# $File: images,v 1.154 2019/02/09 17:56:01 christos Exp $
 # images:  file(1) magic for image formats (see also "iff", and "c-lang" for
 # XPM bitmaps)
 #
 >0     regex/4         P1[\040\t\f\r\n]
 >>0    use             netpbm
 >>0    string          x       \b, bitmap
-!:strength + 45
+!:strength + 65
 !:mime image/x-portable-bitmap
 
 0      search/1        P2
 >0     regex/4         P2[\040\t\f\r\n]
 >>0    use             netpbm
 >>0    string          x       \b, greymap
-!:strength + 45
+!:strength + 65
 !:mime image/x-portable-greymap
 
 0      search/1        P3
 >0     regex/4         P3[\040\t\f\r\n]
 >>0    use             netpbm
 >>0    string          x       \b, pixmap
-!:strength + 45
+!:strength + 65
 !:mime image/x-portable-pixmap
 
 0      string          P4
 >0     regex/4         P4[\040\t\f\r\n]
 >>0    use             netpbm
 >>0    string          x       \b, rawbits, bitmap
-!:strength + 45
+!:strength + 65
 !:mime image/x-portable-bitmap
 
 0      string          P5
 >0     regex/4         P5[\040\t\f\r\n]
 >>0    use             netpbm
 >>0    string          x       \b, rawbits, greymap
-!:strength + 45
+!:strength + 65
 !:mime image/x-portable-greymap
 
 0      string          P6
 >0     regex/4         P6[\040\t\f\r\n]
 >>0    use             netpbm
 >>0    string          x       \b, rawbits, pixmap
-!:strength + 45
+!:strength + 65
 !:mime image/x-portable-pixmap
 
 0      string          P7              Netpbm PAM image file
 >>>>33         string  and
 >>>>>37                string  layers
 >>>>>>43       lelong  x       reMarkable tablet notebook lines, 1404 x 1872, %x page(s)
+
+# newer per-page files for the reMarkable
+0              string  reMarkable
+>11            string  .lines
+>>18           string  file,
+>>>24          string  version=
+>>>>32         byte    x       reMarkable tablet page (v%c), 1404 x 1872,
+>>>>>43                lelong  x       %d layer(s)
index 18e82ea..b9854e5 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------
-# $File: java,v 1.19 2018/08/11 11:32:15 christos Exp $
+# $File: java,v 1.21 2019/02/18 17:58:50 christos Exp $
 # Java ByteCode and Mach-O binaries (e.g., Mac OS X) use the
 # same magic number, 0xcafebabe, so they are both handled
 # in the entry called "cafebabe".
 >0x12  byte            0
 >>0x11 ubyte-0x31      <2      Java HPROF dump,
 >>>0x17        beqdate/1000    x       created %s
+
+# Java jmod module
+# See https://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java
+# Grr. 2 byte magic "JM", really? In 2019?
+0      belong          0x4a4d0100      Java jmod module version 1.0
+!:mime application/x-java-jmod
+
+# Java jlinked image
+# See https://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/java.base/share/native/libjimage/imageFile.hpp
+0      belong  0xcafedada      Java module image (big endian)
+>4     beshort >0x00   \b, version %d
+>6     beshort x       \b.%d
+!:mime application/x-java-image
+
+0      lelong  0xcafedada      Java module image (little endian)
+>6     leshort >0x00   \b, version %d
+>4     leshort x       \b.%d
+!:mime application/x-java-image
index 70d44f6..5a91d9f 100644 (file)
@@ -1,7 +1,7 @@
 
 
 #------------------------------------------------------------------------------
-# $File: map,v 1.3 2015/07/09 15:16:41 christos Exp $
+# $File: map,v 1.5 2018/12/28 00:22:34 christos Exp $
 # map:  file(1) magic for Map data
 #
 
 >>53   byte    8               \b (Elevations)
 >>53   byte    10              \b (Totals)
 
+# Summary: Garmin map
+# From:        Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/Garmin_.img
+# Reference: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/IMG_File_Format
+# sourceforge.net/projects/garmin-img/files/IMG%20File%20Format/1.0/imgformat-1.0.pdf
+# GRR: similar to MBR boot sector handled by ./filesystems
+0x1FE  leshort         =0xAA55
+# look for valid map signature
+>0x13  string          =IMG\0
+>>0    use             garmin-map
+0      name                            garmin-map
+>0     ubyte           x               Garmin
+!:mime application/x-garmin-map
+# If non-zero, every byte of the entire .img file is to be XORed with this value
+>0     ubyte           !0              \b, 0x%x XORed
+# goto block before FAT
+>(0x40.b*512)  ubyte   x
+# 1st fat name "DLLINFO TXT" only found for vpm
+>>&512                 string  =DLLINFO\ TXT   map (Voice Processing)
+# there exist 2 other Garmin VPM formats; see ./audio
+!:ext  vpm
+# Deutsch__Yannick_D4481-00_0210.vpm
+#>>>512        search/0x0116da60/s     RIFF    \b; with
+# determine type voice type by ./riff
+#>>>>&0        indirect        x       \b
+>>&512                 string  !DLLINFO\ TXT   map
+!:ext  img
+# 9 zeros
+>1     ubelong         !0              \b, zeroes 0x%x
+# Map's version major
+>8     ubyte           x               v%u
+# Map's version minor
+>9     ubyte           x               \b.%.2u
+# Map description[20], 0x20 padded
+>0x49  string          x               %.20s
+# Map name, continued (0x20 padded, \0 terminated)
+>0x65  string          >\              \b%.31s
+# Update year (+1900 for val >= 0x63, +2000 for val <= 0x62)
+>0xB   ubyte           x               \b, updated
+>>0xB  ubyte           >0x62
+>>>0xB ubyte-100       x               20%.2u
+>>0xB  ubyte           <0x63
+>>>0xB ubyte           x               20%.2u
+# Update month (0-11)
+>0xA   ubyte           x               \b-%.2u
+# All zeroes
+>0xc   uleshort        !0              \b, zeroes 0x%x
+# Mapsource flag, 1 - file created by Mapsource, 0 - Garmin map visible in Basecamp and Homeport 
+#>0xE  ubyte           !0              \b, Mapsource flag 0x%x
+>0xE   ubyte           1               \b, Mapsource
+# Checksum, sum of all bytes modulo 256 should be 0
+#>0xF  ubyte           x               \b, Checksum 0x%x
+# Signature: DSKIMG 0x00 or DSDIMG 0x00 for demo map 
+>0x10  string          !DSKIMG         \b, signature "%.7s"
+# Creation year
+>0x39  uleshort        x               \b, created %u
+# Creation month (0-11)
+>0x3b  ubyte           x               \b-%.2u
+# Creation day (1-31)
+>0x3c  ubyte           x               \b-%.2u
+# Creation hour (0-23)
+>0x3d  ubyte           x               %u
+# Creation minute (0-59)
+>0x3e  ubyte           x               \b:%.2u
+# Creation second (0-59)
+>0x3f  ubyte           x               \b:%.2u
+# Map file identifier like GARMIN\0
+>0x41  string          !GARMIN         \b, id "%.7s"
+# Block size exponent, E1; appears to always be 0x09; minimum block size 512 bytes
+>0x61  ubyte           !0x09           \b, E1=%u
+# Block size exponent, E2 ; file blocksize=2**(E1+E2)
+>>0x62 ubyte           x               \b, E2=%u
+>0x61  ubyte           =0x09           \b, blocksize
+>>0x62 ubyte           0               512
+>>0x62 ubyte           1               1024
+>>0x62 ubyte           2               2048
+>>0x62 ubyte           3               4096
+>>0x62 ubyte           4               8192
+>>0x62 ubyte           5               16384
+>>0x62 default         x
+>>>0x62        ubyte           x               E2=%u
+# MBR signature
+>0x1FE leshort         !0xAA55         \b, invalid MBR
+# 512 zeros
+>0x200         uquad           !0              \b, zeroes 0x%llx
+# First sub-file offset (absolute); sometimes NO/UNKNOWN sub file!
+>0x40C ulelong         >0              \b, at 0x%x
+# sub-file Header length
+#>>(0x40C.l)   uleshort        x       \b, header len 0x%x
+>>(0x40C.l)    uleshort        x       %u bytes
+# sub-file Type[10] like "GARMIN RGN" "GARMIN TRE", "GARMIN TYP", etc.
+>>(0x40C.l+2)  ubyte   >0x1F
+>>>(0x40C.l+2) ubyte   <0xFF
+>>>>(0x40C.l+2)        string  x               "%.10s"
+# 0x00 for most maps, 0x80 for locked maps (City Nav, City Select, etc.) 
+>>>>(0x40C.l+13)       ubyte   >0              \b, locked 0x%x
+# Block sequence numbers like 0000 0100 0200 ... FFFF
+# >0x420       ubequad         >0      \b, seq. 0x%16.16llx
+# >>0x428      ubequad         >0      \b%16.16llx
+# >>>0x430     ubequad >0      \b%16.16llx
+# >>>>0x438    ubequad >0      \b%16.16llx
+# >>>>>0x440   ubequad >0      \b%16.16llx
+# >>>>>>0x448  ubequad >0      \b%16.16llx
+# >>>>>>>0x450 ubequad >0      \b%16.16llx
+# >>>>>>>>0x458        ubequad >0      \b%16.16llx
+# >>>>>>>>>0x460       ubequad >0      \b%16.16llx
+# >>>>>>>>>>0x468      ubequad >0      \b%16.16llx
+# >>>>>>>>>>>0x470     ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>0x478    ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>>0x480   ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>>>0x488  ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>>>>0x490 ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>>>>>0x498        ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>>>>>>0x4A0       ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>>>>>>>0x4A8      ubequad >0      \b%16.16llx
+# look for end of FAT
+#>>0x420       search/512/s    \xff\xff        FAT END
+# Physical block number of FAT header
+#>0x40 ubyte           x               \b, FAT at phy. block %u
+>0x40  ubyte           x
+>>(0x40.b*512) ubyte   x
+# 1st FAT block
+>>>&511        use     garmin-fat
+# 2nd FAT block
+>>>&1023       use     garmin-fat
+# 3th FAT block
+>>>&1535       use     garmin-fat
+# 4th FAT block
+>>>&2047       use     garmin-fat
+# ... xth FAT block
+#
+# 314 zeros but not in vpm and also gmaptz.img
+>0x84  uquad           !0              \b, at 0x84 0x%llx
+# display FileAllocationTable block entry in garmin map
+0      name                            garmin-fat
+>0     ubyte           x               \b;
+# sub file part; 0x0003 seems to be garbage
+>0x10  uleshort        !0              next 0x%4.4x
+>0x10  uleshort        =0
+# fat flag 0~dummy block 1~true sub file
+>>0    ubyte           !1              flag %u 
+>>0    ubyte           =1
+# sub-file name like MAKEGMAP 12345678
+>>>0x1 string          x               %.8s
+# sub-file typ like RGN TRE MDR LBL
+>>>0x9 string          x               \b.%.3s
+# size of sub file
+>>>0xC ulelong         x               \b, %u bytes
+# 32-bit block sequence numbers
+#>>>0x20       ubequad         x               \b, seq. 0x%16.16llx
+
 # TOM TOM GPS watches ttbin files:
 # http://github.com/ryanbinns/ttwatch/tree/master/ttbin
 # From: Daniel Lenski
index 2b1b1dc..2aa8206 100644 (file)
@@ -1,13 +1,28 @@
 
 #------------------------------------------------------------------------------
-# $File: mozilla,v 1.8 2018/01/17 12:08:36 christos Exp $
+# $File: mozilla,v 1.9 2018/11/26 16:24:40 christos Exp $
 # mozilla:  file(1) magic for Mozilla XUL fastload files
 # (XUL.mfasl and XPC.mfasl)
 # URL: http://www.mozilla.org/
 # From:        Josh Triplett <josh@freedesktop.org>
 
 0      string  XPCOM\nMozFASL\r\n\x1A          Mozilla XUL fastload data
+# Probably the next magic line contains misspelled "mozLz40\0"
 0      string  mozLz4a                         Mozilla lz4 compressed bookmark data
+# From: Joerg Jenderek
+# URL: https://lz4.github.io/lz4/
+# Reference: https://github.com/avih/dejsonlz4/archive/master.zip/
+# dejsonlz4-master\src\dejsonlz4.c 
+# Note: mostly JSON compressed with a non-standard LZ4 header
+# can be unpacked by dejsonlz4 but not lz4 programm.
+0      string  mozLz40\0                       Mozilla lz4 compressed data
+!:mime application/x-lz4+json
+# mozlz4 extension seems to be used for search/store, while jsonlz4 for bookmarks
+!:ext  jsonlz4/mozlz4
+# decomp_size
+>8     ulelong x                               \b, originally %u bytes
+# lz4 data
+#>12   ubequad x                               \b, lz4 data 0x%16.16llx
 
 # From: Joerg Jenderek
 # URL: https://en.wikipedia.org/wiki/Firefox_4
index 5ccb1e9..ac93b36 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: msdos,v 1.125 2018/07/25 06:05:34 christos Exp $
+# $File: msdos,v 1.126 2018/11/11 01:58:19 christos Exp $
 # msdos:  file(1) magic for MS-DOS files
 #
 
 # skip remaining worksheets, because valid only for DIB image (40) or PNG image (\x89PNG)
 >>(18.l)       ulelong         x               MS Windows
 >>>0           ubelong         0x00000100      icon resource
-#!:mime                image/vnd.microsoft.icon
-!:mime         image/x-icon
+# https://www.iana.org/assignments/media-types/image/vnd.microsoft.icon
+!:mime         image/vnd.microsoft.icon
+#!:mime                image/x-icon
 !:ext          ico
 >>>>4          uleshort        x               - %d icon
 # plural s
 #>12           ulelong         x               \b, offset 0x%x
 # PNG header (\x89PNG)
 >(12.l)                ubelong         =0x89504e47
->>&-4          indirect        x       \b with
+# 1 space char after "with" to get phrase "with PNG image" by magic in ./images
+>>&-4          indirect        x       \b with 
 # DIB image
 >(12.l)                ubelong         !0x89504e47
 #>>&-4         use             dib-image
index b7388f2..9253862 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: msooxml,v 1.10 2018/10/08 18:25:25 christos Exp $
+# $File: msooxml,v 1.11 2019/01/18 15:39:18 christos Exp $
 # msooxml:  file(1) magic for Microsoft Office XML
 # From: Ralf Brown <ralf.brown@gmail.com>
 
@@ -25,7 +25,7 @@
 !:strength +10
 # make sure the first file is correct
 >0x1E          use             msooxml
->0x1E          regex           \\[Content_Types\\]\\.xml|_rels/\\.rels
+>0x1E          regex           \\[Content_Types\\]\\.xml|_rels/\\.rels|docProps
 # 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
index 4b1a5dd..77e64f0 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: netbsd,v 1.25 2017/09/28 02:37:47 christos Exp $
+# $File: netbsd,v 1.26 2019/01/01 03:11:23 christos Exp $
 # netbsd:  file(1) magic for NetBSD objects
 #
 # All new-style magic numbers are in network byte order.
 # in aout.
 #
 
-0      belong&0377777777       041400413       a.out NetBSD/i386 demand paged
+0      name    netbsd-detail
+>20    lelong  x               @%#x
+>4     lelong  >0              \b+T=%d
+>8     lelong  >0              \b+D=%d
+>12    lelong  >0              \b+B=%d
+>16    lelong  >0              \b+S=%d
+>24    lelong  >0              \b+TR=%d
+>28    lelong  >0              \b+TD=%d
+
+0      name                    netbsd-4096
 >0     byte                    &0x80
 >>20   lelong                  <4096           shared library
 >>20   lelong                  =4096           dynamically linked executable
 >>20   lelong                  >4096           dynamically linked executable
 >0     byte                    ^0x80           executable
 >16    lelong                  >0              not stripped
-0      belong&0377777777       041400410       a.out NetBSD/i386 pure
->0     byte                    &0x80           dynamically linked executable
+
+0      name                    netbsd-8192
+>0     byte                    &0x80
+>>20   lelong                  <8192           shared library
+>>20   lelong                  =8192           dynamically linked executable
+>>20   lelong                  >8192           dynamically linked executable
 >0     byte                    ^0x80           executable
 >16    lelong                  >0              not stripped
-0      belong&0377777777       041400407       a.out NetBSD/i386
+>0     use                     netbsd-detail
+
+0      name                    netbsd-normal
 >0     byte                    &0x80           dynamically linked executable
 >0     byte                    ^0x80
 >>0    byte                    &0x40           position independent
 >>20   lelong                  !0              executable
 >>20   lelong                  =0              object file
 >16    lelong                  >0              not stripped
-0      belong&0377777777       041400507       a.out NetBSD/i386 core
+>0     use                     netbsd-detail
+
+0      name                    netbsd-pure
+>0     byte                    &0x80           dynamically linked executable
+>0     byte                    ^0x80           executable
+>16    lelong                  >0              not stripped
+>0     use                     netbsd-detail
+
+0      name                    netbsd-core
 >12    string                  >\0             from '%s'
 >32    lelong                  !0              (signal %d)
 
+0      belong&0377777777       041400413       a.out NetBSD/i386 demand paged
+>0     use                     netbsd-4096
+
+0      belong&0377777777       041400410       a.out NetBSD/i386 pure
+>0     use                     netbsd-pure
+
+0      belong&0377777777       041400407       a.out NetBSD/i386
+>0     use                     netbsd-normal
+
+0      belong&0377777777       041400507       a.out NetBSD/i386 core
+>0     use                     netbsd-core
+
 0      belong&0377777777       041600413       a.out NetBSD/m68k demand paged
->0     byte                    &0x80
->>20   belong                  <8192           shared library
->>20   belong                  =8192           dynamically linked executable
->>20   belong                  >8192           dynamically linked executable
->0     byte                    ^0x80           executable
->16    belong                  >0              not stripped
+>0     use                     \^netbsd-8192
+
 0      belong&0377777777       041600410       a.out NetBSD/m68k pure
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80           executable
->16    belong                  >0              not stripped
+>0     use                     \^netbsd-pure
+
 0      belong&0377777777       041600407       a.out NetBSD/m68k
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80
->>0    byte                    &0x40           position independent
->>20   belong                  !0              executable
->>20   belong                  =0              object file
->16    belong                  >0              not stripped
+>0     use                     \^netbsd-normal
+
 0      belong&0377777777       041600507       a.out NetBSD/m68k core
->12    string                  >\0             from '%s'
->32    belong                  !0              (signal %d)
+>0     use                     \^netbsd-core
 
 0      belong&0377777777       042000413       a.out NetBSD/m68k4k demand paged
->0     byte                    &0x80
->>20   belong                  <4096           shared library
->>20   belong                  =4096           dynamically linked executable
->>20   belong                  >4096           dynamically linked executable
->0     byte                    ^0x80           executable
->16    belong                  >0              not stripped
+>0     use                     \^netbsd-4096
+
 0      belong&0377777777       042000410       a.out NetBSD/m68k4k pure
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80           executable
->16    belong                  >0              not stripped
+>0     use                     \^netbsd-pure
+
 0      belong&0377777777       042000407       a.out NetBSD/m68k4k
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80
->>0    byte                    &0x40           position independent
->>20   belong                  !0              executable
->>20   belong                  =0              object file
->16    belong                  >0              not stripped
+>0     use                     \^netbsd-normal
+
 0      belong&0377777777       042000507       a.out NetBSD/m68k4k core
->12    string                  >\0             from '%s'
->32    belong                  !0              (signal %d)
+>0     use                     \^netbsd-core
 
 0      belong&0377777777       042200413       a.out NetBSD/ns32532 demand paged
->0     byte                    &0x80
->>20   lelong                  <4096           shared library
->>20   lelong                  =4096           dynamically linked executable
->>20   lelong                  >4096           dynamically linked executable
->0     byte                    ^0x80           executable
->16    lelong                  >0              not stripped
+>0     use                     netbsd-4096
+
 0      belong&0377777777       042200410       a.out NetBSD/ns32532 pure
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80           executable
->16    lelong                  >0              not stripped
+>0     use                     netbsd-pure
+
 0      belong&0377777777       042200407       a.out NetBSD/ns32532
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80
->>0    byte                    &0x40           position independent
->>20   lelong                  !0              executable
->>20   lelong                  =0              object file
->16    lelong                  >0              not stripped
+>0     use                     netbsd-normal
+
 0      belong&0377777777       042200507       a.out NetBSD/ns32532 core
->12    string                  >\0             from '%s'
->32    lelong                  !0              (signal %d)
+>0     use                     netbsd-core
 
 0      belong&0377777777       045200507       a.out NetBSD/powerpc core
->12    string                  >\0             from '%s'
+>0     use                     netbsd-core
 
 0      belong&0377777777       042400413       a.out NetBSD/SPARC demand paged
->0     byte                    &0x80
->>20   belong                  <8192           shared library
->>20   belong                  =8192           dynamically linked executable
->>20   belong                  >8192           dynamically linked executable
->0     byte                    ^0x80           executable
->16    belong                  >0              not stripped
+>0     use                     \^netbsd-8192
+
 0      belong&0377777777       042400410       a.out NetBSD/SPARC pure
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80           executable
->16    belong                  >0              not stripped
+>0     use                     \^netbsd-pure
+
 0      belong&0377777777       042400407       a.out NetBSD/SPARC
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80
->>0    byte                    &0x40           position independent
->>20   belong                  !0              executable
->>20   belong                  =0              object file
->16    belong                  >0              not stripped
+>0     use                     \^netbsd-normal
+
 0      belong&0377777777       042400507       a.out NetBSD/SPARC core
->12    string                  >\0             from '%s'
->32    belong                  !0              (signal %d)
+>0     use                     \^netbsd-core
 
 0      belong&0377777777       042600413       a.out NetBSD/pmax demand paged
->0     byte                    &0x80
->>20   lelong                  <4096           shared library
->>20   lelong                  =4096           dynamically linked executable
->>20   lelong                  >4096           dynamically linked executable
->0     byte                    ^0x80           executable
->16    lelong                  >0              not stripped
+>0     use                     netbsd-4096
+
 0      belong&0377777777       042600410       a.out NetBSD/pmax pure
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80           executable
->16    lelong                  >0              not stripped
+>0     use                     \^netbsd-pure
+
 0      belong&0377777777       042600407       a.out NetBSD/pmax
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80
->>0    byte                    &0x40           position independent
->>20   lelong                  !0              executable
->>20   lelong                  =0              object file
->16    lelong                  >0              not stripped
+>0     use                     netbsd-normal
+
 0      belong&0377777777       042600507       a.out NetBSD/pmax core
->12    string                  >\0             from '%s'
->32    lelong                  !0              (signal %d)
+>0     use                     netbsd-core
 
 0      belong&0377777777       043000413       a.out NetBSD/vax 1k demand paged
->0     byte                    &0x80
->>20   lelong                  <4096           shared library
->>20   lelong                  =4096           dynamically linked executable
->>20   lelong                  >4096           dynamically linked executable
->0     byte                    ^0x80           executable
->16    lelong                  >0              not stripped
+>0     use                     netbsd-4096
+
 0      belong&0377777777       043000410       a.out NetBSD/vax 1k pure
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80           executable
->16    lelong                  >0              not stripped
+>0     use                     netbsd-pure
+
 0      belong&0377777777       043000407       a.out NetBSD/vax 1k
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80
->>0    byte                    &0x40           position independent
->>20   lelong                  !0              executable
->>20   lelong                  =0              object file
->16    lelong                  >0              not stripped
+>0     use                     netbsd-normal
+
 0      belong&0377777777       043000507       a.out NetBSD/vax 1k core
->12    string                  >\0             from '%s'
->32    lelong                  !0              (signal %d)
+>0     use                     netbsd-core
 
 0      belong&0377777777       045400413       a.out NetBSD/vax 4k demand paged
->0     byte                    &0x80
->>20   lelong                  <4096           shared library
->>20   lelong                  =4096           dynamically linked executable
->>20   lelong                  >4096           dynamically linked executable
->0     byte                    ^0x80           executable
->16    lelong                  >0              not stripped
+>0     use                     netbsd-4096
+
 0      belong&0377777777       045400410       a.out NetBSD/vax 4k pure
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80           executable
->16    lelong                  >0              not stripped
+>0     use                     netbsd-pure
+
 0      belong&0377777777       045400407       a.out NetBSD/vax 4k
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80
->>0    byte                    &0x40           position independent
->>20   lelong                  !0              executable
->>20   lelong                  =0              object file
->16    lelong                  >0              not stripped
+>0     use                     netbsd-normal
+
 0      belong&0377777777       045400507       a.out NetBSD/vax 4k core
->12    string                  >\0             from '%s'
->32    lelong                  !0              (signal %d)
+>0     use                     netbsd-core
 
 # NetBSD/alpha does not support (and has never supported) a.out objects,
 # so no rules are provided for them.  NetBSD/alpha ELF objects are
 >32    lelong                  !0              (signal %d)
 
 0      belong&0377777777       043400413       a.out NetBSD/mips demand paged
->0     byte                    &0x80
->>20   belong                  <8192           shared library
->>20   belong                  =8192           dynamically linked executable
->>20   belong                  >8192           dynamically linked executable
->0     byte                    ^0x80           executable
+>0     use                     \^netbsd-8192
+
 >16    belong                  >0              not stripped
 0      belong&0377777777       043400410       a.out NetBSD/mips pure
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80           executable
->16    belong                  >0              not stripped
+>0     use                     netbsd-pure
+
 0      belong&0377777777       043400407       a.out NetBSD/mips
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80
->>0    byte                    &0x40           position independent
->>20   belong                  !0              executable
->>20   belong                  =0              object file
->16    belong                  >0              not stripped
+>0     use                     netbsd-normal
+
 0      belong&0377777777       043400507       a.out NetBSD/mips core
->12    string                  >\0             from '%s'
->32    belong                  !0              (signal %d)
+>0     use                     netbsd-core
 
 0      belong&0377777777       043600413       a.out NetBSD/arm32 demand paged
->0     byte                    &0x80
->>20   lelong                  <4096           shared library
->>20   lelong                  =4096           dynamically linked executable
->>20   lelong                  >4096           dynamically linked executable
->0     byte                    ^0x80           executable
->16    lelong                  >0              not stripped
+>0     use                     netbsd-4096
+
 0      belong&0377777777       043600410       a.out NetBSD/arm32 pure
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80           executable
->16    lelong                  >0              not stripped
+>0     use                     netbsd-pure
+
 0      belong&0377777777       043600407       a.out NetBSD/arm32
->0     byte                    &0x80           dynamically linked executable
->0     byte                    ^0x80
->>0    byte                    &0x40           position independent
->>20   lelong                  !0              executable
->>20   lelong                  =0              object file
->16    lelong                  >0              not stripped
+>0     use                     netbsd-normal
+
 # NetBSD/arm26 has always used ELF objects, but it shares a core file
 # format with NetBSD/arm32.
 0      belong&0377777777       043600507       a.out NetBSD/arm core
->12    string                  >\0             from '%s'
->32    lelong                  !0              (signal %d)
+>0     use                     netbsd-core
 
 # Kernel core dump format
 0      belong&0x0000ffff 0x00008fca    NetBSD kernel core file
index ecdcf83..d6e18d9 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: pgp,v 1.15 2018/02/24 16:11:23 christos Exp $
+# $File: pgp,v 1.16 2018/10/28 22:37:02 christos Exp $
 # pgp:  file(1) magic for Pretty Good Privacy
 # see http://lists.gnupg.org/pipermail/gnupg-devel/1999-September/016052.html
 #
 
 # PGP RSA (e=65537) secret (sub-)key header
 
-0      byte    0x95                    PGP     Secret Key -
+0      byte    0x95                    PGP Secret Key -
 >1     use     pgpkey
-0      byte    0x97                    PGP     Secret Sub-key -
+0      byte    0x97                    PGP Secret Sub-key -
 >1     use     pgpkey
 0      byte    0x9d
 # Update: Joerg Jenderek
index 56aca12..8cee245 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: sniffer,v 1.20 2018/10/18 16:49:19 christos Exp $
+# $File: sniffer,v 1.21 2019/02/09 17:52:18 christos Exp $
 # sniffer:  file(1) magic for packet capture files
 #
 # From: guy@alum.mit.edu (Guy Harris)
 >0     use     \^pcap-be
 
 #
-# "pcap-ng" capture files.
-# http://www.winpcap.org/ntar/draft/PCAP-DumpFileFormat.html
-# Pcap-ng files can contain multiple sections. Printing the endianness,
+# "pcapng" capture files.
+# https://github.com/pcapng/pcapng
+# Pcapng files can contain multiple sections. Printing the endianness,
 # snaplen, or other information from the first SHB may be misleading.
 #
 0      ubelong         0x0a0d0d0a
->8     ubelong         0x1a2b3c4d      pcap-ng capture file
+>8     ubelong         0x1a2b3c4d      pcapng capture file
 >>12   beshort         x               - version %d
 >>14   beshort         x               \b.%d
 0      ulelong         0x0a0d0d0a
->8     ulelong         0x1a2b3c4d      pcap-ng capture file
+>8     ulelong         0x1a2b3c4d      pcapng capture file
 >>12   leshort         x               - version %d
 >>14   leshort         x               \b.%d
 
index a3764e2..8044ef4 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: tplink,v 1.2 2017/12/14 05:52:56 christos Exp $
+# $File: tplink,v 1.3 2018/12/21 17:37:33 christos Exp $
 # tplink: File magic for openwrt firmware files
 
 # URL: https://wiki.openwrt.org/doc/techref/header
@@ -11,7 +11,9 @@
 >0             ulelong         !0
 # test for header padding with nulls
 >>0x100                long            0
->>>0           use             firmware-tplink
+# skip Norton Commander Cleanup Utility NCCLEAN.INI by looking for valid vendor
+>>>4           ubelong         >0x1F000000
+>>>>0          use             firmware-tplink
 
 0              name            firmware-tplink
 >0             ubyte           x               firmware
 # look for kernel type (gzip compressed vmlinux.bin by ./compress)
 >(0x80.L)      indirect        x
 # root file system data offset
+# WRONG in 5.35 with above indirect expression
 >0x88          ubelong         x               \b, at 0x%x
 # rootfs data length and 1 space
 >0x8C          ubelong         x               %u bytes 
 # in 5.32 only true for offset ~< FILE_BYTES_MAX=9 MB defined in ../../src/file.h 
 >(0x88.L)      indirect        x
+# 'qshs' for wr940nv1_en_3_13_7_up(111228).bin
 #>(0x88.L)     string          x               \b, file system '%.4s'
 #>(0x88.L)     ubequad         x               \b, file system 0x%llx
 # bootloader data offset
index e2edb90..7ca61ba 100644 (file)
@@ -1,10 +1,9 @@
 
 #------------------------------------------------------------------------------
-# $File: unicode,v 1.5 2009/09/19 16:28:13 christos Exp $
+# $File: unicode,v 1.7 2019/02/19 20:34:42 christos Exp $
 # Unicode:  BOM prefixed text files - Adrian Havill <havill@turbolinux.co.jp>
-# GRR: These types should be recognised in file_ascmagic so these
-# encodings can be treated by text patterns.
-# Missing types are already dealt with internally.
+# These types are recognised in file_ascmagic so these encodings can be
+# treated by text patterns.  Missing types are already dealt with internally.
 #
 0      string  +/v8                    Unicode text, UTF-7
 0      string  +/v9                    Unicode text, UTF-7
index 1f8fa63..81d6035 100644 (file)
 
 #------------------------------------------------------------------------------
-# $File: virtual,v 1.5 2014/04/30 21:41:02 christos Exp $
+# $File: virtual,v 1.9 2018/12/15 18:56:07 christos Exp $
 # From: James Nobis <quel@quelrod.net>
 # Microsoft hard disk images for:
 # Virtual Server
 # Virtual PC
-# http://technet.microsoft.com/en-us/virtualserver/bb676673.aspx
-# .vhd
+# VirtualBox
+# URL: http://fileformats.archiveteam.org/wiki/VHD_(Virtual_Hard_Disk)
+# Reference: https://download.microsoft.com/download/f/f/e/ffef50a5-07dd-4cf8-aaa3-442c0673a029/
+# Virtual%20Hard%20Disk%20Format%20Spec_10_18_06.doc
 0      string  conectix        Microsoft Disk Image, Virtual Server or Virtual PC
+# alternative shorter names
+#0     string  conectix        Microsoft Virtual Hard Disk image
+#0     string  conectix        Microsoft Virtual HD image
+!:mime application/x-virtualbox-vhd
+!:ext   vhd
+# Features is a bit field used to indicate specific feature support
+#>8    ubelong         !0x00000002     \b, Features 0x%x
+# Reserved. This bit must always be set to 1.
+#>8    ubelong         &0x00000002     \b, Reserved 0x%x
+# File Format Version for the current specification 0x00010000
+#>12   ubelong         !0x00010000     \b, Version 0x%8.8x
+# Data Offset only found 0x200
+#>16   ubequad         !0x200          \b, Data Offset 0x%llx
+#>16   ubequad         x               \b, at 0x%llx
+# Dynamic Disk Header cookie like cxsparse
+#>(16.Q)       string          x               "%-.8s"
+# This field contains a Unicode string (UTF-16) of the parent hard disk filename
+#>(16.Q+64)    ubequad x               \b, parent name 0x%llx
+# Creator Application
+# vpc~Microsoft Virtual PC, vs~Microsoft Virtual Server, vbox~VirtualBox, d2v~disk2vhd
+>28    string          x               \b, Creator %-4.4s
+# Creator Version: 0x00010000~Virtual Server 2004, 0x00050000~Virtual PC 2004
+# holds the major/minor version of the application that created the image
+>32    ubeshort        x               %x
+>34    ubeshort        x               \b.%x
+#>32   ubelong         x               \b, Version 0x%8.8x
+# Creator Host OS: 0x5769326B~Windows (Wi2k), 0x4D616320~Macintosh (Mac)
+>36    ubelong         x               (
+>>36   ubelong         0x5769326B      \bW2k
+>>36   ubelong         0x4D616320      \bMac
+>>36   default         x               \b0x
+>>>36  ubelong         x               \b%8.8x
+# creation Time in seconds since 1 Jan 2000 UTC~946684800 sec. since Unix Epoch
+>24    bedate+946684800        x       \b) %s
+# Original Size
+#>40   ubequad         x               \b, o.-Size 0x%llx
+# Current Size is same as original size, but change when disk is expanded
+#>48   ubequad         x               \b, Size 0x%llx
+>48    ubequad         x               \b, %llu bytes
+# Disk Geometry: cylinder, heads, and sectors/track for hard disk
+#>56   ubeshort        x               \b, Cylinder 0x%x
+>56    ubeshort        x               \b, CHS %u
+# Heads
+#>58   ubyte           x               \b, Heads 0x%x
+>58    ubyte           x               \b/%u
+# Sectors per track
+#>59   ubyte           x               \b, Sectors 0x%x
+>59    ubyte           x               \b/%u
+# Disk Type: 3~Dynamic hard disk
+>60    ubelong         !0x3            \b, type 0x%x
+# Checksum
+#>64   ubelong         x               \b, cksum 0x%x
+# universally unique identifier (UUID) to associate a parent with its differencing image
+#>68   ubequad         x               \b, id 0x%16.16llx
+#>76   ubequad         x               \b-%16.16llx
+# Saved State: 1~Saved State
+>84    ubyte           !0              \b, State 0x%x
+# Reserved 427 bytes with nils
+#>85   ubequad !0                      \b, Reserved 0x%16.16llx
 
+# From: Joerg Jenderek
+# URL: https://msdn.microsoft.com/en-us/library/mt740058.aspx
+# Reference: https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/
+# MS-VHDX/[MS-VHDX].pdf
+# Note: extends the VHD format with new capabilities, such as a 16TB maximum size
+# TODO:        find and display values like virtual size, disk size, cluster_size, etc
+#      display id in GUID format
+#
+# VHDX_FILE_IDENTIFIER signature 0x656C696678646876
+0      string                  vhdxfile
+# VHDX_HEADER signature. 1 header is stored at offset 64KB and the other at 128KB
+>0x10000       string          head            Microsoft Disk Image eXtended
+#>0x20000      string                  head    \b, 2nd header
+#!:mime        application/x-virtualbox-vhdx
+!:ext  vhdx
+# Creator[256] like "QEMU v3.0.0", "Microsoft Windows 6.3.9600.18512"
+>>8            lestring16              x       \b, by %.256s
+# The Checksum field is a CRC-32C hash over the entire 4 KB structure
+#>>0x10004     ulelong                 x       \b, CRC 0x%x
+# SequenceNumber
+>>0x10008      ulequad                 x       \b, sequence 0x%llx
+# FileWriteGuid
+#>>0x10010     ubequad                 x       \b, file id 0x%llx
+#>>>0x10018    ubequad                 x       \b-%llx
+# DataWriteGuid
+#>>0x10020     ubequad                 x       \b, data id 0x%llx
+#>>>0x10028    ubequad                 x       \b-%llx
+# LogGuid. If this field is zero, then the log is empty or has no valid entries 
+>>0x10030      ubequad                 >0      \b, log id 0x%llx
+>>>0x10038     ubequad                 x       \b-%llx
+# LogVersion. If not 0 there is a log to replay
+>>0x10040      uleshort                >0      \b, LogVersion 0x%x
+# Version. This field must be set to 1
+>>0x10042      uleshort                !1      \b, Version 0x%x
+# LogLength must be multiples of 1 MB
+>>0x10044      ulelong/1048576         >1      \b, LogLength %u MB
+# LogOffset (normally 0x100000 when log direct after header); multiples of 1 MB
+>>0x10048      ulequad                 !0x100000 \b, LogOffset 0x%llx
+# Log Entry Signature must be 0x65676F6C~loge
+>>(0x10048.q)  ulelong                 !0x65676F6C \b, NO Log Signature
+>>(0x10048.q)  ulelong                 =0x65676F6C     \b; LOG
+# Log Entry Checksum
+#>>>(0x10048.q+4)      ulelong         x       \b, Log CRC 0x%x
+# Log Entry Length must be a multiple of 4 KB
+>>>(0x10048.q+8)       ulelong/1024    >4      \b, EntryLength %u KB
+# Log Entry Tail must be a multiple of 4 KB
+#>>>(0x10048.q+12)     ulelong         x       \b, Tail 0x%x
+# Log Entry SequenceNumber
+#>>>(0x10048.q+16)     ulequad         x       \b, # 0x%llx
+# Log Entry DescriptorCount may be zero. only 4 bytes in other docs instead 8
+#>>>(0x10048.q+24)     ulelong         x       \b, DescriptorCount 0x%llx
+# Log Entry Reserved must be set to 0
+>>>(0x10048.q+28)      ulelong         !0      \b, Reserved 0x%x
+# Log Entry LogGuid
+#>>>(0x10048.q+32)     ubequad         x       \b, Log id 0x%llx
+#>>>(0x10048.q+40)     ubequad         x       \b-%llx
+# Log Entry FlushedFileOffset should VHDX size when entry is written.
+#>>>(0x10048.q+48)     ulequad         x       \b, FlushedFileOffset %llu
+# Log Entry LastFileOffset
+#>>>(0x10048.q+56)     ulequad         x       \b, LastFileOffset %llu
+# filling
+#>>>(0x10048.q+64)     ulequad         >0      \b, filling %llx
+# Reserved[4016]
+#>>0x10050     ulequad                 >0      \b, Reserved 0x%llx
+# VHDX_REGION_TABLE_HEADER Signature 0x69676572~regi at offset 192 KB and 256 KB
+>0x30000       ulelong                 !0x69676572 \b, 1st region INVALID
+>0x30000       ulelong                 =0x69676572 \b; region
+# region Checksum. CRC-32C hash over the entire 64-KB table
+#>>0x30004     ulelong                 x       \b, CRC 0x%x
+# The EntryCount specifies number of valid entries; Found 2; This must be =< 2047. 
+>>0x30008      ulelong                 x       \b, %u entries
+# reserved must be zero
+#>>0x3000C     ulelong                 !0      \b, RESERVED 0x%x
+# Region Table Entry starts with identifier for the object. often BAT id
+>>0x30010      use                     vhdx-id
+# FileOffset
+>>0x30020      ulequad         x               \b, at 0x%llx
+# Length. Specifies the length of the object within the file
+#>>0x30028     ulelong         x               \b, Length 0x%x
+# 1 means region entry is required. if region not recognized, then REFUSE to load VHDX
+>>0x3002C      ulelong         x               \b, Required %u
+# 2nd region entry often metadata id
+>>0x30030      use                     vhdx-id
+# 2nd entry FileOffset
+>>0x30040      ulequad         x               \b, at 0x%llx
+# 1 means region entry is required. if region not recognized, then REFUSE to load VHDX
+>>0x3004C      ulelong         x               \b, Required %u
+# 2nd region
+>>0x40000      ulelong         !0x69676572     \b, 2nd region INVALID
+# check in vhdx images for known id and show names instead hexadecimal
+0      name            vhdx-id
+# http://www.windowstricks.in/online-windows-guid-converter
+# 2DC27766-F623-4200-9D64-115E9BFD4A08         BAT GUID
+# 6677C22D23F600429D64115E9BFD4A08             BAT ID
+>0     ubequad         =0x6677C22D23F60042
+>>8    ubequad         =0x9D64115E9BFD4A08     \b, id BAT
+# no BAT id
+>>8    default         x
+>>>0   use             vhdx-id-hex
+# 8B7CA206-4790-4B9A-B8FE-575F050F886E         Metadata region GUID
+# 06A27C8B90479A4BB8FE575F050F886E             Metadata region ID
+>0     ubequad         =0x06A27C8B90479A4B
+>>8    ubequad         =0xB8FE575F050F886E     \b, id Metadata
+# no Metadata id
+>>8    default         x
+>>>0   use             vhdx-id-hex
+# 2FA54224-CD1B-4876-B211-5DBED83BF4B8         Virtual Disk Size GUID
+# 2442A52F1BCD7648B2115DBED83BF4B8             Virtual Disk Size ID
+# value "virtual size" can be verified by command `qemu-img info `
+>0     ubequad         =0x2442A52F1BCD7648
+>>8    ubequad         =0xB2115DBED83BF4B8     \b, id vsize
+# no Virtual Disk Size ID
+>>8    default         x
+>>>0   use             vhdx-id-hex
+# other ids
+>0     default         x
+>>0    use             vhdx-id-hex
+# in vhdx images show id as hexadecimal
+0      name            vhdx-id-hex
+>0     ubequad         x                       \b, ID 0x%16.16llx
+>8     ubequad         x                       \b-%16.16llx
+#
 # libvirt
 # From: Philipp Hahn <hahn@univention.de>
 0      string  LibvirtQemudSave        Libvirt QEMU Suspend Image
 # Updated by Adam Buchbinder (adam.buchbinder@gmail.com)
 # Made by reading sources, reading documentation, and doing trial and error
 # on existing QCOW files
-0      string/b        QFI\xFB QEMU QCOW Image
+0      string/b        QFI\xFB
 
 # Uncomment the following line to display Magic (only used for debugging
 # this magic number)
 
 # There are currently 2 Versions: "1" and "2".
 # http://www.gnome.org/~markmc/qcow-image-format-version-1.html
->4     belong  1       (v1)
+>4     belong          !1      QEMU QCOW2 Image
+>4     belong          1       QEMU QCOW Image (v1)
 
 # Using the existence of the Backing File Offset to determine whether
 # to read Backing File Information
index f8a9c83..f36fc9b 100644 (file)
@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: windows,v 1.22 2018/02/16 15:44:00 christos Exp $
+# $File: windows,v 1.23 2019/01/11 21:00:26 christos Exp $
 # windows:  file(1) magic for Microsoft Windows
 #
 # This file is mainly reserved for files where programs
 >0x78  lelong          &1              \b, DIRTY
 >0x78  lelong          &2              \b, FULL
 
+# Summary:     Windows Error Report text files
+# URL:         https://en.wikipedia.org/wiki/Windows_Error_Reporting
+# Reference:   https://www.nirsoft.net/utils/app_crash_view.html
+# Created by:  Joerg Jenderek
+# Note:                in directories  %ProgramData%\Microsoft\Windows\WER\{ReportArchive,ReportQueue}
+#                              %LOCALAPPDATA%\Microsoft\Windows\WER\{ReportArchive,ReportQueue}
+0      lestring16      Version=        
+>22    lestring16      EventType       Windows Error Report
+!:mime text/plain
+# Report.wer
+!:ext  wer
 
 # Summary: Windows 3.1 group files
 # Extension: .grp
index aa118d2..fbc6c95 100644 (file)
@@ -1,5 +1,5 @@
 #
-# $File: Makefile.am,v 1.138 2018/10/16 12:07:08 christos Exp $
+# $File: Makefile.am,v 1.140 2019/01/16 19:31:06 christos Exp $
 #
 MAGIC_FRAGMENT_BASE = Magdir
 MAGIC_DIR = $(top_srcdir)/magic
@@ -58,6 +58,7 @@ $(MAGIC_FRAGMENT_DIR)/cisco \
 $(MAGIC_FRAGMENT_DIR)/citrus \
 $(MAGIC_FRAGMENT_DIR)/clarion \
 $(MAGIC_FRAGMENT_DIR)/claris \
+$(MAGIC_FRAGMENT_DIR)/clojure \
 $(MAGIC_FRAGMENT_DIR)/clipper \
 $(MAGIC_FRAGMENT_DIR)/coff \
 $(MAGIC_FRAGMENT_DIR)/commands \
@@ -89,6 +90,7 @@ $(MAGIC_FRAGMENT_DIR)/elf \
 $(MAGIC_FRAGMENT_DIR)/encore \
 $(MAGIC_FRAGMENT_DIR)/epoc \
 $(MAGIC_FRAGMENT_DIR)/erlang \
+$(MAGIC_FRAGMENT_DIR)/espressif \
 $(MAGIC_FRAGMENT_DIR)/esri \
 $(MAGIC_FRAGMENT_DIR)/fcs \
 $(MAGIC_FRAGMENT_DIR)/filesystems \
index 2a8d4dc..eca3ae0 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.281 2018/10/10 17:41:10 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.283 2019/02/20 02:35:27 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -52,10 +52,10 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.281 2018/10/10 17:41:10 christos Exp $")
 #include <limits.h>
 
 
-#define        EATAB {while (isascii((unsigned char) *l) && \
-                     isspace((unsigned char) *l))  ++l;}
-#define LOWCASE(l) (isupper((unsigned char) (l)) ? \
-                       tolower((unsigned char) (l)) : (l))
+#define        EATAB {while (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))
 /*
  * Work around a bug in headers on Digital Unix.
  * At least confirmed for: OSF1 V4.0 878
@@ -74,8 +74,8 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.281 2018/10/10 17:41:10 christos Exp $")
 #define MAP_FILE 0
 #endif
 
-#define ALLOC_CHUNK    (size_t)10
-#define ALLOC_INCR     (size_t)200
+#define ALLOC_CHUNK    CAST(size_t, 10)
+#define ALLOC_INCR     CAST(size_t, 200)
 
 #define MAP_TYPE_USER  0
 #define MAP_TYPE_MALLOC        1
@@ -293,9 +293,9 @@ get_type(const struct type_tbl_s *tbl, const char *l, const char **t)
 
 private off_t
 maxoff_t(void) {
-       if (sizeof(off_t) == sizeof(int))
+       if (/*CONSTCOND*/sizeof(off_t) == sizeof(int))
                return CAST(off_t, INT_MAX);
-       if (sizeof(off_t) == sizeof(long))
+       if (/*CONSTCOND*/sizeof(off_t) == sizeof(long))
                return CAST(off_t, LONG_MAX);
        return 0x7fffffff;
 }
@@ -305,7 +305,7 @@ get_standard_integer_type(const char *l, const char **t)
 {
        int type;
 
-       if (isalpha((unsigned char)l[1])) {
+       if (isalpha(CAST(unsigned char, l[1]))) {
                switch (l[1]) {
                case 'C':
                        /* "dC" and "uC" */
@@ -340,7 +340,7 @@ get_standard_integer_type(const char *l, const char **t)
                        return FILE_INVALID;
                }
                l += 2;
-       } else if (isdigit((unsigned char)l[1])) {
+       } else if (isdigit(CAST(unsigned char, l[1]))) {
                /*
                 * "d{num}" and "u{num}"; we only support {num} values
                 * of 1, 2, 4, and 8 - the Single UNIX Specification
@@ -351,7 +351,7 @@ get_standard_integer_type(const char *l, const char **t)
                 * neither of them support values bigger than 8 or
                 * non-power-of-2 values.
                 */
-               if (isdigit((unsigned char)l[2])) {
+               if (isdigit(CAST(unsigned char, l[2]))) {
                        /* Multi-digit, so > 9 */
                        return FILE_INVALID;
                }
@@ -437,8 +437,8 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
 
        if (magicsize != FILE_MAGICSIZE) {
                file_error(ms, 0, "magic element size %lu != %lu",
-                   (unsigned long)sizeof(*map->magic[0]),
-                   (unsigned long)FILE_MAGICSIZE);
+                   CAST(unsigned long, sizeof(*map->magic[0])),
+                   CAST(unsigned long, FILE_MAGICSIZE));
                return -1;
        }
 
@@ -451,7 +451,7 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
 
 #ifndef COMPILE_ONLY
        map = apprentice_map(ms, fn);
-       if (map == (struct magic_map *)-1)
+       if (map == RCAST(struct magic_map *, -1))
                return -1;
        if (map == NULL) {
                if (ms->flags & MAGIC_CHECK)
@@ -503,7 +503,7 @@ file_ms_alloc(int flags)
        struct magic_set *ms;
        size_t i, len;
 
-       if ((ms = CAST(struct magic_set *, calloc((size_t)1,
+       if ((ms = CAST(struct magic_set *, calloc(CAST(size_t, 1u),
            sizeof(struct magic_set)))) == NULL)
                return NULL;
 
@@ -831,7 +831,7 @@ typesize(int type)
        case FILE_LEDOUBLE:
                return 8;
        default:
-               return (size_t)~0;
+               return CAST(size_t, ~0);
        }
 }
 
@@ -886,7 +886,7 @@ apprentice_magic_strength(const struct magic *m)
        case FILE_BEDOUBLE:
        case FILE_LEDOUBLE:
                ts = typesize(m->type);
-               if (ts == (size_t)~0)
+               if (ts == CAST(size_t, ~0))
                        abort();
                val += ts * MULT;
                break;
@@ -1101,7 +1101,7 @@ set_test_type(struct magic *mstart, struct magic *m)
                        break;
 
                /* binary test if pattern is not text */
-               if (file_looks_utf8(m->value.us, (size_t)m->vallen, NULL,
+               if (file_looks_utf8(m->value.us, CAST(size_t, m->vallen), NULL,
                    NULL) <= 0)
                        mstart->flag |= BINTEST;
                else
@@ -1182,7 +1182,7 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
                                size_t i;
 
                                for (i = 0; bang[i].name != NULL; i++) {
-                                       if ((size_t)(len - 2) > bang[i].len &&
+                                       if (CAST(size_t, len - 2) > bang[i].len &&
                                            memcmp(bang[i].name, line + 2,
                                            bang[i].len) == 0)
                                                break;
@@ -1235,7 +1235,7 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
 private int
 cmpstrp(const void *p1, const void *p2)
 {
-        return strcmp(*(char *const *)p1, *(char *const *)p2);
+        return strcmp(*RCAST(char *const *, p1), *RCAST(char *const *, p2));
 }
 
 
@@ -1261,10 +1261,10 @@ set_text_binary(struct magic_set *ms, struct magic_entry *me, uint32_t nme,
                if (me[i].mp->flag & BINTEST) {
                        char *p = strstr(me[i].mp->desc, text);
                        if (p && (p == me[i].mp->desc ||
-                           isspace((unsigned char)p[-1])) &&
+                           isspace(CAST(unsigned char, p[-1]))) &&
                            (p + len - me[i].mp->desc == MAXstring
                            || (p[len] == '\0' ||
-                           isspace((unsigned char)p[len]))))
+                           isspace(CAST(unsigned char, p[len])))))
                                (void)fprintf(stderr, "*** Possible "
                                    "binary test for text type\n");
                }
@@ -1460,12 +1460,12 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
                 * the sign extension must have happened.
                 */
                case FILE_BYTE:
-                       v = (signed char) v;
+                       v = CAST(signed char,  v);
                        break;
                case FILE_SHORT:
                case FILE_BESHORT:
                case FILE_LESHORT:
-                       v = (short) v;
+                       v = CAST(short, v);
                        break;
                case FILE_DATE:
                case FILE_BEDATE:
@@ -1482,7 +1482,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
                case FILE_FLOAT:
                case FILE_BEFLOAT:
                case FILE_LEFLOAT:
-                       v = (int32_t) v;
+                       v = CAST(int32_t, v);
                        break;
                case FILE_QUAD:
                case FILE_BEQUAD:
@@ -1499,7 +1499,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
                case FILE_DOUBLE:
                case FILE_BEDOUBLE:
                case FILE_LEDOUBLE:
-                       v = (int64_t) v;
+                       v = CAST(int64_t, v);
                        break;
                case FILE_STRING:
                case FILE_PSTRING:
@@ -1626,7 +1626,7 @@ get_cond(const char *l, const char **t)
 
        for (p = cond_tbl; p->len; p++) {
                if (strncmp(l, p->name, p->len) == 0 &&
-                   isspace((unsigned char)l[p->len])) {
+                   isspace(CAST(unsigned char, l[p->len]))) {
                        if (t)
                                *t = l + p->len;
                        break;
@@ -1684,7 +1684,7 @@ parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp)
 {
        const char *l = *lp;
 
-       while (!isspace((unsigned char)*++l))
+       while (!isspace(CAST(unsigned char, *++l)))
                switch (*l) {
                case CHAR_INDIRECT_RELATIVE:
                        m->str_flags |= INDIRECT_RELATIVE;
@@ -1710,7 +1710,7 @@ parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp,
 
        ++l;
        m->mask_op |= op;
-       val = (uint64_t)strtoull(l, &t, 0);
+       val = CAST(uint64_t, strtoull(l, &t, 0));
        l = t;
        m->num_mask = file_signextend(ms, m, val);
        eatsize(&l);
@@ -1724,7 +1724,7 @@ parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp)
        char *t;
        int have_range = 0;
 
-       while (!isspace((unsigned char)*++l)) {
+       while (!isspace(CAST(unsigned char, *++l))) {
                switch (*l) {
                case '0':  case '1':  case '2':
                case '3':  case '4':  case '5':
@@ -1806,7 +1806,7 @@ parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp)
                        goto out;
                }
                /* allow multiple '/' for readability */
-               if (l[1] == '/' && !isspace((unsigned char)l[2]))
+               if (l[1] == '/' && !isspace(CAST(unsigned char, l[2])))
                        l++;
        }
        if (string_modifier_check(ms, m) == -1)
@@ -1861,7 +1861,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
                        return -1;
                }
                m = &me->mp[me->cont_count - 1];
-               diff = (int32_t)cont_level - (int32_t)m->cont_level;
+               diff = CAST(int32_t, cont_level) - CAST(int32_t, m->cont_level);
                if (diff > 1)
                        file_magwarn(ms, "New continuation level %u is more "
                            "than one larger than current level %u", cont_level,
@@ -1920,7 +1920,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
        }
 
        /* get offset, then skip over it */
-       m->offset = (int32_t)strtol(l, &t, 0);
+       m->offset = CAST(int32_t, strtol(l, &t, 0));
         if (l == t) {
                if (ms->flags & MAGIC_CHECK)
                        file_magwarn(ms, "offset `%s' invalid", l);
@@ -2018,8 +2018,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
                        m->in_op |= FILE_OPINDIRECT;
                        l++;
                }
-               if (isdigit((unsigned char)*l) || *l == '-') {
-                       m->in_offset = (int32_t)strtol(l, &t, 0);
+               if (isdigit(CAST(unsigned char, *l)) || *l == '-') {
+                       m->in_offset = CAST(int32_t, strtol(l, &t, 0));
                        if (l == t) {
                                if (ms->flags & MAGIC_CHECK)
                                        file_magwarn(ms,
@@ -2082,7 +2082,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
                         */
                        if (*l == 'd')
                                m->type = get_standard_integer_type(l, &l);
-                       else if (*l == 's' && !isalpha((unsigned char)l[1])) {
+                       else if (*l == 's'
+                           && !isalpha(CAST(unsigned char, l[1]))) {
                                m->type = FILE_STRING;
                                ++l;
                        }
@@ -2172,8 +2173,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
                break;
        default:
                m->reln = '=';  /* the default relation */
-               if (*l == 'x' && ((isascii((unsigned char)l[1]) &&
-                   isspace((unsigned char)l[1])) || !l[1])) {
+               if (*l == 'x' && ((isascii(CAST(unsigned char, l[1])) &&
+                   isspace(CAST(unsigned char, l[1]))) || !l[1])) {
                        m->reln = *l;
                        ++l;
                }
@@ -2270,11 +2271,11 @@ parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line)
                file_magwarn(ms, "Too large factor `%lu'", factor);
                goto out;
        }
-       if (*el && !isspace((unsigned char)*el)) {
+       if (*el && !isspace(CAST(unsigned char, *el))) {
                file_magwarn(ms, "Bad factor `%s'", l);
                goto out;
        }
-       m->factor = (uint8_t)factor;
+       m->factor = CAST(uint8_t, factor);
        if (m->factor == 0 && m->factor_op == FILE_FACTOR_OP_DIV) {
                file_magwarn(ms, "Cannot have factor op `%c' and factor %u",
                    m->factor_op, m->factor);
@@ -2305,7 +2306,7 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
        if (buf[0] != '\0') {
                len = nt ? strlen(buf) : len;
                file_magwarn(ms, "Current entry already has a %s type "
-                   "`%.*s', new type `%s'", name, (int)len, buf, l);
+                   "`%.*s', new type `%s'", name, CAST(int, len), buf, l);
                return -1;
        }
 
@@ -2326,7 +2327,7 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
                        file_magwarn(ms, "%s type `%s' truncated %"
                            SIZE_T_FORMAT "u", name, line, i);
        } else {
-               if (!isspace((unsigned char)*l) && !goodchar(*l, extra))
+               if (!isspace(CAST(unsigned char, *l)) && !goodchar(*l, extra))
                        file_magwarn(ms, "%s type `%s' has bad char '%c'",
                            name, line, *l);
                if (nt)
@@ -2428,7 +2429,7 @@ check_format_type(const char *ptr, int type, const char **estr)
                if (*ptr == '#')
                        ptr++;
 #define CHECKLEN() do { \
-       for (len = cnt = 0; isdigit((unsigned char)*ptr); ptr++, cnt++) \
+       for (len = cnt = 0; isdigit(CAST(unsigned char, *ptr)); ptr++, cnt++) \
                len = len * 10 + (*ptr - '0'); \
        if (cnt > 5 || len > 1024) \
                goto toolong; \
@@ -2546,11 +2547,11 @@ check_format_type(const char *ptr, int type, const char **estr)
        case FILE_FMT_STR:
                if (*ptr == '-')
                        ptr++;
-               while (isdigit((unsigned char )*ptr))
+               while (isdigit(CAST(unsigned char, *ptr)))
                        ptr++;
                if (*ptr == '.') {
                        ptr++;
-                       while (isdigit((unsigned char )*ptr))
+                       while (isdigit(CAST(unsigned char , *ptr)))
                                ptr++;
                }
 
@@ -2695,7 +2696,7 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
                return 0;
        default:
                errno = 0;
-               ull = (uint64_t)strtoull(*p, &ep, 0);
+               ull = CAST(uint64_t, strtoull(*p, &ep, 0));
                m->value.q = file_signextend(ms, m, ull);
                if (*p == ep) {
                        file_magwarn(ms, "Unparseable number `%s'", *p);
@@ -2704,24 +2705,24 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
                        uint64_t x;
                        const char *q;
 
-                       if (ts == (size_t)~0) {
+                       if (ts == CAST(size_t, ~0)) {
                                file_magwarn(ms,
                                    "Expected numeric type got `%s'",
                                    type_tbl[m->type].name);
                        }
-                       for (q = *p; isspace((unsigned char)*q); q++)
+                       for (q = *p; isspace(CAST(unsigned char, *q)); q++)
                                continue;
                        if (*q == '-')
-                               ull = -(int64_t)ull;
+                               ull = -CAST(int64_t, ull);
                        switch (ts) {
                        case 1:
-                               x = (uint64_t)(ull & ~0xffULL);
+                               x = CAST(uint64_t, ull & ~0xffULL);
                                break;
                        case 2:
-                               x = (uint64_t)(ull & ~0xffffULL);
+                               x = CAST(uint64_t, ull & ~0xffffULL);
                                break;
                        case 4:
-                               x = (uint64_t)(ull & ~0xffffffffULL);
+                               x = CAST(uint64_t, ull & ~0xffffffffULL);
                                break;
                        case 8:
                                x = 0;
@@ -2761,7 +2762,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
        int     val;
 
        while ((c = *s++) != '\0') {
-               if (isspace((unsigned char) c))
+               if (isspace(CAST(unsigned char, c)))
                        break;
                if (p >= pmax) {
                        file_error(ms, 0, "string too long: `%s'", origs);
@@ -2785,7 +2786,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
                                /*FALLTHROUGH*/
                        default:
                                if (warn) {
-                                       if (isprint((unsigned char)c)) {
+                                       if (isprint(CAST(unsigned char, c))) {
                                                /* Allow escaping of
                                                 * ``relations'' */
                                                if (strchr("<>&^=!", c) == NULL
@@ -2823,7 +2824,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
                        case '!':
                        /* and baskslash itself */
                        case '\\':
-                               *p++ = (char) c;
+                               *p++ = CAST(char, c);
                                break;
 
                        case 'a':
@@ -2875,7 +2876,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
                                }
                                else
                                        --s;
-                               *p++ = (char)val;
+                               *p++ = CAST(char, val);
                                break;
 
                        /* \x and up to 2 hex digits */
@@ -2891,18 +2892,18 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
                                                --s;
                                } else
                                        --s;
-                               *p++ = (char)val;
+                               *p++ = CAST(char, val);
                                break;
                        }
                } else
-                       *p++ = (char)c;
+                       *p++ = CAST(char, c);
        }
        --s;
 out:
        *p = '\0';
        m->vallen = CAST(unsigned char, (p - origp));
        if (m->type == FILE_PSTRING)
-               m->vallen += (unsigned char)file_pstring_length_size(m);
+               m->vallen += CAST(unsigned char, file_pstring_length_size(m));
        return s;
 }
 
@@ -2911,9 +2912,9 @@ out:
 private int
 hextoint(int c)
 {
-       if (!isascii((unsigned char) c))
+       if (!isascii(CAST(unsigned char, c)))
                return -1;
-       if (isdigit((unsigned char) c))
+       if (isdigit(CAST(unsigned char, c)))
                return c - '0';
        if ((c >= 'a') && (c <= 'f'))
                return c + 10 - 'a';
@@ -3068,11 +3069,11 @@ apprentice_map(struct magic_set *ms, const char *fn)
                goto error;
        }
 
-       map->len = (size_t)st.st_size;
+       map->len = CAST(size_t, st.st_size);
 #ifdef QUICK
        map->type = MAP_TYPE_MMAP;
-       if ((map->p = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE,
-           MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) {
+       if ((map->p = mmap(0, CAST(size_t, st.st_size), PROT_READ|PROT_WRITE,
+           MAP_PRIVATE|MAP_FILE, fd, CAST(off_t, 0))) == MAP_FAILED) {
                file_error(ms, errno, "cannot map `%s'", dbname);
                goto error;
        }
@@ -3092,11 +3093,11 @@ apprentice_map(struct magic_set *ms, const char *fn)
        fd = -1;
 
        if (check_buffer(ms, map, dbname) != 0) {
-               rv = (struct magic_map *)-1;
+               rv = RCAST(struct magic_map *, -1);
                goto error;
        }
 #ifdef QUICK
-       if (mprotect(map->p, (size_t)st.st_size, PROT_READ) == -1) {
+       if (mprotect(map->p, CAST(size_t, st.st_size), PROT_READ) == -1) {
                file_error(ms, errno, "cannot mprotect `%s'", dbname);
                goto error;
        }
@@ -3140,7 +3141,7 @@ check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname)
                    VERSIONNO, dbname, version);
                return -1;
        }
-       entries = (uint32_t)(map->len / sizeof(struct magic));
+       entries = CAST(uint32_t, map->len / sizeof(struct magic));
        if ((entries * sizeof(struct magic)) != map->len) {
                file_error(ms, 0, "Size of `%s' %" SIZE_T_FORMAT "u is not "
                    "a multiple of %" SIZE_T_FORMAT "u",
@@ -3202,14 +3203,14 @@ apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn)
        hdr.h[1] = VERSIONNO;
        memcpy(hdr.h + 2, map->nmagic, nm);
 
-       if (write(fd, &hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr)) {
+       if (write(fd, &hdr, sizeof(hdr)) != CAST(ssize_t, sizeof(hdr))) {
                file_error(ms, errno, "error writing `%s'", dbname);
                goto out2;
        }
 
        for (i = 0; i < MAGIC_SETS; i++) {
                len = m * map->nmagic[i];
-               if (write(fd, map->magic[i], len) != (ssize_t)len) {
+               if (write(fd, map->magic[i], len) != CAST(ssize_t, len)) {
                        file_error(ms, errno, "error writing `%s'", dbname);
                        goto out2;
                }
@@ -3255,7 +3256,8 @@ mkdbname(struct magic_set *ms, const char *fn, int strip)
        q++;
        /* Compatibility with old code that looked in .mime */
        if (ms->flags & MAGIC_MIME) {
-               if (asprintf(&buf, "%.*s.mime%s", (int)(q - fn), fn, ext) < 0)
+               if (asprintf(&buf, "%.*s.mime%s", CAST(int, q - fn), fn, ext)
+                   < 0)
                        return NULL;
                if (access(buf, R_OK) != -1) {
                        ms->flags &= MAGIC_MIME_TYPE;
@@ -3263,7 +3265,7 @@ mkdbname(struct magic_set *ms, const char *fn, int strip)
                }
                free(buf);
        }
-       if (asprintf(&buf, "%.*s%s", (int)(q - fn), fn, ext) < 0)
+       if (asprintf(&buf, "%.*s%s", CAST(int, q - fn), fn, ext) < 0)
                return NULL;
 
        /* Compatibility with old code that looked in .mime */
@@ -3290,8 +3292,8 @@ private uint16_t
 swap2(uint16_t sv)
 {
        uint16_t rv;
-       uint8_t *s = (uint8_t *)(void *)&sv;
-       uint8_t *d = (uint8_t *)(void *)&rv;
+       uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+       uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
        d[0] = s[1];
        d[1] = s[0];
        return rv;
@@ -3304,8 +3306,8 @@ private uint32_t
 swap4(uint32_t sv)
 {
        uint32_t rv;
-       uint8_t *s = (uint8_t *)(void *)&sv;
-       uint8_t *d = (uint8_t *)(void *)&rv;
+       uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+       uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
        d[0] = s[3];
        d[1] = s[2];
        d[2] = s[1];
@@ -3320,8 +3322,8 @@ private uint64_t
 swap8(uint64_t sv)
 {
        uint64_t rv;
-       uint8_t *s = (uint8_t *)(void *)&sv;
-       uint8_t *d = (uint8_t *)(void *)&rv;
+       uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+       uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
 #if 0
        d[0] = s[3];
        d[1] = s[2];
@@ -3351,9 +3353,9 @@ private void
 bs1(struct magic *m)
 {
        m->cont_level = swap2(m->cont_level);
-       m->offset = swap4((uint32_t)m->offset);
-       m->in_offset = swap4((uint32_t)m->in_offset);
-       m->lineno = swap4((uint32_t)m->lineno);
+       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);
@@ -3385,7 +3387,7 @@ protected size_t
 file_pstring_get_length(const struct magic *m, const char *ss)
 {
        size_t len = 0;
-       const unsigned char *s = (const unsigned char *)ss;
+       const unsigned char *s = RCAST(const unsigned char *, ss);
        unsigned int s3, s2, s1, s0;
 
        switch (m->str_flags & PSTRING_LEN) {
index fd38f1b..bcebeab 100644 (file)
@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: ascmagic.c,v 1.100 2018/10/15 16:29:16 christos Exp $")
+FILE_RCSID("@(#)$File: ascmagic.c,v 1.102 2019/02/20 02:35:27 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -81,6 +81,12 @@ file_ascmagic(struct magic_set *ms, const struct buffer *b, int text)
 
        bb = *b;
        bb.flen = trim_nuls(CAST(const unsigned char *, b->fbuf), b->flen);
+       /*
+        * Avoid trimming at an odd byte if the original buffer was evenly
+        * sized; this avoids losing the last character on UTF-16 LE text
+        */
+       if ((bb.flen & 1) && !(b->flen & 1))
+               bb.flen++;
 
        /* If file doesn't look like any sort of text, give up. */
        if (file_encoding(ms, &bb, &ubuf, &ulen, &code, &code_mime,
@@ -121,7 +127,7 @@ file_ascmagic_with_encoding(struct magic_set *ms,
        int n_nel = 0;
        int executable = 0;
 
-       size_t last_line_end = (size_t)-1;
+       size_t last_line_end = CAST(size_t, -1);
        int has_long_lines = 0;
 
        nbytes = trim_nuls(buf, nbytes);
@@ -145,7 +151,7 @@ file_ascmagic_with_encoding(struct magic_set *ms,
                    == NULL)
                        goto done;
                buffer_init(&bb, b->fd, utf8_buf,
-                   (size_t)(utf8_end - utf8_buf));
+                   CAST(size_t, utf8_end - utf8_buf));
 
                if ((rv = file_softmagic(ms, &bb, NULL, NULL,
                    TEXTTEST, text)) == 0)
@@ -324,42 +330,42 @@ encode_utf8(unsigned char *buf, size_t len, unichar *ubuf, size_t ulen)
                if (ubuf[i] <= 0x7f) {
                        if (end - buf < 1)
                                return NULL;
-                       *buf++ = (unsigned char)ubuf[i];
+                       *buf++ = CAST(unsigned char, ubuf[i]);
                } else if (ubuf[i] <= 0x7ff) {
                        if (end - buf < 2)
                                return NULL;
-                       *buf++ = (unsigned char)((ubuf[i] >> 6) + 0xc0);
-                       *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] >> 6) + 0xc0);
+                       *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
                } else if (ubuf[i] <= 0xffff) {
                        if (end - buf < 3)
                                return NULL;
-                       *buf++ = (unsigned char)((ubuf[i] >> 12) + 0xe0);
-                       *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
-                       *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] >> 12) + 0xe0);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
                } else if (ubuf[i] <= 0x1fffff) {
                        if (end - buf < 4)
                                return NULL;
-                       *buf++ = (unsigned char)((ubuf[i] >> 18) + 0xf0);
-                       *buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80);
-                       *buf++ = (unsigned char)(((ubuf[i] >>  6) & 0x3f) + 0x80);
-                       *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] >> 18) + 0xf0);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >>  6) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
                } else if (ubuf[i] <= 0x3ffffff) {
                        if (end - buf < 5)
                                return NULL;
-                       *buf++ = (unsigned char)((ubuf[i] >> 24) + 0xf8);
-                       *buf++ = (unsigned char)(((ubuf[i] >> 18) & 0x3f) + 0x80);
-                       *buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80);
-                       *buf++ = (unsigned char)(((ubuf[i] >>  6) & 0x3f) + 0x80);
-                       *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] >> 24) + 0xf8);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 18) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >>  6) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
                } else if (ubuf[i] <= 0x7fffffff) {
                        if (end - buf < 6)
                                return NULL;
-                       *buf++ = (unsigned char)((ubuf[i] >> 30) + 0xfc);
-                       *buf++ = (unsigned char)(((ubuf[i] >> 24) & 0x3f) + 0x80);
-                       *buf++ = (unsigned char)(((ubuf[i] >> 18) & 0x3f) + 0x80);
-                       *buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80);
-                       *buf++ = (unsigned char)(((ubuf[i] >>  6) & 0x3f) + 0x80);
-                       *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] >> 30) + 0xfc);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 24) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 18) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >>  6) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
                } else /* Invalid character */
                        return NULL;
        }
index 5f76b80..fd40416 100644 (file)
@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: buffer.c,v 1.4 2018/02/21 21:26:00 christos Exp $")
+FILE_RCSID("@(#)$File: buffer.c,v 1.5 2019/02/20 02:35:27 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -61,13 +61,13 @@ buffer_fill(const struct buffer *bb)
        struct buffer *b = CCAST(struct buffer *, bb);
 
        if (b->elen != 0)
-               return b->elen == (size_t)~0 ? -1 : 0;
+               return b->elen == CAST(size_t, ~0) ? -1 : 0;
 
        if (!S_ISREG(b->st.st_mode))
                goto out;
 
-       b->elen =  (size_t)b->st.st_size < b->flen ?
-           (size_t)b->st.st_size : b->flen;
+       b->elen =  CAST(size_t, b->st.st_size) < b->flen ?
+           CAST(size_t, b->st.st_size) : b->flen;
        if ((b->ebuf = malloc(b->elen)) == NULL)
                goto out;
 
@@ -79,6 +79,6 @@ buffer_fill(const struct buffer *bb)
 
        return 0;
 out:
-       b->elen = (size_t)~0;
+       b->elen = CAST(size_t, ~0);
        return -1;
 }
index 3cba3ac..556a3ff 100644 (file)
--- a/src/cdf.c
+++ b/src/cdf.c
@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: cdf.c,v 1.113 2018/10/15 16:29:16 christos Exp $")
+FILE_RCSID("@(#)$File: cdf.c,v 1.114 2019/02/20 02:35:27 christos Exp $")
 #endif
 
 #include <assert.h>
@@ -66,11 +66,14 @@ static union {
        uint32_t u;
 } cdf_bo;
 
-#define NEED_SWAP      (cdf_bo.u == (uint32_t)0x01020304)
+#define NEED_SWAP      (cdf_bo.u == CAST(uint32_t, 0x01020304))
 
-#define CDF_TOLE8(x)   ((uint64_t)(NEED_SWAP ? _cdf_tole8(x) : (uint64_t)(x)))
-#define CDF_TOLE4(x)   ((uint32_t)(NEED_SWAP ? _cdf_tole4(x) : (uint32_t)(x)))
-#define CDF_TOLE2(x)   ((uint16_t)(NEED_SWAP ? _cdf_tole2(x) : (uint16_t)(x)))
+#define CDF_TOLE8(x)   \
+    (CAST(uint64_t, NEED_SWAP ? _cdf_tole8(x) : CAST(uint64_t, x)))
+#define CDF_TOLE4(x)   \
+    (CAST(uint32_t, NEED_SWAP ? _cdf_tole4(x) : CAST(uint32_t, x)))
+#define CDF_TOLE2(x)   \
+    (CAST(uint16_t, NEED_SWAP ? _cdf_tole2(x) : CAST(uint16_t, x)))
 #define CDF_TOLE(x)    (/*CONSTCOND*/sizeof(x) == 2 ? \
                            CDF_TOLE2(CAST(uint16_t, x)) : \
                        (/*CONSTCOND*/sizeof(x) == 4 ? \
@@ -120,8 +123,8 @@ static uint16_t
 _cdf_tole2(uint16_t sv)
 {
        uint16_t rv;
-       uint8_t *s = (uint8_t *)(void *)&sv;
-       uint8_t *d = (uint8_t *)(void *)&rv;
+       uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+       uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
        d[0] = s[1];
        d[1] = s[0];
        return rv;
@@ -134,8 +137,8 @@ static uint32_t
 _cdf_tole4(uint32_t sv)
 {
        uint32_t rv;
-       uint8_t *s = (uint8_t *)(void *)&sv;
-       uint8_t *d = (uint8_t *)(void *)&rv;
+       uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+       uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
        d[0] = s[3];
        d[1] = s[2];
        d[2] = s[1];
@@ -150,8 +153,8 @@ static uint64_t
 _cdf_tole8(uint64_t sv)
 {
        uint64_t rv;
-       uint8_t *s = (uint8_t *)(void *)&sv;
-       uint8_t *d = (uint8_t *)(void *)&rv;
+       uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+       uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
        d[0] = s[7];
        d[1] = s[6];
        d[2] = s[5];
@@ -216,15 +219,17 @@ cdf_swap_header(cdf_header_t *h)
        h->h_min_size_standard_stream =
            CDF_TOLE4(h->h_min_size_standard_stream);
        h->h_secid_first_sector_in_short_sat =
-           CDF_TOLE4((uint32_t)h->h_secid_first_sector_in_short_sat);
+           CDF_TOLE4(CAST(uint32_t, h->h_secid_first_sector_in_short_sat));
        h->h_num_sectors_in_short_sat =
            CDF_TOLE4(h->h_num_sectors_in_short_sat);
        h->h_secid_first_sector_in_master_sat =
-           CDF_TOLE4((uint32_t)h->h_secid_first_sector_in_master_sat);
+           CDF_TOLE4(CAST(uint32_t, h->h_secid_first_sector_in_master_sat));
        h->h_num_sectors_in_master_sat =
            CDF_TOLE4(h->h_num_sectors_in_master_sat);
-       for (i = 0; i < __arraycount(h->h_master_sat); i++)
-               h->h_master_sat[i] = CDF_TOLE4((uint32_t)h->h_master_sat[i]);
+       for (i = 0; i < __arraycount(h->h_master_sat); i++) {
+               h->h_master_sat[i] =
+                   CDF_TOLE4(CAST(uint32_t, h->h_master_sat[i]));
+       }
 }
 
 void
@@ -257,15 +262,16 @@ void
 cdf_swap_dir(cdf_directory_t *d)
 {
        d->d_namelen = CDF_TOLE2(d->d_namelen);
-       d->d_left_child = CDF_TOLE4((uint32_t)d->d_left_child);
-       d->d_right_child = CDF_TOLE4((uint32_t)d->d_right_child);
-       d->d_storage = CDF_TOLE4((uint32_t)d->d_storage);
+       d->d_left_child = CDF_TOLE4(CAST(uint32_t, d->d_left_child));
+       d->d_right_child = CDF_TOLE4(CAST(uint32_t, d->d_right_child));
+       d->d_storage = CDF_TOLE4(CAST(uint32_t, d->d_storage));
        d->d_storage_uuid[0] = CDF_TOLE8(d->d_storage_uuid[0]);
        d->d_storage_uuid[1] = CDF_TOLE8(d->d_storage_uuid[1]);
        d->d_flags = CDF_TOLE4(d->d_flags);
-       d->d_created = CDF_TOLE8((uint64_t)d->d_created);
-       d->d_modified = CDF_TOLE8((uint64_t)d->d_modified);
-       d->d_stream_first_sector = CDF_TOLE4((uint32_t)d->d_stream_first_sector);
+       d->d_created = CDF_TOLE8(CAST(uint64_t, d->d_created));
+       d->d_modified = CDF_TOLE8(CAST(uint64_t, d->d_modified));
+       d->d_stream_first_sector = CDF_TOLE4(
+           CAST(uint32_t, d->d_stream_first_sector));
        d->d_size = CDF_TOLE4(d->d_size);
 }
 
@@ -322,11 +328,11 @@ static int
 cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h,
     const void *p, size_t tail, int line)
 {
-       const char *b = (const char *)sst->sst_tab;
-       const char *e = ((const char *)p) + tail;
+       const char *b = RCAST(const char *, sst->sst_tab);
+       const char *e = RCAST(const char *, p) + tail;
        size_t ss = cdf_check_stream(sst, h);
        /*LINTED*/(void)&line;
-       if (e >= b && (size_t)(e - b) <= ss * sst->sst_len)
+       if (e >= b && CAST(size_t, e - b) <= ss * sst->sst_len)
                return 0;
        DPRINTF(("%d: offset begin %p < end %p || %" SIZE_T_FORMAT "u"
            " > %" SIZE_T_FORMAT "u [%" SIZE_T_FORMAT "u %"
@@ -339,23 +345,23 @@ cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h,
 static ssize_t
 cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len)
 {
-       size_t siz = (size_t)off + len;
+       size_t siz = CAST(size_t, off + len);
 
-       if ((off_t)(off + len) != (off_t)siz)
+       if (CAST(off_t, off + len) != CAST(off_t, siz))
                goto out;
 
        if (info->i_buf != NULL && info->i_len >= siz) {
                (void)memcpy(buf, &info->i_buf[off], len);
-               return (ssize_t)len;
+               return CAST(ssize_t, len);
        }
 
        if (info->i_fd == -1)
                goto out;
 
-       if (pread(info->i_fd, buf, len, off) != (ssize_t)len)
+       if (pread(info->i_fd, buf, len, off) != CAST(ssize_t, len))
                return -1;
 
-       return (ssize_t)len;
+       return CAST(ssize_t, len);
 out:
        errno = EINVAL;
        return -1;
@@ -367,7 +373,7 @@ cdf_read_header(const cdf_info_t *info, cdf_header_t *h)
        char buf[512];
 
        (void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
-       if (cdf_read(info, (off_t)0, buf, sizeof(buf)) == -1)
+       if (cdf_read(info, CAST(off_t, 0), buf, sizeof(buf)) == -1)
                return -1;
        cdf_unpack_header(h, buf);
        cdf_swap_header(h);
@@ -401,7 +407,7 @@ cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len,
        size_t ss = CDF_SEC_SIZE(h);
        size_t pos = CDF_SEC_POS(h, id);
        assert(ss == len);
-       return cdf_read(info, (off_t)pos, ((char *)buf) + offs, len);
+       return cdf_read(info, CAST(off_t, pos), RCAST(char *, buf) + offs, len);
 }
 
 ssize_t
@@ -417,8 +423,8 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs,
                    pos + len, CDF_SEC_SIZE(h) * sst->sst_len));
                goto out;
        }
-       (void)memcpy(((char *)buf) + offs,
-           ((const char *)sst->sst_tab) + pos, len);
+       (void)memcpy(RCAST(char *, buf) + offs,
+           RCAST(const char *, sst->sst_tab) + pos, len);
        return len;
 out:
        errno = EFTYPE;
@@ -461,7 +467,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
                if (h->h_master_sat[i] < 0)
                        break;
                if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
-                   h->h_master_sat[i]) != (ssize_t)ss) {
+                   h->h_master_sat[i]) != CAST(ssize_t, ss)) {
                        DPRINTF(("Reading sector %d", h->h_master_sat[i]));
                        goto out1;
                }
@@ -478,12 +484,13 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
                        DPRINTF(("Reading master sector loop limit"));
                        goto out3;
                }
-               if (cdf_read_sector(info, msa, 0, ss, h, mid) != (ssize_t)ss) {
+               if (cdf_read_sector(info, msa, 0, ss, h, mid) !=
+                   CAST(ssize_t, ss)) {
                        DPRINTF(("Reading master sector %d", mid));
                        goto out2;
                }
                for (k = 0; k < nsatpersec; k++, i++) {
-                       sec = CDF_TOLE4((uint32_t)msa[k]);
+                       sec = CDF_TOLE4(CAST(uint32_t, msa[k]));
                        if (sec < 0)
                                goto out;
                        if (i >= sat->sat_len) {
@@ -493,13 +500,13 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
                            goto out3;
                        }
                        if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
-                           sec) != (ssize_t)ss) {
+                           sec) != CAST(ssize_t, ss)) {
                                DPRINTF(("Reading sector %d",
                                    CDF_TOLE4(msa[k])));
                                goto out2;
                        }
                }
-               mid = CDF_TOLE4((uint32_t)msa[nsatpersec]);
+               mid = CDF_TOLE4(CAST(uint32_t, msa[nsatpersec]));
        }
 out:
        sat->sat_len = i;
@@ -518,7 +525,7 @@ size_t
 cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
 {
        size_t i, j;
-       cdf_secid_t maxsector = (cdf_secid_t)((sat->sat_len * size)
+       cdf_secid_t maxsector = CAST(cdf_secid_t, (sat->sat_len * size)
            / sizeof(maxsector));
 
        DPRINTF(("Chain:"));
@@ -538,7 +545,7 @@ cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
                        DPRINTF(("Sector %d >= %d\n", sid, maxsector));
                        goto out;
                }
-               sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
+               sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
        }
        if (i == 0) {
                DPRINTF((" none, sid: %d\n", sid));
@@ -549,7 +556,7 @@ cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
        return i;
 out:
        errno = EFTYPE;
-       return (size_t)-1;
+       return CAST(size_t, -1);
 }
 
 int
@@ -566,7 +573,7 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
        if (sid == CDF_SECID_END_OF_CHAIN || len == 0)
                return cdf_zero_stream(scn);
 
-       if (scn->sst_len == (size_t)-1)
+       if (scn->sst_len == CAST(size_t, -1))
                goto out;
 
        scn->sst_tab = CDF_CALLOC(scn->sst_len, ss);
@@ -585,7 +592,7 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
                        goto out;
                }
                if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h,
-                   sid)) != (ssize_t)ss) {
+                   sid)) != CAST(ssize_t, ss)) {
                        if (i == scn->sst_len - 1 && nr > 0) {
                                /* Last sector might be truncated */
                                return 0;
@@ -593,7 +600,7 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
                        DPRINTF(("Reading long sector chain %d", sid));
                        goto out;
                }
-               sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
+               sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
        }
        return 0;
 out:
@@ -612,7 +619,7 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
        scn->sst_dirlen = len;
        scn->sst_ss = ss;
 
-       if (scn->sst_len == (size_t)-1)
+       if (scn->sst_len == CAST(size_t, -1))
                goto out;
 
        scn->sst_tab = CDF_CALLOC(scn->sst_len, ss);
@@ -631,11 +638,11 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
                        goto out;
                }
                if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h,
-                   sid) != (ssize_t)ss) {
+                   sid) != CAST(ssize_t, ss)) {
                        DPRINTF(("Reading short sector chain %d", sid));
                        goto out;
                }
-               sid = CDF_TOLE4((uint32_t)ssat->sat_tab[sid]);
+               sid = CDF_TOLE4(CAST(uint32_t, ssat->sat_tab[sid]));
        }
        return 0;
 out:
@@ -666,7 +673,7 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
        cdf_secid_t sid = h->h_secid_first_directory;
 
        ns = cdf_count_chain(sat, sid, ss);
-       if (ns == (size_t)-1)
+       if (ns == CAST(size_t, -1))
                return -1;
 
        nd = ss / CDF_DIRECTORY_SIZE;
@@ -687,7 +694,8 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
                        DPRINTF(("Read dir loop limit"));
                        goto out;
                }
-               if (cdf_read_sector(info, buf, 0, ss, h, sid) != (ssize_t)ss) {
+               if (cdf_read_sector(info, buf, 0, ss, h, sid) !=
+                   CAST(ssize_t, ss)) {
                        DPRINTF(("Reading directory sector %d", sid));
                        goto out;
                }
@@ -695,7 +703,7 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
                        cdf_unpack_dir(&dir->dir_tab[i * nd + j],
                            &buf[j * CDF_DIRECTORY_SIZE]);
                }
-               sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
+               sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
        }
        if (NEED_SWAP)
                for (i = 0; i < dir->dir_len; i++)
@@ -720,7 +728,7 @@ cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
 
        ssat->sat_tab = NULL;
        ssat->sat_len = cdf_count_chain(sat, sid, ss);
-       if (ssat->sat_len == (size_t)-1)
+       if (ssat->sat_len == CAST(size_t, -1))
                goto out;
 
        ssat->sat_tab = CAST(cdf_secid_t *, CDF_CALLOC(ssat->sat_len, ss));
@@ -739,11 +747,11 @@ cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
                        goto out;
                }
                if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) !=
-                   (ssize_t)ss) {
+                   CAST(ssize_t, ss)) {
                        DPRINTF(("Reading short sat sector %d", sid));
                        goto out1;
                }
-               sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
+               sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
        }
        return 0;
 out:
@@ -793,7 +801,7 @@ cdf_namecmp(const char *d, const uint16_t *s, size_t l)
 {
        for (; l--; d++, s++)
                if (*d != CDF_TOLE2(*s))
-                       return (unsigned char)*d - CDF_TOLE2(*s);
+                       return CAST(unsigned char, *d) - CDF_TOLE2(*s);
        return 0;
 }
 
@@ -924,7 +932,7 @@ cdf_copy_info(cdf_property_info_t *inp, const void *p, const void *e,
        if (inp->pi_type & CDF_VECTOR)
                return 0;
 
-       if ((size_t)(CAST(const char *, e) - CAST(const char *, p)) < len)
+       if (CAST(size_t, CAST(const char *, e) - CAST(const char *, p)) < len)
                return 0;
 
        (void)memcpy(&inp->pi_val, p, len);
@@ -1110,8 +1118,9 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h,
        const cdf_summary_info_header_t *si =
            CAST(const cdf_summary_info_header_t *, sst->sst_tab);
        const cdf_section_declaration_t *sd =
-           CAST(const cdf_section_declaration_t *, (const void *)
-           ((const char *)sst->sst_tab + CDF_SECTION_DECLARATION_OFFSET));
+           CAST(const cdf_section_declaration_t *, RCAST(const void *,
+           RCAST(const char *, sst->sst_tab)
+           + CDF_SECTION_DECLARATION_OFFSET));
 
        if (cdf_check_stream_offset(sst, h, si, sizeof(*si), __LINE__) == -1 ||
            cdf_check_stream_offset(sst, h, sd, sizeof(*sd), __LINE__) == -1)
@@ -1262,28 +1271,28 @@ cdf_print_elapsed_time(char *buf, size_t bufsiz, cdf_timestamp_t ts)
        int days, hours, mins, secs;
 
        ts /= CDF_TIME_PREC;
-       secs = (int)(ts % 60);
+       secs = CAST(int, ts % 60);
        ts /= 60;
-       mins = (int)(ts % 60);
+       mins = CAST(int, ts % 60);
        ts /= 60;
-       hours = (int)(ts % 24);
+       hours = CAST(int, ts % 24);
        ts /= 24;
-       days = (int)ts;
+       days = CAST(int, ts);
 
        if (days) {
                len += snprintf(buf + len, bufsiz - len, "%dd+", days);
-               if ((size_t)len >= bufsiz)
+               if (CAST(size_t, len) >= bufsiz)
                        return len;
        }
 
        if (days || hours) {
                len += snprintf(buf + len, bufsiz - len, "%.2d:", hours);
-               if ((size_t)len >= bufsiz)
+               if (CAST(size_t, len) >= bufsiz)
                        return len;
        }
 
        len += snprintf(buf + len, bufsiz - len, "%.2d:", mins);
-       if ((size_t)len >= bufsiz)
+       if (CAST(size_t, len) >= bufsiz)
                return len;
 
        len += snprintf(buf + len, bufsiz - len, "%.2d", secs);
@@ -1295,7 +1304,7 @@ cdf_u16tos8(char *buf, size_t len, const uint16_t *p)
 {
        size_t i;
        for (i = 0; i < len && p[i]; i++)
-               buf[i] = (char)p[i];
+               buf[i] = CAST(char, p[i]);
        buf[i] = '\0';
        return buf;
 }
index 7836938..2f7e554 100644 (file)
--- a/src/cdf.h
+++ b/src/cdf.h
@@ -76,9 +76,9 @@ typedef struct {
        cdf_secid_t     h_master_sat[436/4];
 } cdf_header_t;
 
-#define CDF_SEC_SIZE(h) ((size_t)(1 << (h)->h_sec_size_p2))
+#define CDF_SEC_SIZE(h) CAST(size_t, 1 << (h)->h_sec_size_p2)
 #define CDF_SEC_POS(h, secid) (CDF_SEC_SIZE(h) + (secid) * CDF_SEC_SIZE(h))
-#define CDF_SHORT_SEC_SIZE(h)  ((size_t)(1 << (h)->h_short_sec_size_p2))
+#define CDF_SHORT_SEC_SIZE(h)  CAST(size_t, 1 << (h)->h_short_sec_size_p2)
 #define CDF_SHORT_SEC_POS(h, secid) ((secid) * CDF_SHORT_SEC_SIZE(h))
 
 typedef int32_t cdf_dirid_t;
index 4d2088d..bdb2d3a 100644 (file)
@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: cdf_time.c,v 1.17 2018/09/09 20:33:28 christos Exp $")
+FILE_RCSID("@(#)$File: cdf_time.c,v 1.18 2019/02/20 02:35:27 christos Exp $")
 #endif
 
 #include <time.h>
@@ -90,9 +90,9 @@ cdf_getmonth(int year, int days)
                if (m == 1 && isleap(year))
                        days--;
                if (days <= 0)
-                       return (int)m;
+                       return CAST(int, m);
        }
-       return (int)m;
+       return CAST(int, m);
 }
 
 int
@@ -108,22 +108,22 @@ cdf_timestamp_to_timespec(struct timespec *ts, cdf_timestamp_t t)
        ts->tv_nsec = (t % CDF_TIME_PREC) * 100;
 
        t /= CDF_TIME_PREC;
-       tm.tm_sec = (int)(t % 60);
+       tm.tm_sec = CAST(int, t % 60);
        t /= 60;
 
-       tm.tm_min = (int)(t % 60);
+       tm.tm_min = CAST(int, t % 60);
        t /= 60;
 
-       tm.tm_hour = (int)(t % 24);
+       tm.tm_hour = CAST(int, t % 24);
        t /= 24;
 
        /* XXX: Approx */
-       tm.tm_year = (int)(CDF_BASE_YEAR + (t / 365));
+       tm.tm_year = CAST(int, CDF_BASE_YEAR + (t / 365));
 
        rdays = cdf_getdays(tm.tm_year);
        t -= rdays - 1;
-       tm.tm_mday = cdf_getday(tm.tm_year, (int)t);
-       tm.tm_mon = cdf_getmonth(tm.tm_year, (int)t);
+       tm.tm_mday = cdf_getday(tm.tm_year, CAST(int, t));
+       tm.tm_mon = cdf_getmonth(tm.tm_year, CAST(int, t));
        tm.tm_wday = 0;
        tm.tm_yday = 0;
        tm.tm_isdst = 0;
@@ -172,7 +172,7 @@ cdf_ctime(const time_t *sec, char *buf)
        if (ptr != NULL)
                return buf;
        (void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n",
-           (long long)*sec);
+           CAST(long long, *sec));
        return buf;
 }
 
index d229219..89fc570 100644 (file)
@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: compress.c,v 1.113 2018/10/15 16:29:16 christos Exp $")
+FILE_RCSID("@(#)$File: compress.c,v 1.115 2019/02/20 02:35:27 christos Exp $")
 #endif
 
 #include "magic.h"
@@ -378,7 +378,7 @@ sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
                (void)ioctl(fd, FIONREAD, &t);
        }
 
-       if (t > 0 && (size_t)t < n) {
+       if (t > 0 && CAST(size_t, t) < n) {
                n = t;
                rn = n;
        }
@@ -422,7 +422,7 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
 #else
        {
                int te;
-               int ou = umask(0);
+               mode_t ou = umask(0);
                tfd = mkstemp(buf);
                (void)umask(ou);
                te = errno;
@@ -436,11 +436,11 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
                return -1;
        }
 
-       if (swrite(tfd, startbuf, nbytes) != (ssize_t)nbytes)
+       if (swrite(tfd, startbuf, nbytes) != CAST(ssize_t, nbytes))
                r = 1;
        else {
                while ((r = sread(fd, buf, sizeof(buf), 1)) > 0)
-                       if (swrite(tfd, buf, (size_t)r) != r)
+                       if (swrite(tfd, buf, CAST(size_t, r)) != r)
                                break;
        }
 
@@ -465,7 +465,7 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
                return -1;
        }
        (void)close(tfd);
-       if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) {
+       if (lseek(fd, CAST(off_t, 0), SEEK_SET) == CAST(off_t, -1)) {
                file_badseek(ms);
                return -1;
        }
@@ -542,7 +542,7 @@ uncompresszlib(const unsigned char *old, unsigned char **newch,
        if (rc != Z_OK && rc != Z_STREAM_END)
                goto err;
 
-       *n = (size_t)z.total_out;
+       *n = CAST(size_t, z.total_out);
        rc = inflateEnd(&z);
        if (rc != Z_OK)
                goto err;
@@ -552,8 +552,8 @@ uncompresszlib(const unsigned char *old, unsigned char **newch,
 
        return OKDATA;
 err:
-       strlcpy((char *)*newch, z.msg ? z.msg : zError(rc), bytes_max);
-       *n = strlen((char *)*newch);
+       strlcpy(RCAST(char *, *newch), z.msg ? z.msg : zError(rc), bytes_max);
+       *n = strlen(RCAST(char *, *newch));
        return ERRDATA;
 }
 #endif
@@ -573,7 +573,7 @@ makeerror(unsigned char **buf, size_t *len, const char *fmt, ...)
                *len = 0;
                return NODATA;
        }
-       *buf = (unsigned char *)msg;
+       *buf = RCAST(unsigned char *, msg);
        *len = strlen(msg);
        return ERRDATA;
 }
@@ -621,7 +621,7 @@ writechild(int fdp[3][2], const void *old, size_t n)
        switch (fork()) {
        case 0: /* child */
                closefd(fdp[STDOUT_FILENO], 0);
-               if (swrite(fdp[STDIN_FILENO][1], old, n) != (ssize_t)n) {
+               if (swrite(fdp[STDIN_FILENO][1], old, n) != CAST(ssize_t, n)) {
                        DPRINTF("Write failed (%s)\n", strerror(errno));
                        exit(1);
                }
@@ -650,17 +650,17 @@ filter_error(unsigned char *ubuf, ssize_t n)
        char *buf;
 
        ubuf[n] = '\0';
-       buf = (char *)ubuf;
-       while (isspace((unsigned char)*buf))
+       buf = RCAST(char *, ubuf);
+       while (isspace(CAST(unsigned char, *buf)))
                buf++;
        DPRINTF("Filter error[[[%s]]]\n", buf);
-       if ((p = strchr((char *)buf, '\n')) != NULL)
+       if ((p = strchr(CAST(char *, buf), '\n')) != NULL)
                *p = '\0';
-       if ((p = strchr((char *)buf, ';')) != NULL)
+       if ((p = strchr(CAST(char *, buf), ';')) != NULL)
                *p = '\0';
-       if ((p = strrchr((char *)buf, ':')) != NULL) {
+       if ((p = strrchr(CAST(char *, buf), ':')) != NULL) {
                ++p;
-               while (isspace((unsigned char)*p))
+               while (isspace(CAST(unsigned char, *p)))
                        p++;
                n = strlen(p);
                memmove(ubuf, p, CAST(size_t, n + 1));
@@ -715,14 +715,14 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
        case 0: /* child */
                if (fd != -1) {
                        fdp[STDIN_FILENO][0] = fd;
-                       (void) lseek(fd, (off_t)0, SEEK_SET);
+                       (void) lseek(fd, CAST(off_t, 0), SEEK_SET);
                }
 
                for (i = 0; i < __arraycount(fdp); i++)
                        copydesc(CAST(int, i), fdp[i]);
 
                (void)execvp(compr[method].argv[0],
-                   (char *const *)(intptr_t)compr[method].argv);
+                   RCAST(char *const *, RCAST(intptr_t, compr[method].argv)));
                dprintf(STDERR_FILENO, "exec `%s' failed, %s",
                    compr[method].argv[0], strerror(errno));
                exit(1);
index cc27769..8867c56 100644 (file)
--- a/src/der.c
+++ b/src/der.c
@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: der.c,v 1.15 2018/10/15 16:29:16 christos Exp $")
+FILE_RCSID("@(#)$File: der.c,v 1.16 2019/02/20 02:35:27 christos Exp $")
 #endif
 #endif
 
@@ -56,7 +56,7 @@ FILE_RCSID("@(#)$File: der.c,v 1.15 2018/10/15 16:29:16 christos Exp $")
 #include <err.h>
 #endif
 
-#define DER_BAD        ((uint32_t)-1)
+#define DER_BAD        CAST(uint32_t, -1)
 
 #define DER_CLASS_UNIVERSAL    0
 #define        DER_CLASS_APPLICATION   1
@@ -224,7 +224,7 @@ der_data(char *buf, size_t blen, uint32_t tag, const void *q, uint32_t len)
        case DER_TAG_UTF8_STRING:
        case DER_TAG_IA5_STRING:
        case DER_TAG_UTCTIME:
-               return snprintf(buf, blen, "%.*s", len, (const char *)q);
+               return snprintf(buf, blen, "%.*s", len, RCAST(const char *, q));
        default:
                break;
        }
@@ -307,13 +307,13 @@ again:
                s++;
                goto val;
        default:
-               if (!isdigit((unsigned char)*s))
+               if (!isdigit(CAST(unsigned char, *s)))
                        return 0;
 
                slen = 0;
                do
                        slen = slen * 10 + *s - '0';
-               while (isdigit((unsigned char)*++s));
+               while (isdigit(CAST(unsigned char, *++s)));
                if ((ms->flags & MAGIC_DEBUG) != 0)
                        fprintf(stderr, "%s: len %" SIZE_T_FORMAT "u %u\n",
                            __func__, slen, tlen);
index 3b65038..936d8dc 100644 (file)
@@ -41,8 +41,8 @@
                        return toomany(ms, "program headers", phnum);
                flags |= FLAGS_IS_CORE;
                if (dophn_core(ms, clazz, swap, fd,
-                   (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
-                   (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+                   CAST(off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
+                   CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)),
                    fsize, &flags, &notecount) == -1)
                        return -1;
                break;
@@ -56,8 +56,8 @@
                if (shnum > ms->elf_shnum_max)
                        return toomany(ms, "section", shnum);
                if (dophn_exec(ms, clazz, swap, fd,
-                   (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
-                   (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+                   CAST(off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
+                   CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)),
                    fsize, shnum, &flags, &notecount) == -1)
                        return -1;
                /*FALLTHROUGH*/
                if (shnum > ms->elf_shnum_max)
                        return toomany(ms, "section headers", shnum);
                if (doshn(ms, clazz, swap, fd,
-                   (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
-                   (size_t)elf_getu16(swap, elfhdr.e_shentsize),
+                   CAST(off_t, elf_getu(swap, elfhdr.e_shoff)), shnum,
+                   CAST(size_t, elf_getu16(swap, elfhdr.e_shentsize)),
                    fsize, elf_getu16(swap, elfhdr.e_machine),
-                   (int)elf_getu16(swap, elfhdr.e_shstrndx),
+                   CAST(int, elf_getu16(swap, elfhdr.e_shstrndx)),
                    &flags, &notecount) == -1)
                        return -1;
                break;
index ef8493d..81cd925 100644 (file)
@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: encoding.c,v 1.15 2018/10/15 16:29:16 christos Exp $")
+FILE_RCSID("@(#)$File: encoding.c,v 1.17 2019/02/20 02:35:27 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -49,6 +49,7 @@ private int looks_utf8_with_BOM(const unsigned char *, size_t, unichar *,
     size_t *);
 private int looks_utf7(const unsigned char *, size_t, unichar *, size_t *);
 private int looks_ucs16(const unsigned char *, size_t, unichar *, size_t *);
+private int looks_ucs32(const unsigned char *, size_t, unichar *, size_t *);
 private int looks_latin1(const unsigned char *, size_t, unichar *, size_t *);
 private int looks_extended(const unsigned char *, size_t, unichar *, size_t *);
 private void from_ebcdic(const unsigned char *, size_t, unsigned char *);
@@ -88,12 +89,12 @@ file_encoding(struct magic_set *ms, const struct buffer *b, unichar **ubuf,
        *code_mime = "binary";
 
        mlen = (nbytes + 1) * sizeof((*ubuf)[0]);
-       if ((*ubuf = CAST(unichar *, calloc((size_t)1, mlen))) == NULL) {
+       if ((*ubuf = CAST(unichar *, calloc(CAST(size_t, 1), mlen))) == NULL) {
                file_oomem(ms, mlen);
                goto done;
        }
        mlen = (nbytes + 1) * sizeof(nbuf[0]);
-       if ((nbuf = CAST(unsigned char *, calloc((size_t)1, mlen))) == NULL) {
+       if ((nbuf = CAST(unsigned char *, calloc(CAST(size_t, 1), mlen))) == NULL) {
                file_oomem(ms, mlen);
                goto done;
        }
@@ -116,6 +117,15 @@ file_encoding(struct magic_set *ms, const struct buffer *b, unichar **ubuf,
                DPRINTF(("utf8 %" SIZE_T_FORMAT "u\n", *ulen));
                *code = "UTF-8 Unicode";
                *code_mime = "utf-8";
+       } else if ((ucs_type = looks_ucs32(buf, nbytes, *ubuf, ulen)) != 0) {
+               if (ucs_type == 1) {
+                       *code = "Little-endian UTF-32 Unicode";
+                       *code_mime = "utf-32le";
+               } else {
+                       *code = "Big-endian UTF-32 Unicode";
+                       *code_mime = "utf-32be";
+               }
+               DPRINTF(("ucs32 %" SIZE_T_FORMAT "u\n", *ulen));
        } else if ((ucs_type = looks_ucs16(buf, nbytes, *ubuf, ulen)) != 0) {
                if (ucs_type == 1) {
                        *code = "Little-endian UTF-16 Unicode";
@@ -410,7 +420,7 @@ looks_utf7(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
 }
 
 private int
-looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf,
+looks_ucs16(const unsigned char *bf, size_t nbytes, unichar *ubf,
     size_t *ulen)
 {
        int bigend;
@@ -419,9 +429,9 @@ looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf,
        if (nbytes < 2)
                return 0;
 
-       if (buf[0] == 0xff && buf[1] == 0xfe)
+       if (bf[0] == 0xff && bf[1] == 0xfe)
                bigend = 0;
-       else if (buf[0] == 0xfe && buf[1] == 0xff)
+       else if (bf[0] == 0xfe && bf[1] == 0xff)
                bigend = 1;
        else
                return 0;
@@ -432,20 +442,58 @@ looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf,
                /* XXX fix to properly handle chars > 65536 */
 
                if (bigend)
-                       ubuf[(*ulen)++] = buf[i + 1] + 256 * buf[i];
+                       ubf[(*ulen)++] = bf[i + 1] + 256 * bf[i];
                else
-                       ubuf[(*ulen)++] = buf[i] + 256 * buf[i + 1];
+                       ubf[(*ulen)++] = bf[i] + 256 * bf[i + 1];
 
-               if (ubuf[*ulen - 1] == 0xfffe)
+               if (ubf[*ulen - 1] == 0xfffe)
                        return 0;
-               if (ubuf[*ulen - 1] < 128 &&
-                   text_chars[(size_t)ubuf[*ulen - 1]] != T)
+               if (ubf[*ulen - 1] < 128 &&
+                   text_chars[CAST(size_t, ubf[*ulen - 1])] != T)
                        return 0;
        }
 
        return 1 + bigend;
 }
 
+private int
+looks_ucs32(const unsigned char *bf, size_t nbytes, unichar *ubf,
+    size_t *ulen)
+{
+       int bigend;
+       size_t i;
+
+       if (nbytes < 4)
+               return 0;
+
+       if (bf[0] == 0xff && bf[1] == 0xfe && bf[2] == 0 && bf[3] == 0)
+               bigend = 0;
+       else if (bf[0] == 0 && bf[1] == 0 && bf[2] == 0xfe && bf[3] == 0xff)
+               bigend = 1;
+       else
+               return 0;
+
+       *ulen = 0;
+
+       for (i = 4; i + 1 < nbytes; i += 4) {
+               /* XXX fix to properly handle chars > 65536 */
+
+               if (bigend)
+                       ubf[(*ulen)++] = bf[i + 3] | (bf[i + 2] << 8)
+                           | (bf[i + 1] << 16) | bf[i] << 24;
+               else
+                       ubf[(*ulen)++] = bf[i] | (bf[i + 1] << 8) 
+                           | (bf[i + 2] << 16) | (bf[i + 3] << 24);
+
+               if (ubf[*ulen - 1] == 0xfffe)
+                       return 0;
+               if (ubf[*ulen - 1] < 128 &&
+                   text_chars[CAST(size_t, ubf[*ulen - 1])] != T)
+                       return 0;
+       }
+
+       return 1 + bigend;
+}
 #undef F
 #undef T
 #undef I
index 67ef8e7..5f0303e 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: file.c,v 1.178 2018/10/01 18:50:31 christos Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.179 2019/02/20 02:35:27 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -400,7 +400,8 @@ main(int argc, char *argv[])
        }
        else {
                size_t j, wid, nw;
-               for (wid = 0, j = (size_t)optind; j < (size_t)argc; j++) {
+               for (wid = 0, j = CAST(size_t, optind); j < CAST(size_t, argc);
+                   j++) {
                        nw = file_mbswidth(argv[j]);
                        if (nw > wid)
                                wid = nw;
@@ -537,9 +538,8 @@ process(struct magic_set *ms, const char *inname, int wid)
                        (void)putc('\0', stdout);
                if (nulsep < 2) {
                        (void)printf("%s", separator);
-                       (void)printf("%*s ",
-                           (int) (nopad ? 0 : (wid - file_mbswidth(inname))),
-                           "");
+                       (void)printf("%*s ", CAST(int, nopad ? 0
+                           : (wid - file_mbswidth(inname))), "");
                }
        }
 
@@ -566,8 +566,8 @@ file_mbswidth(const char *s)
 
        while (n > 0) {
                bytesconsumed = mbrtowc(&nextchar, s, n, &state);
-               if (bytesconsumed == (size_t)(-1) ||
-                   bytesconsumed == (size_t)(-2)) {
+               if (bytesconsumed == CAST(size_t, -1) ||
+                   bytesconsumed == CAST(size_t, -2)) {
                        /* Something went wrong, return something reasonable */
                        return old_n;
                }
@@ -626,13 +626,13 @@ docprint(const char *opts, int def)
        for (sp = p - 1; sp > opts && *sp == ' '; sp--)
                continue;
 
-       fprintf(stdout, "%.*s", (int)(p - opts), opts);
+       fprintf(stdout, "%.*s", CAST(int, p - opts), opts);
 
        comma = 0;
        for (i = 0; i < __arraycount(nv); i++) {
                fprintf(stdout, "%s%s", comma++ ? ", " : "", nv[i].name);
                if (i && i % 5 == 0 && i != __arraycount(nv) - 1) {
-                       fprintf(stdout, ",\n%*s", (int)(p - sp - 1), "");
+                       fprintf(stdout, ",\n%*s", CAST(int, p - sp - 1), "");
                        comma = 0;
                }
        }
index ce2ff7d..f8e0835 100644 (file)
@@ -27,7 +27,7 @@
  */
 /*
  * file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.199 2018/10/15 16:29:16 christos Exp $
+ * @(#)$File: file.h,v 1.202 2019/02/18 17:46:56 christos Exp $
  */
 
 #ifndef __file_h__
@@ -382,7 +382,7 @@ struct mlist {
 #define CCAST(T, b)    const_cast<T>(b)
 #else
 #define CAST(T, b)     ((T)(b))
-#define RCAST(T, b)    ((T)(b))
+#define RCAST(T, b)    ((T)(uintptr_t)(b))
 #define CCAST(T, b)    ((T)(uintptr_t)(b))
 #endif
 
@@ -506,7 +506,7 @@ protected int file_looks_utf8(const unsigned char *, size_t, unichar *,
     size_t *);
 protected size_t file_pstring_length_size(const struct magic *);
 protected size_t file_pstring_get_length(const struct magic *, const char *);
-protected char * file_printable(char *, size_t, const char *);
+protected char * file_printable(char *, size_t, const char *, size_t);
 #ifdef __EMX__
 protected int file_os2_apptype(struct magic_set *, const char *, const void *,
     size_t);
index 48c8553..eca99ad 100644 (file)
@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.100 2018/10/01 18:45:39 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.102 2019/02/20 02:35:27 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -392,9 +392,9 @@ file_reset(struct magic_set *ms, int checkloaded)
 #define OCTALIFY(n, o) \
        /*LINTED*/ \
        (void)(*(n)++ = '\\', \
-       *(n)++ = (((uint32_t)*(o) >> 6) & 3) + '0', \
-       *(n)++ = (((uint32_t)*(o) >> 3) & 7) + '0', \
-       *(n)++ = (((uint32_t)*(o) >> 0) & 7) + '0', \
+       *(n)++ = ((CAST(uint32_t, *(o)) >> 6) & 3) + '0', \
+       *(n)++ = ((CAST(uint32_t, *(o)) >> 3) & 7) + '0', \
+       *(n)++ = ((CAST(uint32_t, *(o)) >> 0) & 7) + '0', \
        (o)++)
 
 protected const char *
@@ -440,9 +440,9 @@ file_getbuffer(struct magic_set *ms)
 
                while (op < eop) {
                        bytesconsumed = mbrtowc(&nextchar, op,
-                           (size_t)(eop - op), &state);
-                       if (bytesconsumed == (size_t)(-1) ||
-                           bytesconsumed == (size_t)(-2)) {
+                           CAST(size_t, eop - op), &state);
+                       if (bytesconsumed == CAST(size_t, -1) ||
+                           bytesconsumed == CAST(size_t, -2)) {
                                mb_conv = 0;
                                break;
                        }
@@ -465,7 +465,7 @@ file_getbuffer(struct magic_set *ms)
 #endif
 
        for (np = ms->o.pbuf, op = ms->o.buf; *op;) {
-               if (isprint((unsigned char)*op)) {
+               if (isprint(CAST(unsigned char, *op))) {
                        *np++ = *op++;
                } else {
                        OCTALIFY(np, op);
@@ -623,12 +623,13 @@ file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
  * convert string to ascii printable format.
  */
 protected char *
-file_printable(char *buf, size_t bufsiz, const char *str)
+file_printable(char *buf, size_t bufsiz, const char *str, size_t slen)
 {
-       char *ptr, *eptr;
-       const unsigned char *s = (const unsigned char *)str;
+       char *ptr, *eptr = buf + bufsiz - 1;
+       const unsigned char *s = RCAST(const unsigned char *, str);
+       const unsigned char *es = s + slen;
 
-       for (ptr = buf, eptr = ptr + bufsiz - 1; ptr < eptr && *s; s++) {
+       for (ptr = buf;  ptr < eptr && s < es && *s; s++) {
                if (isprint(*s)) {
                        *ptr++ = *s;
                        continue;
index b2acc38..a8a6eca 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: is_json.c,v 1.11 2018/10/15 16:29:16 christos Exp $")
+FILE_RCSID("@(#)$File: is_json.c,v 1.12 2018/10/19 00:26:26 christos Exp $")
 #endif
 
 #include <string.h>
@@ -44,7 +44,7 @@ FILE_RCSID("@(#)$File: is_json.c,v 1.11 2018/10/15 16:29:16 christos Exp $")
 #define DPRINTF(a, b, c)       \
     printf("%s [%.2x/%c] %.20s\n", (a), *(b), *(b), (const char *)(c))
 #else
-#define DPRINTF(a, b, c)       (void)0
+#define DPRINTF(a, b, c)       do { } while (/*CONSTCOND*/0)
 #endif
 
 #define JSON_ARRAY     0
index 2f67245..82b0805 100644 (file)
@@ -40,7 +40,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: is_tar.c,v 1.43 2018/10/15 16:29:16 christos Exp $")
+FILE_RCSID("@(#)$File: is_tar.c,v 1.44 2019/02/20 02:35:27 christos Exp $")
 #endif
 
 #include "magic.h"
@@ -98,7 +98,8 @@ file_is_tar(struct magic_set *ms, const struct buffer *b)
 private int
 is_tar(const unsigned char *buf, size_t nbytes)
 {
-       const union record *header = (const union record *)(const void *)buf;
+       const union record *header = RCAST(const union record *,
+           RCAST(const void *, buf));
        size_t i;
        int sum, recsum;
        const unsigned char *p, *ep;
@@ -147,7 +148,7 @@ from_oct(const char *where, size_t digs)
        if (digs == 0)
                return -1;
 
-       while (isspace((unsigned char)*where)) {        /* Skip spaces */
+       while (isspace(CAST(unsigned char, *where))) {  /* Skip spaces */
                where++;
                if (digs-- == 0)
                        return -1;              /* All blank field */
@@ -158,7 +159,7 @@ from_oct(const char *where, size_t digs)
                digs--;
        }
 
-       if (digs > 0 && *where && !isspace((unsigned char)*where))
+       if (digs > 0 && *where && !isspace(CAST(unsigned char, *where)))
                return -1;                      /* Ended on non-(space/NUL) */
 
        return value;
index 7f469c5..2207f08 100644 (file)
@@ -33,7 +33,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: magic.c,v 1.106 2018/10/01 18:45:39 christos Exp $")
+FILE_RCSID("@(#)$File: magic.c,v 1.109 2019/02/20 02:35:27 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -312,7 +312,8 @@ magic_load_buffers(struct magic_set *ms, void **bufs, size_t *sizes,
 {
        if (ms == NULL)
                return -1;
-       return buffer_apprentice(ms, (struct magic **)bufs, sizes, nbufs);
+       return buffer_apprentice(ms, RCAST(struct magic **, bufs),
+           sizes, nbufs);
 }
 #endif
 
@@ -405,7 +406,7 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
        struct stat     sb;
        ssize_t nbytes = 0;     /* number of bytes read from a datafile */
        int     ispipe = 0;
-       off_t   pos = (off_t)-1;
+       off_t   pos = CAST(off_t, -1);
 
        if (file_reset(ms, 1) == -1)
                goto out;
@@ -464,7 +465,7 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
                if (fstat(fd, &sb) == 0 && S_ISFIFO(sb.st_mode))
                        ispipe = 1;
                if (inname == NULL)
-                       pos = lseek(fd, (off_t)0, SEEK_CUR);
+                       pos = lseek(fd, CAST(off_t, 0), SEEK_CUR);
        }
 
        /*
@@ -473,8 +474,8 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
        if (ispipe) {
                ssize_t r = 0;
 
-               while ((r = sread(fd, (void *)&buf[nbytes],
-                   (size_t)(ms->bytes_max - nbytes), 1)) > 0) {
+               while ((r = sread(fd, RCAST(void *, &buf[nbytes]),
+                   CAST(size_t, ms->bytes_max - nbytes), 1)) > 0) {
                        nbytes += r;
                        if (r < PIPE_BUF) break;
                }
@@ -494,7 +495,7 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
                                _isatty(fd) ? 8 * 1024 :
 #endif
                                ms->bytes_max;
-               if ((nbytes = read(fd, (char *)buf, howmany)) == -1) {
+               if ((nbytes = read(fd, RCAST(void *, buf), howmany)) == -1) {
                        if (inname == NULL && fd != STDIN_FILENO)
                                file_error(ms, errno, "cannot read fd %d", fd);
                        else
@@ -505,13 +506,13 @@ 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, inname, buf, (size_t)nbytes) == -1)
+       if (file_buffer(ms, fd, inname, buf, CAST(size_t, nbytes)) == -1)
                goto done;
        rv = 0;
 done:
        free(buf);
        if (fd != -1) {
-               if (pos != (off_t)-1)
+               if (pos != CAST(off_t, -1))
                        (void)lseek(fd, pos, SEEK_SET);
                close_and_restore(ms, inname, fd, &sb);
        }
@@ -589,25 +590,25 @@ magic_setparam(struct magic_set *ms, int param, const void *val)
                return -1;
        switch (param) {
        case MAGIC_PARAM_INDIR_MAX:
-               ms->indir_max = (uint16_t)*(const size_t *)val;
+               ms->indir_max = CAST(uint16_t, *CAST(const size_t *, val));
                return 0;
        case MAGIC_PARAM_NAME_MAX:
-               ms->name_max = (uint16_t)*(const size_t *)val;
+               ms->name_max = CAST(uint16_t, *CAST(const size_t *, val));
                return 0;
        case MAGIC_PARAM_ELF_PHNUM_MAX:
-               ms->elf_phnum_max = (uint16_t)*(const size_t *)val;
+               ms->elf_phnum_max = CAST(uint16_t, *CAST(const size_t *, val));
                return 0;
        case MAGIC_PARAM_ELF_SHNUM_MAX:
-               ms->elf_shnum_max = (uint16_t)*(const size_t *)val;
+               ms->elf_shnum_max = CAST(uint16_t, *CAST(const size_t *, val));
                return 0;
        case MAGIC_PARAM_ELF_NOTES_MAX:
-               ms->elf_notes_max = (uint16_t)*(const size_t *)val;
+               ms->elf_notes_max = CAST(uint16_t, *CAST(const size_t *, val));
                return 0;
        case MAGIC_PARAM_REGEX_MAX:
-               ms->elf_notes_max = (uint16_t)*(const size_t *)val;
+               ms->regex_max = CAST(uint16_t, *CAST(const size_t *, val));
                return 0;
        case MAGIC_PARAM_BYTES_MAX:
-               ms->bytes_max = *(const size_t *)val;
+               ms->bytes_max = *CAST(const size_t *, val);
                return 0;
        default:
                errno = EINVAL;
@@ -622,25 +623,25 @@ magic_getparam(struct magic_set *ms, int param, void *val)
                return -1;
        switch (param) {
        case MAGIC_PARAM_INDIR_MAX:
-               *(size_t *)val = ms->indir_max;
+               *CAST(size_t *, val) = ms->indir_max;
                return 0;
        case MAGIC_PARAM_NAME_MAX:
-               *(size_t *)val = ms->name_max;
+               *CAST(size_t *, val) = ms->name_max;
                return 0;
        case MAGIC_PARAM_ELF_PHNUM_MAX:
-               *(size_t *)val = ms->elf_phnum_max;
+               *CAST(size_t *, val) = ms->elf_phnum_max;
                return 0;
        case MAGIC_PARAM_ELF_SHNUM_MAX:
-               *(size_t *)val = ms->elf_shnum_max;
+               *CAST(size_t *, val) = ms->elf_shnum_max;
                return 0;
        case MAGIC_PARAM_ELF_NOTES_MAX:
-               *(size_t *)val = ms->elf_notes_max;
+               *CAST(size_t *, val) = ms->elf_notes_max;
                return 0;
        case MAGIC_PARAM_REGEX_MAX:
-               *(size_t *)val = ms->regex_max;
+               *CAST(size_t *, val) = ms->regex_max;
                return 0;
        case MAGIC_PARAM_BYTES_MAX:
-               *(size_t *)val = ms->bytes_max;
+               *CAST(size_t *, val) = ms->bytes_max;
                return 0;
        default:
                errno = EINVAL;
index 23f6051..6dad1de 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: print.c,v 1.83 2018/09/09 20:33:28 christos Exp $")
+FILE_RCSID("@(#)$File: print.c,v 1.84 2019/02/20 02:35:27 christos Exp $")
 #endif  /* lint */
 
 #include <string.h>
@@ -65,7 +65,7 @@ file_mdump(struct magic *m)
                if (m->in_op & FILE_OPINVERSE)
                        (void) fputc('~', stderr);
                (void) fprintf(stderr, "%c%u),",
-                   ((size_t)(m->in_op & FILE_OPS_MASK) <
+                   (CAST(size_t, m->in_op & FILE_OPS_MASK) <
                    SZOF(optyp)) ? optyp[m->in_op & FILE_OPS_MASK] : '?',
                    m->in_offset);
        }
@@ -112,14 +112,14 @@ file_mdump(struct magic *m)
                        (void) fprintf(stderr, "/%u", m->str_range);
        }
        else {
-               if ((size_t)(m->mask_op & FILE_OPS_MASK) < SZOF(optyp))
+               if (CAST(size_t, m->mask_op & FILE_OPS_MASK) < SZOF(optyp))
                        (void) fputc(optyp[m->mask_op & FILE_OPS_MASK], stderr);
                else
                        (void) fputc('?', stderr);
 
                if (m->num_mask) {
                        (void) fprintf(stderr, "%.8llx",
-                           (unsigned long long)m->num_mask);
+                           CAST(unsigned long long, m->num_mask));
                }
        }
        (void) fprintf(stderr, ",%c", m->reln);
@@ -141,7 +141,7 @@ file_mdump(struct magic *m)
                case FILE_LEQUAD:
                case FILE_QUAD:
                        (void) fprintf(stderr, "%" INT64_T_FORMAT "d",
-                           (unsigned long long)m->value.q);
+                           CAST(long long, m->value.q));
                        break;
                case FILE_PSTRING:
                case FILE_STRING:
@@ -149,7 +149,8 @@ file_mdump(struct magic *m)
                case FILE_BESTRING16:
                case FILE_LESTRING16:
                case FILE_SEARCH:
-                       file_showstr(stderr, m->value.s, (size_t)m->vallen);
+                       file_showstr(stderr, m->value.s,
+                           CAST(size_t, m->vallen));
                        break;
                case FILE_DATE:
                case FILE_LEDATE:
@@ -221,7 +222,7 @@ file_magwarn(struct magic_set *ms, const char *f, ...)
 
        if (ms->file)
                (void) fprintf(stderr, "%s, %lu: ", ms->file,
-                   (unsigned long)ms->line);
+                   CAST(unsigned long, ms->line));
        (void) fprintf(stderr, "Warning: ");
        va_start(va, f);
        (void) vfprintf(stderr, f, va);
@@ -243,7 +244,7 @@ file_fmttime(uint64_t v, int flags, char *buf)
        } else {
                // XXX: perhaps detect and print something if overflow
                // on 32 bit time_t?
-               t = (time_t)v;
+               t = CAST(time_t, v);
        }
 
        if (flags & FILE_T_LOCAL) {
index b43a843..5fa98e8 100644 (file)
@@ -26,7 +26,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: readcdf.c,v 1.71 2018/10/15 16:29:16 christos Exp $")
+FILE_RCSID("@(#)$File: readcdf.c,v 1.72 2019/02/20 02:35:27 christos Exp $")
 #endif
 
 #include <assert.h>
@@ -204,7 +204,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
                                    && len--; s += k) {
                                        if (*s == '\0')
                                                break;
-                                       if (isprint((unsigned char)*s))
+                                       if (isprint(CAST(unsigned char, *s)))
                                                vbuf[j++] = *s;
                                }
                                if (j == sizeof(vbuf))
@@ -318,19 +318,19 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
                case 2:
                        if (file_printf(ms, ", Os: Windows, Version %d.%d",
                            si.si_os_version & 0xff,
-                           (uint32_t)si.si_os_version >> 8) == -1)
+                           CAST(uint32_t, si.si_os_version) >> 8) == -1)
                                return -2;
                        break;
                case 1:
                        if (file_printf(ms, ", Os: MacOS, Version %d.%d",
-                           (uint32_t)si.si_os_version >> 8,
+                           CAST(uint32_t, si.si_os_version) >> 8,
                            si.si_os_version & 0xff) == -1)
                                return -2;
                        break;
                default:
                        if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
                            si.si_os_version & 0xff,
-                           (uint32_t)si.si_os_version >> 8) == -1)
+                           CAST(uint32_t, si.si_os_version) >> 8) == -1)
                                return -2;
                        break;
                }
@@ -406,7 +406,7 @@ cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info,
        for (j = 0; str == NULL && j < dir->dir_len; j++) {
                d = &dir->dir_tab[j];
                for (k = 0; k < sizeof(name); k++)
-                       name[k] = (char)cdf_tole2(d->d_name[k]);
+                       name[k] = CAST(char, cdf_tole2(d->d_name[k]));
                str = cdf_app_to_mime(name,
                                      NOTMIME(ms) ? name2desc : name2mime);
        }
index 909e414..db43c6c 100644 (file)
@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.154 2018/10/15 16:29:16 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.162 2019/02/20 02:35:27 christos Exp $")
 #endif
 
 #ifdef BUILTIN_ELF
@@ -262,7 +262,10 @@ static const size_t        prpsoffsets32[] = {
        84,             /* SunOS 5.x (short name) */
 
        44,             /* Linux (command line) */
-       28,             /* Linux 2.0.36 (short name) */
+       28,             /* Linux (short name) */
+
+       48,             /* Linux PowerPC (command line) */
+       32,             /* Linux PowerPC (short name) */
 
        8,              /* FreeBSD */
 };
@@ -393,9 +396,9 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
                }
                offset = 0;
                for (;;) {
-                       if (offset >= (size_t)bufsize)
+                       if (offset >= CAST(size_t, bufsize))
                                break;
-                       offset = donote(ms, nbuf, offset, (size_t)bufsize,
+                       offset = donote(ms, nbuf, offset, CAST(size_t, bufsize),
                            clazz, swap, 4, flags, notecount, fd, ph_off,
                            ph_num, fsize);
                        if (offset == 0)
@@ -533,7 +536,7 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
     int swap __attribute__((__unused__)), uint32_t namesz, uint32_t descsz,
     size_t noff, size_t doff, int *flags)
 {
-       if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
+       if (namesz == 4 && strcmp(RCAST(char *, &nbuf[noff]), "GNU") == 0 &&
            type == NT_GNU_BUILD_ID && (descsz >= 4 && descsz <= 20)) {
                uint8_t desc[20];
                const char *btype;
@@ -561,10 +564,10 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
                        return 1;
                return 1;
        }
-       if (namesz == 4 && strcmp((char *)&nbuf[noff], "Go") == 0 &&
+       if (namesz == 4 && strcmp(RCAST(char *, &nbuf[noff]), "Go") == 0 &&
            type == NT_GO_BUILD_ID && descsz < 128) {
-               if (file_printf(ms, ", Go BuildID=%s",
-                   (char *)&nbuf[doff]) == -1)
+               if (file_printf(ms, ", Go BuildID=%.*s",
+                   CAST(int, descsz), RCAST(char *, &nbuf[doff])) == -1)
                        return -1;
                return 1;
        }
@@ -576,7 +579,9 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
     int swap, uint32_t namesz, uint32_t descsz,
     size_t noff, size_t doff, int *flags)
 {
-       if (namesz == 5 && strcmp((char *)&nbuf[noff], "SuSE") == 0 &&
+       const char *name = RCAST(const char *, &nbuf[noff]);
+
+       if (namesz == 5 && strcmp(name, "SuSE") == 0 &&
                type == NT_GNU_VERSION && descsz == 2) {
                *flags |= FLAGS_DID_OS_NOTE;
                if (file_printf(ms, ", for SuSE %d.%d", nbuf[doff],
@@ -585,7 +590,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
            return 1;
        }
 
-       if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
+       if (namesz == 4 && strcmp(name, "GNU") == 0 &&
            type == NT_GNU_VERSION && descsz == 16) {
                uint32_t desc[4];
                memcpy(desc, &nbuf[doff], sizeof(desc));
@@ -624,7 +629,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
                return 1;
        }
 
-       if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
+       if (namesz == 7 && strcmp(name, "NetBSD") == 0) {
                if (type == NT_NETBSD_VERSION && descsz == 4) {
                        *flags |= FLAGS_DID_OS_NOTE;
                        do_note_netbsd_version(ms, swap, &nbuf[doff]);
@@ -632,7 +637,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
                }
        }
 
-       if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
+       if (namesz == 8 && strcmp(name, "FreeBSD") == 0) {
                if (type == NT_FREEBSD_VERSION && descsz == 4) {
                        *flags |= FLAGS_DID_OS_NOTE;
                        do_note_freebsd_version(ms, swap, &nbuf[doff]);
@@ -640,7 +645,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
                }
        }
 
-       if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
+       if (namesz == 8 && strcmp(name, "OpenBSD") == 0 &&
            type == NT_OPENBSD_VERSION && descsz == 4) {
                *flags |= FLAGS_DID_OS_NOTE;
                if (file_printf(ms, ", for OpenBSD") == -1)
@@ -649,7 +654,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
                return 1;
        }
 
-       if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 &&
+       if (namesz == 10 && strcmp(name, "DragonFly") == 0 &&
            type == NT_DRAGONFLY_VERSION && descsz == 4) {
                uint32_t desc;
                *flags |= FLAGS_DID_OS_NOTE;
@@ -670,7 +675,9 @@ do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
     int swap, uint32_t namesz, uint32_t descsz,
     size_t noff, size_t doff, int *flags)
 {
-       if (namesz == 4 && strcmp((char *)&nbuf[noff], "PaX") == 0 &&
+       const char *name = RCAST(const char *, &nbuf[noff]);
+
+       if (namesz == 4 && strcmp(name, "PaX") == 0 &&
            type == NT_NETBSD_PAX && descsz == 4) {
                static const char *pax[] = {
                    "+mprotect",
@@ -692,7 +699,7 @@ do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
                        return 1;
 
                for (i = 0; i < __arraycount(pax); i++) {
-                       if (((1 << (int)i) & desc) == 0)
+                       if (((1 << CAST(int, i)) & desc) == 0)
                                continue;
                        if (file_printf(ms, "%s%s", did++ ? "," : "",
                            pax[i]) == -1)
@@ -709,6 +716,8 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
     size_t noff, size_t doff, int *flags, size_t size, int clazz)
 {
 #ifdef ELFCORE
+       const char *name = RCAST(const char *, &nbuf[noff]);
+
        int os_style = -1;
        /*
         * Sigh.  The 2.0.36 kernel in Debian 2.1, at
@@ -724,16 +733,16 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
         * doesn't include the terminating null in the
         * name....
         */
-       if ((namesz == 4 && strncmp((char *)&nbuf[noff], "CORE", 4) == 0) ||
-           (namesz == 5 && strcmp((char *)&nbuf[noff], "CORE") == 0)) {
+       if ((namesz == 4 && strncmp(name, "CORE", 4) == 0) ||
+           (namesz == 5 && strcmp(name, "CORE") == 0)) {
                os_style = OS_STYLE_SVR4;
        }
 
-       if ((namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0)) {
+       if ((namesz == 8 && strcmp(name, "FreeBSD") == 0)) {
                os_style = OS_STYLE_FREEBSD;
        }
 
-       if ((namesz >= 11 && strncmp((char *)&nbuf[noff], "NetBSD-CORE", 11)
+       if ((namesz >= 11 && strncmp(name, "NetBSD-CORE", 11)
            == 0)) {
                os_style = OS_STYLE_NETBSD;
        }
@@ -752,17 +761,17 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
                        char sbuf[512];
                        struct NetBSD_elfcore_procinfo pi;
                        memset(&pi, 0, sizeof(pi));
-                       memcpy(&pi, nbuf + doff, descsz);
+                       memcpy(&pi, nbuf + doff, MIN(descsz, sizeof(pi)));
 
                        if (file_printf(ms, ", from '%.31s', pid=%u, uid=%u, "
                            "gid=%u, nlwps=%u, lwp=%u (signal %u/code %u)",
                            file_printable(sbuf, sizeof(sbuf),
-                           RCAST(char *, pi.cpi_name)),
-                           elf_getu32(swap, (uint32_t)pi.cpi_pid),
+                           RCAST(char *, pi.cpi_name), sizeof(pi.cpi_name)),
+                           elf_getu32(swap, CAST(uint32_t, pi.cpi_pid)),
                            elf_getu32(swap, pi.cpi_euid),
                            elf_getu32(swap, pi.cpi_egid),
                            elf_getu32(swap, pi.cpi_nlwps),
-                           elf_getu32(swap, (uint32_t)pi.cpi_siglwp),
+                           elf_getu32(swap, CAST(uint32_t, pi.cpi_siglwp)),
                            elf_getu32(swap, pi.cpi_signo),
                            elf_getu32(swap, pi.cpi_sigcode)) == -1)
                                return 1;
@@ -786,8 +795,8 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
                        pidoff = argoff + 81 + 2;
                        if (doff + pidoff + 4 <= size) {
                                if (file_printf(ms, ", pid=%u",
-                                   elf_getu32(swap, *(uint32_t *)(nbuf +
-                                   doff + pidoff))) == -1)
+                                   elf_getu32(swap, *RCAST(uint32_t *, (nbuf +
+                                   doff + pidoff)))) == -1)
                                        return 1;
                        }
                        *flags |= FLAGS_DID_CORE;
@@ -876,8 +885,8 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
                                                i = k;
                                }
 
-                               cname = (unsigned char *)
-                                   &nbuf[doff + prpsoffsets(i)];
+                               cname = CAST(unsigned char *,
+                                   &nbuf[doff + prpsoffsets(i)]);
                                for (cp = cname; cp < nbuf + size && *cp
                                    && isprint(*cp); cp++)
                                        continue;
@@ -888,7 +897,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'",
-                                   (int)(cp - cname), cname) == -1)
+                                   CAST(int, cp - cname), cname) == -1)
                                        return 1;
                                *flags |= FLAGS_DID_CORE;
                                return 1;
@@ -915,7 +924,8 @@ get_offset_from_virtaddr(struct magic_set *ms, int swap, int clazz, int fd,
         * virtual address in which the "virtaddr" belongs to.
         */
        for ( ; num; num--) {
-               if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) {
+               if (pread(fd, xph_addr, xph_sizeof, off) <
+                   CAST(ssize_t, xph_sizeof)) {
                        file_badread(ms);
                        return -1;
                }
@@ -955,7 +965,7 @@ get_string_on_virtaddr(struct magic_set *ms,
 
        /* We expect only printable characters, so return if buffer contains
         * non-printable character before the '\0' or just '\0'. */
-       for (bptr = buf; *bptr && isprint((unsigned char)*bptr); bptr++)
+       for (bptr = buf; *bptr && isprint(CAST(unsigned char, *bptr)); bptr++)
                continue;
        if (*bptr != '\0')
                return 0;
@@ -1061,8 +1071,8 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
                        if (file_printf(ms, ", %s: '%s'", tag, buf) == -1)
                                return 0;
                } else {
-                       if (file_printf(ms, ", %s: %d", tag, (int) xauxv_val)
-                           == -1)
+                       if (file_printf(ms, ", %s: %d", tag,
+                           CAST(int, xauxv_val)) == -1)
                                return 0;
                }
        }
@@ -1092,7 +1102,7 @@ dodynamic(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
 
        switch (xdh_tag) {
        case DT_FLAGS_1:
-               if (xdh_val == DF_1_PIE)
+               if (xdh_val & DF_1_PIE)
                        ms->mode |= 0111;
                else
                        ms->mode &= ~0111;
@@ -1142,14 +1152,14 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
        if (namesz & 0x80000000) {
                if (file_printf(ms, ", bad note name size %#lx",
                    CAST(unsigned long, namesz)) == -1)
-                       return -1;
+                       return 0;
            return 0;
        }
 
        if (descsz & 0x80000000) {
                if (file_printf(ms, ", bad note description size %#lx",
                    CAST(unsigned long, descsz)) == -1)
-                       return -1;
+                       return 0;
            return 0;
        }
 
@@ -1655,8 +1665,10 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
                switch (xph_type) {
                case PT_DYNAMIC:
                        offset = 0;
+                       // Let DF_1 determine if we are PIE or not.
+                       ms->mode &= ~0111;
                        for (;;) {
-                               if (offset >= (size_t)bufsize)
+                               if (offset >= CAST(size_t, bufsize))
                                        break;
                                offset = dodynamic(ms, nbuf, offset,
                                    CAST(size_t, bufsize), clazz, swap);
@@ -1668,7 +1680,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
                case PT_INTERP:
                        if (bufsize && nbuf[0]) {
                                nbuf[bufsize - 1] = '\0';
-                               memcpy(interp, nbuf, bufsize);
+                               memcpy(interp, nbuf, CAST(size_t, bufsize));
                        } else
                                strlcpy(interp, "*empty*", sizeof(interp));
                        break;
@@ -1679,7 +1691,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
                         */
                        offset = 0;
                        for (;;) {
-                               if (offset >= (size_t)bufsize)
+                               if (offset >= CAST(size_t, bufsize))
                                        break;
                                offset = donote(ms, nbuf, offset,
                                    CAST(size_t, bufsize), clazz, swap, align,
@@ -1697,7 +1709,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
                return -1;
        if (interp[0])
                if (file_printf(ms, ", interpreter %s",
-                   file_printable(ibuf, sizeof(ibuf), interp)) == -1)
+                   file_printable(ibuf, sizeof(ibuf), interp, sizeof(interp)))
+                       == -1)
                        return -1;
        return 0;
 }
index 9cdbe9a..cfc1781 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.271 2018/10/15 16:29:16 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.278 2019/02/20 02:35:27 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -45,11 +45,11 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.271 2018/10/15 16:29:16 christos Exp $")
 
 private int match(struct magic_set *, struct magic *, uint32_t,
     const struct buffer *, size_t, int, int, int, uint16_t *,
-    uint16_t *, int *, int *, int *);
+    uint16_t *, int *, int *, int *, int *);
 private int mget(struct magic_set *, struct magic *, const struct buffer *,
     const unsigned char *, size_t,
     size_t, unsigned int, int, int, int, uint16_t *,
-    uint16_t *, int *, int *, int *);
+    uint16_t *, int *, int *, int *, int *);
 private int msetoffset(struct magic_set *, struct magic *, struct buffer *,
     const struct buffer *, size_t, unsigned int);
 private int magiccheck(struct magic_set *, struct magic *);
@@ -67,24 +67,46 @@ private int cvt_16(union VALUETYPE *, const struct magic *);
 private int cvt_32(union VALUETYPE *, const struct magic *);
 private int cvt_64(union VALUETYPE *, const struct magic *);
 
-#define OFFSET_OOB(n, o, i)    ((n) < (uint32_t)(o) || (i) > ((n) - (o)))
-#define BE64(p) (((uint64_t)(p)->hq[0]<<56)|((uint64_t)(p)->hq[1]<<48)| \
-    ((uint64_t)(p)->hq[2]<<40)|((uint64_t)(p)->hq[3]<<32)| \
-    ((uint64_t)(p)->hq[4]<<24)|((uint64_t)(p)->hq[5]<<16)| \
-    ((uint64_t)(p)->hq[6]<<8)|((uint64_t)(p)->hq[7]))
-#define LE64(p) (((uint64_t)(p)->hq[7]<<56)|((uint64_t)(p)->hq[6]<<48)| \
-    ((uint64_t)(p)->hq[5]<<40)|((uint64_t)(p)->hq[4]<<32)| \
-    ((uint64_t)(p)->hq[3]<<24)|((uint64_t)(p)->hq[2]<<16)| \
-    ((uint64_t)(p)->hq[1]<<8)|((uint64_t)(p)->hq[0]))
-#define LE32(p) (((uint32_t)(p)->hl[3]<<24)|((uint32_t)(p)->hl[2]<<16)| \
-     ((uint32_t)(p)->hl[1]<<8)|((uint32_t)(p)->hl[0]))
-#define BE32(p) (((uint32_t)(p)->hl[0]<<24)|((uint32_t)(p)->hl[1]<<16)| \
-     ((uint32_t)(p)->hl[2]<<8)|((uint32_t)(p)->hl[3]))
-#define ME32(p) (((uint32_t)(p)->hl[1]<<24)|((uint32_t)(p)->hl[0]<<16)| \
-     ((uint32_t)(p)->hl[3]<<8)|((uint32_t)(p)->hl[2]))
-#define BE16(p) (((uint16_t)(p)->hs[0]<<8)|((uint16_t)(p)->hs[1]))
-#define LE16(p) (((uint16_t)(p)->hs[1]<<8)|((uint16_t)(p)->hs[0]))
-#define SEXT(s,v,p) ((s)?(intmax_t)(int##v##_t)(p):(intmax_t)(uint##v##_t)(p))
+#define OFFSET_OOB(n, o, i)    ((n) < CAST(uint32_t, (o)) || (i) > ((n) - (o)))
+#define BE64(p) ( \
+    (CAST(uint64_t, (p)->hq[0])<<56)| \
+    (CAST(uint64_t, (p)->hq[1])<<48)| \
+    (CAST(uint64_t, (p)->hq[2])<<40)| \
+    (CAST(uint64_t, (p)->hq[3])<<32)| \
+    (CAST(uint64_t, (p)->hq[4])<<24)| \
+    (CAST(uint64_t, (p)->hq[5])<<16)| \
+    (CAST(uint64_t, (p)->hq[6])<<8)| \
+    (CAST(uint64_t, (p)->hq[7])))
+#define LE64(p) ( \
+    (CAST(uint64_t, (p)->hq[7])<<56)| \
+    (CAST(uint64_t, (p)->hq[6])<<48)| \
+    (CAST(uint64_t, (p)->hq[5])<<40)| \
+    (CAST(uint64_t, (p)->hq[4])<<32)| \
+    (CAST(uint64_t, (p)->hq[3])<<24)| \
+    (CAST(uint64_t, (p)->hq[2])<<16)| \
+    (CAST(uint64_t, (p)->hq[1])<<8)| \
+    (CAST(uint64_t, (p)->hq[0])))
+#define LE32(p) ( \
+    (CAST(uint32_t, (p)->hl[3])<<24)| \
+    (CAST(uint32_t, (p)->hl[2])<<16)| \
+    (CAST(uint32_t, (p)->hl[1])<<8)| \
+    (CAST(uint32_t, (p)->hl[0])))
+#define BE32(p) ( \
+    (CAST(uint32_t, (p)->hl[0])<<24)| \
+    (CAST(uint32_t, (p)->hl[1])<<16)| \
+    (CAST(uint32_t, (p)->hl[2])<<8)| \
+    (CAST(uint32_t, (p)->hl[3])))
+#define ME32(p) ( \
+    (CAST(uint32_t, (p)->hl[1])<<24)| \
+    (CAST(uint32_t, (p)->hl[0])<<16)| \
+    (CAST(uint32_t, (p)->hl[3])<<8)| \
+    (CAST(uint32_t, (p)->hl[2])))
+
+#define BE16(p) ((CAST(uint16_t, (p)->hs[0])<<8)|(CAST(uint16_t, (p)->hs[1])))
+#define LE16(p) ((CAST(uint16_t, (p)->hs[1])<<8)|(CAST(uint16_t, (p)->hs[0])))
+#define SEXT(s,v,p) ((s) ? \
+       CAST(intmax_t, CAST(int##v##_t, p)) : \
+       CAST(intmax_t, CAST(uint##v##_t, p)))
 
 /*
  * softmagic - lookup one file in parsed, in-memory copy of database
@@ -111,7 +133,7 @@ file_softmagic(struct magic_set *ms, const struct buffer *b,
        for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
                if ((rv = match(ms, ml->magic, ml->nmagic, b, 0, mode,
                    text, 0, indir_count, name_count,
-                   &printed_something, &need_separator, NULL)) != 0)
+                   &printed_something, &need_separator, NULL, NULL)) != 0)
                        return rv;
 
        return 0;
@@ -167,17 +189,25 @@ private int
 match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
     const struct buffer *b, size_t offset, int mode, int text,
     int flip, uint16_t *indir_count, uint16_t *name_count,
-    int *printed_something, int *need_separator, int *returnval)
+    int *printed_something, int *need_separator, int *returnval,
+    int *found_match)
 {
        uint32_t magindex = 0;
        unsigned int cont_level = 0;
-       int returnvalv = 0, e; /* if a match is found it is set to 1*/
+       int found_matchv = 0; /* if a match is found it is set to 1*/
+       int returnvalv = 0, e;
        int firstline = 1; /* a flag to print X\n  X\n- X */
        struct buffer bb;
        int print = (ms->flags & MAGIC_NODESC) == 0;
 
+       /*
+        * returnval can be 0 if a match is found, but there was no
+        * annotation to be printed.
+        */
        if (returnval == NULL)
                returnval = &returnvalv;
+       if (found_match == NULL)
+               found_match = &found_matchv;
 
        if (file_check_mem(ms, cont_level) == -1)
                return -1;
@@ -209,15 +239,18 @@ flush:
                switch (mget(ms, m, b, CAST(const unsigned char *, bb.fbuf),
                    bb.flen, offset, cont_level,
                    mode, text, flip, indir_count, name_count,
-                   printed_something, need_separator, returnval)) {
+                   printed_something, need_separator, returnval, found_match))
+               {
                case -1:
                        return -1;
                case 0:
                        flush = m->reln != '!';
                        break;
                default:
-                       if (m->type == FILE_INDIRECT)
+                       if (m->type == FILE_INDIRECT) {
+                               *found_match = 1;
                                *returnval = 1;
+                       }
 
                        switch (magiccheck(ms, m)) {
                        case -1:
@@ -239,6 +272,9 @@ flush:
                        goto flush;
                }
 
+               if (*m->desc)
+                       *found_match = 1;
+
                if ((e = handle_annotation(ms, m, firstline)) != 0)
                {
                        *need_separator = 1;
@@ -254,6 +290,7 @@ flush:
                if (print && *m->desc) {
                        *need_separator = 1;
                        *printed_something = 1;
+                       *returnval = 1;
                        if (print_sep(ms, firstline) == -1)
                                return -1;
                        if (mprint(ms, m) == -1)
@@ -304,7 +341,7 @@ flush:
                            bb.fbuf), bb.flen, offset,
                            cont_level, mode, text, flip, indir_count,
                            name_count, printed_something, need_separator,
-                           returnval)) {
+                           returnval, found_match)) {
                        case -1:
                                return -1;
                        case 0:
@@ -313,8 +350,10 @@ flush:
                                flush = 1;
                                break;
                        default:
-                               if (m->type == FILE_INDIRECT)
+                               if (m->type == FILE_INDIRECT) {
+                                       *found_match = 1;
                                        *returnval = 1;
+                               }
                                flush = 0;
                                break;
                        }
@@ -339,6 +378,9 @@ flush:
                                } else
                                        ms->c.li[cont_level].got_match = 1;
 
+                               if (*m->desc)
+                                       *found_match = 1;
+
                                if ((e = handle_annotation(ms, m, firstline))
                                    != 0) {
                                        *need_separator = 1;
@@ -370,6 +412,7 @@ flush:
                                                if (file_printf(ms, " ") == -1)
                                                        return -1;
                                        }
+                                       *returnval = 1;
                                        *need_separator = 0;
                                        if (mprint(ms, m) == -1)
                                                return -1;
@@ -399,9 +442,8 @@ flush:
                }
                if (*printed_something) {
                        firstline = 0;
-                       *returnval = 1;
                }
-               if ((ms->flags & MAGIC_CONTINUE) == 0 && *printed_something) {
+               if ((ms->flags & MAGIC_CONTINUE) == 0 && *found_match) {
                        return *returnval; /* don't keep searching */
                }
                cont_level = 0;
@@ -458,7 +500,7 @@ varexpand(struct magic_set *ms, char *buf, size_t len, const char *str)
        size_t l;
 
        for (sptr = str; (ptr = strstr(sptr, "${")) != NULL;) {
-               l = (size_t)(ptr - sptr);
+               l = CAST(size_t, ptr - sptr);
                if (l >= len)
                        return -1;
                memcpy(buf, sptr, l);
@@ -524,19 +566,19 @@ mprint(struct magic_set *ms, struct magic *m)
 
        switch (m->type) {
        case FILE_BYTE:
-               v = file_signextend(ms, m, (uint64_t)p->b);
+               v = file_signextend(ms, m, CAST(uint64_t, p->b));
                switch (check_fmt(ms, desc)) {
                case -1:
                        return -1;
                case 1:
                        (void)snprintf(buf, sizeof(buf), "%d",
-                           (unsigned char)v);
+                           CAST(unsigned char, v));
                        if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
                                return -1;
                        break;
                default:
                        if (file_printf(ms, F(ms, desc, "%d"),
-                           (unsigned char) v) == -1)
+                           CAST(unsigned char, v)) == -1)
                                return -1;
                        break;
                }
@@ -546,19 +588,19 @@ mprint(struct magic_set *ms, struct magic *m)
        case FILE_SHORT:
        case FILE_BESHORT:
        case FILE_LESHORT:
-               v = file_signextend(ms, m, (uint64_t)p->h);
+               v = file_signextend(ms, m, CAST(uint64_t, p->h));
                switch (check_fmt(ms, desc)) {
                case -1:
                        return -1;
                case 1:
                        (void)snprintf(buf, sizeof(buf), "%u",
-                           (unsigned short)v);
+                           CAST(unsigned short, v));
                        if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
                                return -1;
                        break;
                default:
                        if (file_printf(ms, F(ms, desc, "%u"),
-                           (unsigned short) v) == -1)
+                           CAST(unsigned short, v)) == -1)
                                return -1;
                        break;
                }
@@ -569,17 +611,19 @@ mprint(struct magic_set *ms, struct magic *m)
        case FILE_BELONG:
        case FILE_LELONG:
        case FILE_MELONG:
-               v = file_signextend(ms, m, (uint64_t)p->l);
+               v = file_signextend(ms, m, CAST(uint64_t, p->l));
                switch (check_fmt(ms, desc)) {
                case -1:
                        return -1;
                case 1:
-                       (void)snprintf(buf, sizeof(buf), "%u", (uint32_t) v);
+                       (void)snprintf(buf, sizeof(buf), "%u",
+                           CAST(uint32_t, v));
                        if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
                                return -1;
                        break;
                default:
-                       if (file_printf(ms, F(ms, desc, "%u"), (uint32_t) v) == -1)
+                       if (file_printf(ms, F(ms, desc, "%u"),
+                           CAST(uint32_t, v)) == -1)
                                return -1;
                        break;
                }
@@ -595,13 +639,13 @@ mprint(struct magic_set *ms, struct magic *m)
                        return -1;
                case 1:
                        (void)snprintf(buf, sizeof(buf), "%" INT64_T_FORMAT "u",
-                           (unsigned long long)v);
+                           CAST(unsigned long long, v));
                        if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
                                return -1;
                        break;
                default:
                        if (file_printf(ms, F(ms, desc, "%" INT64_T_FORMAT "u"),
-                           (unsigned long long) v) == -1)
+                           CAST(unsigned long long, v)) == -1)
                                return -1;
                        break;
                }
@@ -614,8 +658,8 @@ mprint(struct magic_set *ms, struct magic *m)
        case FILE_LESTRING16:
                if (m->reln == '=' || m->reln == '!') {
                        if (file_printf(ms, F(ms, desc, "%s"),
-                           file_printable(sbuf, sizeof(sbuf), m->value.s))
-                           == -1)
+                           file_printable(sbuf, sizeof(sbuf), m->value.s,
+                           sizeof(m->value.s))) == -1)
                                return -1;
                        t = ms->offset + m->vallen;
                }
@@ -630,19 +674,20 @@ mprint(struct magic_set *ms, struct magic *m)
 
                        if (m->str_flags & STRING_TRIM) {
                                char *last;
-                               while (isspace((unsigned char)*str))
+                               while (isspace(CAST(unsigned char, *str)))
                                        str++;
                                last = str;
                                while (*last)
                                        last++;
                                --last;
-                               while (isspace((unsigned char)*last))
+                               while (isspace(CAST(unsigned char, *last)))
                                        last--;
                                *++last = '\0';
                        }
 
                        if (file_printf(ms, F(ms, desc, "%s"),
-                           file_printable(sbuf, sizeof(sbuf), str)) == -1)
+                           file_printable(sbuf, sizeof(sbuf), str,
+                               sizeof(p->s) - (str - p->s))) == -1)
                                return -1;
 
                        if (m->type == FILE_PSTRING)
@@ -742,13 +787,14 @@ mprint(struct magic_set *ms, struct magic *m)
                char *cp;
                int rval;
 
-               cp = strndup((const char *)ms->search.s, ms->search.rm_len);
+               cp = strndup(RCAST(const char *, ms->search.s),
+                   ms->search.rm_len);
                if (cp == NULL) {
                        file_oomem(ms, ms->search.rm_len);
                        return -1;
                }
                rval = file_printf(ms, F(ms, desc, "%s"),
-                   file_printable(sbuf, sizeof(sbuf), cp));
+                   file_printable(sbuf, sizeof(sbuf), cp, ms->search.rm_len));
                free(cp);
 
                if (rval == -1)
@@ -775,7 +821,8 @@ mprint(struct magic_set *ms, struct magic *m)
                break;
        case FILE_DER:
                if (file_printf(ms, F(ms, desc, "%s"),
-                   file_printable(sbuf, sizeof(sbuf), ms->ms_value.s)) == -1)
+                   file_printable(sbuf, sizeof(sbuf), ms->ms_value.s,
+                       sizeof(ms->ms_value.s))) == -1)
                        return -1;
                t = ms->offset;
                break;
@@ -783,7 +830,7 @@ mprint(struct magic_set *ms, struct magic *m)
                file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
                return -1;
        }
-       return (int32_t)t;
+       return CAST(int32_t, t);
 }
 
 private int
@@ -830,7 +877,8 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
                                p->s[strcspn(p->s, "\r\n")] = '\0';
                        o = CAST(uint32_t, (ms->offset + strlen(p->s)));
                        if (m->type == FILE_PSTRING)
-                               o += (uint32_t)file_pstring_length_size(m);
+                               o += CAST(uint32_t,
+                                   file_pstring_length_size(m));
                }
                break;
 
@@ -896,7 +944,7 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
        case FILE_DER:
                {
                        o = der_offs(ms, m, nbytes);
-                       if (o == -1 || (size_t)o > nbytes) {
+                       if (o == -1 || CAST(size_t, o) > nbytes) {
                                if ((ms->flags & MAGIC_DEBUG) != 0) {
                                        (void)fprintf(stderr,
                                            "Bad DER offset %d nbytes=%"
@@ -913,7 +961,7 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
                break;
        }
 
-       if ((size_t)o > nbytes) {
+       if (CAST(size_t, o) > nbytes) {
 #if 0
                file_error(ms, 0, "Offset out of range %" SIZE_T_FORMAT
                    "u > %" SIZE_T_FORMAT "u", (size_t)o, nbytes);
@@ -986,36 +1034,36 @@ cvt_flip(int type, int flip)
                return type;
        }
 }
-#define DO_CVT(fld, cast) \
+#define DO_CVT(fld, type) \
        if (m->num_mask) \
                switch (m->mask_op & FILE_OPS_MASK) { \
                case FILE_OPAND: \
-                       p->fld &= cast m->num_mask; \
+                       p->fld &= CAST(type, m->num_mask); \
                        break; \
                case FILE_OPOR: \
-                       p->fld |= cast m->num_mask; \
+                       p->fld |= CAST(type, m->num_mask); \
                        break; \
                case FILE_OPXOR: \
-                       p->fld ^= cast m->num_mask; \
+                       p->fld ^= CAST(type, m->num_mask); \
                        break; \
                case FILE_OPADD: \
-                       p->fld += cast m->num_mask; \
+                       p->fld += CAST(type, m->num_mask); \
                        break; \
                case FILE_OPMINUS: \
-                       p->fld -= cast m->num_mask; \
+                       p->fld -= CAST(type, m->num_mask); \
                        break; \
                case FILE_OPMULTIPLY: \
-                       p->fld *= cast m->num_mask; \
+                       p->fld *= CAST(type, m->num_mask); \
                        break; \
                case FILE_OPDIVIDE: \
-                       if (cast m->num_mask == 0) \
+                       if (CAST(type, m->num_mask) == 0) \
                                return -1; \
-                       p->fld /= cast m->num_mask; \
+                       p->fld /= CAST(type, m->num_mask); \
                        break; \
                case FILE_OPMODULO: \
-                       if (cast m->num_mask == 0) \
+                       if (CAST(type, m->num_mask) == 0) \
                                return -1; \
-                       p->fld %= cast m->num_mask; \
+                       p->fld %= CAST(type, m->num_mask); \
                        break; \
                } \
        if (m->mask_op & FILE_OPINVERSE) \
@@ -1024,61 +1072,61 @@ cvt_flip(int type, int flip)
 private int
 cvt_8(union VALUETYPE *p, const struct magic *m)
 {
-       DO_CVT(b, (uint8_t));
+       DO_CVT(b, uint8_t);
        return 0;
 }
 
 private int
 cvt_16(union VALUETYPE *p, const struct magic *m)
 {
-       DO_CVT(h, (uint16_t));
+       DO_CVT(h, uint16_t);
        return 0;
 }
 
 private int
 cvt_32(union VALUETYPE *p, const struct magic *m)
 {
-       DO_CVT(l, (uint32_t));
+       DO_CVT(l, uint32_t);
        return 0;
 }
 
 private int
 cvt_64(union VALUETYPE *p, const struct magic *m)
 {
-       DO_CVT(q, (uint64_t));
+       DO_CVT(q, uint64_t);
        return 0;
 }
 
-#define DO_CVT2(fld, cast) \
+#define DO_CVT2(fld, type) \
        if (m->num_mask) \
                switch (m->mask_op & FILE_OPS_MASK) { \
                case FILE_OPADD: \
-                       p->fld += cast m->num_mask; \
+                       p->fld += CAST(type, m->num_mask); \
                        break; \
                case FILE_OPMINUS: \
-                       p->fld -= cast m->num_mask; \
+                       p->fld -= CAST(type, m->num_mask); \
                        break; \
                case FILE_OPMULTIPLY: \
-                       p->fld *= cast m->num_mask; \
+                       p->fld *= CAST(type, m->num_mask); \
                        break; \
                case FILE_OPDIVIDE: \
-                       if (cast m->num_mask == 0) \
+                       if (CAST(type, m->num_mask) == 0) \
                                return -1; \
-                       p->fld /= cast m->num_mask; \
+                       p->fld /= CAST(type, m->num_mask); \
                        break; \
                } \
 
 private int
 cvt_float(union VALUETYPE *p, const struct magic *m)
 {
-       DO_CVT2(f, (float));
+       DO_CVT2(f, float);
        return 0;
 }
 
 private int
 cvt_double(union VALUETYPE *p, const struct magic *m)
 {
-       DO_CVT2(d, (double));
+       DO_CVT2(d, double);
        return 0;
 }
 
@@ -1143,14 +1191,14 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
                return 1;
        }
        case FILE_BESHORT:
-               p->h = (short)BE16(p);
+               p->h = CAST(short, BE16(p));
                if (cvt_16(p, m) == -1)
                        goto out;
                return 1;
        case FILE_BELONG:
        case FILE_BEDATE:
        case FILE_BELDATE:
-               p->l = (int32_t)BE32(p);
+               p->l = CAST(int32_t, BE32(p));
                if (cvt_32(p, m) == -1)
                        goto out;
                return 1;
@@ -1158,19 +1206,19 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
        case FILE_BEQDATE:
        case FILE_BEQLDATE:
        case FILE_BEQWDATE:
-               p->q = (uint64_t)BE64(p);
+               p->q = CAST(uint64_t, BE64(p));
                if (cvt_64(p, m) == -1)
                        goto out;
                return 1;
        case FILE_LESHORT:
-               p->h = (short)LE16(p);
+               p->h = CAST(short, LE16(p));
                if (cvt_16(p, m) == -1)
                        goto out;
                return 1;
        case FILE_LELONG:
        case FILE_LEDATE:
        case FILE_LELDATE:
-               p->l = (int32_t)LE32(p);
+               p->l = CAST(int32_t, LE32(p));
                if (cvt_32(p, m) == -1)
                        goto out;
                return 1;
@@ -1178,14 +1226,14 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
        case FILE_LEQDATE:
        case FILE_LEQLDATE:
        case FILE_LEQWDATE:
-               p->q = (uint64_t)LE64(p);
+               p->q = CAST(uint64_t, LE64(p));
                if (cvt_64(p, m) == -1)
                        goto out;
                return 1;
        case FILE_MELONG:
        case FILE_MEDATE:
        case FILE_MELDATE:
-               p->l = (int32_t)ME32(p);
+               p->l = CAST(int32_t, ME32(p));
                if (cvt_32(p, m) == -1)
                        goto out;
                return 1;
@@ -1366,7 +1414,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
         * might even cause problems
         */
        if (nbytes < sizeof(*p))
-               (void)memset(((char *)(void *)p) + nbytes, '\0',
+               (void)memset(RCAST(char *, RCAST(void *, p)) + nbytes, '\0',
                    sizeof(*p) - nbytes);
        return 0;
 }
@@ -1407,7 +1455,7 @@ do_ops(struct magic *m, intmax_t lhs, intmax_t off)
        if (m->in_op & FILE_OPINVERSE)
                offset = ~offset;
 
-       return (uint32_t)offset;
+       return CAST(uint32_t, offset);
 }
 
 private int
@@ -1432,10 +1480,10 @@ msetoffset(struct magic_set *ms, struct magic *m, struct buffer *bb,
                            "u at level %u", o, cont_level);
                        return -1;
                }
-               if ((size_t)-m->offset > b->elen)
+               if (CAST(size_t, -m->offset) > b->elen)
                        return -1;
                buffer_init(bb, -1, b->ebuf, b->elen);
-               ms->eoffset = ms->offset = b->elen + m->offset;
+               ms->eoffset = ms->offset = CAST(int32_t, b->elen + m->offset);
        } else {
                if (cont_level == 0) {
 normal:
@@ -1460,7 +1508,8 @@ private int
 mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
     const unsigned char *s, size_t nbytes, size_t o, unsigned int cont_level,
     int mode, int text, int flip, uint16_t *indir_count, uint16_t *name_count,
-    int *printed_something, int *need_separator, int *returnval)
+    int *printed_something, int *need_separator, int *returnval,
+    int *found_match)
 {
        uint32_t offset = ms->offset;
        struct buffer bb;
@@ -1485,8 +1534,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
 
 
 
-       if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
-           (uint32_t)nbytes, m) == -1)
+       if (mcopy(ms, p, m->type, m->flag & INDIR, s,
+           CAST(uint32_t, offset + o), CAST(uint32_t, nbytes), m) == -1)
                return -1;
 
        if ((ms->flags & MAGIC_DEBUG) != 0) {
@@ -1495,7 +1544,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
                    "u, il=%hu, nc=%hu)\n",
                    m->type, m->flag, offset, o, nbytes,
                    *indir_count, *name_count);
-               mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
+               mdebug(offset, RCAST(char *, RCAST(void *, p)),
+                   sizeof(union VALUETYPE));
 #ifndef COMPILE_ONLY
                file_mdump(m);
 #endif
@@ -1506,40 +1556,58 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
                const int sgn = m->in_op & FILE_OPSIGNED;
                if (m->in_op & FILE_OPINDIRECT) {
                        const union VALUETYPE *q = CAST(const union VALUETYPE *,
-                           ((const void *)(s + offset + off)));
-                       if (OFFSET_OOB(nbytes, offset + off, sizeof(*q)))
-                               return 0;
+                           RCAST(const void *, s + offset + off));
                        switch (cvt_flip(m->in_type, flip)) {
                        case FILE_BYTE:
+                               if (OFFSET_OOB(nbytes, offset + off, 1))
+                                       return 0;
                                off = SEXT(sgn,8,q->b);
                                break;
                        case FILE_SHORT:
+                               if (OFFSET_OOB(nbytes, offset + off, 2))
+                                       return 0;
                                off = SEXT(sgn,16,q->h);
                                break;
                        case FILE_BESHORT:
+                               if (OFFSET_OOB(nbytes, offset + off, 2))
+                                       return 0;
                                off = SEXT(sgn,16,BE16(q));
                                break;
                        case FILE_LESHORT:
+                               if (OFFSET_OOB(nbytes, offset + off, 2))
+                                       return 0;
                                off = SEXT(sgn,16,LE16(q));
                                break;
                        case FILE_LONG:
+                               if (OFFSET_OOB(nbytes, offset + off, 4))
+                                       return 0;
                                off = SEXT(sgn,32,q->l);
                                break;
                        case FILE_BELONG:
                        case FILE_BEID3:
+                               if (OFFSET_OOB(nbytes, offset + off, 4))
+                                       return 0;
                                off = SEXT(sgn,32,BE32(q));
                                break;
                        case FILE_LEID3:
                        case FILE_LELONG:
+                               if (OFFSET_OOB(nbytes, offset + off, 4))
+                                       return 0;
                                off = SEXT(sgn,32,LE32(q));
                                break;
                        case FILE_MELONG:
+                               if (OFFSET_OOB(nbytes, offset + off, 4))
+                                       return 0;
                                off = SEXT(sgn,32,ME32(q));
                                break;
                        case FILE_BEQUAD:
+                               if (OFFSET_OOB(nbytes, offset + off, 8))
+                                       return 0;
                                off = SEXT(sgn,64,BE64(q));
                                break;
                        case FILE_LEQUAD:
+                               if (OFFSET_OOB(nbytes, offset + off, 8))
+                                       return 0;
                                off = SEXT(sgn,64,LE64(q));
                                break;
                        default:
@@ -1575,7 +1643,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
                                return 0;
                        lhs = BE32(p);
                        if (in_type == FILE_BEID3)
-                               lhs = cvt_id3(ms, (uint32_t)lhs);
+                               lhs = cvt_id3(ms, CAST(uint32_t, lhs));
                        offset = do_ops(m, SEXT(sgn,32,lhs), off);
                        break;
                case FILE_LELONG:
@@ -1584,7 +1652,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
                                return 0;
                        lhs = LE32(p);
                        if (in_type == FILE_LEID3)
-                               lhs = cvt_id3(ms, (uint32_t)lhs);
+                               lhs = cvt_id3(ms, CAST(uint32_t, lhs));
                        offset = do_ops(m, SEXT(sgn,32,lhs), off);
                        break;
                case FILE_MELONG:
@@ -1627,7 +1695,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
                ms->offset = offset;
 
                if ((ms->flags & MAGIC_DEBUG) != 0) {
-                       mdebug(offset, (char *)(void *)p,
+                       mdebug(offset, RCAST(char *, RCAST(void *, p)),
                            sizeof(union VALUETYPE));
 #ifndef COMPILE_ONLY
                        file_mdump(m);
@@ -1746,7 +1814,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
                        *need_separator = 0;
                rv = match(ms, ml.magic, ml.nmagic, b, offset + o,
                    mode, text, flip, indir_count, name_count,
-                   printed_something, need_separator, returnval);
+                   printed_something, need_separator, returnval, found_match);
                (*name_count)--;
                if (rv != 1)
                    *need_separator = oneed_separator;
@@ -1778,8 +1846,8 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
         * the ctype functions will work correctly without extra
         * casting.
         */
-       const unsigned char *a = (const unsigned char *)s1;
-       const unsigned char *b = (const unsigned char *)s2;
+       const unsigned char *a = RCAST(const unsigned char *, s1);
+       const unsigned char *b = RCAST(const unsigned char *, s2);
        const unsigned char *eb = b + len;
        uint64_t v;
 
@@ -1974,13 +2042,15 @@ magiccheck(struct magic_set *ms, struct magic *m)
        case FILE_STRING:
        case FILE_PSTRING:
                l = 0;
-               v = file_strncmp(m->value.s, p->s, (size_t)m->vallen, m->str_flags);
+               v = file_strncmp(m->value.s, p->s, CAST(size_t, m->vallen),
+                   m->str_flags);
                break;
 
        case FILE_BESTRING16:
        case FILE_LESTRING16:
                l = 0;
-               v = file_strncmp16(m->value.s, p->s, (size_t)m->vallen, m->str_flags);
+               v = file_strncmp16(m->value.s, p->s, CAST(size_t, m->vallen),
+                   m->str_flags);
                break;
 
        case FILE_SEARCH: { /* search ms->search.s for the string m->value.s */
@@ -2022,7 +2092,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
                    ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
                if (rc) {
                        file_regerror(&rx, rc, ms);
-                       v = (uint64_t)-1;
+                       v = CAST(uint64_t, -1);
                } else {
                        regmatch_t pmatch;
                        size_t slen = ms->search.s_len;
@@ -2043,15 +2113,15 @@ magiccheck(struct magic_set *ms, struct magic *m)
                            search = CCAST(char *, "");
                            copy = NULL;
                        }
-                       rc = file_regexec(&rx, (const char *)search,
+                       rc = file_regexec(&rx, RCAST(const char *, search),
                            1, &pmatch, 0);
                        free(copy);
                        switch (rc) {
                        case 0:
-                               ms->search.s += (int)pmatch.rm_so;
-                               ms->search.offset += (size_t)pmatch.rm_so;
-                               ms->search.rm_len =
-                                   (size_t)(pmatch.rm_eo - pmatch.rm_so);
+                               ms->search.s += CAST(int, pmatch.rm_so);
+                               ms->search.offset += CAST(size_t, pmatch.rm_so);
+                               ms->search.rm_len = CAST(size_t, 
+                                   pmatch.rm_eo - pmatch.rm_so);
                                v = 0;
                                break;
 
@@ -2061,12 +2131,12 @@ magiccheck(struct magic_set *ms, struct magic *m)
 
                        default:
                                file_regerror(&rx, rc, ms);
-                               v = (uint64_t)-1;
+                               v = CAST(uint64_t, -1);
                                break;
                        }
                }
                file_regfree(&rx);
-               if (v == (uint64_t)-1)
+               if (v == CAST(uint64_t, -1))
                        return -1;
                break;
        }
@@ -2095,7 +2165,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
        case 'x':
                if ((ms->flags & MAGIC_DEBUG) != 0)
                        (void) fprintf(stderr, "%" INT64_T_FORMAT
-                           "u == *any* = 1\n", (unsigned long long)v);
+                           "u == *any* = 1\n", CAST(unsigned long long, v));
                matched = 1;
                break;
 
@@ -2103,16 +2173,18 @@ magiccheck(struct magic_set *ms, struct magic *m)
                matched = v != l;
                if ((ms->flags & MAGIC_DEBUG) != 0)
                        (void) fprintf(stderr, "%" INT64_T_FORMAT "u != %"
-                           INT64_T_FORMAT "u = %d\n", (unsigned long long)v,
-                           (unsigned long long)l, matched);
+                           INT64_T_FORMAT "u = %d\n",
+                           CAST(unsigned long long, v),
+                           CAST(unsigned long long, l), matched);
                break;
 
        case '=':
                matched = v == l;
                if ((ms->flags & MAGIC_DEBUG) != 0)
                        (void) fprintf(stderr, "%" INT64_T_FORMAT "u == %"
-                           INT64_T_FORMAT "u = %d\n", (unsigned long long)v,
-                           (unsigned long long)l, matched);
+                           INT64_T_FORMAT "u = %d\n",
+                           CAST(unsigned long long, v),
+                           CAST(unsigned long long, l), matched);
                break;
 
        case '>':
@@ -2121,15 +2193,16 @@ magiccheck(struct magic_set *ms, struct magic *m)
                        if ((ms->flags & MAGIC_DEBUG) != 0)
                                (void) fprintf(stderr, "%" INT64_T_FORMAT
                                    "u > %" INT64_T_FORMAT "u = %d\n",
-                                   (unsigned long long)v,
-                                   (unsigned long long)l, matched);
+                                   CAST(unsigned long long, v),
+                                   CAST(unsigned long long, l), matched);
                }
                else {
-                       matched = (int64_t) v > (int64_t) l;
+                       matched = CAST(int64_t, v) > CAST(int64_t, l);
                        if ((ms->flags & MAGIC_DEBUG) != 0)
                                (void) fprintf(stderr, "%" INT64_T_FORMAT
                                    "d > %" INT64_T_FORMAT "d = %d\n",
-                                   (long long)v, (long long)l, matched);
+                                   CAST(long long, v),
+                                   CAST(long long, l), matched);
                }
                break;
 
@@ -2139,15 +2212,16 @@ magiccheck(struct magic_set *ms, struct magic *m)
                        if ((ms->flags & MAGIC_DEBUG) != 0)
                                (void) fprintf(stderr, "%" INT64_T_FORMAT
                                    "u < %" INT64_T_FORMAT "u = %d\n",
-                                   (unsigned long long)v,
-                                   (unsigned long long)l, matched);
+                                   CAST(unsigned long long, v),
+                                   CAST(unsigned long long, l), matched);
                }
                else {
-                       matched = (int64_t) v < (int64_t) l;
+                       matched = CAST(int64_t, v) < CAST(int64_t, l);
                        if ((ms->flags & MAGIC_DEBUG) != 0)
                                (void) fprintf(stderr, "%" INT64_T_FORMAT
                                    "d < %" INT64_T_FORMAT "d = %d\n",
-                                    (long long)v, (long long)l, matched);
+                                    CAST(long long, v),
+                                    CAST(long long, l), matched);
                }
                break;
 
@@ -2156,8 +2230,9 @@ magiccheck(struct magic_set *ms, struct magic *m)
                if ((ms->flags & MAGIC_DEBUG) != 0)
                        (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
                            INT64_T_FORMAT "x) == %" INT64_T_FORMAT
-                           "x) = %d\n", (unsigned long long)v,
-                           (unsigned long long)l, (unsigned long long)l,
+                           "x) = %d\n", CAST(unsigned long long, v),
+                           CAST(unsigned long long, l),
+                           CAST(unsigned long long, l),
                            matched);
                break;
 
@@ -2166,9 +2241,9 @@ magiccheck(struct magic_set *ms, struct magic *m)
                if ((ms->flags & MAGIC_DEBUG) != 0)
                        (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
                            INT64_T_FORMAT "x) != %" INT64_T_FORMAT
-                           "x) = %d\n", (unsigned long long)v,
-                           (unsigned long long)l, (unsigned long long)l,
-                           matched);
+                           "x) = %d\n", CAST(unsigned long long, v),
+                           CAST(unsigned long long, l),
+                           CAST(unsigned long long, l), matched);
                break;
 
        default: