Browse Source

Merge upstream version 5.39

Christoph Biedl 3 years ago
parent
commit
637c5584df
67 changed files with 3104 additions and 891 deletions
  1. 80 0
      ChangeLog
  2. 5 0
      Makefile.am
  3. 76 13
      Makefile.in
  4. 12 11
      configure
  5. 2 2
      configure.ac
  6. 15 6
      doc/file.man
  7. 58 2
      doc/magic.man
  8. 10 0
      libmagic.pc.in
  9. 2 6
      magic/Magdir/animation
  10. 100 17
      magic/Magdir/archive
  11. 132 0
      magic/Magdir/asf
  12. 9 2
      magic/Magdir/cad
  13. 25 1
      magic/Magdir/commands
  14. 11 2
      magic/Magdir/compress
  15. 91 5
      magic/Magdir/console
  16. 25 8
      magic/Magdir/database
  17. 23 1
      magic/Magdir/der
  18. 33 0
      magic/Magdir/dif
  19. 4 3
      magic/Magdir/elf
  20. 3 3
      magic/Magdir/filesystems
  21. 11 1
      magic/Magdir/games
  22. 1 6
      magic/Magdir/gnu
  23. 398 63
      magic/Magdir/images
  24. 58 1
      magic/Magdir/intel
  25. 22 6
      magic/Magdir/kicad
  26. 108 89
      magic/Magdir/linux
  27. 16 3
      magic/Magdir/msdos
  28. 50 2
      magic/Magdir/ole2compounddocs
  29. 2 2
      magic/Magdir/parix
  30. 5 1
      magic/Magdir/pascal
  31. 8 1
      magic/Magdir/pdf
  32. 81 16
      magic/Magdir/pgp
  33. 202 24
      magic/Magdir/python
  34. 114 9
      magic/Magdir/riff
  35. 2 2
      magic/Magdir/rst
  36. 88 10
      magic/Magdir/rtf
  37. 2 2
      magic/Magdir/sgml
  38. 178 178
      magic/Magdir/sniffer
  39. 20 0
      magic/Magdir/ssh
  40. 36 0
      magic/Magdir/sylk
  41. 2 2
      magic/Magdir/ti-8x
  42. 4 2
      magic/Magdir/tplink
  43. 5 5
      magic/Magdir/troff
  44. 12 0
      magic/Magdir/unisig
  45. 21 0
      magic/Magdir/usd
  46. 1 1
      magic/Magdir/virtual
  47. 12 0
      magic/Magdir/web
  48. 123 77
      magic/Magdir/windows
  49. 18 1
      magic/Magdir/wordprocessors
  50. 66 19
      magic/Magdir/zip
  51. 7 1
      magic/Makefile.am
  52. 7 1
      magic/Makefile.in
  53. 108 44
      src/apprentice.c
  54. 6 8
      src/ascmagic.c
  55. 3 3
      src/buffer.c
  56. 29 27
      src/compress.c
  57. 58 20
      src/der.c
  58. 63 27
      src/file.c
  59. 60 34
      src/file.h
  60. 62 35
      src/file_opts.h
  61. 127 11
      src/funcs.c
  62. 12 5
      src/is_json.c
  63. 2 3
      src/magic.c
  64. 20 9
      src/print.c
  65. 35 10
      src/readelf.c
  66. 10 3
      src/seccomp.c
  67. 113 45
      src/softmagic.c

+ 80 - 0
ChangeLog

@@ -1,3 +1,83 @@
+2020-06-14  20:02  Christos Zoulas <christos@zoulas.com>
+
+	* release 5.39
+
+2020-06-07  20:00  Christos Zoulas <christos@zoulas.com>
+
+	* Remove unused subtype_mime (Steve Grubb)
+	* Remove unused check in okstat (Steve Grubb)
+	* Fix mime-type in elf binaries by making sure $x is set
+	* Fix indirect negative offsets broken by OFFNEGATIVE
+	* Fix GUID equality check
+	* PR/165: Handle empty array and strings in JSON
+	* PR/162: Add --exclude-quiet
+
+2020-06-06  15:33  Christos Zoulas <christos@zoulas.com>
+
+	* Fix memory leak in ascmagic (Steve Grubb)
+
+2020-06-04  00:21  Christos Zoulas <christos@zoulas.com>
+
+	* Fix string comparison length with ignore whitespace
+
+2020-05-31  00:11  Christos Zoulas <christos@zoulas.com>
+
+	* Fix mingwin 64 compilation
+
+2020-05-30  23:56  Christos Zoulas <christos@zoulas.com>
+
+	* PR/159: whitelist getpid needed for file_pipe2file()
+
+2020-05-09  18:57  Christos Zoulas <christos@zoulas.com>
+
+	* Indicate negative offsets with a flag OFFNEGATIVE
+	  so that -0 works.
+	* Introduce "offset" magic type that can be used to
+	  detect the file size, and bail on short files.
+	* document DER better in the magic man page.
+
+2020-03-11  21:53  Christos Zoulas <christos@zoulas.com>
+
+	* fix memory leaks (SonarQube)
+
+2020-03-08  21:33  Christos Zoulas <christos@zoulas.com>
+
+	* fix memory leaks (SonarQube)
+	* rewrite confusing loops (SonarQube)
+	* fix bogus test (SonarQube)
+	* pass a sized buffer to file_fmttime() (SonarQube)
+
+	* fix memory leaks (SonarQube)
+
+2020-02-20  15:50  Christos Zoulas <christos@zoulas.com>
+
+	* Don't allow * in printf formats, or the code itself (Christoph Biedl)
+	* Introduce a printf output size checker to avoid DoS attacks
+
+2020-02-17  17:22  Christos Zoulas <christos@zoulas.com>
+
+	* Avoid memory leak on error (oss-fuzz)
+	* Check length of string on DER before derefercing and add new types
+	* Add missing DER string (oss-fuzz)
+
+2020-02-16  20:45  Christos Zoulas <christos@zoulas.com>
+
+	* Add missing DER types, and debugging
+
+2020-02-13  13:10  Christos Zoulas <christos@zoulas.com>
+
+	* PR/140: Avoid abort with hand-crafted magic file (gockelhahn)
+	* PR/139  Avoid DoS in printf with hand-crafted magic file (gockelhahn)
+	* PR/138: Avoid crash with hand-crafted magic file (gockelhahn)
+
+2020-02-12  17:30  Christos Zoulas <christos@zoulas.com>
+
+	* PR/136: Fix static build by adding a libmagic.pc (Fabrice Fontaine)
+
+2019-12-24  14:16  Christos Zoulas <christos@zoulas.com>
+
+	* add guid support
+
 2019-12-16  21:11  Christos Zoulas <christos@zoulas.com>
 
 	* release 5.38

+ 5 - 0
Makefile.am

@@ -3,3 +3,8 @@ ACLOCAL_AMFLAGS = -I m4
 EXTRA_DIST = MAINT
 
 SUBDIRS = src magic tests doc python
+
+# This variable must have 'exec' in its name, in order to be installed
+# by 'install-exec' target (instead of default 'install-data')
+pkgconfigexecdir = $(libdir)/pkgconfig
+pkgconfigexec_DATA = libmagic.pc

+ 76 - 13
Makefile.in

@@ -13,6 +13,7 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
 VPATH = @srcdir@
 am__is_gnu_make = { \
   if test -z '$(MAKELEVEL)'; then \
@@ -100,7 +101,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno config.status.lineno
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = config.h
-CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_FILES = libmagic.pc
 CONFIG_CLEAN_VPATH_FILES =
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -129,6 +130,35 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(pkgconfigexecdir)"
+DATA = $(pkgconfigexec_DATA)
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
   distclean-recursive maintainer-clean-recursive
 am__recursive_targets = \
@@ -159,9 +189,10 @@ ETAGS = etags
 CTAGS = ctags
 CSCOPE = cscope
 DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \
-	COPYING ChangeLog INSTALL NEWS README TODO compile \
-	config.guess config.sub install-sh ltmain.sh missing
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+	$(srcdir)/libmagic.pc.in AUTHORS COPYING ChangeLog INSTALL \
+	NEWS README TODO compile config.guess config.sub install-sh \
+	ltmain.sh missing
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -328,6 +359,11 @@ top_srcdir = @top_srcdir@
 ACLOCAL_AMFLAGS = -I m4
 EXTRA_DIST = MAINT
 SUBDIRS = src magic tests doc python
+
+# This variable must have 'exec' in its name, in order to be installed
+# by 'install-exec' target (instead of default 'install-data')
+pkgconfigexecdir = $(libdir)/pkgconfig
+pkgconfigexec_DATA = libmagic.pc
 all: config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-recursive
 
@@ -380,6 +416,8 @@ $(srcdir)/config.h.in:  $(am__configure_deps)
 
 distclean-hdr:
 	-rm -f config.h stamp-h1
+libmagic.pc: $(top_builddir)/config.status $(srcdir)/libmagic.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
 
 mostlyclean-libtool:
 	-rm -f *.lo
@@ -389,6 +427,27 @@ clean-libtool:
 
 distclean-libtool:
 	-rm -f libtool config.lt
+install-pkgconfigexecDATA: $(pkgconfigexec_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(pkgconfigexec_DATA)'; test -n "$(pkgconfigexecdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigexecdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgconfigexecdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigexecdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigexecdir)" || exit $$?; \
+	done
+
+uninstall-pkgconfigexecDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkgconfigexec_DATA)'; test -n "$(pkgconfigexecdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(pkgconfigexecdir)'; $(am__uninstall_files_from_dir)
 
 # This directory's subdirectories are mostly independent; you can cd
 # into them and run 'make' without going through this Makefile.
@@ -689,9 +748,12 @@ distcleancheck: distclean
 	       exit 1; } >&2
 check-am: all-am
 check: check-recursive
-all-am: Makefile config.h
+all-am: Makefile $(DATA) config.h
 installdirs: installdirs-recursive
 installdirs-am:
+	for dir in "$(DESTDIR)$(pkgconfigexecdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
 install: install-recursive
 install-exec: install-exec-recursive
 install-data: install-data-recursive
@@ -750,7 +812,7 @@ install-dvi: install-dvi-recursive
 
 install-dvi-am:
 
-install-exec-am:
+install-exec-am: install-pkgconfigexecDATA
 
 install-html: install-html-recursive
 
@@ -790,7 +852,7 @@ ps: ps-recursive
 
 ps-am:
 
-uninstall-am:
+uninstall-am: uninstall-pkgconfigexecDATA
 
 .MAKE: $(am__recursive_targets) all install-am install-strip
 
@@ -804,12 +866,13 @@ uninstall-am:
 	info-am install install-am install-data install-data-am \
 	install-dvi install-dvi-am install-exec install-exec-am \
 	install-html install-html-am install-info install-info-am \
-	install-man install-pdf install-pdf-am install-ps \
-	install-ps-am install-strip installcheck installcheck-am \
-	installdirs installdirs-am maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
-	uninstall-am
+	install-man install-pdf install-pdf-am \
+	install-pkgconfigexecDATA install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-pkgconfigexecDATA
 
 .PRECIOUS: Makefile
 

+ 12 - 11
configure

@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for file 5.38.
+# Generated by GNU Autoconf 2.69 for file 5.39.
 #
 # Report bugs to <christos@astron.com>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='file'
 PACKAGE_TARNAME='file'
-PACKAGE_VERSION='5.38'
-PACKAGE_STRING='file 5.38'
+PACKAGE_VERSION='5.39'
+PACKAGE_STRING='file 5.39'
 PACKAGE_BUGREPORT='christos@astron.com'
 PACKAGE_URL=''
 
@@ -1334,7 +1334,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures file 5.38 to adapt to many kinds of systems.
+\`configure' configures file 5.39 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1404,7 +1404,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of file 5.38:";;
+     short | recursive ) echo "Configuration of file 5.39:";;
    esac
   cat <<\_ACEOF
 
@@ -1524,7 +1524,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-file configure 5.38
+file configure 5.39
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2180,7 +2180,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by file $as_me 5.38, which was
+It was created by file $as_me 5.39, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3046,7 +3046,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='file'
- VERSION='5.38'
+ VERSION='5.39'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -15167,7 +15167,7 @@ $as_echo "#define XZLIBSUPPORT 1" >>confdefs.h
 
 fi
 
-ac_config_files="$ac_config_files Makefile src/Makefile magic/Makefile tests/Makefile doc/Makefile python/Makefile"
+ac_config_files="$ac_config_files Makefile src/Makefile magic/Makefile tests/Makefile doc/Makefile python/Makefile libmagic.pc"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -15712,7 +15712,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by file $as_me 5.38, which was
+This file was extended by file $as_me 5.39, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -15778,7 +15778,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-file config.status 5.38
+file config.status 5.39
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -16199,6 +16199,7 @@ do
     "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
     "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
     "python/Makefile") CONFIG_FILES="$CONFIG_FILES python/Makefile" ;;
+    "libmagic.pc") CONFIG_FILES="$CONFIG_FILES libmagic.pc" ;;
 
   *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac

+ 2 - 2
configure.ac

@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_INIT([file],[5.38],[christos@astron.com])
+AC_INIT([file],[5.39],[christos@astron.com])
 AM_INIT_AUTOMAKE([subdir-objects foreign])
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
@@ -217,5 +217,5 @@ if  test "$ac_cv_header_lzma_h$ac_cv_lib_lzma_lzma_stream_decoder" = "yesyes"; t
   AC_DEFINE([XZLIBSUPPORT], 1, [Enable xzlib compression support])
 fi
 
-AC_CONFIG_FILES([Makefile src/Makefile magic/Makefile tests/Makefile doc/Makefile python/Makefile])
+AC_CONFIG_FILES([Makefile src/Makefile magic/Makefile tests/Makefile doc/Makefile python/Makefile libmagic.pc])
 AC_OUTPUT

+ 15 - 6
doc/file.man

@@ -1,5 +1,5 @@
-.\" $File: file.man,v 1.138 2019/10/15 18:00:40 christos Exp $
-.Dd July 13, 2019
+.\" $File: file.man,v 1.140 2020/06/07 17:41:07 christos Exp $
+.Dd June 7, 2020
 .Dt FILE __CSECTION__
 .Os
 .Sh NAME
@@ -10,6 +10,7 @@
 .Bk -words
 .Op Fl bcdEhiklLNnprsSvzZ0
 .Op Fl Fl apple
+.Op Fl Fl exclude-quiet
 .Op Fl Fl extension
 .Op Fl Fl mime-encoding
 .Op Fl Fl mime-type
@@ -229,6 +230,14 @@ the soft magic method.
 A synonym for
 .Sq ascii .
 .El
+.It Fl Fl exclude-quiet
+Like
+.Fl Fl exclude
+but ignore tests that
+.Nm
+does not know about.
+This is intended for compatilibity with older versions of
+.Nm .
 .It Fl Fl extension
 Print a slash-separated list of valid extensions for the file type found.
 .It Fl F , Fl Fl separator Ar separator
@@ -326,13 +335,13 @@ never read them.
 Set various parameter limits.
 .Bl -column "elf_phnum" "Default" "XXXXXXXXXXXXXXXXXXXXXXXXXXX" -offset indent
 .It Sy "Name" Ta Sy "Default" Ta Sy "Explanation"
-.It Li indir Ta 15 Ta recursion limit for indirect magic
-.It Li name Ta 30 Ta use count limit for name/use magic
+.It Li bytes Ta 1048576 Ta max number of bytes to read from file
 .It Li elf_notes Ta 256 Ta max ELF notes processed
-.It Li elf_phnum Ta 128 Ta max ELF program sections processed
+.It Li elf_phnum Ta 2048 Ta max ELF program sections processed
 .It Li elf_shnum Ta 32768 Ta max ELF sections processed
+.It Li indir Ta 50 Ta recursion limit for indirect magic
+.It Li name Ta 50 Ta use count limit for name/use magic
 .It Li regex Ta 8192 Ta length limit for regex searches
-.It Li bytes Ta 1048576 Ta max number of bytes to read from file
 .El
 .It Fl r , Fl Fl raw
 Don't translate unprintable characters to \eooo.

+ 58 - 2
doc/magic.man

@@ -1,5 +1,5 @@
-.\" $File: magic.man,v 1.97 2019/11/15 21:03:14 christos Exp $
-.Dd January 21, 2019
+.\" $File: magic.man,v 1.98 2020/05/09 18:55:23 christos Exp $
+.Dd May 9, 2020
 .Dt MAGIC __FSECTION__
 .Os
 .\" install as magic.4 on USG, magic.5 on V7, Berkeley and Linux systems.
@@ -300,6 +300,62 @@ This test is always true and clears the match flag for that continuation level.
 It is intended to be used with the
 .Dv default
 test.
+.It Dv der
+Parse the file as a DER Certificate file.
+The test field is used as a der type that needs to be matched.
+The DER types are:
+.Dv eoc ,
+.Dv bool ,
+.Dv int ,
+.Dv bit_str ,
+.Dv octet_str ,
+.Dv null ,
+.Dv obj_id ,
+.Dv obj_desc ,
+.Dv ext ,
+.Dv real ,
+.Dv enum ,
+.Dv embed ,
+.Dv utf8_str ,
+.Dv rel_oid ,
+.Dv time ,
+.Dv res2 ,
+.Dv seq ,
+.Dv set ,
+.Dv num_str ,
+.Dv prt_str ,
+.Dv t61_str ,
+.Dv vid_str ,
+.Dv ia5_str ,
+.Dv utc_time ,
+.Dv gen_time ,
+.Dv gr_str ,
+.Dv vis_str ,
+.Dv gen_str ,
+.Dv univ_str ,
+.Dv char_str ,
+.Dv bmp_str ,
+.Dv date ,
+.Dv tod ,
+.Dv datetime ,
+.Dv duration ,
+.Dv oid-iri ,
+.Dv rel-oid-iri .
+These types can be followed by an optional numeric size, which indicates
+the field width in bytes.
+.It Dv guid
+A Globally Unique Identifier, parsed and printed as
+XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
+It's format is a string.
+.It Dv offset
+This is a quad value indicating the current offset of the file.
+It can be used to determine the size of the file or the magic buffer.
+For example the magic entries:
+.Bd -literal -offset indent
+-0	offset	x	this file is %lld bytes
+-0	offset	<=100	must be more than 100 \e
+    bytes and is only %lld
+.Ed
 .El
 .Pp
 For compatibility with the Single

+ 10 - 0
libmagic.pc.in

@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libmagic
+Description: Magic number recognition library
+Version: @VERSION@
+Libs: -L${libdir} -lmagic
+Libs.private: @LIBS@

+ 2 - 6
magic/Magdir/animation

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: animation,v 1.74 2019/10/29 01:06:20 christos Exp $
+# $File: animation,v 1.77 2020/04/26 15:23:43 christos Exp $
 # animation:  file(1) magic for animation/movie formats
 #
 # animation formats
@@ -159,7 +159,7 @@
 >8	string		mqt		\b, Sony / Mobile QuickTime (.MQV) US Pat 7,477,830
 !:mime	video/quicktime
 >8	string		MSNV		\b, MPEG-4 (.MP4) for SonyPSP
-!:mime	audio/mp4
+!:mime	video/mp4
 >8	string		NDAS		\b, MP4 v2 [ISO 14496-14] Nero Digital AAC Audio
 !:mime	audio/mp4
 >8	string		NDSC		\b, MPEG-4 (.MP4) Nero Cinema Profile
@@ -855,10 +855,6 @@
 >3	byte			&0x80		(PAL)
 >3	byte			^0x80		(NTSC)
 
-# Microsoft Advanced Streaming Format (ASF) <mpruett@sgi.com>
-0	belong			0x3026b275	Microsoft ASF
-!:mime  video/x-ms-asf
-
 # MNG Video Format, <URL:http://www.libpng.org/pub/mng/spec/>
 0	string			\x8aMNG		MNG video data,
 !:mime	video/x-mng

+ 100 - 17
magic/Magdir/archive

@@ -1,5 +1,5 @@
 #------------------------------------------------------------------------------
-# $File: archive,v 1.133 2019/11/15 21:03:14 christos Exp $
+# $File: archive,v 1.138 2020/06/07 23:29:26 christos Exp $
 # archive:  file(1) magic for archive formats (see also "msdos" for self-
 #           extracting compressed archives)
 #
@@ -236,7 +236,8 @@
 !:ext	deb/udeb
 >14	string		-binary	Debian binary package
 !:mime	application/vnd.debian.binary-package
-!:ext	deb/udeb
+# For ipk packager see also https://en.wikipedia.org/wiki/Opkg
+!:ext	deb/udeb/ipk
 # This should not happen
 >14	default		x	Unknown Debian package
 # NL terminated version; for most Debian cases this is 2.0 or 2.1 for splitted
@@ -250,7 +251,16 @@
 >>0	search/0x93e4f	data.tar.	\b, data compression
 # the above line only works if FILE_BYTES_MAX in ../../src/file.h is raised
 # for example like libreoffice-dev-doc_1%3a5.2.7-1+rpi1+deb9u3_all.deb
->>>&0	string		x		%.4s
+>>>&0	string		x		%.2s
+# skip space (0x20 BSD) and slash (0x2f System V) character marking end of name
+>>>&2	ubyte		!0x20
+>>>>&-1	ubyte		!0x2f
+# display 3rd character of file name extension like 2 of bz2 or m of lzma
+>>>>>&-1	ubyte	x		\b%c
+>>>>>>&0	ubyte	!0x20
+>>>>>>>&-1	ubyte	!0x2f
+# display 4th character of file name extension like a of lzma
+>>>>>>>>&-1	ubyte	x		\b%c
 # splitted debian package case
 >68	string		=2.1\n
 # dpkg-1.18.25/dpkg-split/info.c
@@ -1124,71 +1134,120 @@
 
 #   OpenOffice formats (for OpenOffice 1.x / StarOffice 6/7)
 #    (mimetype contains "application/vnd.sun.xml.<SUBTYPE>")
+# URL:		https://en.wikipedia.org/wiki/OpenOffice.org_XML
+# reference:	http://fileformats.archiveteam.org/wiki/OpenOffice.org_XML
 >>50	string	vnd.sun.xml.		OpenOffice.org 1.x
 >>>62	string	writer			Writer
 >>>>68	byte	!0x2e			document
+!:mime	application/vnd.sun.xml.writer
+!:ext	sxw
 >>>>68	string	.template		template
+!:mime	application/vnd.sun.xml.writer.template
+!:ext	stw
+>>>>68	string	.web			Web template
+!:mime	application/vnd.sun.xml.writer.web
+!:ext	stw
 >>>>68	string	.global			global document
+!:mime	application/vnd.sun.xml.writer.global
+!:ext	sxg
 >>>62	string	calc			Calc
 >>>>66	byte	!0x2e			spreadsheet
+!:mime	application/vnd.sun.xml.calc
+!:ext	sxc
 >>>>66	string	.template		template
+!:mime	application/vnd.sun.xml.calc.template
+!:ext	stc
 >>>62	string	draw			Draw
 >>>>66	byte	!0x2e			document
+!:mime	application/vnd.sun.xml.draw
+!:ext	sxd
 >>>>66	string	.template		template
+!:mime	application/vnd.sun.xml.draw.template
+!:ext	std
 >>>62	string	impress			Impress
 >>>>69	byte	!0x2e			presentation
+!:mime	application/vnd.sun.xml.impress
+!:ext	sxi
 >>>>69	string	.template		template
+!:mime	application/vnd.sun.xml.impress.template
+!:ext	sti
 >>>62	string	math			Math document
+!:mime	application/vnd.sun.xml.math
+!:ext	sxm
 >>>62	string	base			Database file
+!:mime	application/vnd.sun.xml.base
+!:ext	sdb
 
 #   OpenDocument formats (for OpenOffice 2.x / StarOffice >= 8)
+#   URL: http://fileformats.archiveteam.org/wiki/OpenDocument
 #    https://lists.oasis-open.org/archives/office/200505/msg00006.html
 #    (mimetype contains "application/vnd.oasis.opendocument.<SUBTYPE>")
 >>50	string	vnd.oasis.opendocument.	OpenDocument
 >>>73	string	text
 >>>>77	byte	!0x2d			Text
 !:mime	application/vnd.oasis.opendocument.text
+!:ext	odt
 >>>>77	string	-template		Text Template
 !:mime	application/vnd.oasis.opendocument.text-template
+!:ext	ott
 >>>>77	string	-web			HTML Document Template
 !:mime	application/vnd.oasis.opendocument.text-web
+!:ext	oth
 >>>>77	string	-master			Master Document
 !:mime	application/vnd.oasis.opendocument.text-master
+!:ext	odm
 >>>73	string	graphics
 >>>>81	byte	!0x2d			Drawing
 !:mime	application/vnd.oasis.opendocument.graphics
->>>>81	string	-template		Template
+!:ext	odg
+>>>>81	string	-template		Drawing Template
 !:mime	application/vnd.oasis.opendocument.graphics-template
+!:ext	otg
 >>>73	string	presentation
 >>>>85	byte	!0x2d			Presentation
 !:mime	application/vnd.oasis.opendocument.presentation
->>>>85	string	-template		Template
+!:ext	odp
+>>>>85	string	-template		Presentation Template
 !:mime	application/vnd.oasis.opendocument.presentation-template
+!:ext	otp
 >>>73	string	spreadsheet
 >>>>84	byte	!0x2d			Spreadsheet
 !:mime	application/vnd.oasis.opendocument.spreadsheet
->>>>84	string	-template		Template
+!:ext	ods
+>>>>84	string	-template		Spreadsheet Template
 !:mime	application/vnd.oasis.opendocument.spreadsheet-template
+!:ext	ots
 >>>73	string	chart
 >>>>78	byte	!0x2d			Chart
 !:mime	application/vnd.oasis.opendocument.chart
->>>>78	string	-template		Template
+!:ext	odc
+>>>>78	string	-template		Chart Template
 !:mime	application/vnd.oasis.opendocument.chart-template
+!:ext	otc
 >>>73	string	formula
 >>>>80	byte	!0x2d			Formula
 !:mime	application/vnd.oasis.opendocument.formula
->>>>80	string	-template		Template
+!:ext	odf
+>>>>80	string	-template		Formula Template
 !:mime	application/vnd.oasis.opendocument.formula-template
+!:ext	otf
+# https://www.loc.gov/preservation/digital/formats/fdd/fdd000441.shtml
 >>>73	string	database		Database
 !:mime	application/vnd.oasis.opendocument.database
+!:ext	odb
 # Valid for LibreOffice Base 6.0.1.1 at least
 >>>73	string	base 			Database
-!:mime	application/vnd.oasis.opendocument.base
+# https://bugs.documentfoundation.org/show_bug.cgi?id=45854
+!:mime	application/vnd.oasis.opendocument.database
+#!:mime	application/vnd.oasis.opendocument.base
+!:ext	odb
 >>>73	string	image
 >>>>78	byte	!0x2d			Image
 !:mime	application/vnd.oasis.opendocument.image
->>>>78	string	-template		Template
+!:ext	odi
+>>>>78	string	-template		Image Template
 !:mime	application/vnd.oasis.opendocument.image-template
+!:ext	oti
 
 #  EPUB (OEBPS) books using OCF (OEBPS Container Format)
 #    https://www.idpf.org/ocf/ocf1.0/download/ocf10.htm, section 4.
@@ -1206,12 +1265,33 @@
 >>>62	string	draw.template+zip	Draw template, version 14-16
 !:mime	application/x-vnd.corel.draw.template+zip
 !:ext	cdrt
->>>62	string	zcf.draw.document+zip	Draw drawing, version 17-21
+>>>62	string	zcf.draw.document+zip	Draw drawing, version 17-22
 !:mime	application/x-vnd.corel.zcf.draw.document+zip
 !:ext	cdr
->>>62	string	zcf.draw.template+zip	Draw template, version 17-21
+>>>62	string	zcf.draw.template+zip	Draw template, version 17-22
 !:mime	application/x-vnd.corel.zcf.draw.template+zip
 !:ext	cdt/cdrt
+# URL:	http://product.corel.com/help/CorelDRAW/540240626/Main/EN/Doc/CorelDRAW-Other-file-formats.html
+>>>62	string	zcf.pattern+zip		Draw pattern, version 22
+!:mime	application/x-vnd.corel.zcf.pattern+zip
+!:ext	pat
+# URL:		https://en.wikipedia.org/wiki/Corel_Designer
+# Reference:	http://fileformats.archiveteam.org/wiki/Corel_Designer
+# Note:		called by TrID "Corel DESIGN graphics"
+>>>62	string	designer.document+zip		DESIGNER graphics, version 14-16
+!:mime	application/x-vnd.corel.designer.document+zip
+!:ext	des
+>>>62	string	zcf.designer.document+zip	DESIGNER graphics, version 17-21
+!:mime	application/x-vnd.corel.zcf.designer.document+zip
+!:ext	des
+# URL:	http://product.corel.com/help/CorelDRAW/540223850/Main/EN/Documentation/
+#	CorelDRAW-Corel-Symbol-Library-CSL.html
+>>>62	string	symbol.library+zip		Symbol Library, version 6-16.3
+!:mime	application/x-vnd.corel.symbol.library+zip
+!:ext	csl
+>>>62	string	zcf.symbol.library+zip		Symbol Library, version 17-22
+!:mime	application/x-vnd.corel.zcf.symbol.library+zip
+!:ext	csl
 
 #  Catch other ZIP-with-mimetype formats
 #	In a ZIP file, the bytes immediately after a member's contents are
@@ -1239,16 +1319,19 @@
 >>>>38		search/64       .app/   iOS App
 !:mime application/x-ios-app
 
+>30	search/100/b application/epub+zip	EPUB document
+!:mime application/epub+zip
 
 # Generic zip archives (Greg Roelofs, c/o zip-bugs@wkuvx1.wku.edu)
 #   Next line excludes specialized formats:
 >(26.s+30)	leshort	!0xcafe
->>26    string          !\x8\0\0\0mimetype	Zip archive data
+>>30	search/100/b !application/epub+zip
+>>>26    string          !\x8\0\0\0mimetype	Zip archive data
 !:mime	application/zip
->>>4	beshort		x			\b, at least
->>>4	use		zipversion
->>>4	beshort		x			to extract
->>>0x161	string		WINZIP		\b, WinZIP self-extracting
+>>>>4	beshort		x			\b, at least
+>>>>4	use		zipversion
+>>>>4	beshort		x			to extract
+>>>>0x161	string		WINZIP		\b, WinZIP self-extracting
 
 # StarView Metafile
 # From Pierre Ducroquet <pinaraf@pinaraf.info>

+ 132 - 0
magic/Magdir/asf

@@ -0,0 +1,132 @@
+
+#------------------------------------------------------------------------------
+# $File: asf,v 1.1 2019/12/26 02:07:53 christos Exp $
+# asf:  file(1) magic for Microsoft Advanced Systems Format (ASF) files
+# http://www.staroceans.org/e-book/ASF_Specification.pdf
+
+0	name	asf-name
+# ASF_Data_Object
+#>0	guid	75B22636-668E-11CF-A6D9-00AA0062CE6C
+#>16	lequad	>0
+#>>(16.q)	use	asf-object
+# ASF_Simple_Index_Object
+>0	guid	33000890-E5B1-11CF-89F4-00A0C90349CB
+>0	guid	D6E229D3-35DA-11D1-9034-00A0C90349BE ASF_Index_Object
+>0	guid	FEB103F8-12AD-4C64-840F-2A1D2F7AD48C ASF_Media_Object_Index_Object
+>0	guid	3CB73FD0-0C4A-4803-953D-EDF7B6228F0C ASF_Timecode_Index_Object
+
+# ASF_File_Properties_Object
+>0	guid	8CABDCA1-A947-11CF-8EE4-00C00C205365 
+
+# ASF_Stream_Properties_Object
+>0	guid	B7DC0791-A9B7-11CF-8EE6-00C00C205365
+#>>56	lequad	x		Time Offset %lld
+#>>64	lelong	x		Type-Specicic Data Length %d
+#>>68	lelong	x		Error Correction Data Length %d
+#>>72	leshort	x		Flags 0x%x
+#>>74	lelong	x		Reserved %x
+# ASF_Audio_Media
+>>24	guid	F8699E40-5B4D-11CF-A8FD-00805F5C442B \b, Audio Media (
+>>>78	leshort	x	\bCodec Id %d
+>>>80	leshort	x	\b, Number of channels %d
+>>>82	lelong	x	\b, Samples Per Second %d
+>>>86	lelong	x	\b, Average Number of Bytes Per Second %d
+>>>90	lelong	x	\b, Block Alignment %d
+>>>94	leshort	x	\b, Bits Per Sample %d
+# ASF_Video_Media
+>>24	guid	BC19EFC0-5B4D-11CF-A8FD-00805F5C442B \b, Video Media (
+>>>78	lelong	x	\bEncoded Image Width %d
+>>>82	lelong	x	\b, Encoded Image Height %d
+#>>>85	leshort	x	\b, Format Data Size %x
+>>>93	lelong	x	\b, Image Width %d
+>>>97	lelong	x	\b, Image Height %d
+#>>>101	leshort	x	\b, Reserved 0x%x
+>>>103	leshort	x	\b, Bits Per Pixel Count %d
+#>>>105	lelong	x 	\b, Compression ID %d
+#>>>109	lelong	x	\b, Image Size %d
+#>>>113	lelong	x	\b, Horizontal Pixels Per Meter %d
+#>>>117	lelong	x	\b, Vertical Pixels Per Meter %d
+#>>>121	lelong	x	\b, Colors Used Count %d
+#>>>125	lelong	x	\b, Important Colors Count %d
+>>0	lelong	x	\b, Error correction type
+>>40	use	asf-name 
+>>0	lelong	x	\b)
+#ASF_Header_Extension_Object
+>0	guid	5FBF03B5-A92E-11CF-8EE3-00C00C205365
+# ASF_Codec_List_Object
+>0	guid	86D15240-311D-11D0-A3A4-00A0C90348F6
+>0	guid	1EFB1A30-0B62-11D0-A39B-00A0C90348F6 ASF_Script_Command_Object
+>0	guid	F487CD01-A951-11CF-8EE6-00C00C205365 ASF_Marker_Object
+>0	guid	D6E229DC-35DA-11D1-9034-00A0C90349BE ASF_Bitrate_Mutual_Exclusion_Object
+>0	guid	75B22635-668E-11CF-A6D9-00AA0062CE6C ASF_Error_Correction_Object
+# ASF_Content_Description_Object
+>0	guid	75B22633-668E-11CF-A6D9-00AA0062CE6C
+#>>24	leshort	title length %d
+#>>26	leshort	author length %d
+#>>28	leshort	copyright length %d
+#>>30	leshort	descriptor length %d
+#>>32	leshort	rating length %d
+>0	guid	D2D0A440-E307-11D2-97F0-00A0C95EA850 ASF_Extended_Content_Description_Object
+>0	guid	2211B3FA-BD23-11D2-B4B7-00A0C955FC6E ASF_Content_Branding_Object
+>0	guid	7BF875CE-468D-11D1-8D82-006097C9A2B2 ASF_Stream_Bitrate_Properties_Object
+>0	guid	2211B3FB-BD23-11D2-B4B7-00A0C955FC6E ASF_Content_Encryption_Object
+>0	guid	298AE614-2622-4C17-B935-DAE07EE9289C ASF_Extended_Content_Encryption_Object
+>0	guid	2211B3FC-BD23-11D2-B4B7-00A0C955FC6E ASF_Digital_Signature_Object
+# ASF_Padding_Object
+>0	guid	1806D474-CADF-4509-A4BA-9AABCB96AAE8
+>0	guid	14E6A5CB-C672-4332-8399-A96952065B5A ASF_Extended_Stream_Properties_Object
+>0	guid	A08649CF-4775-4670-8A16-6E35357566CD ASF_Advanced_Mutual_Exclusion_Object
+>0	guid	D1465A40-5A79-4338-B71B-E36B8FD6C249 ASF_Group_Mutual_Exclusion_Object
+>0	guid	D4FED15B-88D3-454F-81F0-ED5C45999E24 ASF_Stream_Prioritization_Object
+>0	guid	A69609E6-517B-11D2-B6AF-00C04FD908E9 ASF_Bandwidth_Sharing_Object
+>0	guid	7C4346A9-EFE0-4BFC-B229-393EDE415C85 ASF_Language_List_Object
+>0	guid	C5F8CBEA-5BAF-4877-8467-AA8C44FA4CCA ASF_Metadata_Object
+>0	guid	44231C94-9498-49D1-A141-1D134E457054 ASF_Metadata_Library_Object
+>0	guid	D6E229DF-35DA-11D1-9034-00A0C90349BE ASF_Index_Parameters_Object
+>0	guid	6B203BAD-3F11-48E4-ACA8-D7613DE2CFA7 ASF_Media_Object_Index_Parameters_Object
+>0	guid	F55E496D-9797-4B5D-8C8B-604DFE9BFB24 ASF_Timecode_Index_Parameters_Object
+>0	guid	26F18B5D-4584-47EC-9F5F-0E651F0452C9 ASF_Compatibility_Object
+>0	guid	43058533-6981-49E6-9B74-AD12CB86D58C ASF_Advanced_Content_Encryption_Object
+>0	guid	59DACFC0-59E6-11D0-A3AC-00A0C90348F6 ASF_Command_Media
+>0	guid	B61BE100-5B4E-11CF-A8FD-00805F5C44 ASF_JFIF_Media
+>0	guid	35907DE0-E415-11CF-A917-00805F5C442B ASF_Degradable_JPEG_Media
+>0	guid	91BD222C-F21C-497A-8B6D-5AA86BFC0185 ASF_File_Transfer_Media
+>0	guid	3AFB65E2-47EF-40F2-AC2C-70A90D71D343 ASF_Binary_Media
+>0	guid	776257D4-C627-41CB-8F81-7AC7FF1C40CC ASF_Web_Stream_Media_Subtype
+>0	guid	DA1E6B13-8359-4050-B398-388E965BF00C ASF_Web_Stream_Format
+>0	guid	20FB5700-5B55-11CF-A8FD-00805F5C442B ASF_No_Error_Correction
+>0	guid	BFC3CD50-618F-11CF-8BB2-00AA00B4E220 ASF_Audio_Spread
+>0	guid	ABD3D211-A9BA-11cf-8EE6-00C00C205365 ASF_Reserved_1
+>0	guid	7A079BB6-DAA4-4e12-A5CA-91D38DC11A8D ASF_Content_Encryption_System_Windows_Media_DRM
+# _Network_Devices
+>0	guid	86D15241-311D-11D0-A3A4-00A0C90348F6 ASF_Reserved_2
+>0	guid	4B1ACBE3-100B-11D0-A39B-00A0C90348F6 ASF_Reserved_3
+>0	guid	4CFEDB20-75F6-11CF-9C0F-00A0C90349CB ASF_Reserved_4
+>0	guid	D6E22A00-35DA-11D1-9034-00A0C90349BE ASF_Mutex_Language
+>0	guid	D6E22A01-35DA-11D1-9034-00A0C90349BE ASF_Mutex_Bitrate
+>0	guid	D6E22A02-35DA-11D1-9034-00A0C90349BE ASF_Mutex_Unknown
+>0	guid	AF6060AA-5197-11D2-B6AF-00C04FD908E9 ASF_Bandwidth_Sharing_Exclusive
+>0	guid	AF6060AB-5197-11D2-B6AF-00C04FD908E9 ASF_Bandwidth_Sharing_Partial
+>0	guid	399595EC-8667-4E2D-8FDB-98814CE76C1E ASF_Payload_Extension_System_Timecode
+>0	guid	E165EC0E-19ED-45D7-B4A7-25CBD1E28E9B ASF_Payload_Extension_System_File_Name
+>0	guid	D590DC20-07BC-436C-9CF7-F3BBFBF1A4DC ASF_Payload_Extension_System_Content_Type
+>0	guid	1B1EE554-F9EA-4BC8-821A-376B74E4C4B8 ASF_Payload_Extension_System_Pixel_Aspect_Ratio
+>0	guid	C6BD9450-867F-4907-83A3-C77921B733AD ASF_Payload_Extension_System_Sample_Duration
+>0	guid	6698B84E-0AFA-4330-AEB2-1C0A98D7A44D ASF_Payload_Extension_System_Encryption_Sample_ID
+>0	guid	00E1AF06-7BEC-11D1-A582-00C04FC29CFB ASF_Payload_Extension_System_Degradable_JPEG
+
+0	name	asf-object
+>0	use	asf-name
+#>>16	lequad	>0					(size %lld) [
+>>16	lequad	>0
+>>>(16.q)	use	asf-object
+#>>16	lequad	0	]
+
+# Microsoft Advanced Streaming Format (ASF) <mpruett@sgi.com>
+0	guid	75B22630-668E-11CF-A6D9-00AA0062CE6C	Microsoft ASF
+!:mime  video/x-ms-asf 
+#>16	lequad	>0					(size %lld
+#>>24	lelong	x					\b, %d header objects)
+>16	lequad	>0
+>>30	use	asf-object
+>>(16.q)	use	asf-object

+ 9 - 2
magic/Magdir/cad

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: cad,v 1.20 2019/08/10 13:34:17 christos Exp $
+# $File: cad,v 1.23 2020/05/30 23:58:07 christos Exp $
 # autocad:  file(1) magic for cad files
 #
 
@@ -229,7 +229,11 @@
 !:mime image/vnd.dwg
 0	string	AC1024	DWG AutoDesk AutoCAD 2010/2011/2012
 !:mime image/vnd.dwg
-0	string	AC1027	DWG AutoDesk AutoCAD 2013/2014
+0	string	AC1027	DWG AutoDesk AutoCAD 2013-2017
+!:mime image/vnd.dwg
+
+# From GNU LibreDWG
+0	string	AC1032	DWG AutoDesk AutoCAD 2018/2019
 !:mime image/vnd.dwg
 
 # KOMPAS 2D drawing from ASCON
@@ -315,3 +319,6 @@
 0	string	\xff\xfe\xff\x0e\x53\x00\x6b\x00\x65\x00\x74\x00\x63\x00\x68\x00\x55\x00\x70\x00\x20\x00\x4d\x00\x6f\x00\x64\x00\x65\x00\x6c\x00	SketchUp Model
 !:mime application/vnd.sketchup.skp
 !:ext skp
+
+4	regex/b	P[0-9][0-9]\\.[0-9][0-9][0-9][0-9]\\.[0-9][0-9][0-9][0-9]\\.[0-9]	NAXOS CAD System file from version %s
+!:strength +40

+ 25 - 1
magic/Magdir/commands

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: commands,v 1.61 2019/10/30 03:16:43 christos Exp $
+# $File: commands,v 1.63 2020/06/06 15:36:30 christos Exp $
 # commands:  file(1) magic for various shells and interpreters
 #
 #0	string/w	:			shell archive or script for antique kernel text
@@ -84,6 +84,30 @@
 0	string/wt	#!\ /usr/bin/env\ bash	Bourne-Again shell script text executable
 !:mime	text/x-shellscript
 
+# Fish shell magic
+# From: Benjamin Lowry <ben@ben.gmbh>
+0	string/wt	#!\ /usr/local/bin/fish		fish shell script text executable
+!:mime	text/x-shellscript
+0	string/wt	#!\ /usr/bin/fish		fish shell script text executable
+!:mime	text/x-shellscript
+0	string/wt	#!\ /usr/bin/env\ fish		fish shell script text executable
+!:mime	text/x-shellscript
+
+
+0	search/1/wt	#!\ /usr/bin/tclsh	Tcl/Tk script text executable
+!:mime  text/x-tcl
+
+0	search/1/wt	#!\ /usr/bin/texlua	LuaTex script text executable
+!:mime	text/x-luatex
+
+0	search/1/wt	#!\ /usr/bin/luatex	LuaTex script text executable
+!:mime	text/x-luatex
+
+0	search/1/wt	#!\ /usr/bin/stap	Systemtap script text executable
+!:mime  text/x-systemtap
+
+
+
 # PHP scripts
 # Ulf Harnhammar <ulfh@update.uu.se>
 0	search/1/c	=<?php			PHP script text

+ 11 - 2
magic/Magdir/compress

@@ -1,5 +1,5 @@
 #------------------------------------------------------------------------------
-# $File: compress,v 1.77 2019/10/08 20:25:13 christos Exp $
+# $File: compress,v 1.79 2020/05/30 23:53:04 christos Exp $
 # compress:  file(1) magic for pure-compression formats (no archives)
 #
 # compress, gzip, pack, compact, huf, squeeze, crunch, freeze, yabba, etc.
@@ -61,7 +61,9 @@
 !:mime	application/gzip
 >>>0	use	gzip-info
 # size of the original (uncompressed) input data modulo 2^32
+>>-0	offset		>48
 >>>-4	ulelong		x		\b, original size modulo 2^32 %u
+>>-0	offset		<48		\b, truncated
 # gzipped TAR or VirtualBox extension package
 #!:mime	application/x-compressed-tar
 #!:mime	application/x-virtualbox-vbox-extpack
@@ -84,7 +86,9 @@
 !:ext	gz/tgz/tpz/zabw/svgz
 >>0	use	gzip-info
 # size of the original (uncompressed) input data modulo 2^32
->>-4	ulelong		x		\b, original size modulo 2^32 %u
+>>-0	offset		>48
+>>>-4	ulelong		x		\b, original size modulo 2^32 %u
+>>-0	offset		<48		\b, truncated
 #	display information of gzip compressed files
 0	name				gzip-info
 #>2	byte		x		THIS iS GZIP
@@ -392,3 +396,8 @@
 0	string	bvx1	lzfse compressed, uncompressed tables
 0	string	bvx2	lzfse compressed, compressed tables
 0	string	bvxn	lzfse encoded, lzvn compressed
+
+# pcxLib.exe compression program
+# http://www.shikadi.net/moddingwiki/PCX_Library
+0	string/b	pcxLib
+>0x0A	string/b	Copyright\020(c)\020Genus\020Microprogramming,\020Inc.	pcxLib compressed

+ 91 - 5
magic/Magdir/console

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: console,v 1.49 2019/05/27 01:33:32 christos Exp $
+# $File: console,v 1.55 2020/04/19 17:30:55 christos Exp $
 # Console game magic
 # Toby Deshane <hac@shoelace.digivill.net>
 
@@ -628,10 +628,12 @@
 
 0	string	CON\x20	Microsoft Xbox 360 package (console-signed)
 >0	use	xbox-360-package
-0	string	PIRS	Microsoft Xbox 360 package (non-Xbox Live)
->0	use	xbox-360-package
-0	string	LIVE	Microsoft Xbox 360 package (Xbox Live)
->0	use	xbox-360-package
+0	string	PIRS
+>0	belong	0	Microsoft Xbox 360 package (non-Xbox Live)
+>>0	use	xbox-360-package
+0	string	LIVE
+>0x104	belong	0	Microsoft Xbox 360 package (Xbox Live)
+>>0	use	xbox-360-package
 
 # Atari Lynx cartridge dump (EXE/BLL header)
 # From: "Stefan A. Haubenthal" <polluks@web.de>
@@ -667,6 +669,30 @@
 # IPS Patch Files from: From: Thomas Klausner <tk@giga.or.at>
 # see https://zerosoft.zophar.net/ips.php
 0	string	PATCH			IPS patch file
+!:ext	ips
+
+# BPS Patch Files - from: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://www.romhacking.net/documents/746/
+0	string	BPS1			BPS patch file
+!:ext	bps
+
+# APS Patch Files - from: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://github.com/btimofeev/UniPatcher/wiki/APS-(N64)
+0	string	APS10			APS patch file
+!:ext	aps
+>5	byte	0			\b, simple patch
+>5	byte	1			\b, N64-specific patch for
+>>58	byte	x			N%c
+>>59	byte	x			\b%c
+>>60	byte	x			\b%c
+>7	byte	!0x20
+# FIXME: /T specifier isn't working with a fixed-length string.
+>>7	string	x			\b: "%.50s"
+
+# UPS Patch Files - from: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: http://fileformats.archiveteam.org/wiki/UPS_(binary_patch_format)
+0	string	UPS1			UPS patch file
+!:ext	ups
 
 # Playstations Patch Files from: From: Thomas Klausner <tk@giga.or.at>
 0	string	PPF30			Playstation Patch File version 3.0
@@ -767,6 +793,8 @@
 >0x07	byte	x	\b, Rev.%02u)
 >0x18	belong	0x5D1C9EA3
 >>0x60	beshort	0x0101	\b (Unencrypted)
+>0x200	string	NKIT	\b (NKit compressed)
+
 
 # Type: Nintendo GameCube disc image
 # From: David Korth <gerbilsoft@gerbilsoft.com>
@@ -1015,3 +1043,61 @@
 >>>>>>0x5B	byte	0x02
 >>>>>>>0x54	belong	x	Nintendo amiibo NFC dump - amiibo ID: %08X-
 >>>>>>>0x58	belong	x	\b%08X
+
+#------------------------------------------------------------------------------
+# Type: Nintendo Switch XCI (Game Cartridge Image)
+# From: Benjamin Lowry <ben@ben.gmbh>
+# Reference: https://switchbrew.org/wiki/Gamecard_Format
+0x100		string	HEAD
+>0x10D		byte	0xFA	Nintendo Switch cartridge image (XCI), 1GB
+>0x10D		byte	0xF8	Nintendo Switch cartridge image (XCI), 2GB
+>0x10D		byte	0xF0	Nintendo Switch cartridge image (XCI), 4GB
+>0x10D		byte	0xE0	Nintendo Switch cartridge image (XCI), 8GB
+>0x10D		byte	0xE1	Nintendo Switch cartridge image (XCI), 16GB
+>0x10D		byte	0xE2	Nintendo Switch cartridge image (XCI), 32GB
+
+#------------------------------------------------------------------------------
+# Type: Nintendo Switch Executable
+# From: Benjamin Lowry <ben@ben.gmbh>
+# Reference: https://switchbrew.org/wiki/NSO
+0x00		string	NSO0	Nintendo Switch executable (NSO)
+
+#------------------------------------------------------------------------------
+# Type: Nintendo Switch PFS0
+# From: Benjamin Lowry <ben@ben.gmbh>
+# Reference: https://switchbrew.org/wiki/NCA_Format#PFS0
+0x00		string	PFS0	Nintendo Switch partition filesystem (PFS0)
+>0x04		ulelong	x	\b, %d files
+
+#------------------------------------------------------------------------------
+# amiibo: file(1) magic for Nintendo Badge Arcade files.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# References:
+# - https://github.com/GerbilSoft/rom-properties/issues/92
+# - https://github.com/CaitSith2/BadgeArcadeTool
+# - https://github.com/TheMachinumps/Advanced-badge-editor
+
+# PRBS: Individual badge and/or mega badge.
+0		string	PRBS
+>0x44		byte	>0x20	Nintendo Badge Arcade
+>>0xB8		ulelong	<2
+>>>0xBC		ulelong	<2	badge:
+>>>0xBC		ulelong	>1	Mega Badge
+>>>>0xB8	ulelong	x	(%ux
+>>>>0xBC	ulelong	x	\b%u):
+>>0xB8		ulelong	>1	Mega Badge
+>>>0xB8		ulelong	x	(%ux
+>>>0xBC		ulelong	x	\b%u):
+>0x44		string	x	"%s"
+>0x3C		ulelong	x	\b, badge ID: %u
+>0x74		byte	>0x20
+>>0x74		string	x	\b, set: "%s"
+>0xA8		ulelong	!0xFFFFFFFF
+>>0xA8		ulelong	x	\b, launch title ID: %08X
+>>0xA4		ulelong	x	\b-%08X
+
+# CABS: Badge set.
+0	string	CABS
+>0x2C	byte	>0x20	Nintendo Badge Arcade badge set:
+>>0x2C	string	x	"%.48s"
+>>0x24	ulelong	x	\b, set ID: %u

+ 25 - 8
magic/Magdir/database

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: database,v 1.56 2019/06/14 20:12:00 christos Exp $
+# $File: database,v 1.59 2020/03/25 01:49:58 christos Exp $
 # database:  file(1) magic for various databases
 #
 # extracted from header/code files by Graeme Wilford (eep2gw@ee.surrey.ac.uk)
@@ -359,16 +359,22 @@
 >>>>>>>>>>>>0	use		foxpro-memo-print
 # dBASE III DBT , garbage
 # skip WORD1XW.DOC with improbably high free block index
->>>>>>>>>0	lelong		<2205083
+>>>>>>>>>0	ulelong		<0x400000
+# skip WinStore.App.exe by looking for printable 2nd character of 1st memo item
+>>>>>>>>>>513	ubyte		>037
 # unusual dBASE III DBT like adressen.dbt
->>>>>>>>>>0	use		dbase3-memo-print
+>>>>>>>>>>>0	use		dbase3-memo-print
 # dBASE III DBT like angest.dbt, or garbage PCX DBF
 >>>>>>>>8	ubelong		!0
 # skip PCX and some DBF by test for for reserved NULL bytes
 >>>>>>>>>510	ubeshort	0
-# skip AI070GEP.EPS with improbably high free block index
->>>>>>>>>>0	lelong		<458766
->>>>>>>>>>>0	use		dbase3-memo-print
+# skip bad symples with improbably high free block index above 2 GiB file limit
+>>>>>>>>>>0	ulelong		<0x400000
+# skip AI070GEP.EPS by printable 1st character of 1st memo item
+>>>>>>>>>>>512	ubyte		>037
+# skip gluon-ffhat-1.0-tp-link-tl-wr1043n-nd-v2-sysupgrade.bin by printable 2nd character
+>>>>>>>>>>>>513	ubyte		>037
+>>>>>>>>>>>>>0	use		dbase3-memo-print
 # dBASE IV DBT with positive block size
 >>>>>>>20	uleshort	>0
 # dBASE IV DBT with valid block length like 512, 1024
@@ -490,9 +496,9 @@
 #>>52	ulelong		3		\b, CleanShutdown
 >>52	ulelong		4		\b, BeingConverted
 >>52	ulelong		5		\b, ForceDetach
-# Windows NT major version when the databases indexes were updated.
+# Windows NT major version when the databases indexes were updated.
 >>216	ulelong		x		\b, Windows version %d
-# Windows NT minor version
+# Windows NT minor version
 >>220	ulelong		x		\b.%d
 
 # From: Joerg Jenderek
@@ -645,3 +651,14 @@
 # From: David Korth <gerbilsoft@gerbilsoft.com>
 0	string	//\ <!--\ <mdb:mork:z\ v="	Mozilla Mork database
 >23	string	x		\b, version %.3s
+
+# URL:		https://en.wikipedia.org/wiki/Management_Information_Format
+# Reference:	https://www.dmtf.org/sites/default/files/standards/documents/DSP0005.pdf
+# From:		Joerg Jenderek
+# Note:		only tested with monitor asset reports of Dell Display Manager
+#		skip start like Language=fr|CA|iso8859-1
+0	search/27/C	Start\040Component	DMI Management Information Format
+#!:mime	text/plain
+!:mime	text/x-dmtf-mif
+!:ext	mif
+

+ 23 - 1
magic/Magdir/der

@@ -1,5 +1,5 @@
 #------------------------------------------------------------------------------
-# $File: der,v 1.2 2017/03/17 21:35:28 christos Exp $
+# $File: der,v 1.3 2020/02/16 20:45:21 christos Exp $
 # der: file(1) magic for DER encoded files
 #
 
@@ -114,3 +114,25 @@
 >>>&0	der	utc_time=x	\b, utcTime=%s
 >>>&0	der	utc_time=x	\b, utcTime=%s
 >>&0	use	certinfo
+
+0	der	seq
+>&0	der	seq
+>>&0	der	eoc		Certificate
+>>>&0	der	int1=02		\b, Version=3
+>>&0	der	int9=x		\b, Serial=%s
+>>&0	der	seq		
+>>>&0	der     obj_id9=2a864886f70d01010b
+>>>&0	der	null
+>>&0	der	seq
+>>>&0	der	set
+>>>>&0	der	seq	
+>>>>>&0	der     obj_id3=550403
+>>>>>&0	der     utf8_str=x      \b, Issuer=%s
+>>&0	der	seq
+>>>&0	der	utc_time=x	\b, not-valid-before=%s
+>>>&0	der	utc_time=x	\b, not-valid-after=%s
+>>&0	der	seq
+>>>&0	der	set
+>>>>&0	der	seq
+>>>>>&0	der     obj_id3=550403
+>>>>>&0	der     utf8_str=x      \b, Subject=%s

+ 33 - 0
magic/Magdir/dif

@@ -0,0 +1,33 @@
+
+#------------------------------------------------------------------------------
+# $File: dif,v 1.1 2020/04/09 19:14:01 christos Exp $
+# dif:  file(1) magic for DIF text files
+
+#------------------------------------------------------------------------------
+# From:	Joerg Jenderek
+# URL:	http://en.wikipedia.org/wiki/Data_Interchange_Format
+#	http://fileformats.archiveteam.org/wiki/Data_Interchange_Format
+# Note:	called by TrID "Data Interchange Format",
+#	by DROID x-fmt/368 "VisiCalc Database"
+0	string		TABLE
+# skip text starting with TABLE by looking for numeric version on 2nd line
+>6	search/2	0,
+# skip DROID x-fmt-41-signature-id-380.dif by looking for key word TUPLES at the beginning
+>>27	search/128	TUPLES		Data Interchange Format
+# https://www.pcmatic.com/company/libraries/fileextension/detail.asp?ext=dif.html
+#!:mime	application/x-dif-spreadsheet	Gnumeric
+# https://github.com/LibreOffice/online/blob/master/discovery.xml
+#!:mime	application/x-dif-document	LibreOffice
+# https://www.wikidata.org/wiki/Wikidata:WikiProject_Informatics/File_formats/Lists/File_formats
+!:mime	application/x-dif
+# https://extension.nirsoft.net/dif
+#!:mime	application/vnd.ms-excel
+#!:mime	text/plain
+!:ext	dif
+# look for double quote 0x22 on 3rd line
+>>>10	search/3	"
+# skip if next character also double quote 
+>>>>&0	ubyte		!0x22		\b, generator or table name
+# comment like EXCEL, pwm enclosed in double quotes
+>>>>>&-2	string	x		%s
+

+ 4 - 3
magic/Magdir/elf

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: elf,v 1.79 2019/12/16 04:24:01 christos Exp $
+# $File: elf,v 1.80 2020/02/12 22:17:33 christos Exp $
 # elf:  file(1) magic for ELF executables
 #
 # We have to check the byte order flag to see what byte order all the
@@ -50,8 +50,9 @@
 !:mime	application/x-object
 >16	leshort		2		executable,
 !:mime	application/x-executable
->16	leshort		3		shared object,
-!:mime	application/x-sharedlib
+>16	leshort		3		${x?pie executable:shared object},
+
+!:mime	application/x-${x?pie-executable:sharedlib}
 >16	leshort		4		core file,
 !:mime	application/x-coredump
 # OS-specific

+ 3 - 3
magic/Magdir/filesystems

@@ -1,5 +1,5 @@
 #------------------------------------------------------------------------------
-# $File: filesystems,v 1.131 2019/11/15 23:49:38 christos Exp $
+# $File: filesystems,v 1.133 2020/05/17 19:32:00 christos Exp $
 # filesystems:  file(1) magic for different filesystems
 #
 0	name	partid
@@ -1994,7 +1994,7 @@
 # to display CD-ROM (70=81-11) after MBR (113=40+72+1), partition-table (71=50+21) and before Apple Driver Map (51)
 #!:strength -11
 # to display CD-ROM (114=81+33) before MBR (113=40+72+1), partition-table (71=50+21) and Apple Driver Map (51)
-!:strength +34
+!:strength +35
 >0	use	cdrom
 
 # URL: https://en.wikipedia.org/wiki/NRG_(file_format)
@@ -2182,7 +2182,7 @@
 >0	use	squashfs
 
 0	string	hsqs	Squashfs filesystem, little endian,
->0	use	^squashfs
+>0	use	\^squashfs
 
 # AFS Dump Magic
 # From: Ty Sarna <tsarna@sarna.org>

+ 11 - 1
magic/Magdir/games

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: games,v 1.18 2019/11/10 19:19:58 christos Exp $
+# $File: games,v 1.20 2020/02/01 16:32:33 christos Exp $
 # games:  file(1) for games
 
 # Fabio Bonelli <fabiobonelli@libero.it>
@@ -303,3 +303,13 @@
 0	string		ESVG
 >4	lelong		0x00160000
 >10	string		TOC\020		Empire Deluxe for DOS saved game
+
+# Sid Meier's Civilization V/VI
+# From: Benjamin Lowry <ben@ben.gmbh>
+0	string	CIV5
+>4	byte	0x08		Sid Meier's Civilization V saved game,
+>>12	regex	[0-9a-z.]+	saved by game version %s
+>4	byte	0x01		Sid Meier's Civilization V replay data,
+>>12	regex	[0-9a-z.]+	saved by game version %s
+
+0	string	CIV6		Sid Meier's Civilization VI saved game

+ 1 - 6
magic/Magdir/gnu

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: gnu,v 1.21 2019/04/19 00:42:27 christos Exp $
+# $File: gnu,v 1.22 2020/04/09 19:11:58 christos Exp $
 # gnu:  file(1) magic for various GNU tools
 #
 # GNU nlsutils message catalog file format
@@ -158,11 +158,6 @@
 >>>20	bedate	x	\b, last-maintained %s
 
 
-# Gnumeric spreadsheet
-# This entry is only semi-helpful, as Gnumeric compresses its files, so
-# they will ordinarily reported as "compressed", but at least -z helps
-39      string          =<gmr:Workbook           Gnumeric spreadsheet
-
 # From: James Youngman <jay@gnu.org>
 # gnu find magic
 0	string	\0LOCATE	GNU findutils locate database data

+ 398 - 63
magic/Magdir/images

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: images,v 1.171 2019/11/23 16:19:47 christos Exp $
+# $File: images,v 1.181 2020/05/30 23:49:03 christos Exp $
 # images:  file(1) magic for image formats (see also "iff", and "c-lang" for
 # XPM bitmaps)
 #
@@ -27,6 +27,8 @@
 # and Image Type 1 2 3 9 10 11 32 33
 # and Color Map Entry Size 0 15 16 24 32
 0	ubequad&0x00FeC400000000C0	0
+# Conflict with MPEG sequences.
+!:strength -40
 # Prevent conflicts with CRI ADX.
 >(2.S-2) belong	!0x28632943
 # skip more garbage like *.iso by looking for positive image type
@@ -523,6 +525,17 @@
 # ImageMagick-7.0.9-2/Magick++/demo/smile_anim.miff
 >>>0	ubyte		!0x7b
 >>>>0	string		>\0		'%-.14s'
+# URL:		https://imagemagick.org/
+# Reference:	https://imagemagick.org/script/magick-vector-graphics.php
+# From:		Joerg Jenderek
+# Note:		all white-spaces between commands are ignored
+0	string		push
+# skip some white spaces
+>5	search/3	graphic-context	ImageMagick Vector Graphic
+# TODO: look for dangerous commands like CVE-2016-3715
+#!:mime	text/plain
+!:mime	image/x-mvg
+!:ext	mvg
 
 # Artisan
 0	long		1123028772	Artisan image data
@@ -1372,6 +1385,8 @@
 # From: Tom Hilinski <tom.hilinski@comcast.net>
 # https://www.unidata.ucar.edu/packages/netcdf/
 0	string	CDF\001			NetCDF Data Format data
+# 64-bit offset netcdf Classic https://www.unidata.ucar.edu/software/netcdf/docs/file_format_specifications
+0	string	CDF\002			NetCDF Data Format data (64-bit offset)
 
 #-----------------------------------------------------------------------
 # Hierarchical Data Format, used to facilitate scientific data exchange
@@ -1882,8 +1897,7 @@
 
 # Type: Khronos KTX texture.
 # From: David Korth <gerbilsoft@gerbilsoft.com>
-# References:
-# - https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
+# Reference: https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
 
 # glEnum decoding.
 # NOTE: Only the most common formats are listed here.
@@ -1900,6 +1914,10 @@
 >0	lelong	0x83A3	\b, RGBA4_S3TC
 >0	lelong	0x83A4	\b, RGBA_DXT5_S3TC
 >0	lelong	0x83A5	\b, RGBA4_DXT5_S3TC
+>0	lelong	0x83F0	\b, COMPRESSED_RGB_S3TC_DXT1_EXT
+>0	lelong	0x83F1	\b, COMPRESSED_RGBA_S3TC_DXT1_EXT
+>0	lelong	0x83F2	\b, COMPRESSED_RGBA_S3TC_DXT3_EXT
+>0	lelong	0x83F3	\b, COMPRESSED_RGBA_S3TC_DXT5_EXT
 >0	lelong	0x8D64	\b, ETC1_RGB8_OES
 >0	lelong	0x9270	\b, COMPRESSED_R11_EAC
 >0	lelong	0x9271	\b, COMPRESSED_SIGNED_R11_EAC
@@ -1959,6 +1977,281 @@
 >12	belong	0x04030201			(big-endian)
 >>16	use	\^khronos-ktx-endian-header
 
+# Type: Khronos KTX2 texture.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Based on draft19.
+# Reference: http://github.khronos.org/KTX-Specification/
+
+# Supercompression enum.
+0	name	khronos-ktx2-supercompression
+>0	lelong	1	Basis Universal
+>0	lelong	2	Zstandard
+
+# Vulkan format identifier.
+# NOTE: Formats prohibited from KTX2 are commented out.
+0	name	khronos-ktx2-vkFormat
+>0	lelong	0	UNDEFINED
+>0	lelong	1	R4G4_UNORM_PACK8
+>0	lelong	2	R4G4B4A4_UNORM_PACK16
+>0	lelong	3	B4G4R4A4_UNORM_PACK16
+>0	lelong	4	R5G6B5_UNORM_PACK16
+>0	lelong	5	B5G6R5_UNORM_PACK16
+>0	lelong	6	R5G5B5A1_UNORM_PACK16
+>0	lelong	7	B5G5R5A1_UNORM_PACK16
+>0	lelong	8	A1R5G5B5_UNORM_PACK16
+>0	lelong	9	R8_UNORM
+>0	lelong	10	R8_SNORM
+#>0	lelong	11	R8_USCALED
+#>0	lelong	12	R8_SSCALED
+>0	lelong	13	R8_UINT
+>0	lelong	14	R8_SINT
+>0	lelong	15	R8_SRGB
+>0	lelong	16	R8G8_UNORM
+>0	lelong	17	R8G8_SNORM
+#>0	lelong	18	R8G8_USCALED
+#>0	lelong	19	R8G8_SSCALED
+>0	lelong	20	R8G8_UINT
+>0	lelong	21	R8G8_SINT
+>0	lelong	22	R8G8_SRGB
+>0	lelong	23	R8G8B8_UNORM
+>0	lelong	24	R8G8B8_SNORM
+#>0	lelong	25	R8G8B8_USCALED
+#>0	lelong	26	R8G8B8_SSCALED
+>0	lelong	27	R8G8B8_UINT
+>0	lelong	28	R8G8B8_SINT
+>0	lelong	29	R8G8B8_SRGB
+>0	lelong	30	B8G8R8_UNORM
+>0	lelong	31	B8G8R8_SNORM
+#>0	lelong	32	B8G8R8_USCALED
+#>0	lelong	33	B8G8R8_SSCALED
+>0	lelong	34	B8G8R8_UINT
+>0	lelong	35	B8G8R8_SINT
+>0	lelong	36	B8G8R8_SRGB
+>0	lelong	37	R8G8B8A8_UNORM
+>0	lelong	38	R8G8B8A8_SNORM
+#>0	lelong	39	R8G8B8A8_USCALED
+#>0	lelong	40	R8G8B8A8_SSCALED
+>0	lelong	41	R8G8B8A8_UINT
+>0	lelong	42	R8G8B8A8_SINT
+>0	lelong	43	R8G8B8A8_SRGB
+>0	lelong	44	B8G8R8A8_UNORM
+>0	lelong	45	B8G8R8A8_SNORM
+#>0	lelong	46	B8G8R8A8_USCALED
+#>0	lelong	47	B8G8R8A8_SSCALED
+>0	lelong	48	B8G8R8A8_UINT
+>0	lelong	49	B8G8R8A8_SINT
+>0	lelong	50	B8G8R8A8_SRGB
+#>0	lelong	51	A8B8G8R8_UNORM_PACK32
+#>0	lelong	52	A8B8G8R8_SNORM_PACK32
+#>0	lelong	53	A8B8G8R8_USCALED_PACK32
+#>0	lelong	54	A8B8G8R8_SSCALED_PACK32
+#>0	lelong	55	A8B8G8R8_UINT_PACK32
+#>0	lelong	56	A8B8G8R8_SINT_PACK32
+#>0	lelong	57	A8B8G8R8_SRGB_PACK32
+>0	lelong	58	A2R10G10B10_UNORM_PACK32
+>0	lelong	59	A2R10G10B10_SNORM_PACK32
+#>0	lelong	60	A2R10G10B10_USCALED_PACK32
+#>0	lelong	61	A2R10G10B10_SSCALED_PACK32
+>0	lelong	62	A2R10G10B10_UINT_PACK32
+>0	lelong	63	A2R10G10B10_SINT_PACK32
+>0	lelong	64	A2B10G10R10_UNORM_PACK32
+>0	lelong	65	A2B10G10R10_SNORM_PACK32
+#>0	lelong	66	A2B10G10R10_USCALED_PACK32
+#>0	lelong	67	A2B10G10R10_SSCALED_PACK32
+>0	lelong	68	A2B10G10R10_UINT_PACK32
+>0	lelong	69	A2B10G10R10_SINT_PACK32
+>0	lelong	70	R16_UNORM
+>0	lelong	71	R16_SNORM
+#>0	lelong	72	R16_USCALED
+#>0	lelong	73	R16_SSCALED
+>0	lelong	74	R16_UINT
+>0	lelong	75	R16_SINT
+>0	lelong	76	R16_SFLOAT
+>0	lelong	77	R16G16_UNORM
+>0	lelong	78	R16G16_SNORM
+#>0	lelong	79	R16G16_USCALED
+#>0	lelong	80	R16G16_SSCALED
+>0	lelong	81	R16G16_UINT
+>0	lelong	82	R16G16_SINT
+>0	lelong	83	R16G16_SFLOAT
+>0	lelong	84	R16G16B16_UNORM
+>0	lelong	85	R16G16B16_SNORM
+#>0	lelong	86	R16G16B16_USCALED
+#>0	lelong	87	R16G16B16_SSCALED
+>0	lelong	88	R16G16B16_UINT
+>0	lelong	89	R16G16B16_SINT
+>0	lelong	90	R16G16B16_SFLOAT
+>0	lelong	91	R16G16B16A16_UNORM
+>0	lelong	92	R16G16B16A16_SNORM
+#>0	lelong	93	R16G16B16A16_USCALED
+#>0	lelong	94	R16G16B16A16_SSCALED
+>0	lelong	95	R16G16B16A16_UINT
+>0	lelong	96	R16G16B16A16_SINT
+>0	lelong	97	R16G16B16A16_SFLOAT
+>0	lelong	98	R32_UINT
+>0	lelong	99	R32_SINT
+>0	lelong	100	R32_SFLOAT
+>0	lelong	101	R32G32_UINT
+>0	lelong	102	R32G32_SINT
+>0	lelong	103	R32G32_SFLOAT
+>0	lelong	104	R32G32B32_UINT
+>0	lelong	105	R32G32B32_SINT
+>0	lelong	106	R32G32B32_SFLOAT
+>0	lelong	107	R32G32B32A32_UINT
+>0	lelong	108	R32G32B32A32_SINT
+>0	lelong	109	R32G32B32A32_SFLOAT
+>0	lelong	110	R64_UINT
+>0	lelong	111	R64_SINT
+>0	lelong	112	R64_SFLOAT
+>0	lelong	113	R64G64_UINT
+>0	lelong	114	R64G64_SINT
+>0	lelong	115	R64G64_SFLOAT
+>0	lelong	116	R64G64B64_UINT
+>0	lelong	117	R64G64B64_SINT
+>0	lelong	118	R64G64B64_SFLOAT
+>0	lelong	119	R64G64B64A64_UINT
+>0	lelong	120	R64G64B64A64_SINT
+>0	lelong	121	R64G64B64A64_SFLOAT
+>0	lelong	122	B10G11R11_UFLOAT_PACK32
+>0	lelong	123	E5B9G9R9_UFLOAT_PACK32
+>0	lelong	124	D16_UNORM
+>0	lelong	125	X8_D24_UNORM_PACK32
+>0	lelong	126	D32_SFLOAT
+>0	lelong	127	S8_UINT
+>0	lelong	128	D16_UNORM_S8_UINT
+>0	lelong	129	D24_UNORM_S8_UINT
+>0	lelong	130	D32_SFLOAT_S8_UINT
+
+>0	lelong	131	BC1_RGB_UNORM_BLOCK
+>0	lelong	132	BC1_RGB_SRGB_BLOCK
+>0	lelong	133	BC1_RGBA_UNORM_BLOCK
+>0	lelong	134	BC1_RGBA_SRGB_BLOCK
+>0	lelong	135	BC2_UNORM_BLOCK
+>0	lelong	136	BC2_SRGB_BLOCK
+>0	lelong	137	BC3_UNORM_BLOCK
+>0	lelong	138	BC3_SRGB_BLOCK
+>0	lelong	139	BC4_UNORM_BLOCK
+>0	lelong	140	BC4_SNORM_BLOCK
+>0	lelong	141	BC5_UNORM_BLOCK
+>0	lelong	142	BC5_SNORM_BLOCK
+>0	lelong	143	BC6H_UFLOAT_BLOCK
+>0	lelong	144	BC6H_SFLOAT_BLOCK
+>0	lelong	145	BC7_UNORM_BLOCK
+>0	lelong	146	BC7_SRGB_BLOCK
+
+>0	lelong	147	ETC2_R8G8B8_UNORM_BLOCK
+>0	lelong	148	ETC2_R8G8B8_SRGB_BLOCK
+>0	lelong	149	ETC2_R8G8B8A1_UNORM_BLOCK
+>0	lelong	150	ETC2_R8G8B8A1_SRGB_BLOCK
+>0	lelong	151	ETC2_R8G8B8A8_UNORM_BLOCK
+>0	lelong	152	ETC2_R8G8B8A8_SRGB_BLOCK
+
+>0	lelong	153	EAC_R11_UNORM_BLOCK
+>0	lelong	154	EAC_R11_SNORM_BLOCK
+>0	lelong	155	EAC_R11G11_UNORM_BLOCK
+>0	lelong	156	EAC_R11G11_SNORM_BLOCK
+
+>0	lelong	157	ASTC_4x4_UNORM_BLOCK
+>0	lelong	158	ASTC_4x4_SRGB_BLOCK
+>0	lelong	159	ASTC_5x4_UNORM_BLOCK
+>0	lelong	160	ASTC_5x4_SRGB_BLOCK
+>0	lelong	161	ASTC_5x5_UNORM_BLOCK
+>0	lelong	162	ASTC_5x5_SRGB_BLOCK
+>0	lelong	163	ASTC_6x5_UNORM_BLOCK
+>0	lelong	164	ASTC_6x5_SRGB_BLOCK
+>0	lelong	165	ASTC_6x6_UNORM_BLOCK
+>0	lelong	166	ASTC_6x6_SRGB_BLOCK
+>0	lelong	167	ASTC_8x5_UNORM_BLOCK
+>0	lelong	168	ASTC_8x5_SRGB_BLOCK
+>0	lelong	169	ASTC_8x6_UNORM_BLOCK
+>0	lelong	170	ASTC_8x6_SRGB_BLOCK
+>0	lelong	171	ASTC_8x8_UNORM_BLOCK
+>0	lelong	172	ASTC_8x8_SRGB_BLOCK
+>0	lelong	173	ASTC_10x5_UNORM_BLOCK
+>0	lelong	174	ASTC_10x5_SRGB_BLOCK
+>0	lelong	175	ASTC_10x6_UNORM_BLOCK
+>0	lelong	176	ASTC_10x6_SRGB_BLOCK
+>0	lelong	177	ASTC_10x8_UNORM_BLOCK
+>0	lelong	178	ASTC_10x8_SRGB_BLOCK
+>0	lelong	179	ASTC_10x10_UNORM_BLOCK
+>0	lelong	180	ASTC_10x10_SRGB_BLOCK
+>0	lelong	181	ASTC_12x10_UNORM_BLOCK
+>0	lelong	182	ASTC_12x10_SRGB_BLOCK
+>0	lelong	183	ASTC_12x12_UNORM_BLOCK
+>0	lelong	184	ASTC_12x12_SRGB_BLOCK
+
+>0	lelong	1000156000	G8B8G8R8_422_UNORM
+>0	lelong	1000156001	B8G8R8G8_422_UNORM
+>0	lelong	1000156002	G8_B8_R8_3PLANE_420_UNORM
+>0	lelong	1000156003	G8_B8R8_2PLANE_420_UNORM
+>0	lelong	1000156004	G8_B8_R8_3PLANE_422_UNORM
+>0	lelong	1000156005	G8_B8R8_2PLANE_422_UNORM
+>0	lelong	1000156006	G8_B8_R8_3PLANE_444_UNORM
+>0	lelong	1000156007	R10X6_UNORM_PACK16
+>0	lelong	1000156008	R10X6G10X6_UNORM_2PACK16
+>0	lelong	1000156009	R10X6G10X6B10X6A10X6_UNORM_4PACK16
+>0	lelong	1000156010	G10X6B10X6G10X6R10X6_422_UNORM_4PACK16
+>0	lelong	1000156011	B10X6G10X6R10X6G10X6_422_UNORM_4PACK16
+>0	lelong	1000156012	G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16
+>0	lelong	1000156013	G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16
+>0	lelong	1000156014	G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16
+>0	lelong	1000156015	G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16
+>0	lelong	1000156016	G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16
+>0	lelong	1000156017	R12X4_UNORM_PACK16
+>0	lelong	1000156018	R12X4G12X4_UNORM_2PACK16
+>0	lelong	1000156019	R12X4G12X4B12X4A12X4_UNORM_4PACK16
+>0	lelong	1000156020	G12X4B12X4G12X4R12X4_422_UNORM_4PACK16
+>0	lelong	1000156021	B12X4G12X4R12X4G12X4_422_UNORM_4PACK16
+>0	lelong	1000156022	G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16
+>0	lelong	1000156023	G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16
+>0	lelong	1000156024	G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16
+>0	lelong	1000156025	G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16
+>0	lelong	1000156026	G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16
+>0	lelong	1000156027	G16B16G16R16_422_UNORM
+>0	lelong	1000156028	B16G16R16G16_422_UNORM
+>0	lelong	1000156029	G16_B16_R16_3PLANE_420_UNORM
+>0	lelong	1000156030	G16_B16R16_2PLANE_420_UNORM
+>0	lelong	1000156031	G16_B16_R16_3PLANE_422_UNORM
+>0	lelong	1000156032	G16_B16R16_2PLANE_422_UNORM
+>0	lelong	1000156033	G16_B16_R16_3PLANE_444_UNORM
+
+>0	lelong	1000054000	PVRTC1_2BPP_UNORM_BLOCK_IMG
+>0	lelong	1000054001	PVRTC1_4BPP_UNORM_BLOCK_IMG
+>0	lelong	1000054002	PVRTC2_2BPP_UNORM_BLOCK_IMG
+>0	lelong	1000054003	PVRTC2_4BPP_UNORM_BLOCK_IMG
+>0	lelong	1000054004	PVRTC1_2BPP_SRGB_BLOCK_IMG
+>0	lelong	1000054005	PVRTC1_4BPP_SRGB_BLOCK_IMG
+>0	lelong	1000054006	PVRTC2_2BPP_SRGB_BLOCK_IMG
+>0	lelong	1000054007	PVRTC2_4BPP_SRGB_BLOCK_IMG
+
+>0	lelong	1000066000	ASTC_4x4_SFLOAT_BLOCK_EXT
+>0	lelong	1000066001	ASTC_5x4_SFLOAT_BLOCK_EXT
+>0	lelong	1000066002	ASTC_5x5_SFLOAT_BLOCK_EXT
+>0	lelong	1000066003	ASTC_6x5_SFLOAT_BLOCK_EXT
+>0	lelong	1000066004	ASTC_6x6_SFLOAT_BLOCK_EXT
+>0	lelong	1000066005	ASTC_8x5_SFLOAT_BLOCK_EXT
+>0	lelong	1000066006	ASTC_8x6_SFLOAT_BLOCK_EXT
+>0	lelong	1000066007	ASTC_8x8_SFLOAT_BLOCK_EXT
+>0	lelong	1000066008	ASTC_10x5_SFLOAT_BLOCK_EXT
+>0	lelong	1000066009	ASTC_10x6_SFLOAT_BLOCK_EXT
+>0	lelong	1000066010	ASTC_10x8_SFLOAT_BLOCK_EXT
+>0	lelong	1000066011	ASTC_10x10_SFLOAT_BLOCK_EXT
+>0	lelong	1000066012	ASTC_12x10_SFLOAT_BLOCK_EXT
+>0	lelong	1000066013	ASTC_12x12_SFLOAT_BLOCK_EXT
+
+# Main KTX2 header.
+0	string	\xABKTX\ 20\xBB\r\n\x1A\n	Khronos KTX2 texture
+>20	lelong	x	\b, %u
+>24	lelong	>1	x %u
+>28	lelong	>1	x %u
+>32	lelong	>1	\b, %u layers
+>36	lelong	>1	\b, %u faces
+>40	lelong	>1	\b, %u mipmaps
+>44	lelong	>0	\b,
+>>44	use	khronos-ktx2-supercompression
+>12	lelong	>0	\b,
+>>12	use	khronos-ktx2-vkFormat
+
 # Type: Valve VTF texture.
 # From: David Korth <gerbilsoft@gerbilsoft.com>
 # References:
@@ -2076,73 +2369,96 @@
 
 # PVR3 pixel formats.
 0	name		pvr3-pixel-format
->4	ulelong	0
->>0	ulelong	0	PVRTC 2bpp RGB
->>0	ulelong	1	PVRTC 2bpp RGBA
->>0	ulelong	2	PVRTC 4bpp RGB
->>0	ulelong	3	PVRTC 4bpp RGBA
->>0	ulelong	4	PVRTC-II 2bpp
->>0	ulelong	5	PVRTC-II 4bpp
->>0	ulelong	6	ETC1
->>0	ulelong	7	DXT1
->>0	ulelong	8	DXT2
->>0	ulelong	9	DXT3
->>0	ulelong	10	DXT4
->>0	ulelong	11	DXT5
->>0	ulelong	12	BC4
->>0	ulelong	13	BC5
->>0	ulelong	14	BC6
->>0	ulelong	15	BC7
->>0	ulelong	16	UYVY
->>0	ulelong	17	YUY2
->>0	ulelong	18	BW1bpp
->>0	ulelong	19	R9G9B9E5 Shared Exponent
->>0	ulelong	20	RGBG8888
->>0	ulelong	21	GRGB8888
->>0	ulelong	22	ETC2 RGB
->>0	ulelong	23	ETC2 RGBA
->>0	ulelong	24	ETC2 RGB A1
->>0	ulelong	25	EAC R11
->>0	ulelong	26	EAC RG11
->>0	ulelong	27	ASTC_4x4
->>0	ulelong	28	ASTC_5x4
->>0	ulelong	29	ASTC_5x5
->>0	ulelong	30	ASTC_6x5
->>0	ulelong	31	ASTC_6x6
->>0	ulelong	32	ASTC_8x5
->>0	ulelong	33	ASTC_8x6
->>0	ulelong	34	ASTC_8x8
->>0	ulelong	35	ASTC_10x5
->>0	ulelong	36	ASTC_10x6
->>0	ulelong	37	ASTC_10x8
->>0	ulelong	38	ASTC_10x10
->>0	ulelong	39	ASTC_12x10
->>0	ulelong	40	ASTC_12x12
->>0	ulelong	41	ASTC_3x3x3
->>0	ulelong	42	ASTC_4x3x3
->>0	ulelong	43	ASTC_4x4x3
->>0	ulelong	44	ASTC_4x4x4
->>0	ulelong	45	ASTC_5x4x4
->>0	ulelong	46	ASTC_5x5x4
->>0	ulelong	47	ASTC_5x5x5
->>0	ulelong	48	ASTC_6x5x5
->>0	ulelong	49	ASTC_6x6x5
->>0	ulelong	50	ASTC_6x6x6
->4	ulelong	!0
->>0	byte	!0	%c
->>1	byte	!0	\b%c
->>2	byte	!0	\b%c
->>3	byte	!0	\b%c
-
-0	string		PVR\x03			PVR 3.0 texture:
+>0	ulelong	0	PVRTC 2bpp RGB
+>0	ulelong	1	PVRTC 2bpp RGBA
+>0	ulelong	2	PVRTC 4bpp RGB
+>0	ulelong	3	PVRTC 4bpp RGBA
+>0	ulelong	4	PVRTC-II 2bpp
+>0	ulelong	5	PVRTC-II 4bpp
+>0	ulelong	6	ETC1
+>0	ulelong	7	DXT1
+>0	ulelong	8	DXT2
+>0	ulelong	9	DXT3
+>0	ulelong	10	DXT4
+>0	ulelong	11	DXT5
+>0	ulelong	12	BC4
+>0	ulelong	13	BC5
+>0	ulelong	14	BC6
+>0	ulelong	15	BC7
+>0	ulelong	16	UYVY
+>0	ulelong	17	YUY2
+>0	ulelong	18	BW1bpp
+>0	ulelong	19	R9G9B9E5 Shared Exponent
+>0	ulelong	20	RGBG8888
+>0	ulelong	21	GRGB8888
+>0	ulelong	22	ETC2 RGB
+>0	ulelong	23	ETC2 RGBA
+>0	ulelong	24	ETC2 RGB A1
+>0	ulelong	25	EAC R11
+>0	ulelong	26	EAC RG11
+>0	ulelong	27	ASTC_4x4
+>0	ulelong	28	ASTC_5x4
+>0	ulelong	29	ASTC_5x5
+>0	ulelong	30	ASTC_6x5
+>0	ulelong	31	ASTC_6x6
+>0	ulelong	32	ASTC_8x5
+>0	ulelong	33	ASTC_8x6
+>0	ulelong	34	ASTC_8x8
+>0	ulelong	35	ASTC_10x5
+>0	ulelong	36	ASTC_10x6
+>0	ulelong	37	ASTC_10x8
+>0	ulelong	38	ASTC_10x10
+>0	ulelong	39	ASTC_12x10
+>0	ulelong	40	ASTC_12x12
+>0	ulelong	41	ASTC_3x3x3
+>0	ulelong	42	ASTC_4x3x3
+>0	ulelong	43	ASTC_4x4x3
+>0	ulelong	44	ASTC_4x4x4
+>0	ulelong	45	ASTC_5x4x4
+>0	ulelong	46	ASTC_5x5x4
+>0	ulelong	47	ASTC_5x5x5
+>0	ulelong	48	ASTC_6x5x5
+>0	ulelong	49	ASTC_6x6x5
+>0	ulelong	50	ASTC_6x6x6
+
+0	string		PVR\x03			PowerVR 3.0 texture:
 >0x18	ulelong		x	%u x
 >0x1C	ulelong		x	%u
 >0x20	ulelong		>1	x %u
 >0x08	byte		x	\b,
->0x08	use	pvr3-pixel-format
+>0x0C	ulelong		0
+>>0x08	use	pvr3-pixel-format
+>0x0C	ulelong		!0
+>>0x08	byte	!0	%c
+>>>0x0C	byte	!0	\b%u
+>>0x09	byte	!0	\b%c
+>>>0x0D	byte	!0	\b%u
+>>0x0A	byte	!0	\b%c
+>>>0x0E	byte	!0	\b%u
+>>0x0B	byte	!0	\b%c
+>>>0x0F	byte	!0	\b%u
 >0x10	ulelong		1	\b, sRGB
 >0x04	ulelong&0x02	0x02	\b, premultiplied alpha
 
+0	string		\x03RVP			PowerVR 3.0 texture: BE,
+>0x18	ubelong		x	%u x
+>0x1C	ubelong		x	%u
+>0x20	ubelong		>1	x %u
+>0x08	byte		x	\b,
+>0x0C	ubelong		0
+>>0x08	use	pvr3-pixel-format
+>0x0C	ubelong		!0
+>>0x0B	byte	!0	%c
+>>>0x0F	byte	!0	\b%u
+>>0x0A	byte	!0	\b%c
+>>>0x0E	byte	!0	\b%u
+>>0x09	byte	!0	\b%c
+>>>0x0D	byte	!0	\b%u
+>>0x08	byte	!0	\b%c
+>>>0x0C	byte	!0	\b%u
+>0x10	ubelong		1	\b, sRGB
+>0x04	ubelong&0x02	0x02	\b, premultiplied alpha
+
 # Type: Microsoft Xbox XPR0 texture.
 # From: David Korth <gerbilsoft@gerbilsoft.com>
 # References:
@@ -2232,3 +2548,22 @@
 # https://github.com/dropbox/lepton
 0	belong&0xfffff0ff	0xcf84005a	Lepton image file
 >2	byte			x		(version %d)
+
+# Apple QuickTake camera raw images
+# https://en.wikipedia.org/wiki/Apple_QuickTake
+# dcraw can decode them
+0	name quicktake
+>4	belong	8
+>>544	beshort	x	\b, %dx
+>>546	beshort	x	\b%d
+>4	belong	4
+>>546	beshort	x	\b, %dx
+>>544	beshort	x	\b%d
+
+0	string	qktk	Apple QuickTake 100 Raw Image
+>0	use quicktake
+
+0	string	qktn
+>4	byte	0	Apple QuickTake 150 Raw Image
+>4	byte	>0	Apple QuickTake 200 Raw Image
+>0	use quicktake

+ 58 - 1
magic/Magdir/intel

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: intel,v 1.17 2018/08/01 10:34:03 christos Exp $
+# $File: intel,v 1.18 2020/04/18 16:19:03 christos Exp $
 # intel:  file(1) magic for x86 Unix
 #
 # Various flavors of x86 UNIX executable/object (other than Xenix, which
@@ -67,3 +67,60 @@
 # From Dr. Jesus <j@hug.gs>
 0	lelong		0x0ff0a55a	Intel serial flash for ICH/PCH ROM <= 5 or 3400 series A-step
 16	lelong		0x0ff0a55a	Intel serial flash for PCH ROM
+
+# From: 	Joerg Jenderek
+# URL:		https://en.wikipedia.org/wiki/Advanced_Configuration_and_Power_Interface
+# Reference:	https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
+# Note:		generated for example by `cat /sys/firmware/acpi/tables/DSDT MyDSDT.aml`
+0	string		DSDT
+>0	use		acpi-table
+# not tested or other file format
+0	string		APIC
+>0	use		acpi-table
+#0	string		ASF!
+#>0	use		acpi-table
+0	string		FACP
+>0	use		acpi-table
+#0	string		FACS
+#>0	use		acpi-table
+0	string		MCFG
+>0	use		acpi-table
+0	string		SLIC
+>0	use		acpi-table
+0	string		SSDT
+>0	use		acpi-table
+0	name		acpi-table
+# skip ASCII text starting with DSDT by looking for valid "low" revision
+>8	ubyte		<17	ACPI Machine Language file
+# assume that ACPI tables size are lower than 16 MiB
+#>4	ulelong		<0x01000000
+# DSDT for Differentiated System Description Table
+>>0	string		x	'%.4s'
+#!:mime	application/octet-stream
+!:mime	application/x-intel-aml
+!:ext	aml
+# the manufacture model ID like: VBOXBIOS BXDSDT
+>>16	string		>\0	%.8s
+# OEM revision of DSDT for supplied OEM Table ID like: 0 1 2 20090511
+>>>24	ulelong		x	%x
+# OEM ID like: INTEL VBOX (VirtualBox) BXDSDT (qemu) MEDION or \030\001\0\0 for s3pt.aml
+>>10	ubyte		>040	by %c
+>>>11		ubyte	>040	\b%c
+>>>>12		ubyte	>040	\b%c
+>>>>>13		ubyte	>040	\b%c
+>>>>>>14	ubyte	>040	\b%c
+>>>>>>>15	ubyte	>040	\b%c
+# This field also sets the global integer width for the AML interpreter.
+# Values less than two will cause the interpreter to use 32-bit.
+# Values of two and greater will cause the interpreter to use full 64-bit.
+# 16 for asf!.aml, 67 fo rsdp.aml
+>>8	ubyte		x	\b, revision %u
+# length, in bytes, of the entire DSDT (including the header)
+>>4	ulelong		x	\b, %u bytes
+# entire table must sum to zero
+#>>9	ubyte		x	\b, checksum 0x%x
+# vendor ID for the ASL Compiler like: INTL MSFT ...
+>>28	string		>\0	\b, created by %.4s
+# revision number of the ASL Compiler like: 20051117 20140724 20190703 20200110 ...
+>>>32	ulelong		x	%x
+

+ 22 - 6
magic/Magdir/kicad

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: kicad,v 1.1 2018/10/01 18:39:21 christos Exp $
+# $File: kicad,v 1.2 2020/05/06 14:03:28 christos Exp $
 # kicad:  file(1) magic for KiCad files
 #
 # See
@@ -9,26 +9,42 @@
 #
 
 # KiCad Schematic Document
+0	    string  (kicad_sch
+>10	    byte    0x20		KiCad Schematic Document
+!:ext kicad_sch/kicad_sch-bak
+>>11	    string  (version
+>>>19	    byte    0x20
+>>>>20	    regex   [0-9.]+		(Version %s)
+
+# KiCad Schematic Document (Legacy)
 0	    string  EESchema
 >8	    byte    0x20
 >>9	    string  Schematic
->>>18	    byte    0x20		KiCad Schematic Document
+>>>18	    byte    0x20		KiCad Schematic Document (Legacy)
 !:ext sch/bak
 >>>>24	    string  Version
 >>>>>31	    byte    0x20
 >>>>>>32    string  x			(Version %s)
 
 # KiCad Symbol Library
+0	    string  (kicad_symbol_lib
+>17	    byte    0x20		KiCad Symbol Library
+!:ext kicad_sym
+>>18	    string  (version
+>>>26	    byte    0x20
+>>>>27	    regex   [0-9.]+		(Version %s)
+
+# KiCad Symbol Library (Legacy)
 0	    string  EESchema-LIBRARY
->16	    byte    0x20		KiCad Symbol Library
+>16	    byte    0x20		KiCad Symbol Library (Legacy)
 !:ext lib
 >>17	    string  Version
 >>>24	    byte    0x20
 >>>>25	    string  x			(Version %s)
 
-# KiCad Symbol Library Documentation
+# KiCad Symbol Library Documentation (Legacy)
 0	    string  EESchema-DOCLIB
->15	    byte    0x20		KiCad Symbol Library Documentation
+>15	    byte    0x20		KiCad Symbol Library Documentation (Legacy)
 !:ext dcm
 >>17	    string  Version
 >>>24	    byte    0x20
@@ -40,7 +56,7 @@
 !:ext kicad_pcb/kicad_pcb-bak
 >>11	    string  (version
 >>>19	    byte    0x20
->>>>20	    byte    x			(Version %c)
+>>>>20	    regex   [0-9.]+		(Version %s)
 
 # KiCad Footprint
 0	    string  (module

+ 108 - 89
magic/Magdir/linux

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: linux,v 1.68 2019/09/11 21:20:56 christos Exp $
+# $File: linux,v 1.72 2020/06/07 21:56:13 christos Exp $
 # linux:  file(1) magic for Linux files
 #
 # Values for Linux/i386 binaries, from Daniel Quinlan <quinlan@yggdrasil.com>
@@ -70,41 +70,69 @@
 >24	lelong		x		%d
 >28	lelong		x		\bx%d
 
-# Linux swap file, from Daniel Quinlan <quinlan@yggdrasil.com>
-4086	string		SWAP-SPACE	Linux/i386 swap file
-# From: Jeff Bailey <jbailey@ubuntu.com>
-# Linux swap file with swsusp1 image, from Jeff Bailey <jbailey@ubuntu.com>
-4076	string		SWAPSPACE2S1SUSPEND	Linux/i386 swap file (new style) with SWSUSP1 image
-# From: James Hunt <james.hunt@ubuntu.com>
-4076    string          SWAPSPACE2LINHIB0001    Linux/i386 swap file (new style) (compressed hibernate)
-# according to man page of mkswap (8) March 1999
-# volume label and UUID Russell Coker
-# https://etbe.coker.com.au/2008/07/08/label-vs-uuid-vs-device/
-4086	string		SWAPSPACE2	Linux/i386 swap file (new style),
->0x400	long		x		version %d (4K pages),
->0x404	long		x		size %d pages,
->1052	string		\0		no label,
->1052	string		>\0		LABEL=%s,
->0x40c	belong		x		UUID=%08x
->0x410	beshort		x		\b-%04x
->0x412	beshort		x		\b-%04x
->0x414	beshort		x		\b-%04x
->0x416	belong		x		\b-%08x
->0x41a	beshort		x		\b%04x
-# From Daniel Novotny <dnovotny@redhat.com>
-# swap file for PowerPC
-65526	string		SWAPSPACE2	Linux/ppc swap file
->0x400	long		x		version %d,
->0x404	long		x		size %d pages,
->1052	string		\0		no label,
->1052	string		>\0		LABEL=%s,
->0x40c	belong		x		UUID=%08x
->0x410	beshort		x		\b-%04x
->0x412	beshort		x		\b-%04x
->0x414	beshort		x		\b-%04x
->0x416	belong		x		\b-%08x
->0x41a	beshort		x		\b%04x
-16374	string		SWAPSPACE2	Linux/ia64 swap file
+# Linux swap and hibernate files
+# Linux kernel: include/linux/swap.h
+# util-linux: libblkid/src/superblocks/swap.c
+
+# format v0, unsupported since 2002
+0xff6	string		SWAP-SPACE	Linux old swap file, 4k page size
+0x1ff6	string		SWAP-SPACE	Linux old swap file, 8k page size
+0x3ff6	string		SWAP-SPACE	Linux old swap file, 16k page size
+0x7ff6	string		SWAP-SPACE	Linux old swap file, 32k page size
+0xfff6	string		SWAP-SPACE	Linux old swap file, 64k page size
+
+# format v1, supported since 1998
+0		name	linux-swap
+>0x400	lelong	1	little endian, version %u,
+>>0x404	lelong	x	size %u pages,
+>>0x408	lelong	x	%u bad pages,
+>0x400	belong	1	big endian, version %u,
+>>0x404	belong	x	size %u pages,
+>>0x408	belong	x	%u bad pages,
+>0x41c	string	\0	no label,
+>0x41c	string	>\0	LABEL=%s,
+>0x40c	belong	x	UUID=%08x
+>0x410	beshort	x	\b-%04x
+>0x412	beshort	x	\b-%04x
+>0x414	beshort	x	\b-%04x
+>0x416	belong	x	\b-%08x
+>0x41a	beshort	x	\b%04x
+
+0xff6	string		SWAPSPACE2	Linux swap file, 4k page size,
+>0		use			linux-swap
+0x1ff6	string		SWAPSPACE2	Linux swap file, 8k page size,
+>0		use			linux-swap
+0x3ff6	string		SWAPSPACE2	Linux swap file, 16k page size,
+>0		use			linux-swap
+0x7ff6	string		SWAPSPACE2	Linux swap file, 32k page size,
+>0		use			linux-swap
+0xfff6	string		SWAPSPACE2	Linux swap file, 64k page size,
+>0		use			linux-swap
+
+0	name	linux-hibernate
+>0	string	S1SUSPEND	\b, with SWSUSP1 image
+>0	string	S2SUSPEND	\b, with SWSUSP2 image
+>0	string	ULSUSPEND	\b, with uswsusp image
+>0	string	LINHIB0001	\b, with compressed hibernate image
+>0	string	\xed\xc3\x02\xe9\x98\x56\xe5\x0c	\b, with tuxonice image
+>0	default	x			\b, with unknown hibernate image
+
+0xfec	string		SWAPSPACE2	Linux swap file, 4k page size,
+>0		use			linux-swap
+>0xff6	use			linux-hibernate
+0x1fec	string		SWAPSPACE2	Linux swap file, 8k page size,
+>0		use			linux-swap
+>0x1ff6	use			linux-hibernate
+0x3fec	string		SWAPSPACE2	Linux swap file, 16k page size,
+>0		use			linux-swap
+>0x3ff6	use			linux-hibernate
+0x7fec	string		SWAPSPACE2	Linux swap file, 32k page size,
+>0		use			linux-swap
+>0x7ff6	use			linux-hibernate
+0xffec	string		SWAPSPACE2	Linux swap file, 64k page size,
+>0		use			linux-swap
+>0xfff6	use			linux-hibernate
+
 #
 # Linux kernel boot images, from Albert Cahalan <acahalan@cs.uml.edu>
 # and others such as Axel Kohlmeyer <akohlmey@rincewind.chemie.uni-ulm.de>
@@ -206,13 +234,29 @@
 >>&0 string \x80\x00\x20\x00\x00\x00\x00\x00 Z990 32bit kernel
 >>&0 string \x80\x00\x00\x00\x00\x00\x00\x00 Z900 32bit kernel
 
+############################################################################
 # Linux ARM compressed kernel image
 # From: Kevin Cernekee <cernekee@gmail.com>
 # Update: Joerg Jenderek
-36	lelong	0x016f2818	Linux kernel ARM boot executable zImage (little-endian)
+0x24	lelong	0x016f2818	Linux kernel ARM boot executable zImage
+# There are three posible situations: LE, BE with LE bootloader and pure BE.
+# In order to aid telling these apart a new endian flag was added. In order
+# to support kernels before the flag and BE with LE bootloader was added we'll
+# do a negative check against the BE variant of the flag when we see a LE magic.
+>0x30	belong	!0x04030201	(little-endian)
+>0x30	belong	0x04030201	(big-endian)
 # raspian "kernel7.img", Vu+ Ultimo4K "kernel_auto.bin"
 !:ext	img/bin
-36	belong	0x016f2818	Linux kernel ARM boot executable zImage (big-endian)
+0x24	belong	0x016f2818	Linux kernel ARM boot executable zImage (big-endian)
+
+############################################################################
+# Linux AARCH64 kernel image
+0x38    lelong  0x644d5241  Linux kernel ARM64 boot executable Image
+>0x18   lelong  ^1          \b, little-endian
+>0x18   lelong  &1          \b, big-endian
+>0x18   lelong  &2          \b, 4K pages
+>0x18   lelong  &4          \b, 16K pages
+>0x18   lelong  &6          \b, 32K pages
 
 ############################################################################
 # Linux 8086 executable
@@ -267,11 +311,11 @@
 #
 # LVM1
 #
-0x0	string	HM\001		LVM1 (Linux Logical Volume Manager), version 1
->0x12c	string	>\0		, System ID: %s
+0x0	string/b	HM\001		LVM1 (Linux Logical Volume Manager), version 1
+>0x12c	string/b	>\0		, System ID: %s
 
-0x0	string	HM\002		LVM1 (Linux Logical Volume Manager), version 2
->0x12c	string	>\0		, System ID: %s
+0x0	string/b	HM\002		LVM1 (Linux Logical Volume Manager), version 2
+>0x12c	string/b	>\0		, System ID: %s
 
 #  LVM2
 #
@@ -279,56 +323,31 @@
 # of the disk... (from _find_labeller in lib/label/label.c of LVM2)
 #
 # 0x200 seems to be the common case
+0		name	lvm2
+# display UUID in LVM format + display all 32 bytes (instead of max string length: 31)
+>0x0          string  >\x2f          \b, UUID: %.6s
+>0x6          string  >\x2f          \b-%.4s
+>0xa          string  >\x2f          \b-%.4s
+>0xe          string  >\x2f          \b-%.4s
+>0x12         string  >\x2f          \b-%.4s
+>0x16         string  >\x2f          \b-%.4s
+>0x1a         string  >\x2f          \b-%.6s
+>0x20         lequad  x              \b, size: %lld
+
 
-0x218           string  LVM2\ 001      LVM2 PV (Linux Logical Volume Manager)
 # read the offset to add to the start of the header, and the header
 # start in 0x200
->&(&-12.l-0x21) byte    x
-# display UUID in LVM format + display all 32 bytes (instead of max string length: 31)
->>&0x0          string  >\x2f          \b, UUID: %.6s
->>&0x6          string  >\x2f          \b-%.4s
->>&0xa          string  >\x2f          \b-%.4s
->>&0xe          string  >\x2f          \b-%.4s
->>&0x12         string  >\x2f          \b-%.4s
->>&0x16         string  >\x2f          \b-%.4s
->>&0x1a         string  >\x2f          \b-%.6s
->>&0x20         lequad  x              \b, size: %lld
-
-0x018           string  LVM2\ 001      LVM2 PV (Linux Logical Volume Manager)
->&(&-12.l-0x21) byte    x
-# display UUID in LVM format + display all 32 bytes (instead of max string length: 31)
->>&0x0          string  >\x2f          \b, UUID: %.6s
->>&0x6          string  >\x2f          \b-%.4s
->>&0xa          string  >\x2f          \b-%.4s
->>&0xe          string  >\x2f          \b-%.4s
->>&0x12         string  >\x2f          \b-%.4s
->>&0x16         string  >\x2f          \b-%.4s
->>&0x1a         string  >\x2f          \b-%.6s
->>&0x20         lequad  x              \b, size: %lld
-
-0x418           string  LVM2\ 001      LVM2 PV (Linux Logical Volume Manager)
->&(&-12.l-0x21) byte    x
-# display UUID in LVM format + display all 32 bytes (instead of max string length: 31)
->>&0x0          string  >\x2f          \b, UUID: %.6s
->>&0x6          string  >\x2f          \b-%.4s
->>&0xa          string  >\x2f          \b-%.4s
->>&0xe          string  >\x2f          \b-%.4s
->>&0x12         string  >\x2f          \b-%.4s
->>&0x16         string  >\x2f          \b-%.4s
->>&0x1a         string  >\x2f          \b-%.6s
->>&0x20         lequad  x              \b, size: %lld
-
-0x618           string  LVM2\ 001      LVM2 PV (Linux Logical Volume Manager)
->&(&-12.l-0x21) byte    x
-# display UUID in LVM format + display all 32 bytes (instead of max string length: 31)
->>&0x0          string  >\x2f          \b, UUID: %.6s
->>&0x6          string  >\x2f          \b-%.4s
->>&0xa          string  >\x2f          \b-%.4s
->>&0xe          string  >\x2f          \b-%.4s
->>&0x12         string  >\x2f          \b-%.4s
->>&0x16         string  >\x2f          \b-%.4s
->>&0x1a         string  >\x2f          \b-%.6s
->>&0x20         lequad  x              \b, size: %lld
+0x218           string/b  LVM2\ 001      LVM2 PV (Linux Logical Volume Manager)
+>&(&-12.l-0x20) use	lvm2
+
+0x018           string/b  LVM2\ 001      LVM2 PV (Linux Logical Volume Manager)
+>&(&-12.l-0x20) use	lvm2
+
+0x418           string/b  LVM2\ 001      LVM2 PV (Linux Logical Volume Manager)
+>&(&-12.l-0x20) use	lvm2
+
+0x618           string/b  LVM2\ 001      LVM2 PV (Linux Logical Volume Manager)
+>&(&-12.l-0x20) use	lvm2
 
 # LVM snapshot
 # from Jason Farrel

+ 16 - 3
magic/Magdir/msdos

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: msdos,v 1.134 2019/10/18 15:16:18 christos Exp $
+# $File: msdos,v 1.137 2020/03/20 17:20:19 christos Exp $
 # msdos:  file(1) magic for MS-DOS files
 #
 
@@ -123,6 +123,7 @@
 >>(0x3c.l+4)	leshort		0x1d3	Matsushita AM33
 >>(0x3c.l+4)	leshort		0x1f0	PowerPC
 >>(0x3c.l+4)	leshort		0x1f1	PowerPC with FPU
+>>(0x3c.l+4)	leshort		0x1f2	PowerPC (big-endian)
 >>(0x3c.l+4)	leshort		0x200	Intel Itanium
 >>(0x3c.l+4)	leshort		0x266	MIPS16
 >>(0x3c.l+4)	leshort		0x268	Motorola 68000
@@ -1215,6 +1216,14 @@
 !:mime	application/vnd.ms-powerpoint
 #!:mime	application/mspowerpoint
 !:ext	ppz
+# URL:		https://en.wikipedia.org/wiki/Windows_Desktop_Gadgets
+# Reference:	https://docs.microsoft.com/en-us/previous-versions/windows/desktop/sidebar/
+# http://win10gadgets.com/download/273/ All_CPU_Meter1.zip/All_CPU_Meter_V4.7.3.gadget
+>0x2c	search/968/c	gadget.xml		\b, Windows Desktop Gadget
+#!:mime	application/vnd.ms-cab-compressed
+# http://extension.nirsoft.net/gadget
+!:mime	application/x-windows-gadget
+!:ext	gadget
 # http://www.incredimail.com/
 # IncrediMail CAB contains an initialisation file "content.ini" like in im2.ims
 >0x2c	search/3369/c	content.ini\0	\b, IncrediMail
@@ -1235,7 +1244,7 @@
 # http://file-extension.net/seeker/file_extension_ime
 >>>0x2c	default		x		emoticons or sound
 !:ext	ime/imw
-# no Diagnostic and IncrediMail
+# no Diagnostic, Packed and Go, Windows Desktop Gadget, IncrediMail
 >0x2c	default		x
 # look for 1st member name
 >>(16.l+16)	ubyte	x
@@ -1243,6 +1252,11 @@
 >>>&-1	string/c 	_accrpt_.snp	\b, Access report snapshot
 !:mime	application/msaccess
 !:ext	snp
+# https://en.wikipedia.org/wiki/Microsoft_InfoPath
+>>>&-1	string 		manifest.xsf	\b, InfoPath Form Template
+!:mime	application/vnd.ms-cab-compressed
+#!:mime	application/vnd.ms-infopath
+!:ext	xsn
 # https://www.cabextract.org.uk/wince_cab_format/
 # extension of DOS 8+3 name with ".000" of 1st archive member name implies Windows CE installer
 >>>&7	string 		=.000		\b, WinCE install
@@ -1306,7 +1320,6 @@
 !:mime	application/vnd.ms-cab-compressed
 !:ext	cab
 # TODO: additional extensions like
-# .xsn	InfoPath Dynamic Form
 # .xtp	InfoPath Template Part
 # .lvf	Logitech Video Effects Face Accessory
 >8	ulelong		x		\b, %u bytes

+ 50 - 2
magic/Magdir/ole2compounddocs

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: ole2compounddocs,v 1.7 2019/08/02 18:08:18 christos Exp $
+# $File: ole2compounddocs,v 1.8 2020/03/28 23:10:30 christos Exp $
 # Microsoft OLE 2 Compound Documents : file(1) magic for Microsoft Structured
 # storage (https://en.wikipedia.org/wiki/Compound_File_Binary_Format)
 # Additional tests for OLE 2 Compound Documents should be under this recipe.
@@ -27,6 +27,25 @@
 >>>0x18	uleshort		x			\b.%u
 # SecID of first sector of the directory stream is often 1 but high like 3144h
 >>>48	ulelong			x			\b, SecID 0x%x
+# Sector Shift Exponent in short-stream container stream: 6~64 bytes
+>>>32	uleshort		!6			\b, exponent of short stream %u
+# total number of sectors used for the FAT
+>>>44	ulelong			>1			\b, %u FAT sectors
+# SecID of first sector of the short-sector allocation table (Mini FAT)
+# or -2 (End Of ChainSecID) if not extant
+>>>60	ulelong			!0xffFFffFE		\b, Mini FAT start sector 0x%x
+# total number of sectors used for the short-sector allocation table
+>>>64	ulelong			!1			\b, %u Mini FAT sector
+# plural s
+>>>>64	ulelong			>1			\bs
+# SecID of first sector of the master sector allocation table (DIFAT)
+# or -2 (End Of Chain SecID) if no additional sectors used
+>>>68	ulelong			!0xffFFffFE		\b, DIFAT start sector 0x%x
+# total number of sectors used for the master sector allocation table (DIFAT)
+>>>72	ulelong			>0			\b, %u DIFAT sectors
+# First part of the master sector allocation table (DIFAT) containing 109 SecIDs
+#>>>76 	ubequad			x			\b, DIFAT=0x%16.16llx
+#>>>84 	ubequad			x			\b%16.16llx...
 # pointer to root entry only works with standard configuration for SecID ~< 800h
 # Red-Carpet-presentation-1.0-1.sdd sg10.sdv 2000_GA_Annual_Review_Data.xls
 # "ORLEN Factbook 2017.xls" XnView_metadata.doc
@@ -51,7 +70,7 @@
 #>66 	ubyte		x			\b, type %x
 # node colour of the entry: 00H ~ Red 01H ~ Black
 #>67 	ubyte		x			\b, color %x
-# the DirIDs of the child nodes. Should both be 1 in the root storage entry
+# the DirIDs of the child nodes. Should both be -1 in the root storage entry
 #>68 	bequad		!0xffffffffffffffff	\b, DirIDs %llx
 # second directory entry name like VisioDocument Control000 
 #>128	lestring16	x \b, 2nd %.20s
@@ -207,6 +226,29 @@
 #!:mime	application/x-ole-storage
 !:mime	application/x-star-sdv
 !:ext	sdv
+# URL:	https://en.wikipedia.org/wiki/SoftMaker_Office
+# second directory entry name Current User
+>>>>128 	lestring16	Current\ User		: SoftMaker
+# third directory entry name SMNativeObjData
+>>>>>256	lestring16	SMNativeObjData		
+# 5th directory entry nane PowerPoint
+>>>>>>512	lestring16	PowerPoint		PowerPoint presentation or template
+!:mime	application/vnd.ms-powerpoint
+!:ext	ppt/pps/pot
+# 4th directory entry name PowerPoint
+>>>>>384	lestring16	PowerPoint		Presentations or template
+# http://extension.nirsoft.net/prv
+!:mime	application/vnd.softmaker.presentations
+!:ext	prd/prv
+# third directory entry name like Current User
+>>>>256 	lestring16	Current\ User		: SoftMaker
+# 5th directory entry name PowerPoint
+>>>>>512	lestring16	PowerPoint		Presentations or template
+# http://extension.nirsoft.net/prd
+!:mime	application/vnd.softmaker.presentations
+!:ext	prd/prv
+# 2nd directory entry name Pictures
+>>>>>>128 	lestring16	Pictures		with pictures
 #	remaining null clsid
 >>>>128 	default		x			: UNKNOWN
 !:mime	application/x-ole-storage
@@ -463,6 +505,12 @@
 !:mime	image/vnd.fpx
 !:apple	????FPix
 !:ext	fpx
+# URL:	https://en.wikipedia.org/wiki/SoftMaker_Office
+>>88 	ubequad		0x95f600a0cc3cca14	: PlanMaker
+>>>80 	ubequad		0x9174088a6452d411	document or template
+!:mime	application/vnd.softmaker.planmaker
+# pmv for template	https://www.file-extensions.org/pmv-file-extension
+!:ext	pmd/pmv
 # remaining non null clsid
 >>88 	default		x			: UNKNOWN
 !:mime	application/x-ole-storage

+ 2 - 2
magic/Magdir/parix

@@ -1,11 +1,11 @@
 
 #------------------------------------------------------------------------------
-# $File: parix,v 1.4 2009/09/19 16:28:11 christos Exp $
+# $File: parix,v 1.5 2020/03/08 22:18:32 christos Exp $
 #
 # Parix COFF executables
 # From: Ignatios Souvatzis <ignatios@cs.uni-bonn.de>
 #
-0	beshort&0xfff	0xACE	PARIX
+0	beshort&0xefff	0x8ACE	PARIX
 >0	byte&0xf0	0x80	T800
 >0	byte&0xf0	0x90	T9000
 >19	byte&0x02	0x02	executable

+ 5 - 1
magic/Magdir/pascal

@@ -1,5 +1,5 @@
 #------------------------------------------------------------------------------
-# $File: pascal,v 1.2 2014/07/14 14:21:33 rrt Exp $
+# $File: pascal,v 1.3 2020/06/07 18:10:26 christos Exp $
 # pascal:  file(1) magic for Pascal source
 #
 0	search/8192	(input,		Pascal source text
@@ -8,3 +8,7 @@
 #!:mime	text/x-pascal
 #0	regex           	\^record		Pascal source text
 #!:mime	text/x-pascal
+
+# Free Pascal
+0	string	PPU	Pascal unit
+>3	string	x	\b, version %s

+ 8 - 1
magic/Magdir/pdf

@@ -1,26 +1,32 @@
 
 #------------------------------------------------------------------------------
-# $File: pdf,v 1.11 2019/09/12 15:53:49 christos Exp $
+# $File: pdf,v 1.12 2020/01/30 01:48:44 christos Exp $
 # pdf:  file(1) magic for Portable Document Format
 #
 
+0	name	pdf
+>8	search/512	/Filter/FlateDecode/	(password protected)
+
 0	string		%PDF-		PDF document
 !:mime	application/pdf
 !:strength +60
 >5	byte		x		\b, version %c
 >7	byte		x		\b.%c
+>0	use		pdf
 
 0	string		\012%PDF-	PDF document
 !:mime	application/pdf
 !:strength +60
 >6	byte		x		\b, version %c
 >8	byte		x		\b.%c
+>0	use		pdf
 
 0	string		\xef\xbb\xbf%PDF-	PDF document (UTF-8)
 !:mime	application/pdf
 !:strength +60
 >6	byte		x		\b, version %c
 >8	byte		x		\b.%c
+>0	use		pdf
 
 # From: Nick Schmalenberger <nick@schmalenberger.us>
 # Forms Data Format
@@ -35,3 +41,4 @@
 !:strength +60
 >&0	byte		x		\b, version %c
 >&2	byte		x		\b.%c
+>0	use		pdf

+ 81 - 16
magic/Magdir/pgp

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: pgp,v 1.17 2019/04/19 00:42:27 christos Exp $
+# $File: pgp,v 1.21 2020/03/20 17:11:05 christos Exp $
 # pgp:  file(1) magic for Pretty Good Privacy
 # see https://lists.gnupg.org/pipermail/gnupg-devel/1999-September/016052.html
 #
@@ -58,16 +58,36 @@
 #>15	string	SIGNED\040MESSAGE-	signed message
 #>15	string	PGP\040SIGNATURE-	signature
 
+# Update:	Joerg Jenderek
+# URL:		http://en.wikipedia.org/wiki/Pretty_Good_Privacy
+# Reference:	https://reposcope.com/mimetype/application/pgp-keys
+2	string	---BEGIN\040PGP\040PRIVATE\040KEY\040BLOCK-	PGP private key block
+#!:mime	text/PGP
+!:mime	application/pgp-keys
+!:ext	asc
 2	string	---BEGIN\040PGP\040PUBLIC\040KEY\040BLOCK-	PGP public key block
 !:mime	application/pgp-keys
+!:ext	asc
 >10	search/100	\n\n
 >>&0	use		pgp
 0	string	-----BEGIN\040PGP\040MESSAGE-		PGP message
-!:mime	application/pgp
+# https://reposcope.com/mimetype/application/pgp-encrypted
+#!:mime	application/pgp
+!:mime	application/pgp-encrypted
+!:ext	asc
+#!:ext	asc/pgp/gpg
 >10	search/100	\n\n
 >>&0	use		pgp
+# Reference:	https://www.gnupg.org/gph/en/manual/x135.html
+0	string	-----BEGIN\040PGP\040SIGNED\040MESSAGE-	PGP signed message
+#!:mime	text/plain
+!:mime	text/PGP
+#!:mime	application/pgp
+!:ext	asc
 0	string	-----BEGIN\040PGP\040SIGNATURE-		PGP signature
+# https://reposcope.com/mimetype/application/pgp-signature
 !:mime	application/pgp-signature
+!:ext	asc
 >10	search/100	\n\n
 >>&0	use		pgp
 
@@ -127,8 +147,8 @@
 # 1024b RSA encrypted data
 
 0	string	\x84\x8c\x03		PGP RSA encrypted session key -
->3	lelong	x			keyid: %X
->7	lelong	x			%X
+>3	belong	x			keyid: %08X
+>7	belong	x			%08X
 >11	byte	0x01			RSA (Encrypt or Sign) 1024b
 >11	byte	0x02			RSA Encrypt-Only 1024b
 >12	string	\x04\x00
@@ -144,8 +164,8 @@
 # 2048b RSA encrypted data
 
 0	string	\x85\x01\x0c\x03	PGP RSA encrypted session key -
->4	lelong	x			keyid: %X
->8	lelong	x			%X
+>4	belong	x			keyid: %08X
+>8	belong	x			%08X
 >12	byte	0x01			RSA (Encrypt or Sign) 2048b
 >12	byte	0x02			RSA Encrypt-Only 2048b
 >13	string	\x08\x00
@@ -161,8 +181,8 @@
 # 3072b RSA encrypted data
 
 0	string	\x85\x01\x8c\x03	PGP RSA encrypted session key -
->4	lelong	x			keyid: %X
->8	lelong	x			%X
+>4	belong	x			keyid: %08X
+>8	belong	x			%08X
 >12	byte	0x01			RSA (Encrypt or Sign) 3072b
 >12	byte	0x02			RSA Encrypt-Only 3072b
 >13	string	\x0c\x00
@@ -175,11 +195,11 @@
 >13	string	\x0b\xf9
 >399	byte	0xd2			.
 
-# 3072b RSA encrypted data
+# 4096b RSA encrypted data
 
 0	string	\x85\x02\x0c\x03	PGP RSA encrypted session key -
->4	lelong	x			keyid: %X
->8	lelong	x			%X
+>4	belong	x			keyid: %08X
+>8	belong	x			%08X
 >12	byte	0x01			RSA (Encrypt or Sign) 4096b
 >12	byte	0x02			RSA Encrypt-Only 4096b
 >13	string	\x10\x00
@@ -192,13 +212,13 @@
 >13	string	\x0f\xf9
 >527	byte	0xd2			.
 
-# 4096b RSA encrypted data
+# 8192b RSA encrypted data
 
 0	string	\x85\x04\x0c\x03	PGP RSA encrypted session key -
->4	lelong	x			keyid: %X
->8	lelong	x			%X
->12	byte	0x01			RSA (Encrypt or Sign) 8129b
->12	byte	0x02			RSA Encrypt-Only 8129b
+>4	belong	x			keyid: %08X
+>8	belong	x			%08X
+>12	byte	0x01			RSA (Encrypt or Sign) 8192b
+>12	byte	0x02			RSA Encrypt-Only 8192b
 >13	string	\x20\x00
 >13	string	\x1f\xff
 >13	string	\x1f\xfe
@@ -209,6 +229,51 @@
 >13	string	\x1f\xf9
 >1039	byte	0xd2			.
 
+# 1024b Elgamal encrypted data
+
+0	string	\x85\x01\x0e\x03	PGP Elgamal encrypted session key -
+>4	belong	x			keyid: %08X
+>8	belong	x			%08X
+>12	byte	0x10			Elgamal Encrypt-Only 1024b.
+>13	string	\x04\x00
+>13	string	\x03\xff
+>13	string	\x03\xfe
+>13	string	\x03\xfd
+>13	string	\x03\xfc
+>13	string	\x03\xfb
+>13	string	\x03\xfa
+>13	string	\x03\xf9
+
+# 2048b Elgamal encrypted data
+
+0	string	\x85\x02\x0e\x03	PGP Elgamal encrypted session key -
+>4	belong	x			keyid: %08X
+>8	belong	x			%08X
+>12	byte	0x10			Elgamal Encrypt-Only 2048b.
+>13	string	\x08\x00
+>13	string	\x07\xff
+>13	string	\x07\xfe
+>13	string	\x07\xfd
+>13	string	\x07\xfc
+>13	string	\x07\xfb
+>13	string	\x07\xfa
+>13	string	\x07\xf9
+
+# 3072b Elgamal encrypted data
+
+0	string	\x85\x03\x0e\x03	PGP Elgamal encrypted session key -
+>4	belong	x			keyid: %08X
+>8	belong	x			%08X
+>12	byte	0x10			Elgamal Encrypt-Only 3072b.
+>13	string	\x0c\x00
+>13	string	\x0b\xff
+>13	string	\x0b\xfe
+>13	string	\x0b\xfd
+>13	string	\x0b\xfc
+>13	string	\x0b\xfb
+>13	string	\x0b\xfa
+>13	string	\x0b\xf9
+
 # crypto algo mapper
 
 0	name	crypto

+ 202 - 24
magic/Magdir/python

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: python,v 1.37 2019/10/21 19:40:58 christos Exp $
+# $File: python,v 1.42 2020/06/04 00:22:50 christos Exp $
 # python:  file(1) magic for python
 #
 # Outlook puts """ too for urgent messages
@@ -10,85 +10,255 @@
 # MAGIC as specified in Python/import.c (1.0 to 3.7)
 # two bytes of magic followed by "\r\n" in little endian order
 0	belong		0x02099900	python 1.0 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x03099900	python 1.1/1.2 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x892e0d0a	python 1.3 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x04170d0a	python 1.4 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x994e0d0a	python 1.5 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0xfcc40d0a	python 1.6 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0xfdc40d0a	python 1.6 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x87c60d0a	python 2.0 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x88c60d0a	python 2.0 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x2aeb0d0a	python 2.1 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x2beb0d0a	python 2.1 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x2ded0d0a	python 2.2 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x2eed0d0a	python 2.2 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x3bf20d0a	python 2.3 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x3cf20d0a	python 2.3 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x45f20d0a	python 2.3 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x59f20d0a	python 2.4 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x63f20d0a	python 2.4 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x6df20d0a	python 2.4 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x6ef20d0a	python 2.4 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x77f20d0a	python 2.5 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x81f20d0a	python 2.5 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x8bf20d0a	python 2.5 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x8cf20d0a	python 2.5 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x95f20d0a	python 2.5 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x9ff20d0a	python 2.5 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xa9f20d0a	python 2.5 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0xb3f20d0a	python 2.5 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0xb4f20d0a	python 2.5 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xc7f20d0a	python 2.6 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0xd1f20d0a	python 2.6 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0xd2f20d0a	python 2.6 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xdbf20d0a	python 2.7 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xe5f20d0a	python 2.7 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xeff20d0a	python 2.7 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xf9f20d0a	python 2.7 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x03f30d0a	python 2.7 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x04f30d0a	python 2.7 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xb80b0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xc20b0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xcc0b0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xd60b0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xe00b0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xea0b0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xf40b0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xf50b0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xff0b0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x090c0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x130c0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x1d0c0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x1f0c0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x270c0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x3b0c0d0a	python 3.0 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x450c0d0a	python 3.1 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x4f0c0d0a	python 3.1 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x580c0d0a	python 3.2 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x620c0d0a	python 3.2 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x6c0c0d0a	python 3.2 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x760c0d0a	python 3.3 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x800c0d0a	python 3.3 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x8a0c0d0a	python 3.3 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x940c0d0a	python 3.3 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x9e0c0d0a	python 3.3 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xb20c0d0a	python 3.4 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xbc0c0d0a	python 3.4 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xc60c0d0a	python 3.4 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xd00c0d0a	python 3.4 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xda0c0d0a	python 3.4 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xe40c0d0a	python 3.4 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0xee0c0d0a	python 3.4 byte-compiled
-0	belong		0x160d0d0a	python 3.5.2- byte-compiled
-0	belong		0x170d0d0a	python 3.5.3+ byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0xf80c0d0a	python 3.5.1- byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x020d0d0a	python 3.5.1- byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x0c0d0d0a	python 3.5.1- byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x160d0d0a	python 3.5.1- byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x170d0d0a	python 3.5.2+ byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x200d0d0a	python 3.6 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x210d0d0a	python 3.6 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x2a0d0d0a	python 3.6 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x2b0d0d0a	python 3.6 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x2c0d0d0a	python 3.6 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x2d0d0d0a	python 3.6 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x2f0d0d0a	python 3.6 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x300d0d0a	python 3.6 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x310d0d0a	python 3.6 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x320d0d0a	python 3.6 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x330d0d0a	python 3.6 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x3e0d0d0a	python 3.7 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x3f0d0d0a	python 3.7 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x400d0d0a	python 3.7 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x410d0d0a	python 3.7 byte-compiled
+!:mime text/x-bytecode.python
 0	belong		0x420d0d0a	python 3.7 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x480d0d0a	python 3.8 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x490d0d0a	python 3.8 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x520d0d0a	python 3.8 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x530d0d0a	python 3.8 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x540d0d0a	python 3.8 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x550d0d0a	python 3.8 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x5c0d0d0a	python 3.9 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x5d0d0d0a	python 3.9 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x5e0d0d0a	python 3.9 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x5f0d0d0a	python 3.9 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x600d0d0a	python 3.9 byte-compiled
+!:mime text/x-bytecode.python
+0	belong		0x610d0d0a	python 3.9 byte-compiled
+!:mime text/x-bytecode.python
 
-
-0	search/1/w	#!\ /usr/bin/python	Python script text executable
-!:strength + 15
-!:mime text/x-python
-0	search/1/w	#!\ /usr/local/bin/python	Python script text executable
+0	search/1/w	#!\040/usr/bin/python	Python script text executable
 !:strength + 15
-!:mime text/x-python
-0	search/1	#!/usr/bin/env\ python	Python script text executable
+!:mime text/x-script.python
+0	search/1/w	#!\040/usr/local/bin/python	Python script text executable
 !:strength + 15
-!:mime text/x-python
-0	search/10	#!\ /usr/bin/env\ python	Python script text executable
+!:mime text/x-script.python
+0	search/10/w	#!\040/usr/bin/env\040python	Python script text executable
 !:strength + 15
-!:mime text/x-python
+!:mime text/x-script.python
 
 
 # from module.submodule import func1, func2
 0	search/8192	import
->0	regex		\^from[\040\t\f\r\n]+([A-Za-z0-9_]|\\.)+[\040\t\f\r\n]+import.*$	Python script text executable
+>0	regex		\^from[\040\t]+([A-Za-z0-9_]|\\.)+[\040\t]+import.*$	Python script text executable
 !:strength + 15
-!:mime text/x-python
+!:mime text/x-script.python
 
 # def __init__ (self, ...):
 0	search/4096	def\ __init__
 >&0	search/64 self	Python script text executable
 !:strength + 15
-!:mime text/x-python
+!:mime text/x-script.python
 
 # if __name__ == "__main__":
 0 search/4096 if\ __name__
 >&0 search/64 '__main__'	Python script text executable
 >&0 search/64 "__main__"	Python script text executable
 !:strength + 15
-!:mime text/x-python
+!:mime text/x-script.python
 
 # import module [as abrev]
 0	search/8192	import
 >0	regex	\^import\ [_[:alpha:]]+\ as\ [[:alpha:]][[:space:]]*$ Python script text executable
-!:mime text/x-python
+!:mime text/x-script.python
 
 # comments
 #0	search/4096	'''
 #>&0	regex	.*'''$	Python script text executable
-#!:mime text/x-python
+#!:mime text/x-script.python
 
 #0	search/4096	"""
 #>&0	regex	.*"""$	Python script text executable
-#!:mime text/x-python
+#!:mime text/x-script.python
 
 # try:
 # except: or finally:
@@ -96,19 +266,27 @@
 0	search/4096	try:
 >&0	regex	\^[[:space:]]*except.*:$	Python script text executable
 !:strength + 15
-!:mime text/x-python
+!:mime text/x-script.python
 >&0	search/4096	finally:	Python script text executable
-!:mime text/x-python
+!:mime text/x-script.python
 
 # class name[(base classes,)]: [pass]
 0	search/8192	class
 >0	regex	\^class\ [_[:alpha:]]+(\\(.*\\))?(\ )*:([\ \t]+pass)?$		Python script text executable
 !:strength + 15
-!:mime text/x-python
+!:mime text/x-script.python
 
 # def name(*args, **kwargs):
 0	search/8192	def\ 
 >0	regex	 \^[[:space:]]{0,50}def\ {1,50}[_a-zA-Z]{1,100}
 >>&0	regex	 \\(([[:alpha:]*_,\ ]){0,255}\\):$ Python script text executable
 !:strength + 15
-!:mime text/x-python
+!:mime text/x-script.python
+
+# https://numpy.org/devdocs/reference/generated/numpy.lib.format.html
+0	string	\223NUMPY		NumPy data file
+!:mime  application/x-numpy-data
+>6	byte	x			\b, version %d
+>7	byte	x			\b.%d
+#>8	leshort	x			\b, header length=%d
+>10	string	x			\b, description %s

+ 114 - 9
magic/Magdir/riff

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: riff,v 1.34 2019/04/19 00:42:27 christos Exp $
+# $File: riff,v 1.35 2020/06/05 17:15:03 christos Exp $
 # riff:  file(1) magic for RIFF format
 # See
 #
@@ -120,11 +120,33 @@
 !:mime	audio/x-wav
 >>12    string  >\0
 >>>12   use     riff-walk
+# Update:	Joerg Jenderek
+# lower case for Corel Draw version 8 Bidi
+>8	string/c	cdr
+# skip Corel CCX Clipart
+>>8	string		!CDRXcont
 # Corel Draw Picture
->8	string		CDRA		\b, Corel Draw Picture
-!:mime	image/x-coreldraw
->8	string		CDR6		\b, Corel Draw Picture, version 6
-!:mime	image/x-coreldraw
+>>>0	use     corel-draw
+# URL:		http://fileformats.archiveteam.org/wiki/CCX_(Corel)
+# Reference:	http://mark0.net/download/triddefs_xml.7z/defs/c/ccx-corel.trid.xml 
+>>8	string		=CDRXcont	\b, Corel Clipart
+!:mime	application/x-corel-ccx
+!:ext	ccx
+# 3rd chunk data {Corel\040Binary\040Meta\040File}
+#>>>20	string		x		\b, 3rd '%-s'
+>>>4	ulelong+8	x		\b, %u bytes
+# From:		Joerg Jenderek
+# URL:		https://en.wikipedia.org/wiki/CorelDRAW
+# Reference:	http://fileformats.archiveteam.org/wiki/CorelDRAW
+# Picture templates created by newer software start with RIFF type CDT
+>8	string		CDT
+>>0	use		corel-draw
+# Picture templates with version 4.4
+>8	string		CDST
+>>0	use		corel-draw
+# pattern created by newer software start with RIFF type PAT
+>8	string		PAT
+>>0	use		corel-draw
 >8	string		NUNDROOT	\b, Steinberg CuBase
 # AVI == Audio Video Interleave
 >8	string		AVI\040		\b, AVI
@@ -255,7 +277,87 @@
 >8      string          WEBP            \b, Web/P image
 !:mime	image/webp
 >>12	use		riff-walk
-
+# From:		Joerg Jenderek
+# URL:		https://en.wikipedia.org/wiki/CorelDRAW
+# Reference:	http://fileformats.archiveteam.org/wiki/CorelDRAW
+# Note:		Since version 3 CorelDraw Pictures are RIFF based
+# but data chunks remain proprietary.
+# Since version 14 til 15 packed as "content/riffData.cdr" and
+# since 16 "content/root.dat" in ZIP container
+# TODO:		distinguish templates with version 12.5 from Designer illustration 12
+#	display information of RIFF based Corel Draw pictures, templates and patterns
+0	name   	corel-draw
+# display second chunk for debugging
+#>8	string		x		\b, [8]=%.8s
+>0	string		x		\b, Corel Draw
+#!:mime	image/x-coreldraw
+!:mime	application/vnd.corel-draw
+# used by newer pictures templates
+>>8	string		CDT
+# used by templates with newer versions since 16
+>>>12	string		=fver		Picture template (root.dat)
+!:ext	dat
+# used by templates with older versions with vrsn tag
+>>>12	string		!fver
+# used by templates with older versions 14-15
+>>>>11	string		>E		Picture template (riffData.cdr)
+!:ext	cdr
+# used by templates with older versions 11-13
+>>>>11	string		<F		Picture template
+!:ext	cdt/cdrt
+# used by older templates with version 4.4
+>>8	string		CDST		Picture template
+!:ext	cdt
+# used by templates with version 12.5
+>>8	string		DESC		Picture template
+!:ext	cdt
+# used by newer patterns with version 22
+>>8	string		PAT		Pattern
+!:ext	dat
+# remaining older templates, patterns, drawings
+>>8	default		x
+# pattern with old version 4.y
+>>>26	ulelong		=0x0000206C	Pattern
+!:ext	pat
+# pattern with newer versions
+>>>26	ulelong		=0x00000D2C	Pattern
+!:ext	pat
+# remaining older templates or pictures
+>>>26	default		x
+# used by older versions 5 - 15
+>>>>12	string		=vrsn
+# 4th chunk size unequal 282Ch only found for CDR
+>>>>>26	ulelong		!0x0000282c	Picture
+!:ext	cdr
+>>>>>26	default		x		Picture or template
+!:ext	cdr/cdt
+# used by newer versions since 16
+>>>>12	string		=fver		Picture (root.dat)
+!:ext	dat
+# version marked by 1 ASCII char: space~3, ... , F~15,  ... , N~22, ... R~22 template
+>11	string		x		\b, version
+>11	string		>\040		'%-.1s'
+>0	use		corel-version
+>4	ulelong+8	x		\b, %u bytes
+#
+#	display numeric version of RIFF based Corel after 3rd RIFF tag
+0	name   	corel-version
+# for debugging purpose; vrsn for short content; fver for 16 byte size
+#>12	string		x		\b, TAG "%-4.4s"
+# 1st data chunk length 2 implies short content version
+>16	ulelong		2
+# vrsn chunk short content interpreted by MajorVersion * 100 + MinorVersion
+>>20	uleshort/100	x		%u
+>>20	uleshort%100	>0		\b.%u
+# for debugging purpose display next chunk like: DISP LIST
+#>>22	string		x		\b, 4th "%-4.4s"
+#>>26	ulelong		x		\b, 4th SIZE 0x%x
+# for debugging purpose display 5th chunk like: LIST DISP ccmm osfp
+#>>(26.l+30)	string	x		\b, 5th "%-4.4s"
+# 1st data chunk length 10h implies 16 byte content with version info
+>16	ulelong		0x10
+>>34	ubyte		x		%u
+>>>33	ubyte		>0		\b.%u
 #
 # XXX - some of the below may only appear in little-endian form.
 #
@@ -292,9 +394,12 @@
 >>22	beshort		=2		\b, stereo
 >>22	beshort		>2		\b, %d channels
 >>24	belong		>0		%d Hz
-# Corel Draw Picture
->8	string		CDRA		\b, Corel Draw Picture
->8	string		CDR6		\b, Corel Draw Picture, version 6
+# Corel Draw Picture big endian not tested by real examples
+#>8	string		CDRA		\b, Corel Draw Picture
+#>8	string		CDR6		\b, Corel Draw Picture, version 6
+>8	string		CDR
+>>0	use     \^corel-draw
+
 # AVI == Audio Video Interleave
 >8	string		AVI\040		\b, AVI
 # Animated Cursor format

+ 2 - 2
magic/Magdir/rst

@@ -1,11 +1,11 @@
 
 #------------------------------------------------------------------------------
-# $File: rst,v 1.2 2019/11/02 18:41:26 christos Exp $
+# $File: rst,v 1.3 2020/04/27 01:50:36 christos Exp $
 # rst: ReStructuredText http://docutils.sourceforge.net/rst.html
 0	search/256	\=\=
 !:strength + 30
 >&0	regex/256	\^[\=]+$
 >>&0	search/512	:Author:	ReStructuredText file
 >>&0	default		x
->>>&0	regex/512	\^\.\.[A-Za-z]	ReStructuredText file
+>>>&0	regex/512	\^\\.\\.[A-Za-z]	ReStructuredText file
 !:ext	rst

+ 88 - 10
magic/Magdir/rtf

@@ -1,16 +1,94 @@
 
 #------------------------------------------------------------------------------
-# $File: rtf,v 1.7 2009/09/19 16:28:12 christos Exp $
+# $File: rtf,v 1.8 2020/05/17 19:28:49 christos Exp $
 # rtf:	file(1) magic for Rich Text Format (RTF)
 #
 # Duncan P. Simpson, D.P.Simpson@dcs.warwick.ac.uk
-#
-0	string		{\\rtf		Rich Text Format data,
+# Update:	Joerg Jenderek
+# URL:		https://en.wikipedia.org/wiki/Rich_Text_Format
+# Reference:	http://www.snake.net/software/RTF/RTF-Spec-1.7.rtf
+#		http://www.kleinlercher.at/tools/Windows_Protocols/Word2007RTFSpec9.pdf
+0	string		{\\rtf
+# skip DROID fmt-355-signature-id-522.rtf by looking for valid version
+>5	ubyte		!0xAB
+# skip also \ in DROID fmt-50-signature-id-158.rtf by looking for valid version
+>>5	ubyte		!0x5C		Rich Text Format data
+!:mime	text/rtf
+!:apple	????RTF
+!:ext	rtf
+>>>0	use		rtf-info
+#	display information like version, language and code page of RTF
+0	name		rtf-info
+# 1 mostly, 2 for newer Pocket Word documents, space for test like fdo78502.rtf, { for some urtf
+>5	ubyte		!0x7b		\b, version %c
+# The word for character set must precede any text or most other control words
+>6	string		\\mac		\b, Apple Macintosh
+>6	string		\\pc
+# control word \pca
+>>9	ubyte		=0x61		\b, IBM PS/2, code page 850
+>>9	ubyte		!0x61		\b, IBM PC, code page 437
+# unknown character set or ANSI later after control words like
+# \adeflang1025 \info \title \author \category \manager
+# "Burow, Steffanie - Im Tal des Schneeleoparden.rtf"
+#>6	search/105	\\ansi		\b, ANSI
+>6	search/502	\\ansi		\b, ANSI
+>6	default		x		\b, unknown character set
+# look for explict codepage keyword
+# "Burow, Steffanie - Im Tal des Schneeleoparden.rtf"
+#>5	search/110	\\ansicpg
+>5	search/500	\\ansicpg
+# skip unknown or buggy codepage string 0 like in fdo78502.rtf
+>>&0	ubyte		!0x30		\b, code page
+# codepage string: 437~United States IBM, ..., 1252~WesternEuropean, ..., 57011~Punjabi
+>>>&-1		string	x		%-.3s
+# skip space or \ and display possible 4th digit of code page string
+>>>&2		ubyte	>0x2F
+>>>>&-1		ubyte	<0x3A		\b%c
+# possible 5th digit of code page string
+>>>>>&0		ubyte	>0x2F
+>>>>>>&-1	ubyte	<0x3A		\b%c
+# look again at version byte to use default clause
+>5	ubyte		x
+# Default language ID for South Asian/Middle Eastern text
+# language ID: 1025, ..., 1065~Persian, ..., 2057~English_UnitedKingdom, ..., 58380~French_NorthAfrica
+# Readme-0.72-Persian.rtf
+#>6	search/1	\\adeflang	\b, default middle east language ID
+>>6	search/497	\\adeflang	\b, default middle east language ID
+# https://docs.microsoft.com/en-us/openspecs/office_standards/ms-oe376/6c085406-a698-4e12-9d4d-c3b0ee3dbc4a
+>>>&0	string		x		%.4s
+# skip \ and NL and show possible 5th digit of language string
+>>>&4	ubyte		>0x2F
+>>>>&-1	ubyte		<0x3A		\b%c
+# else look for default language to be used when the \plain control word is encountered
+>>6	default		x
+# "Burow, Steffanie - Im Tal des Schneeleoparden.rtf"
+#>>>6	search/127	\\deflang
+>>>6	search/505	\\deflang
+>>>>&0	string		>0		\b, default language ID %-.4s
+# possible 5th digit of language string
+>>>>&4		ubyte	>0x2F
+>>>>>&-1	ubyte	<0x3A		\b%c
+
+# Reference:	http://latex2rtf.sourceforge.net/rtfspec_63.html
+# Note:		no real world example found
+0	string		{\\urtf		Rich Text Format unicoded data
 !:mime	text/rtf
->5	string		1		version 1,
->>6	string		\\ansi		ANSI
->>6	string		\\mac		Apple Macintosh
->>6	string		\\pc		IBM PC, code page 437
->>6	string		\\pca		IBM PS/2, code page 850
->>6	default		x		unknown character set
->5	default		x		unknown version
+#!:apple	????RTF
+!:ext	rtf
+>1	use		rtf-info
+
+# URL:		https://en.wikipedia.org/wiki/Microsoft_Word
+# Reference:	http://fileformats.archiveteam.org/wiki/Microsoft_Word
+# Note:	called by TrID "Pocket Word document"
+#	by PlanMaker "Pocket Word-Handheld PC" for pwd
+#	by PlanMaker "Pocket Word-Pocket PC" for psw
+0	string		{\\pwd		Pocket Word document or template
+# by SoftMaker Office	http://extension.nirsoft.net/pwd
+#!:mime	application/msword
+# https://reposcope.com/mimetype/application/x-pocket-word
+!:mime	application/x-pocket-word
+# PWD for Handheld PC variant and PSW for Pocket PC variant
+# PWT for template
+!:ext	pwd/psw/pwt
+>0	use		rtf-info
+

+ 2 - 2
magic/Magdir/sgml

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: sgml,v 1.40 2019/09/30 15:44:22 christos Exp $
+# $File: sgml,v 1.41 2020/06/07 18:16:43 christos Exp $
 # Type:	SVG Vectorial Graphics
 # From:	Noel Torres <tecnico@ejerciciosresueltos.com>
 0	string		\<?xml\ version=
@@ -109,7 +109,7 @@
 >15	string/t	>\0			%.3s document text
 >>23	search/1	\<xsl:stylesheet	(XSL stylesheet)
 >>24	search/1	\<xsl:stylesheet	(XSL stylesheet)
-0	string		\<?xml\ version='	XML
+0	string/t	\<?xml\ version='	XML
 !:mime	text/xml
 !:strength + 5
 >15	string/t	>\0			%.3s document text

+ 178 - 178
magic/Magdir/sniffer

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: sniffer,v 1.27 2019/12/08 18:22:24 christos Exp $
+# $File: sniffer,v 1.28 2020/03/13 16:47:29 christos Exp $
 # sniffer:  file(1) magic for packet capture files
 #
 # From: guy@alum.mit.edu (Guy Harris)
@@ -87,183 +87,183 @@
 >6	beshort		x		\b.%d
 # clear that continuation level match
 >20	clear		x
->20	belong		0		(No link-layer encapsulation
->20	belong		1		(Ethernet
->20	belong		2		(3Mb Ethernet
->20	belong		3		(AX.25
->20	belong		4		(ProNET
->20	belong		5		(CHAOS
->20	belong		6		(Token Ring
->20	belong		7		(BSD ARCNET
->20	belong		8		(SLIP
->20	belong		9		(PPP
->20	belong		10		(FDDI
->20	belong		11		(RFC 1483 ATM
->20	belong		12		(Raw IP
->20	belong		13		(BSD/OS SLIP
->20	belong		14		(BSD/OS PPP
->20	belong		19		(Linux ATM Classical IP
->20	belong		50		(PPP or Cisco HDLC
->20	belong		51		(PPP-over-Ethernet
->20	belong		99		(Symantec Enterprise Firewall
->20	belong		100		(RFC 1483 ATM
->20	belong		101		(Raw IP
->20	belong		102		(BSD/OS SLIP
->20	belong		103		(BSD/OS PPP
->20	belong		104		(BSD/OS Cisco HDLC
->20	belong		105		(802.11
->20	belong		106		(Linux Classical IP over ATM
->20	belong		107		(Frame Relay
->20	belong		108		(OpenBSD loopback
->20	belong		109		(OpenBSD IPsec encrypted
->20	belong		112		(Cisco HDLC
->20	belong		113		(Linux cooked v1
->20	belong		114		(LocalTalk
->20	belong		117		(OpenBSD PFLOG
->20	belong		119		(802.11 with Prism header
->20	belong		122		(RFC 2625 IP over Fibre Channel
->20	belong		123		(SunATM
->20	belong		127		(802.11 with radiotap header
->20	belong		129		(Linux ARCNET
->20	belong		130		(Juniper Multi-Link PPP
->20	belong		131		(Juniper Multi-Link Frame Relay
->20	belong		132		(Juniper Encryption Services PIC
->20	belong		133		(Juniper GGSN PIC
->20	belong		134		(Juniper FRF.16 Frame Relay
->20	belong		135		(Juniper ATM2 PIC
->20	belong		136		(Juniper Advanced Services PIC
->20	belong		137		(Juniper ATM1 PIC
->20	belong		138		(Apple IP over IEEE 1394
->20	belong		139		(SS7 MTP2 with pseudo-header
->20	belong		140		(SS7 MTP2
->20	belong		141		(SS7 MTP3
->20	belong		142		(SS7 SCCP
->20	belong		143		(DOCSIS
->20	belong		144		(Linux IrDA
->20	belong		147		(Private use 0
->20	belong		148		(Private use 1
->20	belong		149		(Private use 2
->20	belong		150		(Private use 3
->20	belong		151		(Private use 4
->20	belong		152		(Private use 5
->20	belong		153		(Private use 6
->20	belong		154		(Private use 7
->20	belong		155		(Private use 8
->20	belong		156		(Private use 9
->20	belong		157		(Private use 10
->20	belong		158		(Private use 11
->20	belong		159		(Private use 12
->20	belong		160		(Private use 13
->20	belong		161		(Private use 14
->20	belong		162		(Private use 15
->20	belong		163		(802.11 with AVS header
->20	belong		164		(Juniper Passive Monitor PIC
->20	belong		165		(BACnet MS/TP
->20	belong		166		(PPPD
->20	belong		167		(Juniper PPPoE
->20	belong		168		(Juniper PPPoE/ATM
->20	belong		169		(GPRS LLC
->20	belong		170		(GPF-T
->20	belong		171		(GPF-F
->20	belong		174		(Juniper PIC Peer
->20	belong		175		(Ethernet with Endace ERF header
->20	belong		176		(Packet-over-SONET with Endace ERF header
->20	belong		177		(Linux LAPD
->20	belong		178		(Juniper Ethernet
->20	belong		179		(Juniper PPP
->20	belong		180		(Juniper Frame Relay
->20	belong		181		(Juniper C-HDLC
->20	belong		182		(FRF.16 Frame Relay
->20	belong		183		(Juniper Voice PIC
->20	belong		184		(Arinc 429
->20	belong		185		(Arinc 653 Interpartition Communication
->20	belong		186		(USB with FreeBSD header
->20	belong		187		(Bluetooth HCI H4
->20	belong		188		(802.16 MAC Common Part Sublayer
->20	belong		189		(Linux USB
->20	belong		190		(Controller Area Network (CAN) v. 2.0B
->20	belong		191		(802.15.4 with Linux padding
->20	belong		192		(PPI
->20	belong		193		(802.16 MAC Common Part Sublayer plus radiotap header
->20	belong		194		(Juniper Integrated Service Module
->20	belong		195		(802.15.4 with FCS
->20	belong		196		(SITA
->20	belong		197		(Endace ERF
->20	belong		198		(Ethernet with u10 Networks pseudo-header
->20	belong		199		(IPMB
->20	belong		200		(Juniper Secure Tunnel
->20	belong		201		(Bluetooth HCI H4 with pseudo-header
->20	belong		202		(AX.25 with KISS header
->20	belong		203		(LAPD
->20	belong		204		(PPP with direction pseudo-header
->20	belong		205		(Cisco HDLC with direction pseudo-header
->20	belong		206		(Frame Relay with direction pseudo-header
->20	belong		209		(Linux IPMB
->20	belong		215		(802.15.4 with non-ASK PHY header
->20	belong		216		(Linux evdev events
->20	belong		219		(MPLS with label as link-layer header
->20	belong		220		(Memory-mapped Linux USB
->20	belong		221		(DECT
->20	belong		222		(AOS Space Data Link protocol
->20	belong		223		(Wireless HART
->20	belong		224		(Fibre Channel FC-2
->20	belong		225		(Fibre Channel FC-2 with frame delimiters
->20	belong		226		(Solaris IPNET
->20	belong		227		(SocketCAN
->20	belong		228		(Raw IPv4
->20	belong		229		(Raw IPv6
->20	belong		230		(802.15.4 without FCS
->20	belong		231		(D-Bus messages
->20	belong		232		(Juniper Virtual Server
->20	belong		233		(Juniper SRX E2E
->20	belong		234		(Juniper Fibre Channel
->20	belong		235		(DVB-CI
->20	belong		236		(MUX27010
->20	belong		237		(STANAG 5066 D_PDUs
->20	belong		238		(Juniper ATM CEMIC
->20	belong		239		(Linux netfilter log messages
->20	belong		240		(Hilscher netAnalyzer
->20	belong		241		(Hilscher netAnalyzer with delimiters
->20	belong		242		(IP-over-Infiniband
->20	belong		243		(MPEG-2 Transport Stream packets
->20	belong		244		(ng4t ng40
->20	belong		245		(NFC LLCP
->20	belong		246		(Packet filter state syncing
->20	belong		247		(InfiniBand
->20	belong		248		(SCTP
->20	belong		249		(USB with USBPcap header
->20	belong		250		(Schweitzer Engineering Laboratories RTAC packets
->20	belong		251		(Bluetooth Low Energy air interface
->20	belong		252		(Wireshark Upper PDU export
->20	belong		253		(Linux netlink
->20	belong		254		(Bluetooth Linux Monitor
->20	belong		255		(Bluetooth Basic Rate/Enhanced Data Rate baseband packets
->20	belong		256		(Bluetooth Low Energy air interface with pseudo-header
->20	belong		257		(PROFIBUS data link layer
->20	belong		258		(Apple DLT_PKTAP
->20	belong		259		(Ethernet with 802.3 Clause 65 EPON preamble
->20	belong		260		(IPMI trace packets
->20	belong		261		(Z-Wave RF profile R1 and R2 packets
->20	belong		262		(Z-Wave RF profile R3 packets
->20	belong		263		(WattStopper Digital Lighting Mngmt/Legrand Nitoo Open Proto
->20	belong		264		(ISO 14443 messages
->20	belong		265		(IEC 62106 Radio Data System groups
->20	belong		266		(USB with Darwin header
->20	belong		267		(OpenBSD DLT_OPENFLOW
->20	belong		268		(IBM SDLC frames
->20	belong		269		(TI LLN sniffer frames
->20	belong		271		(Linux vsock
->20	belong		272		(Nordic Semiconductor Bluetooth LE sniffer frames
->20	belong		273		(Excentis XRA-31 DOCSIS 3.1 RF sniffer frames
->20	belong		274		(802.3br mPackets
->20	belong		275		(DisplayPort AUX channel monitoring data
->20	belong		276		(Linux cooked v2
->20	belong		278		(OpenVizsla USB
->20	belong		279		(Elektrobit High Speed Capture and Replay (EBHSCR)
->20	belong		281		(Broadcom tag
->20	belong		282		(Broadcom tag (prepended)
->20	belong		284		(Marvell DSA
->20	belong		285		(Marvell EDSA
+>20	belong&0x03FFFFFF		0		(No link-layer encapsulation
+>20	belong&0x03FFFFFF		1		(Ethernet
+>20	belong&0x03FFFFFF		2		(3Mb Ethernet
+>20	belong&0x03FFFFFF		3		(AX.25
+>20	belong&0x03FFFFFF		4		(ProNET
+>20	belong&0x03FFFFFF		5		(CHAOS
+>20	belong&0x03FFFFFF		6		(Token Ring
+>20	belong&0x03FFFFFF		7		(BSD ARCNET
+>20	belong&0x03FFFFFF		8		(SLIP
+>20	belong&0x03FFFFFF		9		(PPP
+>20	belong&0x03FFFFFF		10		(FDDI
+>20	belong&0x03FFFFFF		11		(RFC 1483 ATM
+>20	belong&0x03FFFFFF		12		(Raw IP
+>20	belong&0x03FFFFFF		13		(BSD/OS SLIP
+>20	belong&0x03FFFFFF		14		(BSD/OS PPP
+>20	belong&0x03FFFFFF		19		(Linux ATM Classical IP
+>20	belong&0x03FFFFFF		50		(PPP or Cisco HDLC
+>20	belong&0x03FFFFFF		51		(PPP-over-Ethernet
+>20	belong&0x03FFFFFF		99		(Symantec Enterprise Firewall
+>20	belong&0x03FFFFFF		100		(RFC 1483 ATM
+>20	belong&0x03FFFFFF		101		(Raw IP
+>20	belong&0x03FFFFFF		102		(BSD/OS SLIP
+>20	belong&0x03FFFFFF		103		(BSD/OS PPP
+>20	belong&0x03FFFFFF		104		(BSD/OS Cisco HDLC
+>20	belong&0x03FFFFFF		105		(802.11
+>20	belong&0x03FFFFFF		106		(Linux Classical IP over ATM
+>20	belong&0x03FFFFFF		107		(Frame Relay
+>20	belong&0x03FFFFFF		108		(OpenBSD loopback
+>20	belong&0x03FFFFFF		109		(OpenBSD IPsec encrypted
+>20	belong&0x03FFFFFF		112		(Cisco HDLC
+>20	belong&0x03FFFFFF		113		(Linux cooked v1
+>20	belong&0x03FFFFFF		114		(LocalTalk
+>20	belong&0x03FFFFFF		117		(OpenBSD PFLOG
+>20	belong&0x03FFFFFF		119		(802.11 with Prism header
+>20	belong&0x03FFFFFF		122		(RFC 2625 IP over Fibre Channel
+>20	belong&0x03FFFFFF		123		(SunATM
+>20	belong&0x03FFFFFF		127		(802.11 with radiotap header
+>20	belong&0x03FFFFFF		129		(Linux ARCNET
+>20	belong&0x03FFFFFF		130		(Juniper Multi-Link PPP
+>20	belong&0x03FFFFFF		131		(Juniper Multi-Link Frame Relay
+>20	belong&0x03FFFFFF		132		(Juniper Encryption Services PIC
+>20	belong&0x03FFFFFF		133		(Juniper GGSN PIC
+>20	belong&0x03FFFFFF		134		(Juniper FRF.16 Frame Relay
+>20	belong&0x03FFFFFF		135		(Juniper ATM2 PIC
+>20	belong&0x03FFFFFF		136		(Juniper Advanced Services PIC
+>20	belong&0x03FFFFFF		137		(Juniper ATM1 PIC
+>20	belong&0x03FFFFFF		138		(Apple IP over IEEE 1394
+>20	belong&0x03FFFFFF		139		(SS7 MTP2 with pseudo-header
+>20	belong&0x03FFFFFF		140		(SS7 MTP2
+>20	belong&0x03FFFFFF		141		(SS7 MTP3
+>20	belong&0x03FFFFFF		142		(SS7 SCCP
+>20	belong&0x03FFFFFF		143		(DOCSIS
+>20	belong&0x03FFFFFF		144		(Linux IrDA
+>20	belong&0x03FFFFFF		147		(Private use 0
+>20	belong&0x03FFFFFF		148		(Private use 1
+>20	belong&0x03FFFFFF		149		(Private use 2
+>20	belong&0x03FFFFFF		150		(Private use 3
+>20	belong&0x03FFFFFF		151		(Private use 4
+>20	belong&0x03FFFFFF		152		(Private use 5
+>20	belong&0x03FFFFFF		153		(Private use 6
+>20	belong&0x03FFFFFF		154		(Private use 7
+>20	belong&0x03FFFFFF		155		(Private use 8
+>20	belong&0x03FFFFFF		156		(Private use 9
+>20	belong&0x03FFFFFF		157		(Private use 10
+>20	belong&0x03FFFFFF		158		(Private use 11
+>20	belong&0x03FFFFFF		159		(Private use 12
+>20	belong&0x03FFFFFF		160		(Private use 13
+>20	belong&0x03FFFFFF		161		(Private use 14
+>20	belong&0x03FFFFFF		162		(Private use 15
+>20	belong&0x03FFFFFF		163		(802.11 with AVS header
+>20	belong&0x03FFFFFF		164		(Juniper Passive Monitor PIC
+>20	belong&0x03FFFFFF		165		(BACnet MS/TP
+>20	belong&0x03FFFFFF		166		(PPPD
+>20	belong&0x03FFFFFF		167		(Juniper PPPoE
+>20	belong&0x03FFFFFF		168		(Juniper PPPoE/ATM
+>20	belong&0x03FFFFFF		169		(GPRS LLC
+>20	belong&0x03FFFFFF		170		(GPF-T
+>20	belong&0x03FFFFFF		171		(GPF-F
+>20	belong&0x03FFFFFF		174		(Juniper PIC Peer
+>20	belong&0x03FFFFFF		175		(Ethernet with Endace ERF header
+>20	belong&0x03FFFFFF		176		(Packet-over-SONET with Endace ERF header
+>20	belong&0x03FFFFFF		177		(Linux LAPD
+>20	belong&0x03FFFFFF		178		(Juniper Ethernet
+>20	belong&0x03FFFFFF		179		(Juniper PPP
+>20	belong&0x03FFFFFF		180		(Juniper Frame Relay
+>20	belong&0x03FFFFFF		181		(Juniper C-HDLC
+>20	belong&0x03FFFFFF		182		(FRF.16 Frame Relay
+>20	belong&0x03FFFFFF		183		(Juniper Voice PIC
+>20	belong&0x03FFFFFF		184		(Arinc 429
+>20	belong&0x03FFFFFF		185		(Arinc 653 Interpartition Communication
+>20	belong&0x03FFFFFF		186		(USB with FreeBSD header
+>20	belong&0x03FFFFFF		187		(Bluetooth HCI H4
+>20	belong&0x03FFFFFF		188		(802.16 MAC Common Part Sublayer
+>20	belong&0x03FFFFFF		189		(Linux USB
+>20	belong&0x03FFFFFF		190		(Controller Area Network (CAN) v. 2.0B
+>20	belong&0x03FFFFFF		191		(802.15.4 with Linux padding
+>20	belong&0x03FFFFFF		192		(PPI
+>20	belong&0x03FFFFFF		193		(802.16 MAC Common Part Sublayer plus radiotap header
+>20	belong&0x03FFFFFF		194		(Juniper Integrated Service Module
+>20	belong&0x03FFFFFF		195		(802.15.4 with FCS
+>20	belong&0x03FFFFFF		196		(SITA
+>20	belong&0x03FFFFFF		197		(Endace ERF
+>20	belong&0x03FFFFFF		198		(Ethernet with u10 Networks pseudo-header
+>20	belong&0x03FFFFFF		199		(IPMB
+>20	belong&0x03FFFFFF		200		(Juniper Secure Tunnel
+>20	belong&0x03FFFFFF		201		(Bluetooth HCI H4 with pseudo-header
+>20	belong&0x03FFFFFF		202		(AX.25 with KISS header
+>20	belong&0x03FFFFFF		203		(LAPD
+>20	belong&0x03FFFFFF		204		(PPP with direction pseudo-header
+>20	belong&0x03FFFFFF		205		(Cisco HDLC with direction pseudo-header
+>20	belong&0x03FFFFFF		206		(Frame Relay with direction pseudo-header
+>20	belong&0x03FFFFFF		209		(Linux IPMB
+>20	belong&0x03FFFFFF		215		(802.15.4 with non-ASK PHY header
+>20	belong&0x03FFFFFF		216		(Linux evdev events
+>20	belong&0x03FFFFFF		219		(MPLS with label as link-layer header
+>20	belong&0x03FFFFFF		220		(Memory-mapped Linux USB
+>20	belong&0x03FFFFFF		221		(DECT
+>20	belong&0x03FFFFFF		222		(AOS Space Data Link protocol
+>20	belong&0x03FFFFFF		223		(Wireless HART
+>20	belong&0x03FFFFFF		224		(Fibre Channel FC-2
+>20	belong&0x03FFFFFF		225		(Fibre Channel FC-2 with frame delimiters
+>20	belong&0x03FFFFFF		226		(Solaris IPNET
+>20	belong&0x03FFFFFF		227		(SocketCAN
+>20	belong&0x03FFFFFF		228		(Raw IPv4
+>20	belong&0x03FFFFFF		229		(Raw IPv6
+>20	belong&0x03FFFFFF		230		(802.15.4 without FCS
+>20	belong&0x03FFFFFF		231		(D-Bus messages
+>20	belong&0x03FFFFFF		232		(Juniper Virtual Server
+>20	belong&0x03FFFFFF		233		(Juniper SRX E2E
+>20	belong&0x03FFFFFF		234		(Juniper Fibre Channel
+>20	belong&0x03FFFFFF		235		(DVB-CI
+>20	belong&0x03FFFFFF		236		(MUX27010
+>20	belong&0x03FFFFFF		237		(STANAG 5066 D_PDUs
+>20	belong&0x03FFFFFF		238		(Juniper ATM CEMIC
+>20	belong&0x03FFFFFF		239		(Linux netfilter log messages
+>20	belong&0x03FFFFFF		240		(Hilscher netAnalyzer
+>20	belong&0x03FFFFFF		241		(Hilscher netAnalyzer with delimiters
+>20	belong&0x03FFFFFF		242		(IP-over-Infiniband
+>20	belong&0x03FFFFFF		243		(MPEG-2 Transport Stream packets
+>20	belong&0x03FFFFFF		244		(ng4t ng40
+>20	belong&0x03FFFFFF		245		(NFC LLCP
+>20	belong&0x03FFFFFF		246		(Packet filter state syncing
+>20	belong&0x03FFFFFF		247		(InfiniBand
+>20	belong&0x03FFFFFF		248		(SCTP
+>20	belong&0x03FFFFFF		249		(USB with USBPcap header
+>20	belong&0x03FFFFFF		250		(Schweitzer Engineering Laboratories RTAC packets
+>20	belong&0x03FFFFFF		251		(Bluetooth Low Energy air interface
+>20	belong&0x03FFFFFF		252		(Wireshark Upper PDU export
+>20	belong&0x03FFFFFF		253		(Linux netlink
+>20	belong&0x03FFFFFF		254		(Bluetooth Linux Monitor
+>20	belong&0x03FFFFFF		255		(Bluetooth Basic Rate/Enhanced Data Rate baseband packets
+>20	belong&0x03FFFFFF		256		(Bluetooth Low Energy air interface with pseudo-header
+>20	belong&0x03FFFFFF		257		(PROFIBUS data link layer
+>20	belong&0x03FFFFFF		258		(Apple DLT_PKTAP
+>20	belong&0x03FFFFFF		259		(Ethernet with 802.3 Clause 65 EPON preamble
+>20	belong&0x03FFFFFF		260		(IPMI trace packets
+>20	belong&0x03FFFFFF		261		(Z-Wave RF profile R1 and R2 packets
+>20	belong&0x03FFFFFF		262		(Z-Wave RF profile R3 packets
+>20	belong&0x03FFFFFF		263		(WattStopper Digital Lighting Mngmt/Legrand Nitoo Open Proto
+>20	belong&0x03FFFFFF		264		(ISO 14443 messages
+>20	belong&0x03FFFFFF		265		(IEC 62106 Radio Data System groups
+>20	belong&0x03FFFFFF		266		(USB with Darwin header
+>20	belong&0x03FFFFFF		267		(OpenBSD DLT_OPENFLOW
+>20	belong&0x03FFFFFF		268		(IBM SDLC frames
+>20	belong&0x03FFFFFF		269		(TI LLN sniffer frames
+>20	belong&0x03FFFFFF		271		(Linux vsock
+>20	belong&0x03FFFFFF		272		(Nordic Semiconductor Bluetooth LE sniffer frames
+>20	belong&0x03FFFFFF		273		(Excentis XRA-31 DOCSIS 3.1 RF sniffer frames
+>20	belong&0x03FFFFFF		274		(802.3br mPackets
+>20	belong&0x03FFFFFF		275		(DisplayPort AUX channel monitoring data
+>20	belong&0x03FFFFFF		276		(Linux cooked v2
+>20	belong&0x03FFFFFF		278		(OpenVizsla USB
+>20	belong&0x03FFFFFF		279		(Elektrobit High Speed Capture and Replay (EBHSCR)
+>20	belong&0x03FFFFFF		281		(Broadcom tag
+>20	belong&0x03FFFFFF		282		(Broadcom tag (prepended)
+>20	belong&0x03FFFFFF		284		(Marvell DSA
+>20	belong&0x03FFFFFF		285		(Marvell EDSA
 # print default match
 >20	default		x
 >>20	belong		x		(linktype#%u

+ 20 - 0
magic/Magdir/ssh

@@ -17,3 +17,23 @@
 >>12	ubequad	x		\b, version %llx
 >>>20	beqdate	x		\b, generated %s
 
+# From:		Joerg Jenderek
+# URL:		https://en.wikipedia.org/wiki/PuTTY
+# Reference:	https://the.earth.li/~sgtatham/putty/latest/putty-0.73.tar.gz
+#		/sshpubk.c
+0	string		PuTTY-User-Key-File-	PuTTY Private Key File
+#!:mime	text/plain
+# https://github.com/github/putty/blob/master/windows/installer.wxs
+!:mime	application/x-putty-private-key
+!:ext	ppk
+# version 1 or 2
+>20	string		x			\b, version %.1s
+# name of the algorithm like: ssh-dss ssh-rsa ecdsa-sha2-nistp256 ssh-ed25519
+>23	string		x			\b, algorithm %s
+# next line says "Encryption: " plus an encryption type like aes256-cbc or none
+>32	search/13	Encryption:\040		\b, Encryption
+>>&0	string		x			%s
+# next line says "Comment: " plus the comment string
+>>>&0	search/3	Comment:\040
+>>>>&0	string		x			"%s"
+

+ 36 - 0
magic/Magdir/sylk

@@ -0,0 +1,36 @@
+
+#------------------------------------------------------------------------------
+# $File: sylk,v 1.1 2020/04/05 22:18:34 christos Exp $
+# sylk:  file(1) magic for SYLK text files
+
+# From:	Joerg Jenderek
+# URL:	https://en.wikipedia.org/wiki/SYmbolic_LinK_%28SYLK%29
+#	http://fileformats.archiveteam.org/wiki/SYLK
+# Note:	called by TrID "SYLK - SYmbolic LinK data",
+#	by DROID "Microsoft Symbolic Link (SYLK) File"
+#	by FreeDesktop.org "spreadsheet interchange document"
+0	string		ID;P
+# skip short DROID x-fmt-106-signature-id-603.slk
+>7	ubyte		>0		spreadsheet interchange document
+# https://reposcope.com/mimetype/text/spreadsheet
+#!:mime	text/spreadsheet
+# https://reposcope.com/mimetype/application/x-sylk	by Gnumeric
+!:mime	application/x-sylk
+!:ext	slk/sylk
+>>4	ubyte		>037		\b, created by
+# Gnumeric, pmw~PlanMaker, CALCOOO32~LibreOffice OpenOffice, SCALC3~StarOffice
+# MP~Multiplan, XL~Excel WXL~Excel Windows
+>>>4	string		Gnumeric	Gnumeric
+>>>4	string		pmw		PlanMaker
+>>>4	string		CALCOOO32	Libre/OpenOffice Calc
+>>>4	string		SCALC3		StarOffice Calc
+>>>4	string		XL		Excel
+# Excel, version probably running on Windows
+>>>4	string		WXL		Excel
+# not tested
+>>>4	string		MP		Multiplan
+# unknown spreadsheet software
+>>>4	default		x
+>>>>4	string		x		%s
+
+

+ 2 - 2
magic/Magdir/ti-8x

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: ti-8x,v 1.7 2014/04/30 21:41:02 christos Exp $
+# $File: ti-8x,v 1.8 2020/02/12 22:13:01 christos Exp $
 # ti-8x: file(1) magic for the TI-8x and TI-9x Graphing Calculators.
 #
 # From: Ryan McGuire (rmcguire@freenet.columbus.oh.us).
@@ -206,7 +206,7 @@
 #
 # Magic Numbers for the TI-73/83+/89/92+/V200 FLASH upgrades
 #
-0x0000016	string		Advanced	TI-XX Graphing Calculator (FLASH)
+#0x0000016	string		Advanced	TI-XX Graphing Calculator (FLASH)
 0		string		**TIFL**	TI-XX Graphing Calculator (FLASH)
 >8		byte		>0		- Revision %d
 >>9 		byte		x		\b.%d,

+ 4 - 2
magic/Magdir/tplink

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: tplink,v 1.4 2019/04/19 00:42:27 christos Exp $
+# $File: tplink,v 1.5 2020/03/28 23:14:26 christos Exp $
 # tplink: File magic for openwrt firmware files
 
 # URL: https://wiki.openwrt.org/doc/techref/header
@@ -13,7 +13,9 @@
 >>0x100		long		0
 # skip Norton Commander Cleanup Utility NCCLEAN.INI by looking for valid vendor
 >>>4		ubelong		>0x1F000000
->>>>0		use		firmware-tplink
+# skip user.dbt by looking for positive hardware id
+>>>>0x40	ubeshort	>0
+>>>>>0		use		firmware-tplink
 
 0		name		firmware-tplink
 >0		ubyte		x		firmware

+ 5 - 5
magic/Magdir/troff

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: troff,v 1.11 2014/06/03 19:01:34 christos Exp $
+# $File: troff,v 1.13 2020/05/30 23:12:34 christos Exp $
 # troff:  file(1) magic for *roff
 #
 # updated by Daniel Quinlan (quinlan@yggdrasil.com)
@@ -14,11 +14,11 @@
 !:mime	text/troff
 0	search/1	\\"		troff or preprocessor input text
 !:mime	text/troff
-0	search/1	'''		troff or preprocessor input text
+#0	search/1	'''		troff or preprocessor input text
+#!:mime	text/troff
+0	regex/20l	\^\\.[A-Za-z][A-Za-z0-9][\ \t]	troff or preprocessor input text
 !:mime	text/troff
-0	regex/20l	\^\\.[A-Za-z0-9][A-Za-z0-9][\ \t]	troff or preprocessor input text
-!:mime	text/troff
-0	regex/20l	\^\\.[A-Za-z0-9][A-Za-z0-9]$	troff or preprocessor input text
+0	regex/20l	\^\\.[A-Za-z][A-Za-z0-9]$	troff or preprocessor input text
 !:mime	text/troff
 
 # ditroff intermediate output text

+ 12 - 0
magic/Magdir/unisig

@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File: unisig,v 1.1 2020/04/09 19:05:44 christos Exp $
+# unisig:  file(1) magic for files carrying a uniform signature (Unisig)
+# From: Lassi Kortela, John Cowan
+# URL:	https://github.com/unisig
+#
+0	string	\xDC\xDC\x0D\x0A\x1A\x0A\x00	Unisig:
+>7	ubyte	=0				UUID
+>>8	guid	x				%s
+>7	ubyte	>0				URI
+>>7	pstring x				%s

+ 21 - 0
magic/Magdir/usd

@@ -0,0 +1,21 @@
+
+#------------------------------------------------------------------------------
+# $File: usd,v 1.2 2020/05/21 22:17:00 christos Exp $
+#
+# From Christian Schmidbauer
+#
+# https://github.com/PixarAnimationStudios/USD
+
+# USD crate file
+# https://github.com/PixarAnimationStudios/USD/blob/ebac0a8b6703f4fa1c27115f1f013bb9819662f4/pxr/usd/usd/crateFile.h#L441-L450
+0	string		PXR-USDC	USD crate
+>8	byte		x		\b, version %x.
+>9	byte		x		\b%x.
+>10	byte		x		\b%x
+!:ext	usd
+
+# USD ASCII file
+0	string		#usda\040	USD ASCII
+>6	string		x		\b, version %s
+!:mime	text/plain
+!:ext	usd

+ 1 - 1
magic/Magdir/virtual

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: virtual,v 1.10 2019/04/19 00:42:27 christos Exp $
+# $File: virtual,v 1.12 2020/02/15 01:20:15 christos Exp $
 # From: James Nobis <quel@quelrod.net>
 # Microsoft hard disk images for:
 # Virtual Server

+ 12 - 0
magic/Magdir/web

@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File: web,v 1.1 2020/05/17 19:14:28 christos Exp $
+
+# http://www.rdfhdt.org/
+# From Christoph Biedl
+# http://www.rdfhdt.org/hdt-internals/
+# https://github.com/rdfhdt/hdt-cpp
+
+0	string	$HDT\x01 HDT file (binary compressed indexed RDF triples) type 1
+!:mime application/vnd.hdt
+!:ext hdt

+ 123 - 77
magic/Magdir/windows

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: windows,v 1.29 2019/11/18 03:11:20 christos Exp $
+# $File: windows,v 1.31 2020/03/15 16:44:37 christos Exp $
 # windows:  file(1) magic for Microsoft Windows
 #
 # This file is mainly reserved for files where programs
@@ -620,104 +620,144 @@
 
 # Windows Precompiled INF files *.PNF added by Joerg Jenderek at Mar 2013 of _PNF_HEADER inf.h
 # http://read.pudn.com/downloads3/sourcecode/windows/248345/win2k/private/windows/setup/setupapi/inf.h__.htm
-# GRR: line below too general as it catches also PDP-11 UNIX/RT ldp
-0		leshort&0xFeFe	0x0000
-!:strength -5
-# test for unused null bits in PNF_FLAGs
->4	ulelong&0xFCffFe00	0x00000000
-# only found 58h for Offset of WinDirPath immediately after _PNF_HEADER structure
->>68		ulelong		>0x57
-# test for zero high byte of InfValueBlockSize, followed by WinDirPath like
-# C:\WINDOWS (ASCII 0x433a5c.. , unicode 0x43003a005c..) or X:\MININT
->>>(68.l-1)	ubelong&0xffE0C519	=0x00400018	Windows Precompiled iNF
+# URL:		http://fileformats.archiveteam.org/wiki/INF_(Windows)
+# Reference:	http://en.verysource.com/code/10350344_1/inf.h.html
+# Note:		stored in %Windir%\Inf %Windir%\System32\DriverStore\FileRepository
+# check for valid major and minor versions: 101h - 303h 
+0		leshort&0xFcFc	=0x0000
+# GRR: line above (strength 50) is too general as it catches also "PDP-11 UNIX/RT ldp" ./pdp
+>0		leshort&0x0303	!0x0000
+# test for valid InfStyles: 1 2 
+>>2		uleshort	>0
+>>>2		uleshort	<3
+# look for colon in WinDirPath after PNF header
+#>>>>0x59	search/18	:
+>>>>0	use	PreCompiledInf
+0	name	PreCompiledInf
+>0		uleshort	x	Windows Precompiled iNF
 !:mime	application/x-pnf
-# currently only found Major Version=1 and Minor Version=1
-#>>>>0		uleshort	=0x0101
-#>>>>>1		ubyte		x		\b, version %u
-#>>>>>0		ubyte		x		\b.%u
->>>>0		uleshort	!0x0101
->>>>>1		ubyte		x		\b, version %u
->>>>>0		ubyte		x		\b.%u
+!:ext	pnf
+# major version 1 for older Windows like XP and 3 since about Windows Vista
+# 101h~98-XP; 301h~Windows Vista-7 ; 302h~Windows 10 14393; 303h~Windows 10 18362
+>1		ubyte		x		\b, version %u
+>0		ubyte		x		\b.%u
+>0		uleshort	=0x0101		(Windows
+>>4	ulelong&0x00000001	!0x00000001	98)
+>>4	ulelong&0x00000001	=0x00000001	XP)
+>0		uleshort	=0x0301		(Windows Vista-8.1)
+>0		uleshort	=0x0302		(Windows 10 older)
+>0		uleshort	=0x0303		(Windows 10)
 # 1 ,2 (windows 98 SE)
-#>>>>2		uleshort	=2		\b, InfStyle %u
->>>>2		uleshort	!2		\b, InfStyle %u
+>2		uleshort	!2		\b, InfStyle %u
 #	PNF_FLAG_IS_UNICODE		0x00000001
 #	PNF_FLAG_HAS_STRINGS		0x00000002
 #	PNF_FLAG_SRCPATH_IS_URL		0x00000004
 #	PNF_FLAG_HAS_VOLATILE_DIRIDS	0x00000008
 #	PNF_FLAG_INF_VERIFIED		0x00000010
 #	PNF_FLAG_INF_DIGITALLY_SIGNED	0x00000020
-#	??				0x00000100
-#	??				0x01000000
-#	??				0x02000000
->>>>4	ulelong&0x00000001	0x00000001	\b, unicoded
->>>>4	ulelong&0x00000020	0x00000020	\b, digitally signed
-#>>>>8		ulelong		x		\b, InfSubstValueListOffset 0x%x
+#	UNKNOWN8			0x00000080
+#	UNKNOWN				0x00000100
+#	UNKNOWN1			0x01000000
+#	UNKNOWN2			0x02000000
+>4	ulelong&0x03000180	>0		\b, flags
+>>4	ulelong			x		0x%x
+>4	ulelong&0x00000001	0x00000001	\b, unicoded
+>4	ulelong&0x00000002	0x00000002	\b, has strings
+>4	ulelong&0x00000004	0x00000004	\b, src URL
+>4	ulelong&0x00000008	0x00000008	\b, volatile dir ids
+>4	ulelong&0x00000010	0x00000010	\b, verified
+>4	ulelong&0x00000020	0x00000020	\b, digitally signed
+# >4	ulelong&0x00000080	0x00000080	\b, UNKNOWN8
+# >4	ulelong&0x00000100	0x00000100	\b, UNKNOWN
+# >4	ulelong&0x01000000	0x01000000	\b, UNKNOWN1
+# >4	ulelong&0x02000000	0x02000000	\b, UNKNOWN2
+#>8		ulelong		x		\b, InfSubstValueListOffset 0x%x
 # many 0, 1 lmouusb.PNF, 2 linkfx10.PNF , f webfdr16.PNF
-#>>>>12		uleshort	x		\b, InfSubstValueCount 0x%x
-# only < 9 found
-#>>>>14		uleshort	x		\b, InfVersionDatumCount 0x%x
-# only found values lower 0x0000ffff
-#>>>>16		ulelong		x		\b, InfVersionDataSize 0x%x
+# , 6 bth.PNF, 9 usbport.PNF, d netnwifi.PNF, 10h nettcpip.PNF
+#>12		uleshort	x		\b, InfSubstValueCount 0x%x
+# only < 9 found: 8 hcw85b64.PNF
+#>14		uleshort	x		\b, InfVersionDatumCount 0x%x
+# only found values lower 0x0000ffff ??
+#>16		ulelong		x		\b, InfVersionDataSize 0x%x
 # only found positive values lower 0x00ffFFff for InfVersionDataOffset
->>>>20		ulelong		x		\b, at 0x%x
->>>>4	ulelong&0x00000001	=0x00000001
+>20		ulelong		x		\b, at 0x%x
+>4	ulelong&0x00000001	=0x00000001
 # case independent: CatalogFile Class DriverVer layoutfile LayoutFile SetupClass signature Signature
->>>>>(20.l)	lestring16	x		"%s"
->>>>4	ulelong&0x00000001	!0x00000001
->>>>>(20.l)	string		x		"%s"
+>>(20.l)	lestring16	x		"%s"
+>4	ulelong&0x00000001	!0x00000001
+>>(20.l)	string		x		"%s"
 # FILETIME is number of 100-nanosecond intervals since 1 January 1601
-#>>>>24		ulequad		x		\b, InfVersionLastWriteTime %16.16llx
+#>24		ulequad		x		\b, InfVersionLastWriteTime %16.16llx
+#>24		foodate-0xbar	x		\b, InfVersionLastWriteTime %s
+# for Windows 98, XP
+>0		uleshort	<0x0102
 # only found values lower 0x00ffFFff
-#>>>>32		ulelong		x		\b, StringTableBlockOffset 0x%x
-#>>>>36		ulelong		x		\b, StringTableBlockSize 0x%x
-#>>>>40		ulelong		x		\b, InfSectionCount 0x%x
-#>>>>44		ulelong		x		\b, InfSectionBlockOffset 0x%x
-#>>>>48		ulelong		x		\b, InfSectionBlockSize 0x%x
-#>>>>52		ulelong		x		\b, InfLineBlockOffset 0x%x
-#>>>>56		ulelong		x		\b, InfLineBlockSize 0x%x
-#>>>>60		ulelong		x		\b, InfValueBlockOffset 0x%x
-#>>>>64		ulelong		x		\b, InfValueBlockSize 0x%x
+# often 70 but also 78h for corelist.PNF
+# >>32		ulelong		x		\b, StringTableBlockOffset 0x%x
+# >>36		ulelong		x		\b, StringTableBlockSize 0x%x
+# >>40		ulelong		x		\b, InfSectionCount 0x%x
+# >>44		ulelong		x		\b, InfSectionBlockOffset 0x%x
+# >>48		ulelong		x		\b, InfSectionBlockSize 0x%x
+# >>52		ulelong		x		\b, InfLineBlockOffset 0x%x
+# >>56		ulelong		x		\b, InfLineBlockSize 0x%x
+# >>60		ulelong		x		\b, InfValueBlockOffset 0x%x
+# >>64		ulelong		x		\b, InfValueBlockSize 0x%x
 # WinDirPathOffset
-#>>>>68		ulelong		x		\b, at 0x%x
->>>>68		ulelong		>0x57
->>>>>4	ulelong&0x00000001	=0x00000001
->>>>>>(68.l)	ubequad		=0x43003a005c005700
+# like 58h, which means direct after PNF header
+#>>68		ulelong		x		\b, at 0x%x
+>>68		ulelong		x
+>>>4	ulelong&0x00000001	=0x00000001
+#>>>>(68.l)	ubequad		=0x43003a005c005700
 # normally unicoded C:\Windows
-#>>>>>>>(68.l)	lestring16	x		\b, WinDirPath "%s"
->>>>>>(68.l)	ubequad		!0x43003a005c005700
->>>>>>>(68.l)	lestring16	x		\b, WinDirPath "%s"
->>>>>4	ulelong&0x00000001	!0x00000001
+#>>>>>(68.l)	lestring16	x		\b, WinDirPath "%s"
+>>>>(68.l)	ubequad		!0x43003a005c005700
+>>>>>(68.l)	lestring16	x		\b, WinDirPath "%s"
+>>>4	ulelong&0x00000001	!0x00000001
 # normally ASCII C:\WINDOWS
-#>>>>>>(68.l)	string		=C:\\WINDOWS	\b, WinDirPath "%s"
->>>>>>(68.l)	string		!C:\\WINDOWS	\b, WinDirPath "%s"
+#>>>>(68.l)	string		=C:\\WINDOWS	\b, WinDirPath "%s"
+>>>>(68.l)	string		!C:\\WINDOWS
+>>>>>(68.l)	string		x		\b, WinDirPath "%s"
 # found OsLoaderPathOffset values often 0 , once 70h corelist.PNF, once 68h ASCII machine.PNF
-#>>>>72		ulelong		>0		\b, at 0x%x
->>>>72		ulelong		>0		\b,
->>>>>4	ulelong&0x00000001	=0x00000001
->>>>>>(72.l)	lestring16	x		OsLoaderPath "%s"
->>>>>4	ulelong&0x00000001	!0x00000001
+>>>72		ulelong		>0		\b,
+>>>>4	ulelong&0x00000001	=0x00000001
+>>>>>(72.l)	lestring16	x		OsLoaderPath "%s"
+>>>>4	ulelong&0x00000001	!0x00000001
 # seldom C:\ instead empty
->>>>>>(72.l)	string		x		OsLoaderPath "%s"
+>>>>>(72.l)	string		x		OsLoaderPath "%s"
 # 1fdh
-#>>>>76		uleshort	x		\b, StringTableHashBucketCount 0x%x
->>>>78		uleshort	!0x407		\b, LanguageId %x
+#>>>76		uleshort	x		\b, StringTableHashBucketCount 0x%x
 # only 407h found
-#>>>>78		uleshort	=0x407		\b, LanguageId %x
+>>>78		uleshort	!0x409		\b, LanguageID %x
+#>>>78		uleshort	=0x409		\b, LanguageID %x
 # InfSourcePathOffset often 0
-#>>>>80		ulelong		>0		\b, at 0x%x
->>>>80		ulelong		>0		\b,
->>>>>4	ulelong&0x00000001	=0x00000001
->>>>>>(80.l)	lestring16	x		SourcePath "%s"
->>>>>4	ulelong&0x00000001	!0x00000001
->>>>>>(80.l)	string		>\0		SourcePath "%s"
+>>>80		ulelong		>0		\b, at 0x%x
+>>>>4	ulelong&0x00000001	=0x00000001
+>>>>>(80.l)	lestring16	x		SourcePath "%s"
+>>>>4	ulelong&0x00000001	!0x00000001
+>>>>>(80.l)	string		>\0		SourcePath "%s"
 # OriginalInfNameOffset often 0
-#>>>>84		ulelong		>0		\b, at 0x%x
->>>>84		ulelong		>0		\b,
->>>>>4	ulelong&0x00000001	=0x00000001
->>>>>>(84.l)	lestring16	x		InfName "%s"
->>>>>4	ulelong&0x00000001	!0x00000001
->>>>>>(84.l)	string		>\0		InfName "%s"
+>>>84		ulelong		>0		\b, at 0x%x
+>>>>4	ulelong&0x00000001	=0x00000001
+>>>>>(84.l)	lestring16	x		InfName "%s"
+>>>>4	ulelong&0x00000001	!0x00000001
+>>>>>(84.l)	string		>\0		InfName "%s"
+
+# for newer Windows like Vista, 7 , 8.1 , 10
+>0		uleshort	>0x0101
+>>80	ulelong			x		\b, at 0x%x WinDirPath
+>>>4	ulelong&0x00000001	0x00000001
+# normally unicoded C:\Windows
+#>>>>(80.l)	ubequad		=0x43003a005c005700
+#>>>>>(80.l)	lestring16	x		"%s"
+>>>>(80.l)	ubequad		!0x43003a005c005700
+>>>>>(80.l)	lestring16	x		"%s"
+# language id: 0 407h~german 409h~English_US
+>>90		uleshort	!0x409		\b, LanguageID %x
+#>>90		uleshort	=0x409		\b, LanguageID %x
+>>92	ulelong			>0		\b, at 0x%x
+>>>4	ulelong&0x00000001	0x00000001
+# language string like: de-DE en-US
+>>>>(92.l)	lestring16	x		language %s
 
 # Summary: backup file created with utility like NTBACKUP.EXE shipped with Windows NT/2K/XP/2003
 # Extension: .bkf
@@ -991,3 +1031,9 @@
 # URL like File\C:\Users\nutzer\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\desktop.ini
 >>&20		lestring16	x	\b, 1st %-s
 
+# Microsoft SYLK
+# https://en.wikipedia.org/wiki/SYmbolic_LinK_(SYLK)
+# https://outflank.nl/upload/sylksum.txt
+0	string	ID;P	Microsoft SYLK program
+>4	string	>0	\b, created by %s
+!:ext	slk/sylk

+ 18 - 1
magic/Magdir/wordprocessors

@@ -1,6 +1,6 @@
 
 #------------------------------------------------------------------------------
-# $File: wordprocessors,v 1.23 2019/10/25 20:15:49 christos Exp $
+# $File: wordprocessors,v 1.24 2020/05/22 19:28:47 christos Exp $
 # wordprocessors:  file(1) magic fo word processors.
 #
 ####### PWP file format used on Smith Corona Personal Word Processors:
@@ -302,3 +302,20 @@
 # partial file name, URL or internal name like "dd2*" of 1st object or RESRV
 >>>(2.s+11)	pstring/h	x		\b, 1st %s
 
+# From:	Joerg Jenderek
+# URL:	http://fileformats.archiveteam.org/wiki/StarOffice_Gallery
+# Note:	used in Star-, Open- and Libre-Office and found in directories like
+#	%APPDATA%\Roaming\LibreOffice\4\user\gallery
+#	$HOME/.config/libreoffice/4/user/gallery
+0	string		SGA3	StarOffice Gallery thumbnails
+# Unknown like 0x04000?0001000142
+#>4	ubequad		x	\b, UNKNOWN 0x%16.16llx
+#!:mime	application/x-sdg
+!:mime	application/x-stargallery-sdg
+!:ext	sdg
+# display image magic for debugging purpose like 'BM'
+# looking like PC bitmap, Windows 3.x format with unknown compression
+#>11	string		x	\b, image magic '%-.2s'
+# inspect 1st GALLERY thumbnail magic by ./images with 1 space at end
+#>11	indirect	x	\b; contains 
+

+ 66 - 19
magic/Magdir/zip

@@ -1,14 +1,15 @@
 #------------------------------------------------------------------------------
-# $File: zip,v 1.3 2019/07/06 19:25:06 christos Exp $
+# $File: zip,v 1.4 2020/03/03 13:46:52 christos Exp $
 # zip:  file(1) magic for zip files; this is not use
 # Note the version of magic in archive is currently stronger, this is
 # just an example until negative offsets are supported better
 
-# Zip Central Cirectory record
+# Zip Central Directory record
 0	name		zipcd
 >0	string		PK\001\002	Zip archive data
 >>4	leshort		x		\b, made by
 >>4	use		zipversion
+>>4	use		ziphost
 >>6	leshort		x		\b, extract using at least
 >>6	use		zipversion
 >>12	ledate		x		\b, last modified %s
@@ -16,13 +17,27 @@
 >>10	leshort		x		\b, method=
 >>10	use		zipcompression
 
+# URL:		https://en.wikipedia.org/wiki/Zip_(file_format)
+# reference:	https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.6.TXT
 # Zip known compressions
 0	name		zipcompression
 >0	leshort		0		\bstore
+>0	leshort		1		\bShrinking
+>0	leshort		6		\bImploding
+>0	leshort		7		\bTokenizing
 >0	leshort		8		\bdeflate
 >0	leshort		9		\bdeflate64
+>0	leshort		10		\bLibrary imploding
+#>0	leshort		11 		\bReserved by PKWARE
 >0	leshort		12		\bbzip2
+#>0	leshort		13 		\bReserved by PKWARE
 >0	leshort		14		\blzma
+#>0	leshort		15 		\bReserved by PKWARE
+>0	leshort		16		\bCMPSC Compression
+#>0	leshort		17 		\bReserved by PKWARE
+>0	leshort		18		\bIBM TERSE
+>0	leshort		19		\bIBM LZ77
+# https://support.winzip.com/hc/en-us/articles/115012122828-Compression-method-used-for-this-file-is-94
 >0	leshort		94		\bMP3
 >0	leshort		95		\bxz
 >0	leshort		96		\bJpeg
@@ -34,23 +49,55 @@
 
 # Zip known versions
 0	name		zipversion
->0	leshort		0x09		v0.9
->0	leshort		0x0a		v1.0
->0	leshort		0x0b		v1.1
->0	leshort		0x14		v2.0
->0	leshort		0x15		v2.1
->0	leshort		0x19		v2.5
->0	leshort		0x1b		v2.7
->0	leshort		0x2d		v4.5
->0	leshort		0x2e		v4.6
->0	leshort		0x32		v5.0
->0	leshort		0x33		v5.1
->0	leshort		0x34		v5.2
->0	leshort		0x3d		v6.1
->0	leshort		0x3e		v6.2
->0	leshort		0x3f		v6.3
->0	default		x
->>0	leshort		x		v?[%#x]
+# The lower byte indicates the ZIP version of this file. The value/10 indicates
+# the major version number, and the value mod 10 is the minor version number.
+>0	ubyte/10	x		v%u
+>0	ubyte%10	x		\b.%u
+# >0	leshort		0x09		v0.9
+# >0	leshort		0x0a		v1.0
+# >0	leshort		0x0b		v1.1
+# >0	leshort		0x14		v2.0
+# >0	leshort		0x15		v2.1
+# >0	leshort		0x19		v2.5
+# >0	leshort		0x1b		v2.7
+# >0	leshort		0x2d		v4.5
+# >0	leshort		0x2e		v4.6
+# >0	leshort		0x32		v5.0
+# >0	leshort		0x33		v5.1
+# >0	leshort		0x34		v5.2
+# >0	leshort		0x3d		v6.1
+# >0	leshort		0x3e		v6.2
+# >0	leshort		0x3f		v6.3
+# >0	default		x
+# >>0	leshort		x		v?[%#x]
+
+#	display compatible host system name of ZIP archive
+0	name		ziphost
+# The upper byte indicates the compatibility of the file attribute information.
+# If the file is compatible with MS-DOS (v 2.04g) then this value will be zero.
+#>1	ubyte		0		DOS
+>1	ubyte		1 		Amiga
+>1	ubyte		2		OpenVMS
+>1	ubyte		3		UNIX
+>1	ubyte		4		VM/CMS
+>1	ubyte		6		OS/2
+>1	ubyte		7		Macintosh
+>1	ubyte		11		MVS
+>1	ubyte		13		Acorn Risc
+>1	ubyte		16		BeOS
+>1	ubyte		17		Tandem
+# 9 untested
+>1	ubyte		5		Atari ST
+>1	ubyte		8		Z-System
+>1	ubyte		9		CP/M
+>1	ubyte		10		Windows NTFS
+>1	ubyte		12		VSE
+>1	ubyte		14		VFAT
+>1	ubyte		15		alternate MVS
+>1	ubyte		18		OS/400
+>1	ubyte		19		OS X
+# unused
+#>1	ubyte		>19		unused 0x%x
 
 # Zip End Of Central Directory record
 -22	string		PK\005\006

+ 7 - 1
magic/Makefile.am

@@ -1,5 +1,5 @@
 #
-# $File: Makefile.am,v 1.151 2019/11/02 18:37:58 christos Exp $
+# $File: Makefile.am,v 1.157 2020/05/21 16:22:47 christos Exp $
 #
 MAGIC_FRAGMENT_BASE = Magdir
 MAGIC_DIR = $(top_srcdir)/magic
@@ -28,6 +28,7 @@ $(MAGIC_FRAGMENT_DIR)/application \
 $(MAGIC_FRAGMENT_DIR)/applix \
 $(MAGIC_FRAGMENT_DIR)/apt \
 $(MAGIC_FRAGMENT_DIR)/archive \
+$(MAGIC_FRAGMENT_DIR)/asf \
 $(MAGIC_FRAGMENT_DIR)/assembler \
 $(MAGIC_FRAGMENT_DIR)/asterix \
 $(MAGIC_FRAGMENT_DIR)/att3b \
@@ -78,6 +79,7 @@ $(MAGIC_FRAGMENT_DIR)/dataone \
 $(MAGIC_FRAGMENT_DIR)/dbpf \
 $(MAGIC_FRAGMENT_DIR)/der \
 $(MAGIC_FRAGMENT_DIR)/diamond \
+$(MAGIC_FRAGMENT_DIR)/dif \
 $(MAGIC_FRAGMENT_DIR)/diff \
 $(MAGIC_FRAGMENT_DIR)/digital \
 $(MAGIC_FRAGMENT_DIR)/dolby \
@@ -271,6 +273,7 @@ $(MAGIC_FRAGMENT_DIR)/sql \
 $(MAGIC_FRAGMENT_DIR)/ssh \
 $(MAGIC_FRAGMENT_DIR)/ssl \
 $(MAGIC_FRAGMENT_DIR)/sun \
+$(MAGIC_FRAGMENT_DIR)/sylk \
 $(MAGIC_FRAGMENT_DIR)/symbos \
 $(MAGIC_FRAGMENT_DIR)/sysex \
 $(MAGIC_FRAGMENT_DIR)/tcl \
@@ -285,7 +288,9 @@ $(MAGIC_FRAGMENT_DIR)/troff \
 $(MAGIC_FRAGMENT_DIR)/tuxedo \
 $(MAGIC_FRAGMENT_DIR)/typeset \
 $(MAGIC_FRAGMENT_DIR)/unicode \
+$(MAGIC_FRAGMENT_DIR)/unisig \
 $(MAGIC_FRAGMENT_DIR)/unknown \
+$(MAGIC_FRAGMENT_DIR)/usd \
 $(MAGIC_FRAGMENT_DIR)/uterus \
 $(MAGIC_FRAGMENT_DIR)/uuencode \
 $(MAGIC_FRAGMENT_DIR)/vacuum-cleaner \
@@ -301,6 +306,7 @@ $(MAGIC_FRAGMENT_DIR)/vmware \
 $(MAGIC_FRAGMENT_DIR)/vorbis \
 $(MAGIC_FRAGMENT_DIR)/vxl \
 $(MAGIC_FRAGMENT_DIR)/warc \
+$(MAGIC_FRAGMENT_DIR)/web \
 $(MAGIC_FRAGMENT_DIR)/weak \
 $(MAGIC_FRAGMENT_DIR)/webassembly \
 $(MAGIC_FRAGMENT_DIR)/windows \

+ 7 - 1
magic/Makefile.in

@@ -274,7 +274,7 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 
 #
-# $File: Makefile.am,v 1.151 2019/11/02 18:37:58 christos Exp $
+# $File: Makefile.am,v 1.157 2020/05/21 16:22:47 christos Exp $
 #
 MAGIC_FRAGMENT_BASE = Magdir
 MAGIC_DIR = $(top_srcdir)/magic
@@ -301,6 +301,7 @@ $(MAGIC_FRAGMENT_DIR)/application \
 $(MAGIC_FRAGMENT_DIR)/applix \
 $(MAGIC_FRAGMENT_DIR)/apt \
 $(MAGIC_FRAGMENT_DIR)/archive \
+$(MAGIC_FRAGMENT_DIR)/asf \
 $(MAGIC_FRAGMENT_DIR)/assembler \
 $(MAGIC_FRAGMENT_DIR)/asterix \
 $(MAGIC_FRAGMENT_DIR)/att3b \
@@ -351,6 +352,7 @@ $(MAGIC_FRAGMENT_DIR)/dataone \
 $(MAGIC_FRAGMENT_DIR)/dbpf \
 $(MAGIC_FRAGMENT_DIR)/der \
 $(MAGIC_FRAGMENT_DIR)/diamond \
+$(MAGIC_FRAGMENT_DIR)/dif \
 $(MAGIC_FRAGMENT_DIR)/diff \
 $(MAGIC_FRAGMENT_DIR)/digital \
 $(MAGIC_FRAGMENT_DIR)/dolby \
@@ -544,6 +546,7 @@ $(MAGIC_FRAGMENT_DIR)/sql \
 $(MAGIC_FRAGMENT_DIR)/ssh \
 $(MAGIC_FRAGMENT_DIR)/ssl \
 $(MAGIC_FRAGMENT_DIR)/sun \
+$(MAGIC_FRAGMENT_DIR)/sylk \
 $(MAGIC_FRAGMENT_DIR)/symbos \
 $(MAGIC_FRAGMENT_DIR)/sysex \
 $(MAGIC_FRAGMENT_DIR)/tcl \
@@ -558,7 +561,9 @@ $(MAGIC_FRAGMENT_DIR)/troff \
 $(MAGIC_FRAGMENT_DIR)/tuxedo \
 $(MAGIC_FRAGMENT_DIR)/typeset \
 $(MAGIC_FRAGMENT_DIR)/unicode \
+$(MAGIC_FRAGMENT_DIR)/unisig \
 $(MAGIC_FRAGMENT_DIR)/unknown \
+$(MAGIC_FRAGMENT_DIR)/usd \
 $(MAGIC_FRAGMENT_DIR)/uterus \
 $(MAGIC_FRAGMENT_DIR)/uuencode \
 $(MAGIC_FRAGMENT_DIR)/vacuum-cleaner \
@@ -574,6 +579,7 @@ $(MAGIC_FRAGMENT_DIR)/vmware \
 $(MAGIC_FRAGMENT_DIR)/vorbis \
 $(MAGIC_FRAGMENT_DIR)/vxl \
 $(MAGIC_FRAGMENT_DIR)/warc \
+$(MAGIC_FRAGMENT_DIR)/web \
 $(MAGIC_FRAGMENT_DIR)/weak \
 $(MAGIC_FRAGMENT_DIR)/webassembly \
 $(MAGIC_FRAGMENT_DIR)/windows \

+ 108 - 44
src/apprentice.c

@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.284 2019/06/29 22:31:04 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.297 2020/05/09 18:57:15 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -120,6 +120,7 @@ private void apprentice_list(struct mlist *, int );
 private struct magic_map *apprentice_load(struct magic_set *,
     const char *, int);
 private struct mlist *mlist_alloc(void);
+private void mlist_free_all(struct magic_set *);
 private void mlist_free(struct mlist *);
 private void byteswap(struct magic *, uint32_t);
 private void bs1(struct magic *);
@@ -137,10 +138,14 @@ private int apprentice_compile(struct magic_set *, struct magic_map *,
 private int check_format_type(const char *, int, const char **);
 private int check_format(struct magic_set *, struct magic *);
 private int get_op(char);
-private int parse_mime(struct magic_set *, struct magic_entry *, const char *);
-private int parse_strength(struct magic_set *, struct magic_entry *, const char *);
-private int parse_apple(struct magic_set *, struct magic_entry *, const char *);
-private int parse_ext(struct magic_set *, struct magic_entry *, const char *);
+private int parse_mime(struct magic_set *, struct magic_entry *, const char *,
+    size_t);
+private int parse_strength(struct magic_set *, struct magic_entry *,
+    const char *, size_t);
+private int parse_apple(struct magic_set *, struct magic_entry *, const char *,
+    size_t);
+private int parse_ext(struct magic_set *, struct magic_entry *, const char *,
+    size_t);
 
 
 private size_t magicsize = sizeof(struct magic);
@@ -150,7 +155,8 @@ private const char usg_hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc";
 private struct {
 	const char *name;
 	size_t len;
-	int (*fun)(struct magic_set *, struct magic_entry *, const char *);
+	int (*fun)(struct magic_set *, struct magic_entry *, const char *,
+	    size_t);
 } bang[] = {
 #define	DECLARE_FIELD(name) { # name, sizeof(# name) - 1, parse_ ## name }
 	DECLARE_FIELD(mime),
@@ -260,6 +266,8 @@ static const struct type_tbl_s type_tbl[] = {
 	{ XX("use"),		FILE_USE,		FILE_FMT_NONE },
 	{ XX("clear"),		FILE_CLEAR,		FILE_FMT_NONE },
 	{ XX("der"),		FILE_DER,		FILE_FMT_STR },
+	{ XX("guid"),		FILE_GUID,		FILE_FMT_STR },
+	{ XX("offset"),		FILE_OFFSET,		FILE_FMT_QUAD },
 	{ XX_NULL,		FILE_INVALID,		FILE_FMT_NONE },
 };
 
@@ -451,8 +459,6 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
 
 #ifndef COMPILE_ONLY
 	map = apprentice_map(ms, fn);
-	if (map == RCAST(struct magic_map *, -1))
-		return -1;
 	if (map == NULL) {
 		if (ms->flags & MAGIC_CHECK)
 			file_magwarn(ms, "using regular magic file `%s'", fn);
@@ -463,6 +469,11 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
 
 	for (i = 0; i < MAGIC_SETS; i++) {
 		if (add_mlist(ms->mlist[i], map, i) == -1) {
+			/* failed to add to any list, free explicitly */
+			if (i == 0)
+				apprentice_unmap(map);
+			else
+				mlist_free_all(ms);
 			file_oomem(ms, sizeof(*ml));
 			return -1;
 		}
@@ -513,6 +524,7 @@ file_ms_alloc(int flags)
 	}
 
 	ms->o.buf = ms->o.pbuf = NULL;
+	ms->o.blen = 0;
 	len = (ms->c.len = 10) * sizeof(*ms->c.li);
 
 	if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL)
@@ -582,6 +594,17 @@ mlist_alloc(void)
 }
 
 private void
+mlist_free_all(struct magic_set *ms)
+{
+	size_t i;
+
+	for (i = 0; i < MAGIC_SETS; i++) {
+		mlist_free(ms->mlist[i]);
+		ms->mlist[i] = NULL;
+	}
+}
+
+private void
 mlist_free_one(struct mlist *ml)
 {
 	if (ml->map)
@@ -597,9 +620,10 @@ mlist_free(struct mlist *mlist)
 	if (mlist == NULL)
 		return;
 
-	for (ml = mlist->next; ml != mlist; ml = next) {
+	for (ml = mlist->next; ml != mlist;) {
 		next = ml->next;
 		mlist_free_one(ml);
+		ml = next;
 	}
 	mlist_free_one(mlist);
 }
@@ -644,10 +668,7 @@ buffer_apprentice(struct magic_set *ms, struct magic **bufs,
 
 	return 0;
 fail:
-	for (i = 0; i < MAGIC_SETS; i++) {
-		mlist_free(ms->mlist[i]);
-		ms->mlist[i] = NULL;
-	}
+	mlist_free_all(ms);
 	return -1;
 }
 #endif
@@ -658,7 +679,7 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
 {
 	char *p, *mfn;
 	int fileerr, errs = -1;
-	size_t i;
+	size_t i, j;
 
 	(void)file_reset(ms, 0);
 
@@ -676,9 +697,9 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
 		mlist_free(ms->mlist[i]);
 		if ((ms->mlist[i] = mlist_alloc()) == NULL) {
 			file_oomem(ms, sizeof(*ms->mlist[i]));
-			while (i-- > 0) {
-				mlist_free(ms->mlist[i]);
-				ms->mlist[i] = NULL;
+			for (j = 0; j < i; j++) {
+				mlist_free(ms->mlist[j]);
+				ms->mlist[j] = NULL;
 			}
 			free(mfn);
 			return -1;
@@ -829,9 +850,14 @@ typesize(int type)
 	case FILE_DOUBLE:
 	case FILE_BEDOUBLE:
 	case FILE_LEDOUBLE:
+	case FILE_OFFSET:
 		return 8;
+
+	case FILE_GUID:
+		return 16;
+
 	default:
-		return CAST(size_t, ~0);
+		return FILE_BADSIZE;
 	}
 }
 
@@ -885,8 +911,10 @@ apprentice_magic_strength(const struct magic *m)
 	case FILE_DOUBLE:
 	case FILE_BEDOUBLE:
 	case FILE_LEDOUBLE:
+	case FILE_GUID:
+	case FILE_OFFSET:
 		ts = typesize(m->type);
-		if (ts == CAST(size_t, ~0))
+		if (ts == FILE_BADSIZE)
 			abort();
 		val += ts * MULT;
 		break;
@@ -1077,6 +1105,8 @@ set_test_type(struct magic *mstart, struct magic *m)
 	case FILE_BEDOUBLE:
 	case FILE_LEDOUBLE:
 	case FILE_DER:
+	case FILE_GUID:
+	case FILE_OFFSET:
 		mstart->flag |= BINTEST;
 		break;
 	case FILE_STRING:
@@ -1201,7 +1231,8 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
 					continue;
 				}
 				if ((*bang[i].fun)(ms, &me,
-				    line + bang[i].len + 2) != 0) {
+				    line + bang[i].len + 2, 
+				    len - bang[i].len - 2) != 0) {
 					(*errs)++;
 					continue;
 				}
@@ -1381,9 +1412,10 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
 			}
 			if (files >= maxfiles) {
 				size_t mlen;
+				char **nfilearr;
 				maxfiles = (maxfiles + 1) * 2;
 				mlen = maxfiles * sizeof(*filearr);
-				if ((filearr = CAST(char **,
+				if ((nfilearr = CAST(char **,
 				    realloc(filearr, mlen))) == NULL) {
 					file_oomem(ms, mlen);
 					free(mfn);
@@ -1391,6 +1423,7 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
 					errs++;
 					goto out;
 				}
+				filearr = nfilearr;
 			}
 			filearr[files++] = mfn;
 		}
@@ -1402,6 +1435,7 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
 				free(filearr[i]);
 			}
 			free(filearr);
+			filearr = NULL;
 		}
 	} else
 		load_1(ms, action, fn, &errs, mset);
@@ -1436,6 +1470,7 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
 	}
 
 out:
+	free(filearr);
 	for (j = 0; j < MAGIC_SETS; j++)
 		magic_entry_free(mset[j].me, mset[j].count);
 
@@ -1499,6 +1534,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
 		case FILE_DOUBLE:
 		case FILE_BEDOUBLE:
 		case FILE_LEDOUBLE:
+		case FILE_OFFSET:
 			v = CAST(int64_t, v);
 			break;
 		case FILE_STRING:
@@ -1513,12 +1549,13 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
 		case FILE_USE:
 		case FILE_CLEAR:
 		case FILE_DER:
+		case FILE_GUID:
 			break;
 		default:
 			if (ms->flags & MAGIC_CHECK)
 			    file_magwarn(ms, "cannot happen: m->type=%d\n",
 				    m->type);
-			return ~0U;
+			return FILE_BADSIZE;
 		}
 	}
 	return v;
@@ -1920,6 +1957,10 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
 	}
 
 	/* get offset, then skip over it */
+	if (*l == '-') {
+		++l;            /* step over */
+		m->flag |= OFFNEGATIVE;
+	}
 	m->offset = CAST(int32_t, strtol(l, &t, 0));
         if (l == t) {
 		if (ms->flags & MAGIC_CHECK)
@@ -2224,7 +2265,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
  * if valid
  */
 private int
-parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line)
+parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line,
+    size_t len __attribute__((__unused__)))
 {
 	const char *l = line;
 	char *el;
@@ -2286,7 +2328,8 @@ goodchar(unsigned char x, const char *extra)
 
 private int
 parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
-    off_t off, size_t len, const char *name, const char *extra, int nt)
+    size_t llen, off_t off, size_t len, const char *name, const char *extra,
+    int nt)
 {
 	size_t i;
 	const char *l = line;
@@ -2307,7 +2350,8 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
 	}
 
 	EATAB;
-	for (i = 0; *l && i < len && goodchar(*l, extra); buf[i++] = *l++)
+	for (i = 0; *l && i < llen && i < len && goodchar(*l, extra);
+	    buf[i++] = *l++)
 		continue;
 
 	if (i == len && *l) {
@@ -2336,11 +2380,12 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
  * magic[index - 1]
  */
 private int
-parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line)
+parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line,
+    size_t len)
 {
 	struct magic *m = &me->mp[0];
 
-	return parse_extra(ms, me, line,
+	return parse_extra(ms, me, line, len,
 	    CAST(off_t, offsetof(struct magic, apple)),
 	    sizeof(m->apple), "APPLE", "!+-./?", 0);
 }
@@ -2349,11 +2394,12 @@ parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line)
  * Parse a comma-separated list of extensions
  */
 private int
-parse_ext(struct magic_set *ms, struct magic_entry *me, const char *line)
+parse_ext(struct magic_set *ms, struct magic_entry *me, const char *line,
+    size_t len)
 {
 	struct magic *m = &me->mp[0];
 
-	return parse_extra(ms, me, line,
+	return parse_extra(ms, me, line, len,
 	    CAST(off_t, offsetof(struct magic, ext)),
 	    sizeof(m->ext), "EXTENSION", ",!+-/@?_$", 0);
 }
@@ -2363,11 +2409,12 @@ parse_ext(struct magic_set *ms, struct magic_entry *me, const char *line)
  * if valid
  */
 private int
-parse_mime(struct magic_set *ms, struct magic_entry *me, const char *line)
+parse_mime(struct magic_set *ms, struct magic_entry *me, const char *line,
+    size_t len)
 {
 	struct magic *m = &me->mp[0];
 
-	return parse_extra(ms, me, line,
+	return parse_extra(ms, me, line, len,
 	    CAST(off_t, offsetof(struct magic, mimetype)),
 	    sizeof(m->mimetype), "MIME", "+-/.$?:{}", 1);
 }
@@ -2684,6 +2731,11 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
 		if (errno == 0)
 			*p = ep;
 		return 0;
+	case FILE_GUID:
+		if (file_parse_guid(*p, m->value.guid) == -1)
+			return -1;
+		*p += FILE_GUID_SIZE - 1;
+		return 0;
 	default:
 		errno = 0;
 		ull = CAST(uint64_t, strtoull(*p, &ep, 0));
@@ -2695,7 +2747,7 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
 			uint64_t x;
 			const char *q;
 
-			if (ts == CAST(size_t, ~0)) {
+			if (ts == FILE_BADSIZE) {
 				file_magwarn(ms,
 				    "Expected numeric type got `%s'",
 				    type_tbl[m->type].name);
@@ -2892,8 +2944,12 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
 out:
 	*p = '\0';
 	m->vallen = CAST(unsigned char, (p - origp));
-	if (m->type == FILE_PSTRING)
-		m->vallen += CAST(unsigned char, file_pstring_length_size(m));
+	if (m->type == FILE_PSTRING) {
+		size_t l =  file_pstring_length_size(ms, m);
+		if (l == FILE_BADSIZE)
+			return NULL;
+		m->vallen += CAST(unsigned char, l);
+	}
 	return s;
 }
 
@@ -2923,7 +2979,7 @@ file_showstr(FILE *fp, const char *s, size_t len)
 	char	c;
 
 	for (;;) {
-		if (len == ~0U) {
+		if (len == FILE_BADSIZE) {
 			c = *s++;
 			if (c == '\0')
 				break;
@@ -3077,13 +3133,11 @@ apprentice_map(struct magic_set *ms, const char *fn)
 		file_badread(ms);
 		goto error;
 	}
-#define RET	1
 #endif
 	(void)close(fd);
 	fd = -1;
 
 	if (check_buffer(ms, map, dbname) != 0) {
-		rv = RCAST(struct magic_map *, -1);
 		goto error;
 	}
 #ifdef QUICK
@@ -3357,7 +3411,7 @@ bs1(struct magic *m)
 }
 
 protected size_t
-file_pstring_length_size(const struct magic *m)
+file_pstring_length_size(struct magic_set *ms, const struct magic *m)
 {
 	switch (m->str_flags & PSTRING_LEN) {
 	case PSTRING_1_LE:
@@ -3369,12 +3423,15 @@ file_pstring_length_size(const struct magic *m)
 	case PSTRING_4_BE:
 		return 4;
 	default:
-		abort();	/* Impossible */
-		return 1;
+		file_error(ms, 0, "corrupt magic file "
+		    "(bad pascal string length %d)",
+		    m->str_flags & PSTRING_LEN);
+		return FILE_BADSIZE;
 	}
 }
 protected size_t
-file_pstring_get_length(const struct magic *m, const char *ss)
+file_pstring_get_length(struct magic_set *ms, const struct magic *m,
+    const char *ss)
 {
 	size_t len = 0;
 	const unsigned char *s = RCAST(const unsigned char *, ss);
@@ -3409,11 +3466,18 @@ file_pstring_get_length(const struct magic *m, const char *ss)
 		len = (s0 << 24) | (s1 << 16) | (s2 << 8) | s3;
 		break;
 	default:
-		abort();	/* Impossible */
+		file_error(ms, 0, "corrupt magic file "
+		    "(bad pascal string length %d)",
+		    m->str_flags & PSTRING_LEN);
+		return FILE_BADSIZE;
 	}
 
-	if (m->str_flags & PSTRING_LENGTH_INCLUDES_ITSELF)
-		len -= file_pstring_length_size(m);
+	if (m->str_flags & PSTRING_LENGTH_INCLUDES_ITSELF) {
+		size_t l = file_pstring_length_size(ms, m);
+		if (l == FILE_BADSIZE)
+			return l;
+		len -= l;
+	}
 
 	return len;
 }

+ 6 - 8
src/ascmagic.c

@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: ascmagic.c,v 1.105 2019/06/08 20:49:14 christos Exp $")
+FILE_RCSID("@(#)$File: ascmagic.c,v 1.107 2020/06/08 19:58:36 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -115,7 +115,6 @@ file_ascmagic_with_encoding(struct magic_set *ms,
 	int need_separator = 0;
 
 	const char *subtype = NULL;
-	const char *subtype_mime = NULL;
 
 	int has_escapes = 0;
 	int has_backspace = 0;
@@ -164,8 +163,11 @@ file_ascmagic_with_encoding(struct magic_set *ms,
 			goto done;
 		}
 	}
-	if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)))
-		return 0;
+
+	if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))) {
+		rv = 0;
+		goto done;
+	}
 
 	/* Now try to discover other details about the file. */
 	for (i = 0; i < ulen; i++) {
@@ -222,10 +224,6 @@ file_ascmagic_with_encoding(struct magic_set *ms,
 				}
 				if (need_separator && file_separator(ms) == -1)
 					goto done;
-			}
-			if (subtype_mime) {
-				if (file_printf(ms, "%s", subtype_mime) == -1)
-					goto done;
 			} else {
 				if (file_printf(ms, "text/plain") == -1)
 					goto done;

+ 3 - 3
src/buffer.c

@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: buffer.c,v 1.7 2019/06/10 21:35:26 christos Exp $")
+FILE_RCSID("@(#)$File: buffer.c,v 1.8 2020/02/16 15:52:49 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -64,7 +64,7 @@ buffer_fill(const struct buffer *bb)
 	struct buffer *b = CCAST(struct buffer *, bb);
 
 	if (b->elen != 0)
-		return b->elen == CAST(size_t, ~0) ? -1 : 0;
+		return b->elen == FILE_BADSIZE ? -1 : 0;
 
 	if (!S_ISREG(b->st.st_mode))
 		goto out;
@@ -83,6 +83,6 @@ buffer_fill(const struct buffer *bb)
 
 	return 0;
 out:
-	b->elen = CAST(size_t, ~0);
+	b->elen = FILE_BADSIZE;
 	return -1;
 }

+ 29 - 27
src/compress.c

@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: compress.c,v 1.124 2019/07/21 11:42:09 christos Exp $")
+FILE_RCSID("@(#)$File: compress.c,v 1.127 2020/05/31 00:11:06 christos Exp $")
 #endif
 
 #include "magic.h"
@@ -51,7 +51,7 @@ FILE_RCSID("@(#)$File: compress.c,v 1.124 2019/07/21 11:42:09 christos Exp $")
 #ifndef HAVE_SIG_T
 typedef void (*sig_t)(int);
 #endif /* HAVE_SIG_T */
-#if !defined(__MINGW32__) && !defined(WIN32)
+#if !defined(__MINGW32__) && !defined(WIN32) && !defined(__MINGW64__)
 #include <sys/ioctl.h>
 #endif
 #ifdef HAVE_SYS_WAIT_H
@@ -66,12 +66,12 @@ typedef void (*sig_t)(int);
 #include <zlib.h>
 #endif
 
-#if defined(HAVE_BZLIB_H) || defined(BZLIBSUPPORT)
+#if defined(HAVE_BZLIB_H) && defined(BZLIBSUPPORT)
 #define BUILTIN_BZLIB
 #include <bzlib.h>
 #endif
 
-#if defined(HAVE_XZLIB_H) || defined(XZLIBSUPPORT)
+#if defined(HAVE_XZLIB_H) && defined(XZLIBSUPPORT)
 #define BUILTIN_XZLIB
 #include <lzma.h>
 #endif
@@ -161,7 +161,10 @@ static const char *zstd_args[] = {
 #define	do_bzlib	NULL
 
 private const struct {
-	const void *magic;
+	union {
+		const char *magic;
+		int (*func)(const unsigned char *);
+	} u;
 	int maglen;
 	const char **argv;
 	void *unused;
@@ -171,26 +174,26 @@ private const struct {
 #define METH_XZ		9
 #define METH_LZMA	13
 #define METH_ZLIB	14
-	{ "\037\235",	2, gzip_args, NULL },		/* 0, compressed */
-	/* Uncompress can get stuck; so use gzip first if we have it
-	 * Idea from Damien Clark, thanks! */
-	{ "\037\235",	2, uncompress_args, NULL },	/* 1, compressed */
-	{ "\037\213",	2, gzip_args, do_zlib },	/* 2, gzipped */
-	{ "\037\236",	2, gzip_args, NULL },		/* 3, frozen */
-	{ "\037\240",	2, gzip_args, NULL },		/* 4, SCO LZH */
-	/* the standard pack utilities do not accept standard input */
-	{ "\037\036",	2, gzip_args, NULL },		/* 5, packed */
-	{ "PK\3\4",	4, gzip_args, NULL },		/* 6, pkzipped, */
-	/* ...only first file examined */
-	{ "BZh",	3, bzip2_args, do_bzlib },	/* 7, bzip2-ed */
-	{ "LZIP",	4, lzip_args, NULL },		/* 8, lzip-ed */
- 	{ "\3757zXZ\0",	6, xz_args, NULL },		/* 9, XZ Utils */
- 	{ "LRZI",	4, lrzip_args, NULL },	/* 10, LRZIP */
- 	{ "\004\"M\030",4, lz4_args, NULL },		/* 11, LZ4 */
- 	{ "\x28\xB5\x2F\xFD", 4, zstd_args, NULL },	/* 12, zstd */
-	{ RCAST(const void *, lzmacmp),	-13, xz_args, NULL },	/* 13, lzma */
+    { { .magic = "\037\235" },	2, gzip_args, NULL },	/* 0, compressed */
+    /* Uncompress can get stuck; so use gzip first if we have it
+     * Idea from Damien Clark, thanks! */
+    { { .magic = "\037\235" },	2, uncompress_args, NULL },/* 1, compressed */
+    { { .magic = "\037\213" },	2, gzip_args, do_zlib },/* 2, gzipped */
+    { { .magic = "\037\236" },	2, gzip_args, NULL },	/* 3, frozen */
+    { { .magic = "\037\240" },	2, gzip_args, NULL },	/* 4, SCO LZH */
+    /* the standard pack utilities do not accept standard input */
+    { { .magic = "\037\036" },	2, gzip_args, NULL },	/* 5, packed */
+    { { .magic = "PK\3\4" },	4, gzip_args, NULL },	/* 6, pkziped */
+    /* ...only first file examined */
+    { { .magic = "BZh" },	3, bzip2_args, do_bzlib },/* 7, bzip2-ed */
+    { { .magic = "LZIP" },	4, lzip_args, NULL },	/* 8, lzip-ed */
+    { { .magic = "\3757zXZ\0" },6, xz_args, NULL },	/* 9, XZ Util */
+    { { .magic = "LRZI" },	4, lrzip_args, NULL },	/* 10, LRZIP */
+    { { .magic = "\004\"M\030" },4, lz4_args, NULL },	/* 11, LZ4 */
+    { { .magic = "\x28\xB5\x2F\xFD" }, 4, zstd_args, NULL },/* 12, zstd */
+    { { .func = lzmacmp },	-13, xz_args, NULL },	/* 13, lzma */
 #ifdef ZLIBSUPPORT
-	{ RCAST(const void *, zlibcmp),	-2, zlib_args, NULL },	/* 14, zlib */
+    { { .func = zlibcmp },	-2, zlib_args, NULL },	/* 14, zlib */
 #endif
 };
 
@@ -262,10 +265,9 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
 		if (nbytes < CAST(size_t, abs(compr[i].maglen)))
 			continue;
 		if (compr[i].maglen < 0) {
-			zm = (RCAST(int (*)(const unsigned char *),
-			    CCAST(void *, compr[i].magic)))(buf);
+			zm = (*compr[i].u.func)(buf);
 		} else {
-			zm = memcmp(buf, compr[i].magic,
+			zm = memcmp(buf, compr[i].u.magic,
 			    CAST(size_t, compr[i].maglen)) == 0;
 		}
 

+ 58 - 20
src/der.c

@@ -35,8 +35,11 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: der.c,v 1.16 2019/02/20 02:35:27 christos Exp $")
+FILE_RCSID("@(#)$File: der.c,v 1.20 2020/06/07 19:10:37 christos Exp $")
 #endif
+#else
+#define SIZE_T_FORMAT "z"
+#define CAST(a, b) ((a)(b))
 #endif
 
 #include <sys/types.h>
@@ -62,13 +65,13 @@ FILE_RCSID("@(#)$File: der.c,v 1.16 2019/02/20 02:35:27 christos Exp $")
 #define	DER_CLASS_APPLICATION	1
 #define	DER_CLASS_CONTEXT	2
 #define	DER_CLASS_PRIVATE	3
-#ifdef DEBUG_DER
+#if defined(DEBUG_DER) || defined(TEST_DER)
 static const char der_class[] = "UACP";
 #endif
 
 #define DER_TYPE_PRIMITIVE	0
 #define DER_TYPE_CONSTRUCTED	1
-#ifdef DEBUG_DER
+#if defined(DEBUG_DER) || defined(TEST_DER)
 static const char der_type[] = "PC";
 #endif
 
@@ -86,7 +89,7 @@ static const char der_type[] = "PC";
 #define	DER_TAG_EMBEDDED_PDV		0x0b
 #define	DER_TAG_UTF8_STRING		0x0c
 #define	DER_TAG_RELATIVE_OID		0x0d
-#define DER_TAG_RESERVED_1		0x0e
+#define DER_TAG_TIME			0x0e
 #define DER_TAG_RESERVED_2		0x0f
 #define	DER_TAG_SEQUENCE		0x10
 #define	DER_TAG_SET			0x11
@@ -103,16 +106,23 @@ static const char der_type[] = "PC";
 #define	DER_TAG_UNIVERSAL_STRING	0x1c
 #define	DER_TAG_CHARACTER_STRING	0x1d
 #define	DER_TAG_BMP_STRING		0x1e
-#define	DER_TAG_LONG			0x1f
+#define	DER_TAG_DATE			0x1f
+#define	DER_TAG_TIME_OF_DAY		0x20
+#define	DER_TAG_DATE_TIME		0x21
+#define	DER_TAG_DURATION		0x22
+#define	DER_TAG_OID_IRI			0x23
+#define	DER_TAG_RELATIVE_OID_IRI	0x24
+#define	DER_TAG_LAST			0x25
 
 static const char *der__tag[] = {
 	"eoc", "bool", "int", "bit_str", "octet_str",
 	"null", "obj_id", "obj_desc", "ext", "real",
-	"enum", "embed", "utf8_str", "oid", "res1",
+	"enum", "embed", "utf8_str", "rel_oid", "time",
 	"res2", "seq", "set", "num_str", "prt_str",
-	"t61_str", "vid_str", "ia5_str", "utc_time",
-	"gen_time", "gr_str", "vis_str", "gen_str",
-	"char_str", "bmp_str", "long"
+	"t61_str", "vid_str", "ia5_str", "utc_time", "gen_time",
+	"gr_str", "vis_str", "gen_str", "univ_str", "char_str",
+	"bmp_str", "date", "tod", "datetime", "duration",
+	"oid-iri", "rel-oid-iri",
 };
 
 #ifdef DEBUG_DER
@@ -175,8 +185,10 @@ getlength(const uint8_t *c, size_t *p, size_t l)
 	size_t len;
 	int is_onebyte_result;
 
-	if (*p >= l)
+	if (*p >= l) {
+		DPRINTF(("%s:[1] %zu >= %zu\n", __func__, *p, l));
 		return DER_BAD;
+	}
 
 	/*
 	 * Digits can either be 0b0 followed by the result, or 0b1
@@ -185,8 +197,10 @@ getlength(const uint8_t *c, size_t *p, size_t l)
 	 */
 	is_onebyte_result = (c[*p] & 0x80) == 0;
 	digits = c[(*p)++] & 0x7f;
-	if (*p + digits >= l)
+	if (*p + digits >= l) {
+		DPRINTF(("%s:[2] %zu + %u >= %zu\n", __func__, *p, digits, l));
 		return DER_BAD;
+	}
 
 	if (is_onebyte_result)
 		return digits;
@@ -199,15 +213,18 @@ getlength(const uint8_t *c, size_t *p, size_t l)
 	for (i = 0; i < digits; i++)
 		len = (len << 8) | c[(*p)++];
 
-	if (len > UINT32_MAX - *p || *p + len >= l)
+	if (len > UINT32_MAX - *p || *p + len > l) {
+		DPRINTF(("%s:[3] bad len %zu + %zu >= %zu\n",
+		    __func__, *p, len, l));
 		return DER_BAD;
+	}
 	return CAST(uint32_t, len);
 }
 
 static const char *
 der_tag(char *buf, size_t len, uint32_t tag)
 {
-	if (tag < DER_TAG_LONG)
+	if (tag < DER_TAG_LAST)
 		strlcpy(buf, der__tag[tag], len);
 	else
 		snprintf(buf, len, "%#x", tag);
@@ -223,8 +240,14 @@ der_data(char *buf, size_t blen, uint32_t tag, const void *q, uint32_t len)
 	case DER_TAG_PRINTABLE_STRING:
 	case DER_TAG_UTF8_STRING:
 	case DER_TAG_IA5_STRING:
-	case DER_TAG_UTCTIME:
 		return snprintf(buf, blen, "%.*s", len, RCAST(const char *, q));
+	case DER_TAG_UTCTIME:
+		if (len < 12)
+			break;
+		return snprintf(buf, blen,
+		    "20%c%c-%c%c-%c%c %c%c:%c%c:%c%c GMT", d[0], d[1], d[2],
+		    d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11]);
+		break;
 	default:
 		break;
 	}
@@ -243,14 +266,18 @@ der_offs(struct magic_set *ms, struct magic *m, size_t nbytes)
 	const uint8_t *b = RCAST(const uint8_t *, ms->search.s);
 	size_t offs = 0, len = ms->search.s_len ? ms->search.s_len : nbytes;
 
-	if (gettag(b, &offs, len) == DER_BAD)
+	if (gettag(b, &offs, len) == DER_BAD) {
+		DPRINTF(("%s: bad tag 1\n", __func__));
 		return -1;
+	}
 	DPRINTF(("%s1: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset,
 	    offs, m->offset));
 
 	uint32_t tlen = getlength(b, &offs, len);
-	if (tlen == DER_BAD)
+	if (tlen == DER_BAD) {
+		DPRINTF(("%s: bad tag 2\n", __func__));
 		return -1;
+	}
 	DPRINTF(("%s2: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset,
 	    offs, tlen));
 
@@ -280,13 +307,22 @@ der_cmp(struct magic_set *ms, struct magic *m)
 	uint32_t tag, tlen;
 	char buf[128];
 
+	DPRINTF(("%s: compare %zu bytes\n", __func__, len));
+
 	tag = gettag(b, &offs, len);
-	if (tag == DER_BAD)
+	if (tag == DER_BAD) {
+		DPRINTF(("%s: bad tag 1\n", __func__));
 		return -1;
+	}
+
+	DPRINTF(("%s1: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset,
+	    offs, m->offset));
 
 	tlen = getlength(b, &offs, len);
-	if (tlen == DER_BAD)
+	if (tlen == DER_BAD) {
+		DPRINTF(("%s: bad tag 2\n", __func__));
 		return -1;
+	}
 
 	der_tag(buf, sizeof(buf), tag);
 	if ((ms->flags & MAGIC_DEBUG) != 0)
@@ -342,6 +378,8 @@ printtag(uint32_t tag, const void *q, uint32_t len)
 	switch (tag) {
 	case DER_TAG_PRINTABLE_STRING:
 	case DER_TAG_UTF8_STRING:
+	case DER_TAG_IA5_STRING:
+	case DER_TAG_UTCTIME:
 		printf("%.*s\n", len, (const char *)q);
 		return;
 	default:
@@ -365,8 +403,8 @@ printdata(size_t level, const void *v, size_t x, size_t l)
 		uint8_t c = getclass(p[x]);
 		uint8_t t = gettype(p[x]);
 		ox = x;
-		if (x != 0)
-		printf("%.2x %.2x %.2x\n", p[x - 1], p[x], p[x + 1]);
+//		if (x != 0)
+//		printf("%.2x %.2x %.2x\n", p[x - 1], p[x], p[x + 1]);
 		uint32_t tag = gettag(p, &x, ep - p + x);
 		if (p + x >= ep)
 			break;

+ 63 - 27
src/file.c

@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: file.c,v 1.184 2019/08/03 11:51:59 christos Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.187 2020/06/07 17:38:30 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -83,7 +83,8 @@ int getopt_long(int, char * const *, const char *,
     "Usage: %s [-" FILE_FLAGS "] [--apple] [--extension] [--mime-encoding]\n" \
     "            [--mime-type] [-e <testname>] [-F <separator>] " \
     " [-f <namefile>]\n" \
-    "            [-m <magicfiles>] [-P <parameter=value>] <file> ...\n" \
+    "            [-m <magicfiles>] [-P <parameter=value>] [--exclude-quiet]\n" \
+    "            <file> ...\n" \
     "       %s -C [-m <magicfiles>]\n" \
     "       %s [--help]\n"
 
@@ -100,9 +101,10 @@ private const struct option long_options[] = {
 #define OPT_EXTENSIONS		3
 #define OPT_MIME_TYPE		4
 #define OPT_MIME_ENCODING	5
-#define OPT(shortname, longname, opt, def, doc)      \
+#define OPT_EXCLUDE_QUIET	6
+#define OPT(shortname, longname, opt, def, doc)		\
     {longname, opt, NULL, shortname},
-#define OPT_LONGONLY(longname, opt, def, doc, id)        \
+#define OPT_LONGONLY(longname, opt, def, doc, id)	\
     {longname, opt, NULL, id},
 #include "file_opts.h"
 #undef OPT
@@ -133,14 +135,23 @@ private struct {
 	int tag;
 	size_t value;
 	int set;
+	size_t def;
+	const char *desc;
 } pm[] = {
-	{ "indir",	MAGIC_PARAM_INDIR_MAX, 0, 0 },
-	{ "name",	MAGIC_PARAM_NAME_MAX, 0, 0 },
-	{ "elf_phnum",	MAGIC_PARAM_ELF_PHNUM_MAX, 0, 0 },
-	{ "elf_shnum",	MAGIC_PARAM_ELF_SHNUM_MAX, 0, 0 },
-	{ "elf_notes",	MAGIC_PARAM_ELF_NOTES_MAX, 0, 0 },
-	{ "regex",	MAGIC_PARAM_REGEX_MAX, 0, 0 },
-	{ "bytes",	MAGIC_PARAM_BYTES_MAX, 0, 0 },
+	{ "bytes",	MAGIC_PARAM_BYTES_MAX, 0, 0, FILE_BYTES_MAX,
+	    "max bytes to look inside file" },
+	{ "elf_notes",	MAGIC_PARAM_ELF_NOTES_MAX, 0, 0, FILE_ELF_NOTES_MAX,
+	    "max ELF notes processed" },
+	{ "elf_phnum",	MAGIC_PARAM_ELF_PHNUM_MAX, 0, 0, FILE_ELF_PHNUM_MAX,
+	    "max ELF prog sections processed" },
+	{ "elf_shnum",	MAGIC_PARAM_ELF_SHNUM_MAX, 0, 0, FILE_ELF_SHNUM_MAX,
+	    "max ELF sections processed" },
+	{ "indir",	MAGIC_PARAM_INDIR_MAX, 0, 0, FILE_INDIR_MAX,
+	    "recursion limit for indirection" },
+	{ "name",	MAGIC_PARAM_NAME_MAX, 0, 0, FILE_NAME_MAX,
+	    "use limit for name/use magic" },
+	{ "regex",	MAGIC_PARAM_REGEX_MAX, 0, 0, FILE_REGEX_MAX,
+	    "length limit for REGEX searches" },
 };
 
 private int posixly;
@@ -237,13 +248,15 @@ main(int argc, char *argv[])
 			flags |= MAGIC_ERROR;
 			break;
 		case 'e':
+		case OPT_EXCLUDE_QUIET:
 			for (i = 0; i < __arraycount(nv); i++)
 				if (strcmp(nv[i].name, optarg) == 0)
 					break;
 
-			if (i == __arraycount(nv))
-				errflg++;
-			else
+			if (i == __arraycount(nv)) {
+				if (c != OPT_EXCLUDE_QUIET)
+					errflg++;
+			} else
 				flags |= nv[i].value;
 			break;
 
@@ -609,10 +622,10 @@ private void
 docprint(const char *opts, int def)
 {
 	size_t i;
-	int comma;
+	int comma, pad;
 	char *sp, *p;
 
-	p = strstr(opts, "%o");
+	p = strchr(opts, '%');
 	if (p == NULL) {
 		fprintf(stdout, "%s", opts);
 		defprint(def);
@@ -623,17 +636,34 @@ docprint(const char *opts, int def)
 		continue;
 
 	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", CAST(int, p - sp - 1), "");
-			comma = 0;
+	pad = (int)CAST(int, p - sp - 1);
+
+	switch (*++p) {
+	case 'e':
+		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", pad, "");
+				comma = 0;
+			}
+		}
+		break;
+	case 'P':
+		for (i = 0; i < __arraycount(pm); i++) {
+			fprintf(stdout, "%9s %7zu %s", pm[i].name, pm[i].def,
+			    pm[i].desc);
+			if (i != __arraycount(pm) - 1)
+				fprintf(stdout, "\n%*s", pad, "");
 		}
+		break;
+	default:
+		file_errx(EXIT_FAILURE, "Unknown escape `%c' in long options",
+		   *p);
+		break;
 	}
+	fprintf(stdout, "%s", opts + (p - opts) + 1);
 
-	fprintf(stdout, "%s", opts + (p - opts) + 2);
 }
 
 private void
@@ -646,7 +676,7 @@ help(void)
 #define OPT(shortname, longname, opt, def, doc)      \
 	fprintf(stdout, "  -%c, --" longname, shortname), \
 	docprint(doc, def);
-#define OPT_LONGONLY(longname, opt, def, doc, id)        \
+#define OPT_LONGONLY(longname, opt, def, doc, id)    	\
 	fprintf(stdout, "      --" longname),	\
 	docprint(doc, def);
 #include "file_opts.h"
@@ -680,7 +710,10 @@ file_err(int e, const char *fmt, ...)
 	fprintf(stderr, "%s: ", file_progname);
 	vfprintf(stderr, fmt, ap);
 	va_end(ap);
-	fprintf(stderr, " (%s)\n", strerror(se));
+	if (se)
+		fprintf(stderr, " (%s)\n", strerror(se));
+	else
+		fputc('\n', stderr);
 	exit(e);
 }
 
@@ -707,7 +740,10 @@ file_warn(const char *fmt, ...)
 	fprintf(stderr, "%s: ", file_progname);
 	vfprintf(stderr, fmt, ap);
 	va_end(ap);
-	fprintf(stderr, " (%s)\n", strerror(se));
+	if (se)
+		fprintf(stderr, " (%s)\n", strerror(se));
+	else
+		fputc('\n', stderr);
 	errno = se;
 }
 

+ 60 - 34
src/file.h

@@ -27,7 +27,7 @@
  */
 /*
  * file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.208 2019/06/26 20:31:31 christos Exp $
+ * @(#)$File: file.h,v 1.220 2020/06/08 17:38:27 christos Exp $
  */
 
 #ifndef __file_h__
@@ -36,7 +36,15 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+
 #ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
 #ifndef __STDC_LIMIT_MACROS
 #define __STDC_LIMIT_MACROS
 #endif
@@ -44,28 +52,33 @@
 #define __STDC_FORMAT_MACROS
 #endif
 
-#ifdef WIN32
-  #ifdef _WIN64
-    #define SIZE_T_FORMAT "I64"
-  #else
-    #define SIZE_T_FORMAT ""
-  #endif
-  #define INT64_T_FORMAT "I64"
-  #define INTMAX_T_FORMAT "I64"
+#ifdef _WIN32
+# ifdef PRIu32
+#  ifdef _WIN64
+#   define SIZE_T_FORMAT PRIu64
+#  else
+#   define SIZE_T_FORMAT PRIu32
+#  endif
+#  define INT64_T_FORMAT PRIi64
+#  define INTMAX_T_FORMAT PRIiMAX
+# else
+#  ifdef _WIN64
+#   define SIZE_T_FORMAT "I64"
+#  else
+#   define SIZE_T_FORMAT ""
+#  endif
+#  define INT64_T_FORMAT "I64"
+#  define INTMAX_T_FORMAT "I64"
+# endif
 #else
-  #define SIZE_T_FORMAT "z"
-  #define INT64_T_FORMAT "ll"
-  #define INTMAX_T_FORMAT "j"
-#endif
-#include <stdint.h>
+# define SIZE_T_FORMAT "z"
+# define INT64_T_FORMAT "ll"
+# define INTMAX_T_FORMAT "j"
 #endif
 
 #include <stdio.h>	/* Include that here, to make sure __P gets defined */
 #include <errno.h>
 #include <fcntl.h>	/* For open and flags */
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
 #include <regex.h>
 #include <time.h>
 #include <sys/types.h>
@@ -130,18 +143,16 @@
 #define	MAX(a,b)	(((a) > (b)) ? (a) : (b))
 #endif
 
-#ifndef FILE_BYTES_MAX
-# define FILE_BYTES_MAX (1024 * 1024)	/* how much of the file to look at */
-#endif
-#define MAXMAGIS 8192		/* max entries in any one magic file
-				   or directory */
+#define FILE_BADSIZE CAST(size_t, ~0ul)
 #define MAXDESC	64		/* max len of text description/MIME type */
 #define MAXMIME	80		/* max len of text MIME type */
-#define MAXstring 96		/* max len of "string" types */
+#define MAXstring 128		/* max len of "string" types */
 
 #define MAGICNO		0xF11E041C
-#define VERSIONNO	14
-#define FILE_MAGICSIZE	344
+#define VERSIONNO	16
+#define FILE_MAGICSIZE	376
+
+#define FILE_GUID_SIZE	sizeof("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
 
 #define	FILE_LOAD	0
 #define FILE_CHECK	1
@@ -168,6 +179,7 @@ union VALUETYPE {
 	uint8_t hq[8];	/* 8 bytes of a fixed-endian "quad" */
 	char s[MAXstring];	/* the search string or regex pattern */
 	unsigned char us[MAXstring];
+	uint64_t guid[2];
 	float f;
 	double d;
 };
@@ -184,6 +196,7 @@ struct magic {
 #define BINTEST		0x20	/* test is for a binary type (set only
 				   for top-level tests) */
 #define TEXTTEST	0x40	/* for passing to file_softmagic */
+#define OFFNEGATIVE	0x80	/* relative to the end of file */
 
 	uint8_t factor;
 
@@ -241,7 +254,9 @@ struct magic {
 #define				FILE_USE	46
 #define				FILE_CLEAR	47
 #define				FILE_DER	48
-#define				FILE_NAMES_SIZE	49 /* size of array to contain all names */
+#define				FILE_GUID	49
+#define				FILE_OFFSET	50
+#define				FILE_NAMES_SIZE	51 /* size of array to contain all names */
 
 #define IS_STRING(t) \
 	((t) == FILE_STRING || \
@@ -405,9 +420,10 @@ struct magic_set {
 	} c;
 	struct out {
 		char *buf;		/* Accumulation buffer */
+		size_t blen;		/* Length of buffer */
 		char *pbuf;		/* Printable buffer */
 	} o;
-	uint32_t offset;		/* a copy of m->offset while we */
+	uint32_t offset;			/* a copy of m->offset while we */
 					/* are working on the magic entry */
 	uint32_t eoffset;		/* offset from end of file */
 	int error;
@@ -436,11 +452,14 @@ struct magic_set {
 	uint16_t elf_notes_max;
 	uint16_t regex_max;
 	size_t bytes_max;		/* number of bytes to read from file */
-#define	FILE_INDIR_MAX			50
-#define	FILE_NAME_MAX			30
-#define	FILE_ELF_SHNUM_MAX		32768
-#define	FILE_ELF_PHNUM_MAX		2048
+#ifndef FILE_BYTES_MAX
+# define FILE_BYTES_MAX (1024 * 1024)	/* how much of the file to look at */
+#endif
 #define	FILE_ELF_NOTES_MAX		256
+#define	FILE_ELF_PHNUM_MAX		2048
+#define	FILE_ELF_SHNUM_MAX		32768
+#define	FILE_INDIR_MAX			50
+#define	FILE_NAME_MAX			50
 #define	FILE_REGEX_MAX			8192
 };
 
@@ -450,7 +469,7 @@ typedef unsigned long unichar;
 struct stat;
 #define FILE_T_LOCAL	1
 #define FILE_T_WINDOWS	2
-protected const char *file_fmttime(uint64_t, int, char *);
+protected const char *file_fmttime(char *, size_t, uint64_t, int);
 protected struct magic_set *file_ms_alloc(int);
 protected void file_ms_free(struct magic_set *);
 protected int file_default(struct magic_set *, size_t);
@@ -461,7 +480,11 @@ protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
 protected int file_vprintf(struct magic_set *, const char *, va_list)
     __attribute__((__format__(__printf__, 2, 0)));
 protected int file_separator(struct magic_set *);
+protected char *file_copystr(char *, size_t, size_t, const char *);
+protected int file_checkfmt(char *, size_t, const char *);
 protected size_t file_printedlen(const struct magic_set *);
+protected int file_print_guid(char *, size_t, const uint64_t *);
+protected int file_parse_guid(const char *, uint64_t *);
 protected int file_replace(struct magic_set *, const char *, const char *);
 protected int file_printf(struct magic_set *, const char *, ...)
     __attribute__((__format__(__printf__, 2, 3)));
@@ -506,8 +529,10 @@ protected ssize_t sread(int, void *, size_t, int);
 protected int file_check_mem(struct magic_set *, unsigned int);
 protected int file_looks_utf8(const unsigned char *, size_t, unichar *,
     size_t *);
-protected size_t file_pstring_length_size(const struct magic *);
-protected size_t file_pstring_get_length(const struct magic *, const char *);
+protected size_t file_pstring_length_size(struct magic_set *,
+    const struct magic *);
+protected size_t file_pstring_get_length(struct magic_set *,
+    const struct magic *, 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 *,
@@ -545,6 +570,7 @@ protected void file_regerror(file_regex_t *, int, struct magic_set *);
 
 typedef struct {
 	char *buf;
+	size_t blen;
 	uint32_t offset;
 } file_pushbuf_t;
 

+ 62 - 35
src/file_opts.h

@@ -15,48 +15,75 @@
  * switch statement!
  */
 
-OPT_LONGONLY("help", 0, 0, "                 display this help and exit\n", OPT_HELP)
-OPT('v', "version", 0, 0, "              output version information and exit\n")
-OPT('m', "magic-file", 1, 0, " LIST      use LIST as a colon-separated list of magic\n"
+OPT_LONGONLY("help", 0, 0,
+    "                 display this help and exit\n", OPT_HELP)
+OPT('v', "version", 0, 0,
+    "              output version information and exit\n")
+OPT('m', "magic-file", 1, 0,
+    " LIST      use LIST as a colon-separated list of magic\n"
     "                               number files\n")
-OPT('z', "uncompress", 0, 0, "           try to look inside compressed files\n")
-OPT('Z', "uncompress-noreport", 0, 0, "  only print the contents of compressed files\n")
-OPT('b', "brief", 0, 0, "                do not prepend filenames to output lines\n")
-OPT('c', "checking-printout", 0, 0, "    print the parsed form of the magic file, use in\n"
+OPT('z', "uncompress", 0, 0,
+    "           try to look inside compressed files\n")
+OPT('Z', "uncompress-noreport", 0, 0,
+    "  only print the contents of compressed files\n")
+OPT('b', "brief", 0, 0,
+    "                do not prepend filenames to output lines\n")
+OPT('c', "checking-printout", 0, 0,
+    "    print the parsed form of the magic file, use in\n"
     "                               conjunction with -m to debug a new magic file\n"
     "                               before installing it\n")
-OPT('e', "exclude", 1, 0, " TEST         exclude TEST from the list of test to be\n"
+OPT('e', "exclude", 1, 0,
+    " TEST         exclude TEST from the list of test to be\n"
     "                               performed for file. Valid tests are:\n"
-    "                               %o\n")
-OPT('f', "files-from", 1, 0, " FILE      read the filenames to be examined from FILE\n")
-OPT('F', "separator", 1, 0, " STRING     use string as separator instead of `:'\n")
-OPT('i', "mime", 0, 0, "                 output MIME type strings (--mime-type and\n"
+    "                               %e\n")
+OPT_LONGONLY("exclude-quiet", 1, 0,
+    " TEST         like exclude, but ignore unknown tests\n", OPT_EXCLUDE_QUIET)
+OPT('f', "files-from", 1, 0,
+    " FILE      read the filenames to be examined from FILE\n")
+OPT('F', "separator", 1, 0,
+    " STRING     use string as separator instead of `:'\n")
+OPT('i', "mime", 0, 0,
+    "                 output MIME type strings (--mime-type and\n"
     "                               --mime-encoding)\n")
-OPT_LONGONLY("apple", 0, 0, "                output the Apple CREATOR/TYPE\n", OPT_APPLE)
-OPT_LONGONLY("extension", 0, 0, "            output a slash-separated list of extensions\n", OPT_EXTENSIONS)
-OPT_LONGONLY("mime-type", 0, 0, "            output the MIME type\n", OPT_MIME_TYPE)
-OPT_LONGONLY("mime-encoding", 0, 0, "        output the MIME encoding\n", OPT_MIME_ENCODING)
-OPT('k', "keep-going", 0, 0, "           don't stop at the first match\n")
-OPT('l', "list", 0, 0, "                 list magic strength\n")
+OPT_LONGONLY("apple", 0, 0,
+    "                output the Apple CREATOR/TYPE\n", OPT_APPLE)
+OPT_LONGONLY("extension", 0, 0,
+    "            output a slash-separated list of extensions\n", OPT_EXTENSIONS)
+OPT_LONGONLY("mime-type", 0, 0,
+    "            output the MIME type\n", OPT_MIME_TYPE)
+OPT_LONGONLY("mime-encoding", 0, 0,
+    "        output the MIME encoding\n", OPT_MIME_ENCODING)
+OPT('k', "keep-going", 0, 0,
+    "           don't stop at the first match\n")
+OPT('l', "list", 0, 0,
+    "                 list magic strength\n")
 #ifdef S_IFLNK
-OPT('L', "dereference", 0, 1, "          follow symlinks")
-OPT('h', "no-dereference", 0, 2, "       don't follow symlinks")
+OPT('L', "dereference", 0, 1,
+    "          follow symlinks")
+OPT('h', "no-dereference", 0, 2,
+    "       don't follow symlinks")
 #endif
-OPT('n', "no-buffer", 0, 0, "            do not buffer output\n")
-OPT('N', "no-pad", 0, 0, "               do not pad output\n")
-OPT('0', "print0", 0, 0, "               terminate filenames with ASCII NUL\n")
+OPT('n', "no-buffer", 0, 0,
+    "            do not buffer output\n")
+OPT('N', "no-pad", 0, 0,
+    "               do not pad output\n")
+OPT('0', "print0", 0, 0,
+    "               terminate filenames with ASCII NUL\n")
 #if defined(HAVE_UTIME) || defined(HAVE_UTIMES)
-OPT('p', "preserve-date", 0, 0, "        preserve access times on files\n")
+OPT('p', "preserve-date", 0, 0,
+    "        preserve access times on files\n")
 #endif
-OPT('P', "parameter", 1, 0, "            set file engine parameter limits\n"
-    "                               indir        15 recursion limit for indirection\n"
-    "                               name         30 use limit for name/use magic\n"
-    "                               elf_notes   256 max ELF notes processed\n"
-    "                               elf_phnum   128 max ELF prog sections processed\n"
-    "                               elf_shnum 32768 max ELF sections processed\n")
-OPT('r', "raw", 0, 0, "                  don't translate unprintable chars to \\ooo\n")
-OPT('s', "special-files", 0, 0, "        treat special (block/char devices) files as\n"
+OPT('P', "parameter", 1, 0,
+    "            set file engine parameter limits\n"
+    "                               %P\n")
+OPT('r', "raw", 0, 0,
+    "                  don't translate unprintable chars to \\ooo\n")
+OPT('s', "special-files", 0, 0,
+    "        treat special (block/char devices) files as\n"
     "                             ordinary ones\n")
-OPT('S', "no-sandbox", 0, 0, "           disable system call sandboxing\n")
-OPT('C', "compile", 0, 0, "              compile file specified by -m\n")
-OPT('d', "debug", 0, 0, "                print debugging messages\n")
+OPT('S', "no-sandbox", 0, 0,
+    "           disable system call sandboxing\n")
+OPT('C', "compile", 0, 0,
+    "              compile file specified by -m\n")
+OPT('d', "debug", 0, 0,
+    "                print debugging messages\n")

+ 127 - 11
src/funcs.c

@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.108 2019/11/09 00:35:46 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.115 2020/02/20 15:50:20 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -48,6 +48,77 @@ FILE_RCSID("@(#)$File: funcs.c,v 1.108 2019/11/09 00:35:46 christos Exp $")
 #define SIZE_MAX	((size_t)~0)
 #endif
 
+protected char *
+file_copystr(char *buf, size_t blen, size_t width, const char *str)
+{
+	if (++width > blen)
+		width = blen;
+	strlcpy(buf, str, width);
+	return buf;
+}
+
+private void
+file_clearbuf(struct magic_set *ms)
+{
+	free(ms->o.buf);
+	ms->o.buf = NULL;
+	ms->o.blen = 0;
+}
+
+private int
+file_checkfield(char *msg, size_t mlen, const char *what, const char **pp)
+{
+	const char *p = *pp;
+	int fw = 0;
+
+	while (*p && isdigit((unsigned char)*p))
+		fw = fw * 10 + (*p++ - '0');
+
+	*pp = p;
+
+	if (fw < 1024)
+		return 1;
+	if (msg)
+		snprintf(msg, mlen, "field %s too large: %d", what, fw);
+
+	return 0;
+}
+
+protected int
+file_checkfmt(char *msg, size_t mlen, const char *fmt)
+{
+	for (const char *p = fmt; *p; p++) {
+		if (*p != '%')
+			continue;
+		if (*++p == '%')
+			continue;
+		// Skip uninteresting.
+		while (strchr("0.'+- ", *p) != NULL)
+			p++;
+		if (*p == '*') {
+			if (msg)
+				snprintf(msg, mlen, "* not allowed in format");
+			return -1;
+		}
+
+		if (!file_checkfield(msg, mlen, "width", &p))
+			return -1;
+
+		if (*p == '.') {
+			p++;
+			if (!file_checkfield(msg, mlen, "precision", &p))
+				return -1;
+		}
+
+		if (!isalpha((unsigned char)*p)) {
+			if (msg)
+				snprintf(msg, mlen, "bad format char: %c", *p);
+			return -1;
+		}
+	}
+	return 0;
+}
+
 /*
  * Like printf, only we append to a buffer.
  */
@@ -56,12 +127,26 @@ file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
 {
 	int len;
 	char *buf, *newstr;
+	char tbuf[1024];
 
 	if (ms->event_flags & EVENT_HAD_ERR)
 		return 0;
+
+	if (file_checkfmt(tbuf, sizeof(tbuf), fmt)) {
+		file_clearbuf(ms);
+		file_error(ms, 0, "Bad magic format `%s' (%s)", fmt, tbuf);
+		return -1;
+	}
+
 	len = vasprintf(&buf, fmt, ap);
-	if (len < 0)
-		goto out;
+	if (len < 0 || (size_t)len > 1024 || len + ms->o.blen > 1024 * 1024) {
+		size_t blen = ms->o.blen;
+		free(buf);
+		file_clearbuf(ms);
+		file_error(ms, 0, "Output buffer space exceeded %d+%zu", len,
+		    blen);
+		return -1;
+	}
 
 	if (ms->o.buf != NULL) {
 		len = asprintf(&newstr, "%s%s", ms->o.buf, buf);
@@ -72,9 +157,11 @@ file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
 		buf = newstr;
 	}
 	ms->o.buf = buf;
+	ms->o.blen = len;
 	return 0;
 out:
-	fprintf(stderr, "vasprintf failed (%s)", strerror(errno));
+	file_clearbuf(ms);
+	file_error(ms, errno, "vasprintf failed");
 	return -1;
 }
 
@@ -103,8 +190,7 @@ file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
 	if (ms->event_flags & EVENT_HAD_ERR)
 		return;
 	if (lineno != 0) {
-		free(ms->o.buf);
-		ms->o.buf = NULL;
+		file_clearbuf(ms);
 		(void)file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno);
 	}
 	if (ms->o.buf && *ms->o.buf)
@@ -393,10 +479,7 @@ file_reset(struct magic_set *ms, int checkloaded)
 		file_error(ms, 0, "no magic files loaded");
 		return -1;
 	}
-	if (ms->o.buf) {
-		free(ms->o.buf);
-		ms->o.buf = NULL;
-	}
+	file_clearbuf(ms);
 	if (ms->o.pbuf) {
 		free(ms->o.pbuf);
 		ms->o.pbuf = NULL;
@@ -518,7 +601,7 @@ file_check_mem(struct magic_set *ms, unsigned int level)
 protected size_t
 file_printedlen(const struct magic_set *ms)
 {
-	return ms->o.buf == NULL ? 0 : strlen(ms->o.buf);
+	return ms->o.blen;
 }
 
 protected int
@@ -614,9 +697,11 @@ file_push_buffer(struct magic_set *ms)
 		return NULL;
 
 	pb->buf = ms->o.buf;
+	pb->blen = ms->o.blen;
 	pb->offset = ms->offset;
 
 	ms->o.buf = NULL;
+	ms->o.blen = 0;
 	ms->offset = 0;
 
 	return pb;
@@ -636,6 +721,7 @@ file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
 	rbuf = ms->o.buf;
 
 	ms->o.buf = pb->buf;
+	ms->o.blen = pb->blen;
 	ms->offset = pb->offset;
 
 	free(pb);
@@ -667,3 +753,33 @@ file_printable(char *buf, size_t bufsiz, const char *str, size_t slen)
 	*ptr = '\0';
 	return buf;
 }
+
+struct guid {
+	uint32_t data1;
+	uint16_t data2;
+	uint16_t data3;
+	uint8_t data4[8];
+};
+
+protected int
+file_parse_guid(const char *s, uint64_t *guid)
+{
+	struct guid *g = CAST(struct guid *, guid);
+	return sscanf(s,
+	    "%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
+	    &g->data1, &g->data2, &g->data3, &g->data4[0], &g->data4[1],
+	    &g->data4[2], &g->data4[3], &g->data4[4], &g->data4[5],
+	    &g->data4[6], &g->data4[7]) == 11 ? 0 : -1;
+}
+
+protected int
+file_print_guid(char *str, size_t len, const uint64_t *guid)
+{
+	const struct guid *g = CAST(const struct guid *, guid);
+
+	return snprintf(str, len, "%.8X-%.4hX-%.4hX-%.2hhX%.2hhX-"
+	    "%.2hhX%.2hhX%.2hhX%.2hhX%.2hhX%.2hhX",
+	    g->data1, g->data2, g->data3, g->data4[0], g->data4[1],
+	    g->data4[2], g->data4[3], g->data4[4], g->data4[5],
+	    g->data4[6], g->data4[7]);
+}

+ 12 - 5
src/is_json.c

@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: is_json.c,v 1.13 2019/03/02 01:08:10 christos Exp $")
+FILE_RCSID("@(#)$File: is_json.c,v 1.15 2020/06/07 19:05:47 christos Exp $")
 #endif
 
 #include <string.h>
@@ -156,6 +156,7 @@ json_parse_string(const unsigned char **ucp, const unsigned char *ue)
 			}
 		case '"':
 			*ucp = uc;
+			DPRINTF("Good string: ", uc, *ucp);
 			return 1;
 		default:
 			continue;
@@ -172,23 +173,24 @@ json_parse_array(const unsigned char **ucp, const unsigned char *ue,
 	size_t *st, size_t lvl)
 {
 	const unsigned char *uc = *ucp;
-	int more = 0;	/* Array has more than 1 element */
 
 	DPRINTF("Parse array: ", uc, *ucp);
 	while (uc < ue) {
+		if (*uc == ']')
+			goto done;
 		if (!json_parse(&uc, ue, st, lvl + 1))
 			goto out;
 		if (uc == ue)
 			goto out;
 		switch (*uc) {
 		case ',':
-			more++;
 			uc++;
 			continue;
 		case ']':
-			if (more)
-				st[JSON_ARRAYN]++;
+		done:
+			st[JSON_ARRAYN]++;
 			*ucp = uc + 1;
+			DPRINTF("Good array: ", uc, *ucp);
 			return 1;
 		default:
 			goto out;
@@ -210,6 +212,10 @@ json_parse_object(const unsigned char **ucp, const unsigned char *ue,
 		uc = json_skip_space(uc, ue);
 		if (uc == ue)
 			goto out;
+		if (*uc == '}') {
+			uc++;
+			goto done;
+		}
 		if (*uc++ != '"') {
 			DPRINTF("not string", uc, *ucp);
 			goto out;
@@ -236,6 +242,7 @@ json_parse_object(const unsigned char **ucp, const unsigned char *ue,
 		case ',':
 			continue;
 		case '}': /* { */
+		done:
 			*ucp = uc;
 			DPRINTF("Good object: ", uc, *ucp);
 			return 1;

+ 2 - 3
src/magic.c

@@ -33,7 +33,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: magic.c,v 1.111 2019/05/07 02:27:11 christos Exp $")
+FILE_RCSID("@(#)$File: magic.c,v 1.112 2020/06/08 19:44:10 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -463,8 +463,7 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
 	}
 
 	if (fd != -1) {
-		if (!okstat)
-			okstat = fstat(fd, &sb) == 0;
+		okstat = fstat(fd, &sb) == 0;
 		if (okstat && S_ISFIFO(sb.st_mode))
 			ispipe = 1;
 		if (inname == NULL)

+ 20 - 9
src/print.c

@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: print.c,v 1.85 2019/03/12 20:43:05 christos Exp $")
+FILE_RCSID("@(#)$File: print.c,v 1.88 2020/05/09 18:57:15 christos Exp $")
 #endif  /* lint */
 
 #include <string.h>
@@ -50,7 +50,7 @@ protected void
 file_mdump(struct magic *m)
 {
 	static const char optyp[] = { FILE_OPS };
-	char tbuf[26];
+	char tbuf[256];
 
 	(void) fprintf(stderr, "%u: %.*s %u", m->lineno,
 	    (m->cont_level & 7) + 1, ">>>>>>>>", m->offset);
@@ -139,6 +139,7 @@ file_mdump(struct magic *m)
 		case FILE_BEQUAD:
 		case FILE_LEQUAD:
 		case FILE_QUAD:
+		case FILE_OFFSET:
 			(void) fprintf(stderr, "%" INT64_T_FORMAT "d",
 			    CAST(long long, m->value.q));
 			break;
@@ -156,32 +157,35 @@ file_mdump(struct magic *m)
 		case FILE_BEDATE:
 		case FILE_MEDATE:
 			(void)fprintf(stderr, "%s,",
-			    file_fmttime(m->value.l, 0, tbuf));
+			    file_fmttime(tbuf, sizeof(tbuf), m->value.l, 0));
 			break;
 		case FILE_LDATE:
 		case FILE_LELDATE:
 		case FILE_BELDATE:
 		case FILE_MELDATE:
 			(void)fprintf(stderr, "%s,",
-			    file_fmttime(m->value.l, FILE_T_LOCAL, tbuf));
+			    file_fmttime(tbuf, sizeof(tbuf), m->value.l,
+			    FILE_T_LOCAL));
 			break;
 		case FILE_QDATE:
 		case FILE_LEQDATE:
 		case FILE_BEQDATE:
 			(void)fprintf(stderr, "%s,",
-			    file_fmttime(m->value.q, 0, tbuf));
+			    file_fmttime(tbuf, sizeof(tbuf), m->value.q, 0));
 			break;
 		case FILE_QLDATE:
 		case FILE_LEQLDATE:
 		case FILE_BEQLDATE:
 			(void)fprintf(stderr, "%s,",
-			    file_fmttime(m->value.q, FILE_T_LOCAL, tbuf));
+			    file_fmttime(tbuf, sizeof(tbuf), m->value.q,
+			    FILE_T_LOCAL));
 			break;
 		case FILE_QWDATE:
 		case FILE_LEQWDATE:
 		case FILE_BEQWDATE:
 			(void)fprintf(stderr, "%s,",
-			    file_fmttime(m->value.q, FILE_T_WINDOWS, tbuf));
+			    file_fmttime(tbuf, sizeof(tbuf), m->value.q,
+			    FILE_T_WINDOWS));
 			break;
 		case FILE_FLOAT:
 		case FILE_BEFLOAT:
@@ -201,6 +205,12 @@ file_mdump(struct magic *m)
 		case FILE_DER:
 			(void) fprintf(stderr, "'%s'", m->value.s);
 			break;
+		case FILE_GUID:
+			(void) file_print_guid(tbuf, sizeof(tbuf),
+			    m->value.guid);
+			(void) fprintf(stderr, "%s", tbuf);
+			break;
+
 		default:
 			(void) fprintf(stderr, "*bad type %d*", m->type);
 			break;
@@ -230,7 +240,7 @@ file_magwarn(struct magic_set *ms, const char *f, ...)
 }
 
 protected const char *
-file_fmttime(uint64_t v, int flags, char *buf)
+file_fmttime(char *buf, size_t bsize, uint64_t v, int flags)
 {
 	char *pp;
 	time_t t;
@@ -260,5 +270,6 @@ file_fmttime(uint64_t v, int flags, char *buf)
 	pp[strcspn(pp, "\n")] = '\0';
 	return pp;
 out:
-	return strcpy(buf, "*Invalid time*");
+	strlcpy(buf, "*Invalid time*", bsize);
+	return buf;
 }

+ 35 - 10
src/readelf.c

@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.168 2019/12/16 03:49:19 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.173 2020/06/07 22:12:54 christos Exp $")
 #endif
 
 #ifdef BUILTIN_ELF
@@ -67,6 +67,8 @@ private uint64_t getu64(int, uint64_t);
 private int
 toomany(struct magic_set *ms, const char *name, uint16_t num)
 {
+	if (ms->flags & MAGIC_MIME)
+		return 1;
 	if (file_printf(ms, ", too many %s (%u)", name, num) == -1)
 		return -1;
 	return 1;
@@ -355,6 +357,9 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
 	off_t ph_off = off;
 	int ph_num = num;
 
+	if (ms->flags & MAGIC_MIME)
+		return 0;
+
 	if (num == 0) {
 		if (file_printf(ms, ", no program header") == -1)
 			return -1;
@@ -568,8 +573,10 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
 	}
 	if (namesz == 4 && strcmp(RCAST(char *, &nbuf[noff]), "Go") == 0 &&
 	    type == NT_GO_BUILD_ID && descsz < 128) {
-		if (file_printf(ms, ", Go BuildID=%.*s",
-		    CAST(int, descsz), RCAST(char *, &nbuf[doff])) == -1)
+		char buf[256];
+		if (file_printf(ms, ", Go BuildID=%s",
+		    file_copystr(buf, sizeof(buf), descsz,
+		    RCAST(const char *, &nbuf[doff]))) == -1)
 			return -1;
 		return 1;
 	}
@@ -721,6 +728,7 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
     size_t noff, size_t doff, int *flags, size_t size, int clazz)
 {
 #ifdef ELFCORE
+	char buf[256];
 	const char *name = RCAST(const char *, &nbuf[noff]);
 
 	int os_style = -1;
@@ -901,8 +909,10 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
 				 */
 				while (cp > cname && isspace(cp[-1]))
 					cp--;
-				if (file_printf(ms, ", from '%.*s'",
-				    CAST(int, cp - cname), cname) == -1)
+				if (file_printf(ms, ", from '%s'",
+				    file_copystr(buf, sizeof(buf),
+				    CAST(size_t, cp - cname),
+				    CAST(const char *, cname))) == -1)
 					return -1;
 				*flags |= FLAGS_DID_CORE;
 				return 1;
@@ -1128,6 +1138,7 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
 	Elf64_Nhdr nh64;
 	size_t noff, doff;
 	uint32_t namesz, descsz;
+	char buf[256];
 	unsigned char *nbuf = CAST(unsigned char *, vbuf);
 
 	if (*notecount == 0)
@@ -1255,7 +1266,8 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
 		str = RCAST(const char *, &nbuf[doff]);
 		descw = CAST(int, descsz);
 		*flags |= flag;
-		file_printf(ms, ", %s: %.*s", tag, descw, str);
+		file_printf(ms, ", %s: %s", tag,
+		    file_copystr(buf, sizeof(buf), descw, str));
 		return offset;
 	}
 
@@ -1328,6 +1340,9 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
 	char name[50];
 	ssize_t namesize;
 
+	if (ms->flags & MAGIC_MIME)
+		return 0;
+
 	if (num == 0) {
 		if (file_printf(ms, ", no section header") == -1)
 			return -1;
@@ -1349,8 +1364,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
 	name_off = xsh_offset;
 
 	if (fsize != SIZE_UNKNOWN && fsize < name_off) {
-		if (file_printf(ms, ", too large section header offset %td",
-		    name_off) == -1)
+		if (file_printf(ms, ", too large section header offset %jd",
+		    (intmax_t)name_off) == -1)
 			return -1;
 		return 0;
 	}
@@ -1639,6 +1654,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
 		switch (xph_type) {
 		case PT_DYNAMIC:
 			doread = 1;
+			linking_style = "dynamically";
 			break;
 		case PT_NOTE:
 			if (sh_num)	/* Did this through section headers */
@@ -1653,7 +1669,6 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
 			}
 			/*FALLTHROUGH*/
 		case PT_INTERP:
-			linking_style = "dynamically";
 			doread = 1;
 			break;
 		default:
@@ -1690,9 +1705,13 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
 				if (offset == 0)
 					break;
 			}
+			if (ms->flags & MAGIC_MIME)
+				continue;
 			break;
 
 		case PT_INTERP:
+			if (ms->flags & MAGIC_MIME)
+				continue;
 			if (bufsize && nbuf[0]) {
 				nbuf[bufsize - 1] = '\0';
 				memcpy(interp, nbuf, CAST(size_t, bufsize));
@@ -1700,6 +1719,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
 				strlcpy(interp, "*empty*", sizeof(interp));
 			break;
 		case PT_NOTE:
+			if (ms->flags & MAGIC_MIME)
+				return 0;
 			/*
 			 * This is a PT_NOTE section; loop through all the notes
 			 * in the section.
@@ -1716,9 +1737,13 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
 			}
 			break;
 		default:
+			if (ms->flags & MAGIC_MIME)
+				continue;
 			break;
 		}
 	}
+	if (ms->flags & MAGIC_MIME)
+		return 0;
 	if (file_printf(ms, ", %s linked", linking_style)
 	    == -1)
 		return -1;
@@ -1751,7 +1776,7 @@ file_tryelf(struct magic_set *ms, const struct buffer *b)
 	Elf64_Ehdr elf64hdr;
 	uint16_t type, phnum, shnum, notecount;
 
-	if (ms->flags & (MAGIC_MIME|MAGIC_APPLE|MAGIC_EXTENSION))
+	if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))
 		return 0;
 	/*
 	 * ELF executables have multiple section headers in arbitrary

+ 10 - 3
src/seccomp.c

@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: seccomp.c,v 1.11 2019/07/18 20:32:06 christos Exp $")
+FILE_RCSID("@(#)$File: seccomp.c,v 1.15 2020/05/30 23:56:26 christos Exp $")
 #endif	/* lint */
 
 #if HAVE_LIBSECCOMP
@@ -186,9 +186,13 @@ enable_sandbox_full(void)
 	ALLOW_IOCTL_RULE(FIONREAD);
 #endif
 #ifdef TIOCGWINSZ
-	// musl libc may call ioctl TIOCGWINSZ when calling stdout
+	// musl libc may call ioctl TIOCGWINSZ on stdout
 	ALLOW_IOCTL_RULE(TIOCGWINSZ);
 #endif
+#ifdef TCGETS
+	// glibc may call ioctl TCGETS on stdout on physical terminal
+	ALLOW_IOCTL_RULE(TCGETS);
+#endif
 	ALLOW_RULE(lseek);
  	ALLOW_RULE(_llseek);
 	ALLOW_RULE(lstat);
@@ -207,6 +211,9 @@ enable_sandbox_full(void)
 	ALLOW_RULE(pread64);
 	ALLOW_RULE(read);
 	ALLOW_RULE(readlink);
+#ifdef __NR_readlinkat
+	ALLOW_RULE(readlinkat);
+#endif
 	ALLOW_RULE(rt_sigaction);
 	ALLOW_RULE(rt_sigprocmask);
 	ALLOW_RULE(rt_sigreturn);
@@ -215,6 +222,7 @@ enable_sandbox_full(void)
 	ALLOW_RULE(stat64);
 	ALLOW_RULE(sysinfo);
 	ALLOW_RULE(umask);	// Used in file_pipe2file()
+	ALLOW_RULE(getpid);	// Used by glibc in file_pipe2file()
 	ALLOW_RULE(unlink);
 	ALLOW_RULE(write);
 
@@ -222,7 +230,6 @@ enable_sandbox_full(void)
 #if 0
 	// needed by valgrind
 	ALLOW_RULE(gettid);
-	ALLOW_RULE(getpid);
 	ALLOW_RULE(rt_sigtimedwait);
 #endif
 

+ 113 - 45
src/softmagic.c

@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef	lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.286 2019/05/17 02:24:59 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.299 2020/06/07 21:58:01 christos Exp $")
 #endif	/* lint */
 
 #include "magic.h"
@@ -331,6 +331,13 @@ flush:
 			if (msetoffset(ms, m, &bb, b, offset, cont_level) == -1)
 				goto flush;
 			if (m->flag & OFFADD) {
+				if (cont_level == 0) {
+					if ((ms->flags & MAGIC_DEBUG) != 0)
+						fprintf(stderr,
+						    "direct *zero*"
+						    " cont_level\n");
+					return 0;
+				}
 				ms->offset +=
 				    ms->c.li[cont_level - 1].off;
 			}
@@ -642,6 +649,7 @@ mprint(struct magic_set *ms, struct magic *m)
   	case FILE_QUAD:
   	case FILE_BEQUAD:
   	case FILE_LEQUAD:
+	case FILE_OFFSET:
 		v = file_signextend(ms, m, p->q);
 		switch (check_fmt(ms, desc)) {
 		case -1:
@@ -699,8 +707,12 @@ mprint(struct magic_set *ms, struct magic *m)
 				sizeof(p->s) - (str - p->s))) == -1)
 				return -1;
 
-			if (m->type == FILE_PSTRING)
-				t += file_pstring_length_size(m);
+			if (m->type == FILE_PSTRING) {
+				size_t l = file_pstring_length_size(ms, m);
+				if (l == FILE_BADSIZE)
+					return -1;
+				t += l;
+			}
 		}
 		break;
 
@@ -709,7 +721,7 @@ mprint(struct magic_set *ms, struct magic *m)
 	case FILE_LEDATE:
 	case FILE_MEDATE:
 		if (file_printf(ms, F(ms, desc, "%s"),
-		    file_fmttime(p->l, 0, tbuf)) == -1)
+		    file_fmttime(tbuf, sizeof(tbuf), p->l, 0)) == -1)
 			return -1;
 		t = ms->offset + sizeof(uint32_t);
 		break;
@@ -719,7 +731,7 @@ mprint(struct magic_set *ms, struct magic *m)
 	case FILE_LELDATE:
 	case FILE_MELDATE:
 		if (file_printf(ms, F(ms, desc, "%s"),
-		    file_fmttime(p->l, FILE_T_LOCAL, tbuf)) == -1)
+		    file_fmttime(tbuf, sizeof(tbuf), p->l, FILE_T_LOCAL)) == -1)
 			return -1;
 		t = ms->offset + sizeof(uint32_t);
 		break;
@@ -728,7 +740,7 @@ mprint(struct magic_set *ms, struct magic *m)
 	case FILE_BEQDATE:
 	case FILE_LEQDATE:
 		if (file_printf(ms, F(ms, desc, "%s"),
-		    file_fmttime(p->q, 0, tbuf)) == -1)
+		    file_fmttime(tbuf, sizeof(tbuf), p->q, 0)) == -1)
 			return -1;
 		t = ms->offset + sizeof(uint64_t);
 		break;
@@ -737,7 +749,7 @@ mprint(struct magic_set *ms, struct magic *m)
 	case FILE_BEQLDATE:
 	case FILE_LEQLDATE:
 		if (file_printf(ms, F(ms, desc, "%s"),
-		    file_fmttime(p->q, FILE_T_LOCAL, tbuf)) == -1)
+		    file_fmttime(tbuf, sizeof(tbuf), p->q, FILE_T_LOCAL)) == -1)
 			return -1;
 		t = ms->offset + sizeof(uint64_t);
 		break;
@@ -746,7 +758,8 @@ mprint(struct magic_set *ms, struct magic *m)
 	case FILE_BEQWDATE:
 	case FILE_LEQWDATE:
 		if (file_printf(ms, F(ms, desc, "%s"),
-		    file_fmttime(p->q, FILE_T_WINDOWS, tbuf)) == -1)
+		    file_fmttime(tbuf, sizeof(tbuf), p->q, FILE_T_WINDOWS))
+		    == -1)
 			return -1;
 		t = ms->offset + sizeof(uint64_t);
 		break;
@@ -835,6 +848,12 @@ mprint(struct magic_set *ms, struct magic *m)
 			return -1;
 		t = ms->offset;
 		break;
+	case FILE_GUID:
+		(void) file_print_guid(buf, sizeof(buf), ms->ms_value.guid);
+		if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
+			return -1;
+		t = ms->offset;
+		break;
 	default:
 		file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
 		return -1;
@@ -885,9 +904,12 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
 			if (*m->value.s == '\0')
 				p->s[strcspn(p->s, "\r\n")] = '\0';
 			o = CAST(uint32_t, (ms->offset + strlen(p->s)));
-			if (m->type == FILE_PSTRING)
-				o += CAST(uint32_t,
-				    file_pstring_length_size(m));
+			if (m->type == FILE_PSTRING) {
+				size_t l = file_pstring_length_size(ms, m);
+				if (l == FILE_BADSIZE)
+					return -1;
+				o += CAST(uint32_t, l);
+			}
 		}
 		break;
 
@@ -947,23 +969,26 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
 	case FILE_CLEAR:
 	case FILE_DEFAULT:
 	case FILE_INDIRECT:
+	case FILE_OFFSET:
 		o = ms->offset;
 		break;
 
 	case FILE_DER:
-		{
-			o = der_offs(ms, m, nbytes);
-			if (o == -1 || CAST(size_t, o) > nbytes) {
-				if ((ms->flags & MAGIC_DEBUG) != 0) {
-					(void)fprintf(stderr,
-					    "Bad DER offset %d nbytes=%"
-					    SIZE_T_FORMAT "u", o, nbytes);
-				}
-				*op = 0;
-				return 0;
+		o = der_offs(ms, m, nbytes);
+		if (o == -1 || CAST(size_t, o) > nbytes) {
+			if ((ms->flags & MAGIC_DEBUG) != 0) {
+				(void)fprintf(stderr,
+				    "Bad DER offset %d nbytes=%"
+				    SIZE_T_FORMAT "u", o, nbytes);
 			}
-			break;
+			*op = 0;
+			return 0;
 		}
+		break;
+
+	case FILE_GUID:
+		o = CAST(int32_t, (ms->offset + 2 * sizeof(uint64_t)));
+		break;
 
 	default:
 		o = 0;
@@ -1168,6 +1193,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
 	case FILE_QDATE:
 	case FILE_QLDATE:
 	case FILE_QWDATE:
+	case FILE_OFFSET:
 		if (cvt_64(p, m) == -1)
 			goto out;
 		return 1;
@@ -1179,9 +1205,15 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
 		return 1;
 	}
 	case FILE_PSTRING: {
-		size_t sz = file_pstring_length_size(m);
-		char *ptr1 = p->s, *ptr2 = ptr1 + sz;
-		size_t len = file_pstring_get_length(m, ptr1);
+		char *ptr1, *ptr2;
+		size_t len, sz = file_pstring_length_size(ms, m);
+		if (sz == FILE_BADSIZE)
+			return 0;
+		ptr1 = p->s;
+		ptr2 = ptr1 + sz;
+		len = file_pstring_get_length(ms, m, ptr1);
+		if (len == FILE_BADSIZE)
+			return 0;
 		sz = sizeof(p->s) - sz; /* maximum length of string */
 		if (len >= sz) {
 			/*
@@ -1281,6 +1313,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
 	case FILE_NAME:
 	case FILE_USE:
 	case FILE_DER:
+	case FILE_GUID:
 		return 1;
 	default:
 		file_magerror(ms, "invalid type %d in mconvert()", m->type);
@@ -1407,6 +1440,12 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
 		}
 	}
 
+	if (type == FILE_OFFSET) {
+		(void)memset(p, '\0', sizeof(*p));
+		p->q = offset;
+		return 0;
+	}
+
 	if (offset >= nbytes) {
 		(void)memset(p, '\0', sizeof(*p));
 		return 0;
@@ -1471,7 +1510,9 @@ private int
 msetoffset(struct magic_set *ms, struct magic *m, struct buffer *bb,
     const struct buffer *b, size_t o, unsigned int cont_level)
 {
-	if (m->offset < 0) {
+	int32_t offset;
+	if (m->flag & OFFNEGATIVE) {
+		offset = -m->offset;
 		if (cont_level > 0) {
 			if (m->flag & (OFFADD|INDIROFFADD))
 				goto normal;
@@ -1489,26 +1530,28 @@ msetoffset(struct magic_set *ms, struct magic *m, struct buffer *bb,
 			    "u at level %u", o, cont_level);
 			return -1;
 		}
-		if (CAST(size_t, -m->offset) > b->elen)
+		if (CAST(size_t, m->offset) > b->elen)
 			return -1;
 		buffer_init(bb, -1, NULL, b->ebuf, b->elen);
-		ms->eoffset = ms->offset = CAST(int32_t, b->elen + m->offset);
+		ms->eoffset = ms->offset = CAST(int32_t, b->elen - m->offset);
 	} else {
+		offset = m->offset;
 		if (cont_level == 0) {
 normal:
 			// XXX: Pass real fd, then who frees bb?
 			buffer_init(bb, -1, NULL, b->fbuf, b->flen);
-			ms->offset = m->offset;
+			ms->offset = offset;
 			ms->eoffset = 0;
 		} else {
-			ms->offset = ms->eoffset + m->offset;
+			ms->offset = ms->eoffset + offset;
 		}
 	}
 	if ((ms->flags & MAGIC_DEBUG) != 0) {
-		fprintf(stderr, "bb=[%p,%" SIZE_T_FORMAT "u], %d [b=%p,%"
-		    SIZE_T_FORMAT "u], [o=%#x, c=%d]\n",
-		    bb->fbuf, bb->flen, ms->offset, b->fbuf, b->flen,
-		    m->offset, cont_level);
+		fprintf(stderr, "bb=[%p,%" SIZE_T_FORMAT "u,%"
+		    SIZE_T_FORMAT "u], %d [b=%p,%"
+		    SIZE_T_FORMAT "u,%" SIZE_T_FORMAT "u], [o=%#x, c=%d]\n",
+		    bb->fbuf, bb->flen, bb->elen, ms->offset, b->fbuf,
+		    b->flen, b->elen, offset, cont_level);
 	}
 	return 0;
 }
@@ -1566,7 +1609,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
 		if (m->in_op & FILE_OPINDIRECT) {
 			const union VALUETYPE *q = CAST(const union VALUETYPE *,
 			    RCAST(const void *, s + offset + off));
-			switch (cvt_flip(m->in_type, flip)) {
+			int op;
+			switch (op = cvt_flip(m->in_type, flip)) {
 			case FILE_BYTE:
 				if (OFFSET_OOB(nbytes, offset + off, 1))
 					return 0;
@@ -1620,7 +1664,9 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
 				off = SEXT(sgn,64,LE64(q));
 				break;
 			default:
-				abort();
+				if ((ms->flags & MAGIC_DEBUG) != 0)
+					fprintf(stderr, "bad op=%d\n", op);
+				return 0;
 			}
 			if ((ms->flags & MAGIC_DEBUG) != 0)
 				fprintf(stderr, "indirect offs=%jd\n", off);
@@ -1685,11 +1731,19 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
 			offset = do_ops(m, SEXT(sgn,64,BE64(p)), off);
 			break;
 		default:
-			abort();
+			if ((ms->flags & MAGIC_DEBUG) != 0)
+				fprintf(stderr, "bad in_type=%d\n", in_type);
+			return 0;
 		}
 
 		if (m->flag & INDIROFFADD) {
-			offset += ms->c.li[cont_level-1].off;
+			if (cont_level == 0) {
+				if ((ms->flags & MAGIC_DEBUG) != 0)
+					fprintf(stderr,
+					    "indirect *zero* cont_level\n");
+				return 0;
+			}
+			offset += ms->c.li[cont_level - 1].off;
 			if (offset == 0) {
 				if ((ms->flags & MAGIC_DEBUG) != 0)
 					fprintf(stderr,
@@ -1752,6 +1806,11 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
 			return 0;
 		break;
 
+	case FILE_GUID:
+		if (OFFSET_OOB(nbytes, offset, 16))
+			return 0;
+		break;
+
 	case FILE_STRING:
 	case FILE_PSTRING:
 	case FILE_SEARCH:
@@ -1847,7 +1906,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
 }
 
 private uint64_t
-file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
+file_strncmp(const char *s1, const char *s2, size_t len, size_t maxlen,
+    uint32_t flags)
 {
 	/*
 	 * Convert the source args to unsigned here so that (1) the
@@ -1857,7 +1917,9 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
 	 */
 	const unsigned char *a = RCAST(const unsigned char *, s1);
 	const unsigned char *b = RCAST(const unsigned char *, s2);
-	const unsigned char *eb = b + len;
+	uint32_t ws = flags & (STRING_COMPACT_WHITESPACE |
+	    STRING_COMPACT_OPTIONAL_WHITESPACE);
+	const unsigned char *eb = b + (ws ? maxlen : len);
 	uint64_t v;
 
 	/*
@@ -1915,7 +1977,8 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
 }
 
 private uint64_t
-file_strncmp16(const char *a, const char *b, size_t len, uint32_t flags)
+file_strncmp16(const char *a, const char *b, size_t len, size_t maxlen,
+    uint32_t flags)
 {
 	/*
 	 * XXX - The 16-bit string compare probably needs to be done
@@ -1923,7 +1986,7 @@ file_strncmp16(const char *a, const char *b, size_t len, uint32_t flags)
 	 * At the moment, I am unsure.
 	 */
 	flags = 0;
-	return file_strncmp(a, b, len, flags);
+	return file_strncmp(a, b, len, maxlen, flags);
 }
 
 private int
@@ -1974,6 +2037,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
 	case FILE_QWDATE:
 	case FILE_BEQWDATE:
 	case FILE_LEQWDATE:
+	case FILE_OFFSET:
 		v = p->q;
 		break;
 
@@ -2052,14 +2116,14 @@ magiccheck(struct magic_set *ms, struct magic *m)
 	case FILE_PSTRING:
 		l = 0;
 		v = file_strncmp(m->value.s, p->s, CAST(size_t, m->vallen),
-		    m->str_flags);
+		    sizeof(p->s), m->str_flags);
 		break;
 
 	case FILE_BESTRING16:
 	case FILE_LESTRING16:
 		l = 0;
 		v = file_strncmp16(m->value.s, p->s, CAST(size_t, m->vallen),
-		    m->str_flags);
+		    sizeof(p->s), m->str_flags);
 		break;
 
 	case FILE_SEARCH: { /* search ms->search.s for the string m->value.s */
@@ -2094,7 +2158,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
 				return 0;
 
 			v = file_strncmp(m->value.s, ms->search.s + idx, slen,
-			    m->str_flags);
+			    ms->search.s_len - idx, m->str_flags);
 			if (v == 0) {	/* found match */
 				ms->search.offset += idx;
 				ms->search.rm_len = ms->search.s_len - idx;
@@ -2179,6 +2243,10 @@ magiccheck(struct magic_set *ms, struct magic *m)
 			return 0;
 		}
 		return matched;
+	case FILE_GUID:
+		l = 0;
+		v = memcmp(m->value.guid, p->guid, sizeof(p->guid));
+		break;
 	default:
 		file_magerror(ms, "invalid type %d in magiccheck()", m->type);
 		return -1;