+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
-## 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/
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])])
-.\" $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
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
-.\" $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.
.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
#------------------------------------------------------------------------------
-# $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
#------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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)
#------------------------------------------------------------------------------
-# $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
--- /dev/null
+#------------------------------------------------------------------------------
+# 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
#------------------------------------------------------------------------------
-# $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
>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),
--- /dev/null
+
+# $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)
+
+
#------------------------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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"
+
#------------------------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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)
#------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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>
!: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
#------------------------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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
>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
#------------------------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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
#------------------------------------------------------------------------------
-# $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
#
-# $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
$(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 \
$(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 \
#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"
#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
#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
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;
}
{
int type;
- if (isalpha((unsigned char)l[1])) {
+ if (isalpha(CAST(unsigned char, l[1]))) {
switch (l[1]) {
case 'C':
/* "dC" and "uC" */
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
* 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;
}
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;
}
#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)
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;
case FILE_LEDOUBLE:
return 8;
default:
- return (size_t)~0;
+ return CAST(size_t, ~0);
}
}
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;
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
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;
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));
}
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");
}
* 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:
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:
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:
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;
{
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;
++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);
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':
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)
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,
}
/* 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);
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,
*/
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;
}
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;
}
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);
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;
}
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)
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; \
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++;
}
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);
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;
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);
/*FALLTHROUGH*/
default:
if (warn) {
- if (isprint((unsigned char)c)) {
+ if (isprint(CAST(unsigned char, c))) {
/* Allow escaping of
* ``relations'' */
if (strchr("<>&^=!", c) == NULL
case '!':
/* and baskslash itself */
case '\\':
- *p++ = (char) c;
+ *p++ = CAST(char, c);
break;
case 'a':
}
else
--s;
- *p++ = (char)val;
+ *p++ = CAST(char, val);
break;
/* \x and up to 2 hex digits */
--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;
}
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';
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;
}
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;
}
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",
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;
}
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;
}
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 */
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;
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];
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];
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);
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) {
#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"
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,
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);
== 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)
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;
}
#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"
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;
return 0;
out:
- b->elen = (size_t)~0;
+ b->elen = CAST(size_t, ~0);
return -1;
}
#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>
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 ? \
_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;
_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];
_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];
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
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);
}
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 %"
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;
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);
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
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;
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;
}
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) {
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;
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:"));
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));
return i;
out:
errno = EFTYPE;
- return (size_t)-1;
+ return CAST(size_t, -1);
}
int
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);
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;
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:
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);
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:
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;
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;
}
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++)
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));
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:
{
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;
}
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);
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)
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);
{
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;
}
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;
#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>
if (m == 1 && isleap(year))
days--;
if (days <= 0)
- return (int)m;
+ return CAST(int, m);
}
- return (int)m;
+ return CAST(int, m);
}
int
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;
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;
}
#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"
(void)ioctl(fd, FIONREAD, &t);
}
- if (t > 0 && (size_t)t < n) {
+ if (t > 0 && CAST(size_t, t) < n) {
n = t;
rn = n;
}
#else
{
int te;
- int ou = umask(0);
+ mode_t ou = umask(0);
tfd = mkstemp(buf);
(void)umask(ou);
te = errno;
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;
}
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;
}
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;
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
*len = 0;
return NODATA;
}
- *buf = (unsigned char *)msg;
+ *buf = RCAST(unsigned char *, msg);
*len = strlen(msg);
return ERRDATA;
}
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);
}
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));
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);
#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
#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
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;
}
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);
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, ¬ecount) == -1)
return -1;
break;
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, ¬ecount) == -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, ¬ecount) == -1)
return -1;
break;
#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"
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 *);
*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;
}
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";
}
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;
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;
/* 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
#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"
}
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;
(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))), "");
}
}
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;
}
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;
}
}
*/
/*
* 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__
#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
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);
#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"
#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 *
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;
}
#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);
* 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;
#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>
#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
#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"
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;
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 */
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;
#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"
{
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
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;
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);
}
/*
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;
}
_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
}
(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);
}
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;
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;
#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>
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);
}
(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);
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:
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:
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);
} 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) {
#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>
&& 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))
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;
}
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);
}
#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
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 */
};
}
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)
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;
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;
}
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],
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));
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]);
}
}
- 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]);
}
}
- 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)
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;
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",
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)
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
* 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;
}
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;
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;
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;
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;
* 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;
}
/* 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;
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;
}
}
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;
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;
}
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);
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;
*/
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,
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;
}
#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"
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 *);
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
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;
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;
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:
goto flush;
}
+ if (*m->desc)
+ *found_match = 1;
+
if ((e = handle_annotation(ms, m, firstline)) != 0)
{
*need_separator = 1;
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)
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:
flush = 1;
break;
default:
- if (m->type == FILE_INDIRECT)
+ if (m->type == FILE_INDIRECT) {
+ *found_match = 1;
*returnval = 1;
+ }
flush = 0;
break;
}
} 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;
if (file_printf(ms, " ") == -1)
return -1;
}
+ *returnval = 1;
*need_separator = 0;
if (mprint(ms, m) == -1)
return -1;
}
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;
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);
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;
}
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;
}
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;
}
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;
}
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;
}
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)
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)
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;
file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
return -1;
}
- return (int32_t)t;
+ return CAST(int32_t, t);
}
private int
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;
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=%"
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);
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) \
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;
}
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;
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;
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;
* 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;
}
if (m->in_op & FILE_OPINVERSE)
offset = ~offset;
- return (uint32_t)offset;
+ return CAST(uint32_t, offset);
}
private int
"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:
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;
- 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) {
"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
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:
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:
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:
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);
*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;
* 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;
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 */
((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;
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;
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;
}
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;
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 '>':
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;
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;
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;
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: