From 35cf6a5ad0d5d1552a3f4380db4b98a2197c4bc6 Mon Sep 17 00:00:00 2001 From: Vlad Seryakov Date: Sun, 15 Mar 2020 15:51:43 -0400 Subject: [PATCH 1/2] updated libmagic to version 5.38 --- deps/libmagic/AUTHORS | 2 +- deps/libmagic/COPYING | 4 +- deps/libmagic/ChangeLog | 175 ++++++- deps/libmagic/MAINT | 2 +- deps/libmagic/NEWS | 2 +- deps/libmagic/README | 132 +++--- deps/libmagic/TODO | 15 +- deps/libmagic/libmagic.gyp | 3 + deps/libmagic/src/apprentice.c | 559 ++++++++++++---------- deps/libmagic/src/apptype.c | 12 +- deps/libmagic/src/ascmagic.c | 102 ++-- deps/libmagic/src/asctime_r.c | 4 +- deps/libmagic/src/asprintf.c | 6 +- deps/libmagic/src/buffer.c | 88 ++++ deps/libmagic/src/cdf.c | 220 +++++---- deps/libmagic/src/cdf.h | 7 +- deps/libmagic/src/cdf_time.c | 28 +- deps/libmagic/src/compress.c | 501 ++++++++++++++------ deps/libmagic/src/ctime_r.c | 4 +- deps/libmagic/src/der.c | 110 +++-- deps/libmagic/src/dprintf.c | 11 +- deps/libmagic/src/elfclass.h | 18 +- deps/libmagic/src/encoding.c | 92 +++- deps/libmagic/src/file.c | 232 ++++++--- deps/libmagic/src/file.h | 163 ++++--- deps/libmagic/src/file_opts.h | 6 +- deps/libmagic/src/fmtcheck.c | 2 +- deps/libmagic/src/fsmagic.c | 45 +- deps/libmagic/src/funcs.c | 342 ++++++++++---- deps/libmagic/src/getline.c | 3 - deps/libmagic/src/getopt_long.c | 12 +- deps/libmagic/src/gmtime_r.c | 4 +- deps/libmagic/src/is_csv.c | 197 ++++++++ deps/libmagic/src/is_json.c | 462 ++++++++++++++++++ deps/libmagic/src/is_tar.c | 23 +- deps/libmagic/src/localtime_r.c | 4 +- deps/libmagic/src/magic.c | 111 +++-- deps/libmagic/src/magic.h | 8 +- deps/libmagic/src/mygetopt.h | 2 +- deps/libmagic/src/pread.c | 5 +- deps/libmagic/src/print.c | 68 +-- deps/libmagic/src/readcdf.c | 427 ++++++++--------- deps/libmagic/src/readelf.c | 617 +++++++++++++++--------- deps/libmagic/src/readelf.h | 120 ++++- deps/libmagic/src/softmagic.c | 806 ++++++++++++++++++++++---------- deps/libmagic/src/tar.h | 2 +- deps/libmagic/src/vasprintf.c | 674 +++++++++++++++++++++++++- magic/magic.mgc | Bin 4964608 -> 6439752 bytes 48 files changed, 4655 insertions(+), 1777 deletions(-) create mode 100644 deps/libmagic/src/buffer.c create mode 100644 deps/libmagic/src/is_csv.c create mode 100644 deps/libmagic/src/is_json.c diff --git a/deps/libmagic/AUTHORS b/deps/libmagic/AUTHORS index 3d3d34a..bac5d5b 100644 --- a/deps/libmagic/AUTHORS +++ b/deps/libmagic/AUTHORS @@ -1 +1 @@ -See COPYING. \ No newline at end of file +See COPYING. diff --git a/deps/libmagic/COPYING b/deps/libmagic/COPYING index b3db8b2..16410a1 100644 --- a/deps/libmagic/COPYING +++ b/deps/libmagic/COPYING @@ -1,4 +1,4 @@ -$File: COPYING,v 1.1 2008/02/05 19:08:11 christos Exp $ +$File: COPYING,v 1.2 2018/09/09 20:33:28 christos Exp $ Copyright (c) Ian F. Darwin 1986, 1987, 1989, 1990, 1991, 1992, 1994, 1995. Software written by Ian F. Darwin and others; maintained 1994- Christos Zoulas. @@ -15,7 +15,7 @@ are met: 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE diff --git a/deps/libmagic/ChangeLog b/deps/libmagic/ChangeLog index 2063a23..767798b 100644 --- a/deps/libmagic/ChangeLog +++ b/deps/libmagic/ChangeLog @@ -1,3 +1,146 @@ +2020-02-13 13:10 Christos Zoulas + + * 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 + + * PR/136: Fix static build by adding a libmagic.pc (Fabrice Fontaine) + +2019-12-24 14:16 Christos Zoulas + + * add guid support + +2019-12-16 21:11 Christos Zoulas + + * release 5.38 + +2019-12-15 22:13 Christos Zoulas + Document changes since the previous release: + - Always accept -S (no sandbox) even if we don't support sandboxing + - More syscalls elided for sandboxiing + - For ELF dynamic means having an interpreter not just PT_DYNAMIC + - Check for large ELF session header offset + - When saving and restoring a locale, keep the locale name in our + own storage. + - Add a flag to disable CSV file detection. + - Don't pass NULL/0 to memset to appease sanitizers. + - Avoid spurious prints when looks for extensions or apple strings + in fsmagic. + - Add builtin decompressors for xz and and bzip. + - Add a limit for the number of CDF elements. + - More checks for overflow in CDF. + +2019-05-14 22:26 Christos Zoulas + + * release 5.37 + +2019-05-09 22:27 Christos Zoulas + + * Make sure that continuation separators are printed + with -k within softmagic + +2019-05-06 22:27 Christos Zoulas + + * Change SIGPIPE saving and restoring during compression to use + sigaction(2) instead of signal(3) and cache it. (Denys Vlasenko) + * Cache stat(2) calls more to reduce number of calls (Denys Vlasenko) + +2019-05-06 17:25 Christos Zoulas + + * PR/77: Handle --mime-type and -k correctly. + +2019-05-03 15:26 Christos Zoulas + + * Switch decompression code to use vfork() because + tools like rpmdiff and rpmbuild call libmagic + with large process footprints (Denys Vlasenko) + +2019-04-07 14:05 Christos Zoulas + + * PR/75: --enable-zlib, did not work. + +2019-02-27 11:54 Christos Zoulas + + * Improve regex efficiency (Michael Schroeder) by: + 1. Prefixing regex searches with regular search + for keywords where possible + 2. Using memmem(3) where available + +2019-02-20 10:16 Christos Zoulas + + * release 5.36 + +2019-02-19 15:30 Christos Zoulas + + * Fix cast to use cast macros + * Add UCS-32 builtin detection (PR/61) reported by tmc + +2019-02-18 18:24 Christos Zoulas + + * Fix stack read (PR/62) and write (PR/64) stack overflows + reported by spinpx + +2018-10-18 19:32 Christos Zoulas + + * release 5.35 + +2018-09-10 20:38 Christos Zoulas + + * Add FreeBSD ELF core file support (John Baldwin) + +2018-08-20 18:40 Christos Zoulas + + * PR/30: Allow all parameter values to be set (don't treat 0 specially) + * handle default annotations on the softmagic match instead at the + end. + +2018-07-25 10:17 Christos Zoulas + + * PR/23: Recognize JSON files + +2018-07-25 10:17 Christos Zoulas + + * PR/18: file --mime-encoding should not print mime-type + +2018-07-25 8:50 Christos Zoulas + + * release 5.34 + +2018-06-22 16:38 Christos Zoulas + + * Add Quad indirect offsets + +2018-05-24 14:10 Christos Zoulas + + * Enable parsing of ELF dynamic sections to handle PIE better + +2018-04-15 14:52 Christos Zoulas + + * release 5.33 + +2018-02-24 14:50 Christos Zoulas + + * extend the support for ${x?:} expansions for magic descriptions + +2018-02-21 16:25 Christos Zoulas + + * add support for ${x?:} in mime types to handle + pie binaries. + +2017-11-03 9:23 Christos Zoulas + + * add support for negative offsets (offsets from the end of file) + +2017-09-26 8:22 Christos Zoulas + + * close the file on error when writing magic (Steve Grubb) + +2017-09-24 12:02 Christos Zoulas + + * seccomp support (Paul Moore) + 2017-09-02 11:53 Christos Zoulas * release 5.32 @@ -53,7 +196,7 @@ * Add missing overflow check in der magic (Jonas Wagner) 2016-10-25 10:40 Christos Zoulas - + * release 5.29 2016-10-24 11:20 Christos Zoulas @@ -94,11 +237,11 @@ - set offset to 0 on failure. 2016-05-13 12:00 Christos Zoulas - + * release 5.27 2016-04-18 9:35 Christos Zoulas - + * Errors comparing DER entries or computing offsets are just indications of malformed non-DER files. Don't print them. @@ -107,7 +250,7 @@ * Put new bytes constant in the right file (not the generated one) 2016-04-16 18:34 Christos Zoulas - + * release 5.26 2016-03-31 13:50 Christos Zoulas @@ -153,7 +296,7 @@ * PR/492: compression forking was broken with magic_buffer. 2015-09-16 9:50 Christos Zoulas - + * release 5.25 2015-09-11 13:25 Christos Zoulas @@ -181,7 +324,7 @@ * release 5.23 2015-06-09 16:10 Christos Zoulas - + * Fix issue with regex range for magic with offset * Always return true from mget with USE (success to mget not match indication). Fixes mime evaluation after USE magic @@ -234,12 +377,12 @@ * add indirect relative for TIFF/Exif 2014-12-16 18:10 Christos Zoulas - + * restructure elf note printing to avoid repeated messages * add note limit, suggested by Alexander Cherepanov 2014-12-16 16:53 Christos Zoulas - + * Bail out on partial pread()'s (Alexander Cherepanov) * Fix incorrect bounds check in file_printable (Alexander Cherepanov) @@ -250,7 +393,7 @@ more places for safety * in ELF, instead of "(uses dynamic libraries)" when PT_INTERP is present print the interpreter name. - + 2014-12-10 20:01 Christos Zoulas * release 5.21 @@ -293,7 +436,7 @@ on a byte by byte basis, so that we don't get issues with locale's trying to interpret random byte streams as UTF-8 and having printf error out with EILSEQ. - + 2014-10-17 11:48 Christos Zoulas * fix bounds in note reading (Francisco Alonso / Red Hat) @@ -324,7 +467,7 @@ * release 5.19 2014-06-09 9:04 Christos Zoulas - + * Misc buffer overruns and missing buffer size tests in cdf parsing (Francisco Alonso, Jan Kaluza) @@ -354,7 +497,7 @@ 2014-05-04 14:55 Christos Zoulas - * PR/351: Fix compilation of empty files + * PR/351: Fix compilation of empty files 2014-04-30 17:39 Christos Zoulas @@ -458,7 +601,7 @@ * Don't treat magic as an error if offset was past EOF (Christoph Biedl) 2013-05-28 17:25 Christos Zoulas - + * Fix spacing issues in softmagic and elf (Jan Kaluza) 2013-05-02 18:00 Christos Zoulas @@ -514,7 +657,7 @@ * Make getline public so that file can link against it. Perhaps it is better to rename it, or hide it differently. Fixes builds on platforms that do not provide it. - + 2013-01-07 16:30 Christos Zoulas * Add SuS d{,1,2,4,8}, u{,1,2,4,8} and document @@ -864,7 +1007,7 @@ (Cheng Renquan) 2009-05-08 13:40 Christos Zoulas - + * lint fixes and more from NetBSD 2009-05-06 10:25 Christos Zoulas @@ -884,7 +1027,7 @@ 2009-03-27 18:43 Christos Zoulas - * don't print \012- separators in the same magic entry + * don't print \012- separators in the same magic entry if it consists of multiple magic printing lines. 2009-03-23 10:20 Christos Zoulas diff --git a/deps/libmagic/MAINT b/deps/libmagic/MAINT index b881615..6820306 100644 --- a/deps/libmagic/MAINT +++ b/deps/libmagic/MAINT @@ -1,4 +1,4 @@ -$File: MAINT,v 1.10 2008/02/05 19:08:11 christos Exp $ +$File: MAINT,v 1.9 2007/01/19 21:15:27 christos Exp $ Maintenance notes: diff --git a/deps/libmagic/NEWS b/deps/libmagic/NEWS index 939a279..898a3da 100644 --- a/deps/libmagic/NEWS +++ b/deps/libmagic/NEWS @@ -1 +1 @@ -See ChangeLog. \ No newline at end of file +See ChangeLog. diff --git a/deps/libmagic/README b/deps/libmagic/README index bb8186f..f69dc43 100644 --- a/deps/libmagic/README +++ b/deps/libmagic/README @@ -1,13 +1,12 @@ -## README for file(1) Command ## +## README for file(1) Command and the libmagic(3) library ## - @(#) $File: README,v 1.50 2016/04/16 22:40:54 christos Exp $ + @(#) $File: README,v 1.59 2019/09/19 01:04:01 christos Exp $ -Mailing List: file@mx.gw.com -Mailing List archives: http://mx.gw.com/pipermail/file/ -Bug tracker: http://bugs.gw.com/ +Mailing List: file@astron.com +Mailing List archives: http://mailman.astron.com/pipermail/file/ +Bug tracker: http://bugs.astron.com/ E-mail: christos@astron.com - -[![Build Status](https://travis-ci.org/file/file.png?branch=master)](https://travis-ci.org/file/file) +Build Status: https://travis-ci.org/file/file Phone: Do not even think of telephoning me about this program. Send cash first! @@ -25,6 +24,10 @@ A public read-only git repository of the same sources is available at: https://github.com/file/file +We are continuously being fuzzed by OSS-FUZZ: + + https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:file + The major changes for 5.x are CDF file parsing, indirect magic, name/use (recursion) and overhaul in mime and ascii encoding handling. @@ -64,73 +67,55 @@ magic numbers assigned to all sorts of data files that are in reasonable circulation. Send your magic numbers, in magic(5) format please, to the maintainer, Christos Zoulas. -COPYING - read this first. -README - read this second (you are currently reading this file). +COPYING - read this first. +README - read this second (you are currently reading this file). INSTALL - read on how to install -src/localtime_r.c -src/magic.c -src/magic.h -src/mygetopt.h -src/newtest2.c -src/newtest3.c -src/pread.c -src/print.c -src/readcdf.c -src/readelf.c -src/readelf.h -src/regex.c -src/regex2.c -src/softmagic.c -src/strcasestr.c -src/strlcat.c -src/strlcpy.c -src/strndup.c -src/tar.h -src/teststrchr.c -src/vasprintf.c -src/x.c -src/apprentice.c - parses /etc/magic to learn magic -src/apptype.c - used for OS/2 specific application type magic -src/ascmagic.c - third & last set of tests, based on hardwired assumptions. -src/asctime_r.c - replacement for OS's that don't have it. -src/asprintf.c - replacement for OS's that don't have it. -src/asctime_r.c - replacement for OS's that don't have it. -src/asprintf.c - replacement for OS's that don't have it. -src/cdf.[ch] - parser for Microsoft Compound Document Files -src/cdf_time.c - time converter for CDF. -src/compress.c - handles decompressing files to look inside. -src/ctime_r.c - replacement for OS's that don't have it. +src/apprentice.c - parses /etc/magic to learn magic +src/apptype.c - used for OS/2 specific application type magic +src/ascmagic.c - third & last set of tests, based on hardwired assumptions. +src/asctime_r.c - replacement for OS's that don't have it. +src/asprintf.c - replacement for OS's that don't have it. +src/asctime_r.c - replacement for OS's that don't have it. +src/asprintf.c - replacement for OS's that don't have it. +src/buffer.c - buffer handling functions. +src/cdf.[ch] - parser for Microsoft Compound Document Files +src/cdf_time.c - time converter for CDF. +src/compress.c - handles decompressing files to look inside. +src/ctime_r.c - replacement for OS's that don't have it. src/der.[ch] - parser for Distinguished Encoding Rules src/dprintf.c - replacement for OS's that don't have it. src/elfclass.h - common code for elf 32/64. -src/encoding.c - handles unicode encodings -src/file.c - the main program -src/file.h - header file +src/encoding.c - handles unicode encodings +src/file.c - the main program +src/file.h - header file src/file_opts.h - list of options -src/fmtcheck.c - replacement for OS's that don't have it. -src/fsmagic.c - first set of tests the program runs, based on filesystem info -src/funcs.c - utilility functions -src/getline.c - replacement for OS's that don't have it. -src/getopt_long.c - replacement for OS's that don't have it. -src/gmtime_r.c - replacement for OS's that don't have it. -src/is_tar.c, tar.h - knows about Tape ARchive format (courtesy John Gilmore). -src/localtime_r.c - replacement for OS's that don't have it. +src/fmtcheck.c - replacement for OS's that don't have it. +src/fsmagic.c - first set of tests the program runs, based on filesystem info +src/funcs.c - utilility functions +src/getline.c - replacement for OS's that don't have it. +src/getopt_long.c - replacement for OS's that don't have it. +src/gmtime_r.c - replacement for OS's that don't have it. +src/is_csv.c - knows about Comma Separated Value file format (RFC 4180). +src/is_json.c - knows about JavaScript Object Notation format (RFC 8259). +src/is_tar.c, tar.h - knows about Tape ARchive format (courtesy John Gilmore). +src/localtime_r.c - replacement for OS's that don't have it. src/magic.h.in - source file for magic.h -src/mygetopt.h - replacement for OS's that don't have it. -src/magic.c - the libmagic api -src/names.h - header file for ascmagic.c -src/pread.c - replacement for OS's that don't have it. -src/print.c - print results, errors, warnings. -src/readcdf.c - CDF wrapper. -src/readelf.[ch] - Stand-alone elf parsing code. -src/softmagic.c - 2nd set of tests, based on /etc/magic -src/mygetopt.h - replacement for OS's that don't have it. -src/strcasestr.c - replacement for OS's that don't have it. -src/strlcat.c - replacement for OS's that don't have it. -src/strlcpy.c - replacement for OS's that don't have it. +src/mygetopt.h - replacement for OS's that don't have it. +src/magic.c - the libmagic api +src/names.h - header file for ascmagic.c +src/pread.c - replacement for OS's that don't have it. +src/print.c - print results, errors, warnings. +src/readcdf.c - CDF wrapper. +src/readelf.[ch] - Stand-alone elf parsing code. +src/softmagic.c - 2nd set of tests, based on /etc/magic +src/mygetopt.h - replacement for OS's that don't have it. +src/strcasestr.c - replacement for OS's that don't have it. +src/strlcat.c - replacement for OS's that don't have it. +src/strlcpy.c - replacement for OS's that don't have it. +src/strndup.c - replacement for OS's that don't have it. src/tar.h - tar file definitions -src/vasprintf.c - for systems that don't have it. -doc/file.man - man page for the command +src/vasprintf.c - for systems that don't have it. +doc/file.man - man page for the command doc/magic.man - man page for the magic file, courtesy Guy Harris. Install as magic.4 on USG and magic.5 on V7 or Berkeley; cf Makefile. @@ -156,6 +141,19 @@ guidelines: ------------------------------------------------------------------------------ +gpg for dummies: + +$ gpg --verify file-X.YY.tar.gz.asc file-X.YY.tar.gz +gpg: assuming signed data in `file-X.YY.tar.gz' +gpg: Signature made WWW MMM DD HH:MM:SS YYYY ZZZ using DSA key ID KKKKKKKK + +To download the key: + +$ gpg --keyserver hkp://keys.gnupg.net --recv-keys KKKKKKKK + +------------------------------------------------------------------------------ + + Parts of this software were developed at SoftQuad Inc., developers of SGML/HTML/XML publishing software, in Toronto, Canada. SoftQuad was swallowed up by Corel in 2002 and does not exist any longer. diff --git a/deps/libmagic/TODO b/deps/libmagic/TODO index 78890cf..836d6b5 100644 --- a/deps/libmagic/TODO +++ b/deps/libmagic/TODO @@ -31,6 +31,19 @@ could require structural changes to the matching code :-( # rule 2 >0 .... ... +--- +- Merge the stat code dance in one place and keep it in one place + (perhaps struct buffer). +- Enable seeking around if offset > nbytes if possible (the fd + is seekable). +- We could use file_pipe2file more (for EOF offsets, CDF documents), + but that is expensive; perhaps we should provide a way to disable it +- The implementation of struct buffer needs re-thinking and more work. + For example we don't always pass the fd in the child. This is not + important yet as we don't have yet cases where use/indirect magic + needs negative offsets. +- Really the whole thing just needs here's an (offset, buffer, size) + you have (filebuffer, filebuffersize &&|| fd), fill the buffer with + data from offset. The buffer API should be changed to just do that. christos - diff --git a/deps/libmagic/libmagic.gyp b/deps/libmagic/libmagic.gyp index 76be697..301638e 100644 --- a/deps/libmagic/libmagic.gyp +++ b/deps/libmagic/libmagic.gyp @@ -66,6 +66,7 @@ 'src/apprentice.c', 'src/apptype.c', 'src/ascmagic.c', + 'src/buffer.c', 'src/cdf.c', 'src/cdf_time.c', 'src/compress.c', @@ -74,6 +75,8 @@ 'src/fsmagic.c', 'src/funcs.c', 'src/is_tar.c', + 'src/is_csv.c', + 'src/is_json.c', 'src/magic.c', 'src/print.c', 'src/readcdf.c', diff --git a/deps/libmagic/src/apprentice.c b/deps/libmagic/src/apprentice.c index 8197f65..adc4c84 100644 --- a/deps/libmagic/src/apprentice.c +++ b/deps/libmagic/src/apprentice.c @@ -2,7 +2,7 @@ * Copyright (c) Ian F. Darwin 1986-1995. * Software written by Ian F. Darwin and others; * maintained 1995-present by Christos Zoulas and others. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: apprentice.c,v 1.262 2017/08/28 13:39:18 christos Exp $") +FILE_RCSID("@(#)$File: apprentice.c,v 1.295 2020/03/11 21:53:27 christos Exp $") #endif /* lint */ #include "magic.h" @@ -40,9 +40,7 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.262 2017/08/28 13:39:18 christos Exp $") #ifdef HAVE_UNISTD_H #include #endif -#ifdef HAVE_STDDEF_H #include -#endif #include #include #include @@ -50,24 +48,14 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.262 2017/08/28 13:39:18 christos Exp $") #ifdef QUICK #include #endif -// XXX: change by mscdex -#ifdef HAVE_DIRENT_H #include -#endif -#if defined(HAVE_LIMITS_H) #include -#endif -#ifndef SSIZE_MAX -#define MAXMAGIC_SIZE ((ssize_t)0x7fffffff) -#else -#define MAXMAGIC_SIZE SSIZE_MAX -#endif -#define EATAB {while (isascii((unsigned char) *l) && \ - isspace((unsigned char) *l)) ++l;} -#define LOWCASE(l) (isupper((unsigned char) (l)) ? \ - tolower((unsigned char) (l)) : (l)) +#define EATAB {while (isascii(CAST(unsigned char, *l)) && \ + isspace(CAST(unsigned char, *l))) ++l;} +#define LOWCASE(l) (isupper(CAST(unsigned char, l)) ? \ + tolower(CAST(unsigned char, l)) : (l)) /* * Work around a bug in headers on Digital Unix. * At least confirmed for: OSF1 V4.0 878 @@ -86,15 +74,15 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.262 2017/08/28 13:39:18 christos Exp $") #define MAP_FILE 0 #endif -#define ALLOC_CHUNK (size_t)10 -#define ALLOC_INCR (size_t)200 +#define ALLOC_CHUNK CAST(size_t, 10) +#define ALLOC_INCR CAST(size_t, 200) #define MAP_TYPE_USER 0 #define MAP_TYPE_MALLOC 1 #define MAP_TYPE_MMAP 2 struct magic_entry { - struct magic *mp; + struct magic *mp; uint32_t cont_count; uint32_t max_count; }; @@ -129,9 +117,10 @@ private int apprentice_1(struct magic_set *, const char *, int); private size_t apprentice_magic_strength(const struct magic *); private int apprentice_sort(const void *, const void *); private void apprentice_list(struct mlist *, int ); -private struct magic_map *apprentice_load(struct magic_set *, +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 *); @@ -149,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); @@ -162,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), @@ -272,6 +266,7 @@ 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_NULL, FILE_INVALID, FILE_FMT_NONE }, }; @@ -303,12 +298,21 @@ get_type(const struct type_tbl_s *tbl, const char *l, const char **t) return p->type; } +private off_t +maxoff_t(void) { + if (/*CONSTCOND*/sizeof(off_t) == sizeof(int)) + return CAST(off_t, INT_MAX); + if (/*CONSTCOND*/sizeof(off_t) == sizeof(long)) + return CAST(off_t, LONG_MAX); + return 0x7fffffff; +} + private int get_standard_integer_type(const char *l, const char **t) { int type; - if (isalpha((unsigned char)l[1])) { + if (isalpha(CAST(unsigned char, l[1]))) { switch (l[1]) { case 'C': /* "dC" and "uC" */ @@ -343,7 +347,7 @@ get_standard_integer_type(const char *l, const char **t) return FILE_INVALID; } l += 2; - } else if (isdigit((unsigned char)l[1])) { + } else if (isdigit(CAST(unsigned char, l[1]))) { /* * "d{num}" and "u{num}"; we only support {num} values * of 1, 2, 4, and 8 - the Single UNIX Specification @@ -354,7 +358,7 @@ get_standard_integer_type(const char *l, const char **t) * neither of them support values bigger than 8 or * non-power-of-2 values. */ - if (isdigit((unsigned char)l[2])) { + if (isdigit(CAST(unsigned char, l[2]))) { /* Multi-digit, so > 9 */ return FILE_INVALID; } @@ -440,8 +444,8 @@ apprentice_1(struct magic_set *ms, const char *fn, int action) if (magicsize != FILE_MAGICSIZE) { file_error(ms, 0, "magic element size %lu != %lu", - (unsigned long)sizeof(*map->magic[0]), - (unsigned long)FILE_MAGICSIZE); + CAST(unsigned long, sizeof(*map->magic[0])), + CAST(unsigned long, FILE_MAGICSIZE)); return -1; } @@ -454,8 +458,6 @@ apprentice_1(struct magic_set *ms, const char *fn, int action) #ifndef COMPILE_ONLY map = apprentice_map(ms, fn); - if (map == (struct magic_map *)-1) - return -1; if (map == NULL) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "using regular magic file `%s'", fn); @@ -466,6 +468,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; } @@ -506,7 +513,7 @@ file_ms_alloc(int flags) struct magic_set *ms; size_t i, len; - if ((ms = CAST(struct magic_set *, calloc((size_t)1, + if ((ms = CAST(struct magic_set *, calloc(CAST(size_t, 1u), sizeof(struct magic_set)))) == NULL) return NULL; @@ -516,6 +523,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) @@ -584,6 +592,25 @@ mlist_alloc(void) return mlist; } +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) + apprentice_unmap(CAST(struct magic_map *, ml->map)); + free(ml); +} + private void mlist_free(struct mlist *mlist) { @@ -592,14 +619,12 @@ mlist_free(struct mlist *mlist) if (mlist == NULL) return; - ml = mlist->next; - for (ml = mlist->next; (next = ml->next) != NULL; ml = next) { - if (ml->map) - apprentice_unmap(CAST(struct magic_map *, ml->map)); - free(ml); - if (ml == mlist) - break; + for (ml = mlist->next; ml != mlist;) { + next = ml->next; + mlist_free_one(ml); + ml = next; } + mlist_free_one(mlist); } #ifndef COMPILE_ONLY @@ -642,10 +667,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 @@ -655,8 +677,8 @@ protected int file_apprentice(struct magic_set *ms, const char *fn, int action) { char *p, *mfn; - int file_err, errs = -1; - size_t i; + int fileerr, errs = -1; + size_t i, j; (void)file_reset(ms, 0); @@ -674,9 +696,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; @@ -690,8 +712,8 @@ file_apprentice(struct magic_set *ms, const char *fn, int action) *p++ = '\0'; if (*fn == '\0') break; - file_err = apprentice_1(ms, fn, action); - errs = MAX(errs, file_err); + fileerr = apprentice_1(ms, fn, action); + errs = MAX(errs, fileerr); fn = p; } @@ -702,8 +724,7 @@ file_apprentice(struct magic_set *ms, const char *fn, int action) mlist_free(ms->mlist[i]); ms->mlist[i] = NULL; } - // XXX: change by mscdex - file_error(ms, 0, "could not load any valid magic files!"); + file_error(ms, 0, "could not find any valid magic files!"); return -1; } @@ -829,8 +850,12 @@ typesize(int type) case FILE_BEDOUBLE: case FILE_LEDOUBLE: return 8; + + case FILE_GUID: + return 16; + default: - return (size_t)~0; + return FILE_BADSIZE; } } @@ -840,8 +865,9 @@ typesize(int type) private size_t apprentice_magic_strength(const struct magic *m) { -#define MULT 10 - size_t ts, v, val = 2 * MULT; /* baseline strength */ +#define MULT 10U + size_t ts, v; + ssize_t val = 2 * MULT; /* baseline strength */ switch (m->type) { case FILE_DEFAULT: /* make sure this sorts last */ @@ -883,8 +909,9 @@ apprentice_magic_strength(const struct magic *m) case FILE_DOUBLE: case FILE_BEDOUBLE: case FILE_LEDOUBLE: + case FILE_GUID: ts = typesize(m->type); - if (ts == (size_t)~0) + if (ts == FILE_BADSIZE) abort(); val += ts * MULT; break; @@ -900,6 +927,8 @@ apprentice_magic_strength(const struct magic *m) break; case FILE_SEARCH: + if (m->vallen == 0) + break; val += m->vallen * MAX(MULT / m->vallen, 1); break; @@ -947,9 +976,6 @@ apprentice_magic_strength(const struct magic *m) abort(); } - if (val == 0) /* ensure we only return 0 for FILE_DEFAULT */ - val = 1; - switch (m->factor_op) { case FILE_FACTOR_OP_NONE: break; @@ -969,6 +995,9 @@ apprentice_magic_strength(const struct magic *m) abort(); } + if (val <= 0) /* ensure we only return 0 for FILE_DEFAULT */ + val = 1; + /* * Magic entries with no description get a bonus because they depend * on subsequent magic entries to print something. @@ -978,7 +1007,7 @@ apprentice_magic_strength(const struct magic *m) return val; } -/* +/* * Sort callback for sorting entries by "strength" (basically length) */ private int @@ -996,7 +1025,7 @@ apprentice_sort(const void *a, const void *b) return 1; } -/* +/* * Shows sorted patterns list in the order which is used for the matching */ private void @@ -1073,6 +1102,7 @@ set_test_type(struct magic *mstart, struct magic *m) case FILE_BEDOUBLE: case FILE_LEDOUBLE: case FILE_DER: + case FILE_GUID: mstart->flag |= BINTEST; break; case FILE_STRING: @@ -1092,12 +1122,12 @@ set_test_type(struct magic *mstart, struct magic *m) mstart->flag |= BINTEST; if (mstart->str_flags & STRING_TEXTTEST) mstart->flag |= TEXTTEST; - + if (mstart->flag & (TEXTTEST|BINTEST)) break; /* binary test if pattern is not text */ - if (file_looks_utf8(m->value.us, (size_t)m->vallen, NULL, + if (file_looks_utf8(m->value.us, CAST(size_t, m->vallen), NULL, NULL) <= 0) mstart->flag |= BINTEST; else @@ -1178,7 +1208,7 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs, size_t i; for (i = 0; bang[i].name != NULL; i++) { - if ((size_t)(len - 2) > bang[i].len && + if (CAST(size_t, len - 2) > bang[i].len && memcmp(bang[i].name, line + 2, bang[i].len) == 0) break; @@ -1197,7 +1227,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; } @@ -1231,7 +1262,7 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs, private int cmpstrp(const void *p1, const void *p2) { - return strcmp(*(char *const *)p1, *(char *const *)p2); + return strcmp(*RCAST(char *const *, p1), *RCAST(char *const *, p2)); } @@ -1257,10 +1288,10 @@ set_text_binary(struct magic_set *ms, struct magic_entry *me, uint32_t nme, if (me[i].mp->flag & BINTEST) { char *p = strstr(me[i].mp->desc, text); if (p && (p == me[i].mp->desc || - isspace((unsigned char)p[-1])) && + isspace(CAST(unsigned char, p[-1]))) && (p + len - me[i].mp->desc == MAXstring || (p[len] == '\0' || - isspace((unsigned char)p[len])))) + isspace(CAST(unsigned char, p[len]))))) (void)fprintf(stderr, "*** Possible " "binary test for text type\n"); } @@ -1284,7 +1315,7 @@ set_last_default(struct magic_set *ms, struct magic_entry *me, uint32_t nme) file_magwarn(ms, "level 0 \"default\" did not sort last"); } - return; + return; } } } @@ -1340,8 +1371,7 @@ apprentice_load(struct magic_set *ms, const char *fn, int action) struct dirent *d; memset(mset, 0, sizeof(mset)); - // XXX: change by mscdex - //ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */ + ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */ if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) @@ -1378,9 +1408,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); @@ -1388,16 +1419,20 @@ apprentice_load(struct magic_set *ms, const char *fn, int action) errs++; goto out; } + filearr = nfilearr; } filearr[files++] = mfn; } closedir(dir); - qsort(filearr, files, sizeof(*filearr), cmpstrp); - for (i = 0; i < files; i++) { - load_1(ms, action, filearr[i], &errs, mset); - free(filearr[i]); + if (filearr) { + qsort(filearr, files, sizeof(*filearr), cmpstrp); + for (i = 0; i < files; i++) { + load_1(ms, action, filearr[i], &errs, mset); + free(filearr[i]); + } + free(filearr); + filearr = NULL; } - free(filearr); } else load_1(ms, action, fn, &errs, mset); if (errs) @@ -1431,6 +1466,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); @@ -1455,12 +1491,12 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v) * the sign extension must have happened. */ case FILE_BYTE: - v = (signed char) v; + v = CAST(signed char, v); break; case FILE_SHORT: case FILE_BESHORT: case FILE_LESHORT: - v = (short) v; + v = CAST(short, v); break; case FILE_DATE: case FILE_BEDATE: @@ -1477,7 +1513,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v) case FILE_FLOAT: case FILE_BEFLOAT: case FILE_LEFLOAT: - v = (int32_t) v; + v = CAST(int32_t, v); break; case FILE_QUAD: case FILE_BEQUAD: @@ -1494,7 +1530,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v) case FILE_DOUBLE: case FILE_BEDOUBLE: case FILE_LEDOUBLE: - v = (int64_t) v; + v = CAST(int64_t, v); break; case FILE_STRING: case FILE_PSTRING: @@ -1513,7 +1549,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v) if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "cannot happen: m->type=%d\n", m->type); - return ~0U; + return FILE_BADSIZE; } } return v; @@ -1621,7 +1657,7 @@ get_cond(const char *l, const char **t) for (p = cond_tbl; p->len; p++) { if (strncmp(l, p->name, p->len) == 0 && - isspace((unsigned char)l[p->len])) { + isspace(CAST(unsigned char, l[p->len]))) { if (t) *t = l + p->len; break; @@ -1679,7 +1715,7 @@ parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp) { const char *l = *lp; - while (!isspace((unsigned char)*++l)) + while (!isspace(CAST(unsigned char, *++l))) switch (*l) { case CHAR_INDIRECT_RELATIVE: m->str_flags |= INDIRECT_RELATIVE; @@ -1705,7 +1741,7 @@ parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp, ++l; m->mask_op |= op; - val = (uint64_t)strtoull(l, &t, 0); + val = CAST(uint64_t, strtoull(l, &t, 0)); l = t; m->num_mask = file_signextend(ms, m, val); eatsize(&l); @@ -1719,7 +1755,7 @@ parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp) char *t; int have_range = 0; - while (!isspace((unsigned char)*++l)) { + while (!isspace(CAST(unsigned char, *++l))) { switch (*l) { case '0': case '1': case '2': case '3': case '4': case '5': @@ -1801,7 +1837,7 @@ parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp) goto out; } /* allow multiple '/' for readability */ - if (l[1] == '/' && !isspace((unsigned char)l[2])) + if (l[1] == '/' && !isspace(CAST(unsigned char, l[2]))) l++; } if (string_modifier_check(ms, m) == -1) @@ -1838,7 +1874,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, */ while (*l == '>') { ++l; /* step over */ - cont_level++; + cont_level++; } #ifdef ENABLE_CONDITIONALS if (cont_level == 0 || cont_level > last_cont_level) @@ -1856,7 +1892,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, return -1; } m = &me->mp[me->cont_count - 1]; - diff = (int32_t)cont_level - (int32_t)m->cont_level; + diff = CAST(int32_t, cont_level) - CAST(int32_t, m->cont_level); if (diff > 1) file_magwarn(ms, "New continuation level %u is more " "than one larger than current level %u", cont_level, @@ -1869,7 +1905,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, file_oomem(ms, sizeof(*nm) * cnt); return -1; } - me->mp = m = nm; + me->mp = nm; me->max_count = CAST(uint32_t, cnt); } m = &me->mp[me->cont_count++]; @@ -1915,12 +1951,13 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, } /* get offset, then skip over it */ - m->offset = (uint32_t)strtoul(l, &t, 0); + m->offset = CAST(int32_t, strtol(l, &t, 0)); if (l == t) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "offset `%s' invalid", l); return -1; } + l = t; if (m->flag & INDIR) { @@ -1974,6 +2011,12 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, case 'I': m->in_type = FILE_BEID3; break; + case 'q': + m->in_type = FILE_LEQUAD; + break; + case 'Q': + m->in_type = FILE_BEQUAD; + break; default: if (ms->flags & MAGIC_CHECK) file_magwarn(ms, @@ -1996,8 +2039,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, m->in_op |= FILE_OPINDIRECT; l++; } - if (isdigit((unsigned char)*l) || *l == '-') { - m->in_offset = (int32_t)strtol(l, &t, 0); + if (isdigit(CAST(unsigned char, *l)) || *l == '-') { + m->in_offset = CAST(int32_t, strtol(l, &t, 0)); if (l == t) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, @@ -2006,7 +2049,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, } l = t; } - if (*l++ != ')' || + if (*l++ != ')' || ((m->in_op & FILE_OPINDIRECT) && *l++ != ')')) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, @@ -2031,7 +2074,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, /* * Try it as a keyword type prefixed by "u"; match what * follows the "u". If that fails, try it as an SUS - * integer type. + * integer type. */ m->type = get_type(type_tbl, l + 1, &l); if (m->type == FILE_INVALID) { @@ -2060,7 +2103,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, */ if (*l == 'd') m->type = get_standard_integer_type(l, &l); - else if (*l == 's' && !isalpha((unsigned char)l[1])) { + else if (*l == 's' + && !isalpha(CAST(unsigned char, l[1]))) { m->type = FILE_STRING; ++l; } @@ -2071,7 +2115,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, /* Not found - try it as a special keyword. */ m->type = get_type(special_tbl, l, &l); } - + if (m->type == FILE_INVALID) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "type `%s' invalid", l); @@ -2118,7 +2162,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, * anything if mask = 0 (unless you have a better idea) */ EATAB; - + switch (*l) { case '>': case '<': @@ -2150,8 +2194,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, break; default: m->reln = '='; /* the default relation */ - if (*l == 'x' && ((isascii((unsigned char)l[1]) && - isspace((unsigned char)l[1])) || !l[1])) { + if (*l == 'x' && ((isascii(CAST(unsigned char, l[1])) && + isspace(CAST(unsigned char, l[1]))) || !l[1])) { m->reln = *l; ++l; } @@ -2165,7 +2209,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, /* * TODO finish this macro and start using it! - * #define offsetcheck {if (offset > ms->bytes_max -1) + * #define offsetcheck {if (offset > ms->bytes_max -1) * magwarn("offset too big"); } */ @@ -2211,7 +2255,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; @@ -2248,11 +2293,11 @@ parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line) file_magwarn(ms, "Too large factor `%lu'", factor); goto out; } - if (*el && !isspace((unsigned char)*el)) { + if (*el && !isspace(CAST(unsigned char, *el))) { file_magwarn(ms, "Bad factor `%s'", l); goto out; } - m->factor = (uint8_t)factor; + m->factor = CAST(uint8_t, factor); if (m->factor == 0 && m->factor_op == FILE_FACTOR_OP_DIV) { file_magwarn(ms, "Cannot have factor op `%c' and factor %u", m->factor_op, m->factor); @@ -2273,7 +2318,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; @@ -2283,9 +2329,9 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line, if (buf[0] != '\0') { len = nt ? strlen(buf) : len; file_magwarn(ms, "Current entry already has a %s type " - "`%.*s', new type `%s'", name, (int)len, buf, l); + "`%.*s', new type `%s'", name, CAST(int, len), buf, l); return -1; - } + } if (*m->desc == '\0') { file_magwarn(ms, "Current entry does not yet have a " @@ -2294,7 +2340,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) { @@ -2304,7 +2351,7 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line, file_magwarn(ms, "%s type `%s' truncated %" SIZE_T_FORMAT "u", name, line, i); } else { - if (!isspace((unsigned char)*l) && !goodchar(*l, extra)) + if (!isspace(CAST(unsigned char, *l)) && !goodchar(*l, extra)) file_magwarn(ms, "%s type `%s' has bad char '%c'", name, line, *l); if (nt) @@ -2323,11 +2370,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); } @@ -2336,13 +2384,14 @@ 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); + sizeof(m->ext), "EXTENSION", ",!+-/@?_$", 0); } /* @@ -2350,13 +2399,14 @@ 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); + sizeof(m->mimetype), "MIME", "+-/.$?:{}", 1); } private int @@ -2406,7 +2456,7 @@ check_format_type(const char *ptr, int type, const char **estr) if (*ptr == '#') ptr++; #define CHECKLEN() do { \ - for (len = cnt = 0; isdigit((unsigned char)*ptr); ptr++, cnt++) \ + for (len = cnt = 0; isdigit(CAST(unsigned char, *ptr)); ptr++, cnt++) \ len = len * 10 + (*ptr - '0'); \ if (cnt > 5 || len > 1024) \ goto toolong; \ @@ -2422,7 +2472,7 @@ check_format_type(const char *ptr, int type, const char **estr) if (*ptr++ != 'l') goto invalid; } - + switch (*ptr++) { #ifdef STRICT_FORMAT /* "long" formats are int formats for us */ /* so don't accept the 'l' modifier */ @@ -2440,7 +2490,7 @@ check_format_type(const char *ptr, int type, const char **estr) default: goto invalid; } - + /* * Don't accept h and hh modifiers. They make writing * magic entries more complicated, for very little benefit @@ -2496,7 +2546,7 @@ check_format_type(const char *ptr, int type, const char **estr) default: goto invalid; } - + case FILE_FMT_FLOAT: case FILE_FMT_DOUBLE: if (*ptr == '-') @@ -2515,30 +2565,30 @@ check_format_type(const char *ptr, int type, const char **estr) case 'g': case 'G': return 0; - + default: goto invalid; } - + case FILE_FMT_STR: if (*ptr == '-') ptr++; - while (isdigit((unsigned char )*ptr)) + while (isdigit(CAST(unsigned char, *ptr))) ptr++; if (*ptr == '.') { ptr++; - while (isdigit((unsigned char )*ptr)) + while (isdigit(CAST(unsigned char , *ptr))) ptr++; } - + switch (*ptr++) { case 's': return 0; default: goto invalid; } - + default: /* internal error */ abort(); @@ -2549,7 +2599,7 @@ check_format_type(const char *ptr, int type, const char **estr) *estr = "too long"; return -1; } - + /* * Check that the optional printf format in description matches * the type of the magic. @@ -2572,7 +2622,7 @@ check_format(struct magic_set *ms, struct magic *m) if (m->type >= file_nformats) { file_magwarn(ms, "Internal error inconsistency between " - "m->type and format strings"); + "m->type and format strings"); return -1; } if (file_formats[m->type] == FILE_FMT_NONE) { @@ -2592,7 +2642,7 @@ check_format(struct magic_set *ms, struct magic *m) file_names[m->type], m->desc); return -1; } - + for (; *ptr; ptr++) { if (*ptr == '%') { file_magwarn(ms, @@ -2605,14 +2655,17 @@ check_format(struct magic_set *ms, struct magic *m) return 0; } -/* - * Read a numeric value from a pointer, into the value union of a magic - * pointer, according to the magic type. Update the string pointer to point +/* + * Read a numeric value from a pointer, into the value union of a magic + * pointer, according to the magic type. Update the string pointer to point * just after the number read. Return 0 for success, non-zero for failure. */ private int getvalue(struct magic_set *ms, struct magic *m, const char **p, int action) { + char *ep; + uint64_t ull; + switch (m->type) { case FILE_BESTRING16: case FILE_LESTRING16: @@ -2641,79 +2694,83 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action) return rc ? -1 : 0; } return 0; + default: + if (m->reln == 'x') + return 0; + break; + } + + switch (m->type) { case FILE_FLOAT: case FILE_BEFLOAT: case FILE_LEFLOAT: - if (m->reln != 'x') { - char *ep; - errno = 0; + errno = 0; #ifdef HAVE_STRTOF - m->value.f = strtof(*p, &ep); + m->value.f = strtof(*p, &ep); #else - m->value.f = (float)strtod(*p, &ep); + m->value.f = (float)strtod(*p, &ep); #endif - if (errno == 0) - *p = ep; - } + if (errno == 0) + *p = ep; return 0; case FILE_DOUBLE: case FILE_BEDOUBLE: case FILE_LEDOUBLE: - if (m->reln != 'x') { - char *ep; - errno = 0; - m->value.d = strtod(*p, &ep); - if (errno == 0) - *p = ep; - } + errno = 0; + m->value.d = strtod(*p, &ep); + 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: - if (m->reln != 'x') { - char *ep; - uint64_t ull; - errno = 0; - ull = (uint64_t)strtoull(*p, &ep, 0); - m->value.q = file_signextend(ms, m, ull); - if (*p == ep) { - file_magwarn(ms, "Unparseable number `%s'", *p); - } else { - size_t ts = typesize(m->type); - uint64_t x; - const char *q; - - if (ts == (size_t)~0) { - file_magwarn(ms, "Expected numeric type got `%s'", - type_tbl[m->type].name); - } - for (q = *p; isspace((unsigned char)*q); q++) - continue; - if (*q == '-') - ull = -(int64_t)ull; - switch (ts) { - case 1: - x = ull & ~0xffULL; - break; - case 2: - x = ull & ~0xffffULL; - break; - case 4: - x = ull & ~0xffffffffULL; - break; - case 8: - x = 0; - break; - default: - abort(); - } - if (x) { - file_magwarn(ms, "Overflow for numeric type `%s' value %#" PRIx64, - type_tbl[m->type].name, ull); - } + errno = 0; + ull = CAST(uint64_t, strtoull(*p, &ep, 0)); + m->value.q = file_signextend(ms, m, ull); + if (*p == ep) { + file_magwarn(ms, "Unparseable number `%s'", *p); + } else { + size_t ts = typesize(m->type); + uint64_t x; + const char *q; + + if (ts == FILE_BADSIZE) { + file_magwarn(ms, + "Expected numeric type got `%s'", + type_tbl[m->type].name); } - if (errno == 0) { - *p = ep; - eatsize(p); + for (q = *p; isspace(CAST(unsigned char, *q)); q++) + continue; + if (*q == '-') + ull = -CAST(int64_t, ull); + switch (ts) { + case 1: + x = CAST(uint64_t, ull & ~0xffULL); + break; + case 2: + x = CAST(uint64_t, ull & ~0xffffULL); + break; + case 4: + x = CAST(uint64_t, ull & ~0xffffffffULL); + break; + case 8: + x = 0; + break; + default: + abort(); } + if (x) { + file_magwarn(ms, "Overflow for numeric" + " type `%s' value %#" PRIx64, + type_tbl[m->type].name, ull); + } + } + if (errno == 0) { + *p = ep; + eatsize(p); } return 0; } @@ -2737,7 +2794,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn) int val; while ((c = *s++) != '\0') { - if (isspace((unsigned char) c)) + if (isspace(CAST(unsigned char, c))) break; if (p >= pmax) { file_error(ms, 0, "string too long: `%s'", origs); @@ -2761,8 +2818,8 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn) /*FALLTHROUGH*/ default: if (warn) { - if (isprint((unsigned char)c)) { - /* Allow escaping of + if (isprint(CAST(unsigned char, c))) { + /* Allow escaping of * ``relations'' */ if (strchr("<>&^=!", c) == NULL && (m->type != FILE_REGEX || @@ -2799,7 +2856,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn) case '!': /* and baskslash itself */ case '\\': - *p++ = (char) c; + *p++ = CAST(char, c); break; case 'a': @@ -2851,7 +2908,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn) } else --s; - *p++ = (char)val; + *p++ = CAST(char, val); break; /* \x and up to 2 hex digits */ @@ -2867,18 +2924,22 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn) --s; } else --s; - *p++ = (char)val; + *p++ = CAST(char, val); break; } } else - *p++ = (char)c; + *p++ = CAST(char, c); } --s; out: *p = '\0'; m->vallen = CAST(unsigned char, (p - origp)); - if (m->type == FILE_PSTRING) - m->vallen += (unsigned char)file_pstring_length_size(m); + 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; } @@ -2887,9 +2948,9 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn) private int hextoint(int c) { - if (!isascii((unsigned char) c)) + if (!isascii(CAST(unsigned char, c))) return -1; - if (isdigit((unsigned char) c)) + if (isdigit(CAST(unsigned char, c))) return c - '0'; if ((c >= 'a') && (c <= 'f')) return c + 10 - 'a'; @@ -2908,7 +2969,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; @@ -2967,7 +3028,7 @@ eatsize(const char **p) { const char *l = *p; - if (LOWCASE(*l) == 'u') + if (LOWCASE(*l) == 'u') l++; switch (LOWCASE(*l)) { @@ -3038,17 +3099,17 @@ apprentice_map(struct magic_set *ms, const char *fn) file_error(ms, errno, "cannot stat `%s'", dbname); goto error; } - if (st.st_size < 8 || st.st_size > MAXMAGIC_SIZE) { + if (st.st_size < 8 || st.st_size > maxoff_t()) { file_error(ms, 0, "file `%s' is too %s", dbname, st.st_size < 8 ? "small" : "large"); goto error; } - map->len = (size_t)st.st_size; + map->len = CAST(size_t, st.st_size); #ifdef QUICK map->type = MAP_TYPE_MMAP; - if ((map->p = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) { + if ((map->p = mmap(0, CAST(size_t, st.st_size), PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_FILE, fd, CAST(off_t, 0))) == MAP_FAILED) { file_error(ms, errno, "cannot map `%s'", dbname); goto error; } @@ -3062,17 +3123,15 @@ 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 = (struct magic_map *)-1; goto error; } #ifdef QUICK - if (mprotect(map->p, (size_t)st.st_size, PROT_READ) == -1) { + if (mprotect(map->p, CAST(size_t, st.st_size), PROT_READ) == -1) { file_error(ms, errno, "cannot mprotect `%s'", dbname); goto error; } @@ -3116,7 +3175,7 @@ check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname) VERSIONNO, dbname, version); return -1; } - entries = (uint32_t)(map->len / sizeof(struct magic)); + entries = CAST(uint32_t, map->len / sizeof(struct magic)); if ((entries * sizeof(struct magic)) != map->len) { file_error(ms, 0, "Size of `%s' %" SIZE_T_FORMAT "u is not " "a multiple of %" SIZE_T_FORMAT "u", @@ -3165,10 +3224,10 @@ apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn) dbname = mkdbname(ms, fn, 1); - if (dbname == NULL) + if (dbname == NULL) goto out; - if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1) + if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1) { file_error(ms, errno, "cannot open `%s'", dbname); goto out; @@ -3178,22 +3237,23 @@ apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn) hdr.h[1] = VERSIONNO; memcpy(hdr.h + 2, map->nmagic, nm); - if (write(fd, &hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr)) { + if (write(fd, &hdr, sizeof(hdr)) != CAST(ssize_t, sizeof(hdr))) { file_error(ms, errno, "error writing `%s'", dbname); - goto out; + goto out2; } for (i = 0; i < MAGIC_SETS; i++) { len = m * map->nmagic[i]; - if (write(fd, map->magic[i], len) != (ssize_t)len) { + if (write(fd, map->magic[i], len) != CAST(ssize_t, len)) { file_error(ms, errno, "error writing `%s'", dbname); - goto out; + goto out2; } } + rv = 0; +out2: if (fd != -1) (void)close(fd); - rv = 0; out: apprentice_unmap(map); free(dbname); @@ -3230,7 +3290,8 @@ mkdbname(struct magic_set *ms, const char *fn, int strip) q++; /* Compatibility with old code that looked in .mime */ if (ms->flags & MAGIC_MIME) { - if (asprintf(&buf, "%.*s.mime%s", (int)(q - fn), fn, ext) < 0) + if (asprintf(&buf, "%.*s.mime%s", CAST(int, q - fn), fn, ext) + < 0) return NULL; if (access(buf, R_OK) != -1) { ms->flags &= MAGIC_MIME_TYPE; @@ -3238,7 +3299,7 @@ mkdbname(struct magic_set *ms, const char *fn, int strip) } free(buf); } - if (asprintf(&buf, "%.*s%s", (int)(q - fn), fn, ext) < 0) + if (asprintf(&buf, "%.*s%s", CAST(int, q - fn), fn, ext) < 0) return NULL; /* Compatibility with old code that looked in .mime */ @@ -3265,8 +3326,8 @@ private uint16_t swap2(uint16_t sv) { uint16_t rv; - uint8_t *s = (uint8_t *)(void *)&sv; - uint8_t *d = (uint8_t *)(void *)&rv; + uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv)); + uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv)); d[0] = s[1]; d[1] = s[0]; return rv; @@ -3279,8 +3340,8 @@ private uint32_t swap4(uint32_t sv) { uint32_t rv; - uint8_t *s = (uint8_t *)(void *)&sv; - uint8_t *d = (uint8_t *)(void *)&rv; + uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv)); + uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv)); d[0] = s[3]; d[1] = s[2]; d[2] = s[1]; @@ -3295,8 +3356,8 @@ private uint64_t swap8(uint64_t sv) { uint64_t rv; - uint8_t *s = (uint8_t *)(void *)&sv; - uint8_t *d = (uint8_t *)(void *)&rv; + uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv)); + uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv)); #if 0 d[0] = s[3]; d[1] = s[2]; @@ -3326,9 +3387,9 @@ private void bs1(struct magic *m) { m->cont_level = swap2(m->cont_level); - m->offset = swap4((uint32_t)m->offset); - m->in_offset = swap4((uint32_t)m->in_offset); - m->lineno = swap4((uint32_t)m->lineno); + m->offset = swap4(CAST(uint32_t, m->offset)); + m->in_offset = swap4(CAST(uint32_t, m->in_offset)); + m->lineno = swap4(CAST(uint32_t, m->lineno)); if (IS_STRING(m->type)) { m->str_range = swap4(m->str_range); m->str_flags = swap4(m->str_flags); @@ -3339,8 +3400,8 @@ bs1(struct magic *m) } } -protected size_t -file_pstring_length_size(const struct magic *m) +protected size_t +file_pstring_length_size(struct magic_set *ms, const struct magic *m) { switch (m->str_flags & PSTRING_LEN) { case PSTRING_1_LE: @@ -3352,15 +3413,18 @@ 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 = (const unsigned char *)ss; + const unsigned char *s = RCAST(const unsigned char *, ss); unsigned int s3, s2, s1, s0; switch (m->str_flags & PSTRING_LEN) { @@ -3392,11 +3456,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; } diff --git a/deps/libmagic/src/apptype.c b/deps/libmagic/src/apptype.c index fcd764e..1bb33e4 100644 --- a/deps/libmagic/src/apptype.c +++ b/deps/libmagic/src/apptype.c @@ -1,15 +1,15 @@ /* * Adapted from: apptype.c, Written by Eberhard Mattes and put into the * public domain - * + * * Notes: 1. Qualify the filename so that DosQueryAppType does not do extraneous * searches. - * + * * 2. DosQueryAppType will return FAPPTYP_DOS on a file ending with ".com" * (other than an OS/2 exe or Win exe with this name). Eberhard Mattes * remarks Tue, 6 Apr 93: Moreover, it reports the type of the (new and very * bug ridden) Win Emacs as "OS/2 executable". - * + * * 3. apptype() uses the filename if given, otherwise a tmp file is created with * the contents of buf. If buf is not the complete file, apptype can * incorrectly identify the exe type. The "-z" option of "file" is the reason @@ -18,16 +18,16 @@ /* * amai: Darrel Hankerson did the changes described here. - * + * * It remains to check the validity of comments (2.) since it's referred to an * "old" OS/2 version. - * + * */ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: apptype.c,v 1.13 2011/09/07 21:57:15 christos Exp $") +FILE_RCSID("@(#)$File: apptype.c,v 1.14 2018/09/09 20:33:28 christos Exp $") #endif /* lint */ #include diff --git a/deps/libmagic/src/ascmagic.c b/deps/libmagic/src/ascmagic.c index 85a973e..3bb7359 100644 --- a/deps/libmagic/src/ascmagic.c +++ b/deps/libmagic/src/ascmagic.c @@ -35,12 +35,11 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: ascmagic.c,v 1.97 2016/06/27 20:56:25 christos Exp $") +FILE_RCSID("@(#)$File: ascmagic.c,v 1.105 2019/06/08 20:49:14 christos Exp $") #endif /* lint */ #include "magic.h" #include -#include #include #include #ifdef HAVE_UNISTD_H @@ -68,26 +67,33 @@ trim_nuls(const unsigned char *buf, size_t nbytes) } protected int -file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, - int text) +file_ascmagic(struct magic_set *ms, const struct buffer *b, int text) { unichar *ubuf = NULL; size_t ulen = 0; int rv = 1; + struct buffer bb; const char *code = NULL; const char *code_mime = NULL; const char *type = NULL; - nbytes = trim_nuls(buf, nbytes); + bb = *b; + bb.flen = trim_nuls(CAST(const unsigned char *, b->fbuf), b->flen); + /* + * Avoid trimming at an odd byte if the original buffer was evenly + * sized; this avoids losing the last character on UTF-16 LE text + */ + if ((bb.flen & 1) && !(b->flen & 1)) + bb.flen++; /* If file doesn't look like any sort of text, give up. */ - if (file_encoding(ms, buf, nbytes, &ubuf, &ulen, &code, &code_mime, + if (file_encoding(ms, &bb, &ubuf, &ulen, &code, &code_mime, &type) == 0) rv = 0; else - rv = file_ascmagic_with_encoding(ms, buf, nbytes, ubuf, ulen, code, - type, text); + rv = file_ascmagic_with_encoding(ms, &bb, + ubuf, ulen, code, type, text); free(ubuf); @@ -95,14 +101,18 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, } protected int -file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf, - size_t nbytes, unichar *ubuf, size_t ulen, const char *code, +file_ascmagic_with_encoding(struct magic_set *ms, + const struct buffer *b, unichar *ubuf, size_t ulen, const char *code, const char *type, int text) { + struct buffer bb; + const unsigned char *buf = CAST(const unsigned char *, b->fbuf); + size_t nbytes = b->flen; unsigned char *utf8_buf = NULL, *utf8_end; - size_t mlen, i; + size_t mlen, i, len; int rv = -1; int mime = ms->flags & MAGIC_MIME; + int need_separator = 0; const char *subtype = NULL; const char *subtype_mime = NULL; @@ -117,7 +127,7 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf, int n_nel = 0; int executable = 0; - size_t last_line_end = (size_t)-1; + size_t last_line_end = CAST(size_t, -1); int has_long_lines = 0; nbytes = trim_nuls(buf, nbytes); @@ -140,10 +150,15 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf, if ((utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen)) == NULL) goto done; - if ((rv = file_softmagic(ms, utf8_buf, - (size_t)(utf8_end - utf8_buf), NULL, NULL, + buffer_init(&bb, b->fd, &b->st, utf8_buf, + CAST(size_t, utf8_end - utf8_buf)); + + if ((rv = file_softmagic(ms, &bb, NULL, NULL, TEXTTEST, text)) == 0) rv = -1; + else + need_separator = 1; + buffer_fini(&bb); if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))) { rv = rv == -1 ? 0 : 1; goto done; @@ -193,8 +208,21 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf, rv = 0; goto done; } + len = file_printedlen(ms); if (mime) { - if (!file_printedlen(ms) && (mime & MAGIC_MIME_TYPE) != 0) { + if ((mime & MAGIC_MIME_TYPE) != 0) { + if (len) { + /* + * Softmagic printed something, we + * are either done, or we need a separator + */ + if ((ms->flags & MAGIC_CONTINUE) == 0) { + rv = 1; + goto done; + } + if (need_separator && file_separator(ms) == -1) + goto done; + } if (subtype_mime) { if (file_printf(ms, "%s", subtype_mime) == -1) goto done; @@ -204,7 +232,7 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf, } } } else { - if (file_printedlen(ms)) { + if (len) { switch (file_replace(ms, " text$", ", ")) { case 0: switch (file_replace(ms, " text executable$", @@ -317,42 +345,42 @@ encode_utf8(unsigned char *buf, size_t len, unichar *ubuf, size_t ulen) if (ubuf[i] <= 0x7f) { if (end - buf < 1) return NULL; - *buf++ = (unsigned char)ubuf[i]; + *buf++ = CAST(unsigned char, ubuf[i]); } else if (ubuf[i] <= 0x7ff) { if (end - buf < 2) return NULL; - *buf++ = (unsigned char)((ubuf[i] >> 6) + 0xc0); - *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, (ubuf[i] >> 6) + 0xc0); + *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80); } else if (ubuf[i] <= 0xffff) { if (end - buf < 3) return NULL; - *buf++ = (unsigned char)((ubuf[i] >> 12) + 0xe0); - *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80); - *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, (ubuf[i] >> 12) + 0xe0); + *buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80); } else if (ubuf[i] <= 0x1fffff) { if (end - buf < 4) return NULL; - *buf++ = (unsigned char)((ubuf[i] >> 18) + 0xf0); - *buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80); - *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80); - *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, (ubuf[i] >> 18) + 0xf0); + *buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80); } else if (ubuf[i] <= 0x3ffffff) { if (end - buf < 5) return NULL; - *buf++ = (unsigned char)((ubuf[i] >> 24) + 0xf8); - *buf++ = (unsigned char)(((ubuf[i] >> 18) & 0x3f) + 0x80); - *buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80); - *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80); - *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, (ubuf[i] >> 24) + 0xf8); + *buf++ = CAST(unsigned char, ((ubuf[i] >> 18) & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80); } else if (ubuf[i] <= 0x7fffffff) { if (end - buf < 6) return NULL; - *buf++ = (unsigned char)((ubuf[i] >> 30) + 0xfc); - *buf++ = (unsigned char)(((ubuf[i] >> 24) & 0x3f) + 0x80); - *buf++ = (unsigned char)(((ubuf[i] >> 18) & 0x3f) + 0x80); - *buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80); - *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80); - *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, (ubuf[i] >> 30) + 0xfc); + *buf++ = CAST(unsigned char, ((ubuf[i] >> 24) & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, ((ubuf[i] >> 18) & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80); + *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80); } else /* Invalid character */ return NULL; } diff --git a/deps/libmagic/src/asctime_r.c b/deps/libmagic/src/asctime_r.c index 3a0ec04..876fae6 100644 --- a/deps/libmagic/src/asctime_r.c +++ b/deps/libmagic/src/asctime_r.c @@ -1,8 +1,8 @@ -/* $File: asctime_r.c,v 1.1 2012/05/15 17:14:36 christos Exp $ */ +/* $File$ */ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: asctime_r.c,v 1.1 2012/05/15 17:14:36 christos Exp $") +FILE_RCSID("@(#)$File: ascmagic.c,v 1.84 2011/12/08 12:38:24 rrt Exp $") #endif /* lint */ #include #include diff --git a/deps/libmagic/src/asprintf.c b/deps/libmagic/src/asprintf.c index 30852d2..2d14e80 100644 --- a/deps/libmagic/src/asprintf.c +++ b/deps/libmagic/src/asprintf.c @@ -2,7 +2,7 @@ * Copyright (c) Ian F. Darwin 1986-1995. * Software written by Ian F. Darwin and others; * maintained 1995-present by Christos Zoulas and others. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -29,7 +29,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: asprintf.c,v 1.4 2010/07/21 16:47:17 christos Exp $") +FILE_RCSID("@(#)$File: asprintf.c,v 1.5 2018/09/09 20:33:28 christos Exp $") #endif int asprintf(char **ptr, const char *fmt, ...) diff --git a/deps/libmagic/src/buffer.c b/deps/libmagic/src/buffer.c new file mode 100644 index 0000000..227015a --- /dev/null +++ b/deps/libmagic/src/buffer.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) Christos Zoulas 2017. + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "file.h" + +#ifndef lint +FILE_RCSID("@(#)$File: buffer.c,v 1.8 2020/02/16 15:52:49 christos Exp $") +#endif /* lint */ + +#include "magic.h" +#include +#include +#include +#include + +void +buffer_init(struct buffer *b, int fd, const struct stat *st, const void *data, + size_t len) +{ + b->fd = fd; + if (st) + memcpy(&b->st, st, sizeof(b->st)); + else if (b->fd == -1 || fstat(b->fd, &b->st) == -1) + memset(&b->st, 0, sizeof(b->st)); + b->fbuf = data; + b->flen = len; + b->eoff = 0; + b->ebuf = NULL; + b->elen = 0; +} + +void +buffer_fini(struct buffer *b) +{ + free(b->ebuf); +} + +int +buffer_fill(const struct buffer *bb) +{ + struct buffer *b = CCAST(struct buffer *, bb); + + if (b->elen != 0) + return b->elen == FILE_BADSIZE ? -1 : 0; + + if (!S_ISREG(b->st.st_mode)) + goto out; + + b->elen = CAST(size_t, b->st.st_size) < b->flen ? + CAST(size_t, b->st.st_size) : b->flen; + if ((b->ebuf = malloc(b->elen)) == NULL) + goto out; + + b->eoff = b->st.st_size - b->elen; + if (pread(b->fd, b->ebuf, b->elen, b->eoff) == -1) { + free(b->ebuf); + b->ebuf = NULL; + goto out; + } + + return 0; +out: + b->elen = FILE_BADSIZE; + return -1; +} diff --git a/deps/libmagic/src/cdf.c b/deps/libmagic/src/cdf.c index 0bb22e6..bb81d63 100644 --- a/deps/libmagic/src/cdf.c +++ b/deps/libmagic/src/cdf.c @@ -35,7 +35,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: cdf.c,v 1.106 2017/04/30 17:05:02 christos Exp $") +FILE_RCSID("@(#)$File: cdf.c,v 1.116 2019/08/26 14:31:39 christos Exp $") #endif #include @@ -43,19 +43,20 @@ FILE_RCSID("@(#)$File: cdf.c,v 1.106 2017/04/30 17:05:02 christos Exp $") #include #endif #include -// XXX: change by mscdex -//#include +#include #include #include #include -#ifdef HAVE_LIMITS_H #include -#endif #ifndef EFTYPE #define EFTYPE EINVAL #endif +#ifndef SIZE_T_MAX +#define SIZE_T_MAX CAST(size_t, ~0ULL) +#endif + #include "cdf.h" #ifdef CDF_DEBUG @@ -69,11 +70,14 @@ static union { uint32_t u; } cdf_bo; -#define NEED_SWAP (cdf_bo.u == (uint32_t)0x01020304) +#define NEED_SWAP (cdf_bo.u == CAST(uint32_t, 0x01020304)) -#define CDF_TOLE8(x) ((uint64_t)(NEED_SWAP ? _cdf_tole8(x) : (uint64_t)(x))) -#define CDF_TOLE4(x) ((uint32_t)(NEED_SWAP ? _cdf_tole4(x) : (uint32_t)(x))) -#define CDF_TOLE2(x) ((uint16_t)(NEED_SWAP ? _cdf_tole2(x) : (uint16_t)(x))) +#define CDF_TOLE8(x) \ + (CAST(uint64_t, NEED_SWAP ? _cdf_tole8(x) : CAST(uint64_t, x))) +#define CDF_TOLE4(x) \ + (CAST(uint32_t, NEED_SWAP ? _cdf_tole4(x) : CAST(uint32_t, x))) +#define CDF_TOLE2(x) \ + (CAST(uint16_t, NEED_SWAP ? _cdf_tole2(x) : CAST(uint16_t, x))) #define CDF_TOLE(x) (/*CONSTCOND*/sizeof(x) == 2 ? \ CDF_TOLE2(CAST(uint16_t, x)) : \ (/*CONSTCOND*/sizeof(x) == 4 ? \ @@ -86,27 +90,33 @@ static union { #define CDF_CALLOC(n, u) cdf_calloc(__FILE__, __LINE__, (n), (u)) +/*ARGSUSED*/ static void * cdf_malloc(const char *file __attribute__((__unused__)), size_t line __attribute__((__unused__)), size_t n) { - DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n)); + DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n", + file, line, __func__, n)); return malloc(n); } +/*ARGSUSED*/ static void * cdf_realloc(const char *file __attribute__((__unused__)), size_t line __attribute__((__unused__)), void *p, size_t n) { - DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n)); + DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n", + file, line, __func__, n)); return realloc(p, n); } +/*ARGSUSED*/ static void * cdf_calloc(const char *file __attribute__((__unused__)), size_t line __attribute__((__unused__)), size_t n, size_t u) { - DPRINTF(("%s,%zu: %s %zu %zu\n", file, line, __func__, n, u)); + DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u %" + SIZE_T_FORMAT "u\n", file, line, __func__, n, u)); return calloc(n, u); } @@ -117,8 +127,8 @@ static uint16_t _cdf_tole2(uint16_t sv) { uint16_t rv; - uint8_t *s = (uint8_t *)(void *)&sv; - uint8_t *d = (uint8_t *)(void *)&rv; + uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv)); + uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv)); d[0] = s[1]; d[1] = s[0]; return rv; @@ -131,8 +141,8 @@ static uint32_t _cdf_tole4(uint32_t sv) { uint32_t rv; - uint8_t *s = (uint8_t *)(void *)&sv; - uint8_t *d = (uint8_t *)(void *)&rv; + uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv)); + uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv)); d[0] = s[3]; d[1] = s[2]; d[2] = s[1]; @@ -147,8 +157,8 @@ static uint64_t _cdf_tole8(uint64_t sv) { uint64_t rv; - uint8_t *s = (uint8_t *)(void *)&sv; - uint8_t *d = (uint8_t *)(void *)&rv; + uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv)); + uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv)); d[0] = s[7]; d[1] = s[6]; d[2] = s[5]; @@ -213,15 +223,17 @@ cdf_swap_header(cdf_header_t *h) h->h_min_size_standard_stream = CDF_TOLE4(h->h_min_size_standard_stream); h->h_secid_first_sector_in_short_sat = - CDF_TOLE4((uint32_t)h->h_secid_first_sector_in_short_sat); + CDF_TOLE4(CAST(uint32_t, h->h_secid_first_sector_in_short_sat)); h->h_num_sectors_in_short_sat = CDF_TOLE4(h->h_num_sectors_in_short_sat); h->h_secid_first_sector_in_master_sat = - CDF_TOLE4((uint32_t)h->h_secid_first_sector_in_master_sat); + CDF_TOLE4(CAST(uint32_t, h->h_secid_first_sector_in_master_sat)); h->h_num_sectors_in_master_sat = CDF_TOLE4(h->h_num_sectors_in_master_sat); - for (i = 0; i < __arraycount(h->h_master_sat); i++) - h->h_master_sat[i] = CDF_TOLE4((uint32_t)h->h_master_sat[i]); + for (i = 0; i < __arraycount(h->h_master_sat); i++) { + h->h_master_sat[i] = + CDF_TOLE4(CAST(uint32_t, h->h_master_sat[i])); + } } void @@ -254,15 +266,16 @@ void cdf_swap_dir(cdf_directory_t *d) { d->d_namelen = CDF_TOLE2(d->d_namelen); - d->d_left_child = CDF_TOLE4((uint32_t)d->d_left_child); - d->d_right_child = CDF_TOLE4((uint32_t)d->d_right_child); - d->d_storage = CDF_TOLE4((uint32_t)d->d_storage); + d->d_left_child = CDF_TOLE4(CAST(uint32_t, d->d_left_child)); + d->d_right_child = CDF_TOLE4(CAST(uint32_t, d->d_right_child)); + d->d_storage = CDF_TOLE4(CAST(uint32_t, d->d_storage)); d->d_storage_uuid[0] = CDF_TOLE8(d->d_storage_uuid[0]); d->d_storage_uuid[1] = CDF_TOLE8(d->d_storage_uuid[1]); d->d_flags = CDF_TOLE4(d->d_flags); - d->d_created = CDF_TOLE8((uint64_t)d->d_created); - d->d_modified = CDF_TOLE8((uint64_t)d->d_modified); - d->d_stream_first_sector = CDF_TOLE4((uint32_t)d->d_stream_first_sector); + d->d_created = CDF_TOLE8(CAST(uint64_t, d->d_created)); + d->d_modified = CDF_TOLE8(CAST(uint64_t, d->d_modified)); + d->d_stream_first_sector = CDF_TOLE4( + CAST(uint32_t, d->d_stream_first_sector)); d->d_size = CDF_TOLE4(d->d_size); } @@ -319,11 +332,11 @@ static int cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h, const void *p, size_t tail, int line) { - const char *b = (const char *)sst->sst_tab; - const char *e = ((const char *)p) + tail; + const char *b = RCAST(const char *, sst->sst_tab); + const char *e = RCAST(const char *, p) + tail; size_t ss = cdf_check_stream(sst, h); /*LINTED*/(void)&line; - if (e >= b && (size_t)(e - b) <= ss * sst->sst_len) + if (e >= b && CAST(size_t, e - b) <= ss * sst->sst_len) return 0; DPRINTF(("%d: offset begin %p < end %p || %" SIZE_T_FORMAT "u" " > %" SIZE_T_FORMAT "u [%" SIZE_T_FORMAT "u %" @@ -336,23 +349,23 @@ cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h, static ssize_t cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len) { - size_t siz = (size_t)off + len; + size_t siz = CAST(size_t, off + len); - if ((off_t)(off + len) != (off_t)siz) + if (CAST(off_t, off + len) != CAST(off_t, siz)) goto out; if (info->i_buf != NULL && info->i_len >= siz) { (void)memcpy(buf, &info->i_buf[off], len); - return (ssize_t)len; + return CAST(ssize_t, len); } if (info->i_fd == -1) goto out; - if (pread(info->i_fd, buf, len, off) != (ssize_t)len) + if (pread(info->i_fd, buf, len, off) != CAST(ssize_t, len)) return -1; - return (ssize_t)len; + return CAST(ssize_t, len); out: errno = EINVAL; return -1; @@ -364,7 +377,7 @@ cdf_read_header(const cdf_info_t *info, cdf_header_t *h) char buf[512]; (void)memcpy(cdf_bo.s, "\01\02\03\04", 4); - if (cdf_read(info, (off_t)0, buf, sizeof(buf)) == -1) + if (cdf_read(info, CAST(off_t, 0), buf, sizeof(buf)) == -1) return -1; cdf_unpack_header(h, buf); cdf_swap_header(h); @@ -396,9 +409,14 @@ cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len, const cdf_header_t *h, cdf_secid_t id) { size_t ss = CDF_SEC_SIZE(h); - size_t pos = CDF_SEC_POS(h, id); + size_t pos; + + if (SIZE_T_MAX / ss < CAST(size_t, id)) + return -1; + + pos = CDF_SEC_POS(h, id); assert(ss == len); - return cdf_read(info, (off_t)pos, ((char *)buf) + offs, len); + return cdf_read(info, CAST(off_t, pos), RCAST(char *, buf) + offs, len); } ssize_t @@ -406,7 +424,12 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, size_t len, const cdf_header_t *h, cdf_secid_t id) { size_t ss = CDF_SHORT_SEC_SIZE(h); - size_t pos = CDF_SHORT_SEC_POS(h, id); + size_t pos; + + if (SIZE_T_MAX / ss < CAST(size_t, id)) + return -1; + + pos = CDF_SHORT_SEC_POS(h, id); assert(ss == len); if (pos + len > CDF_SEC_SIZE(h) * sst->sst_len) { DPRINTF(("Out of bounds read %" SIZE_T_FORMAT "u > %" @@ -414,8 +437,8 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, pos + len, CDF_SEC_SIZE(h) * sst->sst_len)); goto out; } - (void)memcpy(((char *)buf) + offs, - ((const char *)sst->sst_tab) + pos, len); + (void)memcpy(RCAST(char *, buf) + offs, + RCAST(const char *, sst->sst_tab) + pos, len); return len; out: errno = EFTYPE; @@ -437,7 +460,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat) if (h->h_master_sat[i] == CDF_SECID_FREE) break; -#define CDF_SEC_LIMIT (UINT32_MAX / (8 * ss)) +#define CDF_SEC_LIMIT (UINT32_MAX / (64 * ss)) if ((nsatpersec > 0 && h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec) || i > CDF_SEC_LIMIT) { @@ -458,7 +481,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat) if (h->h_master_sat[i] < 0) break; if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h, - h->h_master_sat[i]) != (ssize_t)ss) { + h->h_master_sat[i]) != CAST(ssize_t, ss)) { DPRINTF(("Reading sector %d", h->h_master_sat[i])); goto out1; } @@ -475,27 +498,29 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat) DPRINTF(("Reading master sector loop limit")); goto out3; } - if (cdf_read_sector(info, msa, 0, ss, h, mid) != (ssize_t)ss) { + if (cdf_read_sector(info, msa, 0, ss, h, mid) != + CAST(ssize_t, ss)) { DPRINTF(("Reading master sector %d", mid)); goto out2; } for (k = 0; k < nsatpersec; k++, i++) { - sec = CDF_TOLE4((uint32_t)msa[k]); + sec = CDF_TOLE4(CAST(uint32_t, msa[k])); if (sec < 0) goto out; if (i >= sat->sat_len) { - DPRINTF(("Out of bounds reading MSA %" SIZE_T_FORMAT - "u >= %" SIZE_T_FORMAT "u", i, sat->sat_len)); + DPRINTF(("Out of bounds reading MSA %" + SIZE_T_FORMAT "u >= %" SIZE_T_FORMAT "u", + i, sat->sat_len)); goto out3; } if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h, - sec) != (ssize_t)ss) { + sec) != CAST(ssize_t, ss)) { DPRINTF(("Reading sector %d", CDF_TOLE4(msa[k]))); goto out2; } } - mid = CDF_TOLE4((uint32_t)msa[nsatpersec]); + mid = CDF_TOLE4(CAST(uint32_t, msa[nsatpersec])); } out: sat->sat_len = i; @@ -514,7 +539,7 @@ size_t cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size) { size_t i, j; - cdf_secid_t maxsector = (cdf_secid_t)((sat->sat_len * size) + cdf_secid_t maxsector = CAST(cdf_secid_t, (sat->sat_len * size) / sizeof(maxsector)); DPRINTF(("Chain:")); @@ -534,7 +559,7 @@ cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size) DPRINTF(("Sector %d >= %d\n", sid, maxsector)); goto out; } - sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]); + sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid])); } if (i == 0) { DPRINTF((" none, sid: %d\n", sid)); @@ -545,7 +570,7 @@ cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size) return i; out: errno = EFTYPE; - return (size_t)-1; + return CAST(size_t, -1); } int @@ -562,7 +587,7 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h, if (sid == CDF_SECID_END_OF_CHAIN || len == 0) return cdf_zero_stream(scn); - if (scn->sst_len == (size_t)-1) + if (scn->sst_len == CAST(size_t, -1)) goto out; scn->sst_tab = CDF_CALLOC(scn->sst_len, ss); @@ -581,7 +606,7 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h, goto out; } if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h, - sid)) != (ssize_t)ss) { + sid)) != CAST(ssize_t, ss)) { if (i == scn->sst_len - 1 && nr > 0) { /* Last sector might be truncated */ return 0; @@ -589,7 +614,7 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h, DPRINTF(("Reading long sector chain %d", sid)); goto out; } - sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]); + sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid])); } return 0; out: @@ -608,7 +633,7 @@ cdf_read_short_sector_chain(const cdf_header_t *h, scn->sst_dirlen = len; scn->sst_ss = ss; - if (scn->sst_len == (size_t)-1) + if (scn->sst_len == CAST(size_t, -1)) goto out; scn->sst_tab = CDF_CALLOC(scn->sst_len, ss); @@ -627,11 +652,11 @@ cdf_read_short_sector_chain(const cdf_header_t *h, goto out; } if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h, - sid) != (ssize_t)ss) { + sid) != CAST(ssize_t, ss)) { DPRINTF(("Reading short sector chain %d", sid)); goto out; } - sid = CDF_TOLE4((uint32_t)ssat->sat_tab[sid]); + sid = CDF_TOLE4(CAST(uint32_t, ssat->sat_tab[sid])); } return 0; out: @@ -662,7 +687,7 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h, cdf_secid_t sid = h->h_secid_first_directory; ns = cdf_count_chain(sat, sid, ss); - if (ns == (size_t)-1) + if (ns == CAST(size_t, -1)) return -1; nd = ss / CDF_DIRECTORY_SIZE; @@ -683,7 +708,8 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h, DPRINTF(("Read dir loop limit")); goto out; } - if (cdf_read_sector(info, buf, 0, ss, h, sid) != (ssize_t)ss) { + if (cdf_read_sector(info, buf, 0, ss, h, sid) != + CAST(ssize_t, ss)) { DPRINTF(("Reading directory sector %d", sid)); goto out; } @@ -691,7 +717,7 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h, cdf_unpack_dir(&dir->dir_tab[i * nd + j], &buf[j * CDF_DIRECTORY_SIZE]); } - sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]); + sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid])); } if (NEED_SWAP) for (i = 0; i < dir->dir_len; i++) @@ -716,7 +742,7 @@ cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h, ssat->sat_tab = NULL; ssat->sat_len = cdf_count_chain(sat, sid, ss); - if (ssat->sat_len == (size_t)-1) + if (ssat->sat_len == CAST(size_t, -1)) goto out; ssat->sat_tab = CAST(cdf_secid_t *, CDF_CALLOC(ssat->sat_len, ss)); @@ -735,11 +761,11 @@ cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h, goto out; } if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) != - (ssize_t)ss) { + CAST(ssize_t, ss)) { DPRINTF(("Reading short sat sector %d", sid)); goto out1; } - sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]); + sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid])); } return 0; out: @@ -789,7 +815,7 @@ cdf_namecmp(const char *d, const uint16_t *s, size_t l) { for (; l--; d++, s++) if (*d != CDF_TOLE2(*s)) - return (unsigned char)*d - CDF_TOLE2(*s); + return CAST(unsigned char, *d) - CDF_TOLE2(*s); return 0; } @@ -847,8 +873,8 @@ cdf_find_stream(const cdf_dir_t *dir, const char *name, int type) return 0; } -#define CDF_SHLEN_LIMIT (UINT32_MAX / 8) -#define CDF_PROP_LIMIT (UINT32_MAX / (8 * sizeof(cdf_property_info_t))) +#define CDF_SHLEN_LIMIT (UINT32_MAX / 64) +#define CDF_PROP_LIMIT (UINT32_MAX / (64 * sizeof(cdf_property_info_t))) static const void * cdf_offset(const void *p, size_t l) @@ -857,7 +883,7 @@ cdf_offset(const void *p, size_t l) } static const uint8_t * -cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h, +cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h, const uint8_t *p, const uint8_t *e, size_t i) { size_t tail = (i << 1) + 1; @@ -872,7 +898,7 @@ cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h, __LINE__) == -1) return NULL; ofs = CDF_GETUINT32(p, tail); - q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p), + q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p), ofs - 2 * sizeof(uint32_t))); if (q < p) { @@ -894,8 +920,8 @@ cdf_grow_info(cdf_property_info_t **info, size_t *maxcount, size_t incr) size_t newcount = *maxcount + incr; if (newcount > CDF_PROP_LIMIT) { - DPRINTF(("exceeded property limit %zu > %zu\n", - newcount, CDF_PROP_LIMIT)); + DPRINTF(("exceeded property limit %" SIZE_T_FORMAT "u > %" + SIZE_T_FORMAT "u\n", newcount, CDF_PROP_LIMIT)); goto out; } inp = CAST(cdf_property_info_t *, @@ -920,7 +946,7 @@ cdf_copy_info(cdf_property_info_t *inp, const void *p, const void *e, if (inp->pi_type & CDF_VECTOR) return 0; - if ((size_t)(CAST(const char *, e) - CAST(const char *, p)) < len) + if (CAST(size_t, CAST(const char *, e) - CAST(const char *, p)) < len) return 0; (void)memcpy(&inp->pi_val, p, len); @@ -1001,8 +1027,9 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, goto out; } nelements = CDF_GETUINT32(q, 1); - if (nelements == 0) { - DPRINTF(("CDF_VECTOR with nelements == 0\n")); + if (nelements > CDF_ELEMENT_LIMIT || nelements == 0) { + DPRINTF(("CDF_VECTOR with nelements == %" + SIZE_T_FORMAT "u\n", nelements)); goto out; } slen = 2; @@ -1044,8 +1071,6 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, goto out; inp += nelem; } - DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n", - nelements)); for (j = 0; j < nelements && i < sh.sh_properties; j++, i++) { @@ -1063,10 +1088,10 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, inp[i].pi_str.s_buf = CAST(const char *, CAST(const void *, &q[o4])); - DPRINTF(("o=%zu l=%d(%" SIZE_T_FORMAT - "u), t=%zu s=%s\n", o4, l, - CDF_ROUND(l, sizeof(l)), left, - inp[i].pi_str.s_buf)); + DPRINTF(("o=%" SIZE_T_FORMAT "u l=%d(%" + SIZE_T_FORMAT "u), t=%" SIZE_T_FORMAT + "u s=%s\n", o4, l, CDF_ROUND(l, sizeof(l)), + left, inp[i].pi_str.s_buf)); if (l & 1) l++; @@ -1106,8 +1131,9 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h, const cdf_summary_info_header_t *si = CAST(const cdf_summary_info_header_t *, sst->sst_tab); const cdf_section_declaration_t *sd = - CAST(const cdf_section_declaration_t *, (const void *) - ((const char *)sst->sst_tab + CDF_SECTION_DECLARATION_OFFSET)); + CAST(const cdf_section_declaration_t *, RCAST(const void *, + RCAST(const char *, sst->sst_tab) + + CDF_SECTION_DECLARATION_OFFSET)); if (cdf_check_stream_offset(sst, h, si, sizeof(*si), __LINE__) == -1 || cdf_check_stream_offset(sst, h, sd, sizeof(*sd), __LINE__) == -1) @@ -1258,28 +1284,28 @@ cdf_print_elapsed_time(char *buf, size_t bufsiz, cdf_timestamp_t ts) int days, hours, mins, secs; ts /= CDF_TIME_PREC; - secs = (int)(ts % 60); + secs = CAST(int, ts % 60); ts /= 60; - mins = (int)(ts % 60); + mins = CAST(int, ts % 60); ts /= 60; - hours = (int)(ts % 24); + hours = CAST(int, ts % 24); ts /= 24; - days = (int)ts; + days = CAST(int, ts); if (days) { len += snprintf(buf + len, bufsiz - len, "%dd+", days); - if ((size_t)len >= bufsiz) + if (CAST(size_t, len) >= bufsiz) return len; } if (days || hours) { len += snprintf(buf + len, bufsiz - len, "%.2d:", hours); - if ((size_t)len >= bufsiz) + if (CAST(size_t, len) >= bufsiz) return len; } len += snprintf(buf + len, bufsiz - len, "%.2d:", mins); - if ((size_t)len >= bufsiz) + if (CAST(size_t, len) >= bufsiz) return len; len += snprintf(buf + len, bufsiz - len, "%.2d", secs); @@ -1291,7 +1317,7 @@ cdf_u16tos8(char *buf, size_t len, const uint16_t *p) { size_t i; for (i = 0; i < len && p[i]; i++) - buf[i] = (char)p[i]; + buf[i] = CAST(char, p[i]); buf[i] = '\0'; return buf; } @@ -1571,32 +1597,32 @@ main(int argc, char *argv[]) info.i_len = 0; for (i = 1; i < argc; i++) { if ((info.i_fd = open(argv[1], O_RDONLY)) == -1) - err(1, "Cannot open `%s'", argv[1]); + err(EXIT_FAILURE, "Cannot open `%s'", argv[1]); if (cdf_read_header(&info, &h) == -1) - err(1, "Cannot read header"); + err(EXIT_FAILURE, "Cannot read header"); #ifdef CDF_DEBUG cdf_dump_header(&h); #endif if (cdf_read_sat(&info, &h, &sat) == -1) - err(1, "Cannot read sat"); + err(EXIT_FAILURE, "Cannot read sat"); #ifdef CDF_DEBUG cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h)); #endif if (cdf_read_ssat(&info, &h, &sat, &ssat) == -1) - err(1, "Cannot read ssat"); + err(EXIT_FAILURE, "Cannot read ssat"); #ifdef CDF_DEBUG cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h)); #endif if (cdf_read_dir(&info, &h, &sat, &dir) == -1) - err(1, "Cannot read dir"); + err(EXIT_FAILURE, "Cannot read dir"); if (cdf_read_short_stream(&info, &h, &sat, &dir, &sst, &root) == -1) - err(1, "Cannot read short stream"); + err(EXIT_FAILURE, "Cannot read short stream"); #ifdef CDF_DEBUG cdf_dump_stream(&sst); #endif diff --git a/deps/libmagic/src/cdf.h b/deps/libmagic/src/cdf.h index f2df830..0505666 100644 --- a/deps/libmagic/src/cdf.h +++ b/deps/libmagic/src/cdf.h @@ -48,6 +48,7 @@ typedef int32_t cdf_secid_t; #define CDF_LOOP_LIMIT 10000 +#define CDF_ELEMENT_LIMIT 100000 #define CDF_SECID_NULL 0 #define CDF_SECID_FREE -1 @@ -76,9 +77,9 @@ typedef struct { cdf_secid_t h_master_sat[436/4]; } cdf_header_t; -#define CDF_SEC_SIZE(h) ((size_t)(1 << (h)->h_sec_size_p2)) +#define CDF_SEC_SIZE(h) CAST(size_t, 1 << (h)->h_sec_size_p2) #define CDF_SEC_POS(h, secid) (CDF_SEC_SIZE(h) + (secid) * CDF_SEC_SIZE(h)) -#define CDF_SHORT_SEC_SIZE(h) ((size_t)(1 << (h)->h_short_sec_size_p2)) +#define CDF_SHORT_SEC_SIZE(h) CAST(size_t, 1 << (h)->h_short_sec_size_p2) #define CDF_SHORT_SEC_POS(h, secid) ((secid) * CDF_SHORT_SEC_SIZE(h)) typedef int32_t cdf_dirid_t; @@ -272,7 +273,7 @@ typedef struct { typedef struct { uint16_t ce_namlen; uint32_t ce_num; - uint64_t ce_timestamp; + uint64_t ce_timestamp; uint16_t ce_name[256]; } cdf_catalog_entry_t; diff --git a/deps/libmagic/src/cdf_time.c b/deps/libmagic/src/cdf_time.c index 2bdcd2a..e4eea4c 100644 --- a/deps/libmagic/src/cdf_time.c +++ b/deps/libmagic/src/cdf_time.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: cdf_time.c,v 1.16 2017/03/29 15:57:48 christos Exp $") +FILE_RCSID("@(#)$File: cdf_time.c,v 1.19 2019/03/12 20:43:05 christos Exp $") #endif #include @@ -56,7 +56,7 @@ cdf_getdays(int year) for (y = CDF_BASE_YEAR; y < year; y++) days += isleap(y) + 365; - + return days; } @@ -68,7 +68,7 @@ cdf_getday(int year, int days) { size_t m; - for (m = 0; m < sizeof(mdays) / sizeof(mdays[0]); m++) { + for (m = 0; m < __arraycount(mdays); m++) { int sub = mdays[m] + (m == 1 && isleap(year)); if (days < sub) return days; @@ -77,7 +77,7 @@ cdf_getday(int year, int days) return days; } -/* +/* * Return the 0...11 month number. */ static int @@ -85,14 +85,14 @@ cdf_getmonth(int year, int days) { size_t m; - for (m = 0; m < sizeof(mdays) / sizeof(mdays[0]); m++) { + for (m = 0; m < __arraycount(mdays); m++) { days -= mdays[m]; if (m == 1 && isleap(year)) days--; if (days <= 0) - return (int)m; + return CAST(int, m); } - return (int)m; + return CAST(int, m); } int @@ -108,22 +108,22 @@ cdf_timestamp_to_timespec(struct timespec *ts, cdf_timestamp_t t) ts->tv_nsec = (t % CDF_TIME_PREC) * 100; t /= CDF_TIME_PREC; - tm.tm_sec = (int)(t % 60); + tm.tm_sec = CAST(int, t % 60); t /= 60; - tm.tm_min = (int)(t % 60); + tm.tm_min = CAST(int, t % 60); t /= 60; - tm.tm_hour = (int)(t % 24); + tm.tm_hour = CAST(int, t % 24); t /= 24; /* XXX: Approx */ - tm.tm_year = (int)(CDF_BASE_YEAR + (t / 365)); + tm.tm_year = CAST(int, CDF_BASE_YEAR + (t / 365)); rdays = cdf_getdays(tm.tm_year); t -= rdays - 1; - tm.tm_mday = cdf_getday(tm.tm_year, (int)t); - tm.tm_mon = cdf_getmonth(tm.tm_year, (int)t); + tm.tm_mday = cdf_getday(tm.tm_year, CAST(int, t)); + tm.tm_mon = cdf_getmonth(tm.tm_year, CAST(int, t)); tm.tm_wday = 0; tm.tm_yday = 0; tm.tm_isdst = 0; @@ -172,7 +172,7 @@ cdf_ctime(const time_t *sec, char *buf) if (ptr != NULL) return buf; (void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n", - (long long)*sec); + CAST(long long, *sec)); return buf; } diff --git a/deps/libmagic/src/compress.c b/deps/libmagic/src/compress.c index 2f789cd..904c215 100644 --- a/deps/libmagic/src/compress.c +++ b/deps/libmagic/src/compress.c @@ -2,7 +2,7 @@ * Copyright (c) Ian F. Darwin 1986-1995. * Software written by Ian F. Darwin and others; * maintained 1995-present by Christos Zoulas and others. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -29,13 +29,13 @@ * compress routines: * zmagic() - returns 0 if not recognized, uncompresses and prints * information if recognized - * uncompress(method, old, n, newch) - uncompress old into new, + * uncompress(method, old, n, newch) - uncompress old into new, * using method, return sizeof new */ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: compress.c,v 1.105 2017/05/25 00:13:03 christos Exp $") +FILE_RCSID("@(#)$File: compress.c,v 1.126 2019/12/24 17:38:12 christos Exp $") #endif #include "magic.h" @@ -47,12 +47,10 @@ FILE_RCSID("@(#)$File: compress.c,v 1.105 2017/05/25 00:13:03 christos Exp $") #include #include #include -#ifdef HAVE_SIGNAL_H #include -# ifndef HAVE_SIG_T +#ifndef HAVE_SIG_T typedef void (*sig_t)(int); -# endif /* HAVE_SIG_T */ -#endif +#endif /* HAVE_SIG_T */ #if !defined(__MINGW32__) && !defined(WIN32) #include #endif @@ -62,10 +60,22 @@ typedef void (*sig_t)(int); #if defined(HAVE_SYS_TIME_H) #include #endif + #if defined(HAVE_ZLIB_H) && defined(ZLIBSUPPORT) #define BUILTIN_DECOMPRESS #include #endif + +#if defined(HAVE_BZLIB_H) && defined(BZLIBSUPPORT) +#define BUILTIN_BZLIB +#include +#endif + +#if defined(HAVE_XZLIB_H) && defined(XZLIBSUPPORT) +#define BUILTIN_XZLIB +#include +#endif + #ifdef DEBUG int tty = -1; #define DPRINTF(...) do { \ @@ -108,6 +118,16 @@ zlibcmp(const unsigned char *buf) } #endif +static int +lzmacmp(const unsigned char *buf) +{ + if (buf[0] != 0x5d || buf[1] || buf[2]) + return 0; + if (buf[12] && buf[12] != 0xff) + return 0; + return 1; +} + #define gzip_flags "-cd" #define lrzip_flags "-do" #define lzip_flags gzip_flags @@ -137,30 +157,43 @@ static const char *zstd_args[] = { "zstd", "-cd", NULL }; +#define do_zlib NULL +#define do_bzlib NULL + private const struct { - const void *magic; - size_t maglen; + union { + const char *magic; + int (*func)(const unsigned char *); + } u; + int maglen; const char **argv; + void *unused; } compr[] = { - { "\037\235", 2, gzip_args }, /* compressed */ - /* Uncompress can get stuck; so use gzip first if we have it - * Idea from Damien Clark, thanks! */ - { "\037\235", 2, uncompress_args }, /* compressed */ - { "\037\213", 2, gzip_args }, /* gzipped */ - { "\037\236", 2, gzip_args }, /* frozen */ - { "\037\240", 2, gzip_args }, /* SCO LZH */ - /* the standard pack utilities do not accept standard input */ - { "\037\036", 2, gzip_args }, /* packed */ - { "PK\3\4", 4, gzip_args }, /* pkzipped, */ - /* ...only first file examined */ - { "BZh", 3, bzip2_args }, /* bzip2-ed */ - { "LZIP", 4, lzip_args }, /* lzip-ed */ - { "\3757zXZ\0", 6, xz_args }, /* XZ Utils */ - { "LRZI", 4, lrzip_args }, /* LRZIP */ - { "\004\"M\030",4, lz4_args }, /* LZ4 */ - { "\x28\xB5\x2F\xFD", 4, zstd_args }, /* zstd */ +#define METH_FROZEN 2 +#define METH_BZIP 7 +#define METH_XZ 9 +#define METH_LZMA 13 +#define METH_ZLIB 14 + { { .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), 0, zlib_args }, /* zlib */ + { { .func = zlibcmp }, -2, zlib_args, NULL }, /* 14, zlib */ #endif }; @@ -170,7 +203,7 @@ private const struct { private ssize_t swrite(int, const void *, size_t); #if HAVE_FORK -private size_t ncompr = sizeof(compr) / sizeof(compr[0]); +private size_t ncompr = __arraycount(compr); private int uncompressbuf(int, size_t, size_t, const unsigned char *, unsigned char **, size_t *); #ifdef BUILTIN_DECOMPRESS @@ -179,13 +212,38 @@ private int uncompresszlib(const unsigned char *, unsigned char **, size_t, private int uncompressgzipped(const unsigned char *, unsigned char **, size_t, size_t *); #endif +#ifdef BUILTIN_BZLIB +private int uncompressbzlib(const unsigned char *, unsigned char **, size_t, + size_t *); +#endif +#ifdef BUILTIN_XZLIB +private int uncompressxzlib(const unsigned char *, unsigned char **, size_t, + size_t *); +#endif + static int makeerror(unsigned char **, size_t *, const char *, ...) __attribute__((__format__(__printf__, 3, 4))); private const char *methodname(size_t); +private int +format_decompression_error(struct magic_set *ms, size_t i, unsigned char *buf) +{ + unsigned char *p; + int mime = ms->flags & MAGIC_MIME; + + if (!mime) + return file_printf(ms, "ERROR:[%s: %s]", methodname(i), buf); + + for (p = buf; *p; p++) + if (!isalnum(*p)) + *p = '-'; + + return file_printf(ms, "application/x-decompression-error-%s-%s", + methodname(i), buf); +} + protected int -file_zmagic(struct magic_set *ms, int fd, const char *name, - const unsigned char *buf, size_t nbytes) +file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name) { unsigned char *newbuf = NULL; size_t i, nsz; @@ -193,44 +251,50 @@ file_zmagic(struct magic_set *ms, int fd, const char *name, file_pushbuf_t *pb; int urv, prv, rv = 0; int mime = ms->flags & MAGIC_MIME; -#ifdef HAVE_SIGNAL_H - sig_t osigpipe; -#endif + int fd = b->fd; + const unsigned char *buf = CAST(const unsigned char *, b->fbuf); + size_t nbytes = b->flen; + int sa_saved = 0; + struct sigaction sig_act; if ((ms->flags & MAGIC_COMPRESS) == 0) return 0; -#ifdef HAVE_SIGNAL_H - osigpipe = signal(SIGPIPE, SIG_IGN); -#endif for (i = 0; i < ncompr; i++) { int zm; - if (nbytes < compr[i].maglen) + if (nbytes < CAST(size_t, abs(compr[i].maglen))) continue; -#ifdef ZLIBSUPPORT - if (compr[i].maglen == 0) - zm = (RCAST(int (*)(const unsigned char *), - CCAST(void *, compr[i].magic)))(buf); - else -#endif - zm = memcmp(buf, compr[i].magic, compr[i].maglen) == 0; + if (compr[i].maglen < 0) { + zm = (*compr[i].u.func)(buf); + } else { + zm = memcmp(buf, compr[i].u.magic, + CAST(size_t, compr[i].maglen)) == 0; + } if (!zm) continue; + + /* Prevent SIGPIPE death if child dies unexpectedly */ + if (!sa_saved) { + //We can use sig_act for both new and old, but + struct sigaction new_act; + memset(&new_act, 0, sizeof(new_act)); + new_act.sa_handler = SIG_IGN; + sa_saved = sigaction(SIGPIPE, &new_act, &sig_act) != -1; + } + nsz = nbytes; urv = uncompressbuf(fd, ms->bytes_max, i, buf, &newbuf, &nsz); - DPRINTF("uncompressbuf = %d, %s, %zu\n", urv, (char *)newbuf, - nsz); + DPRINTF("uncompressbuf = %d, %s, %" SIZE_T_FORMAT "u\n", urv, + (char *)newbuf, nsz); switch (urv) { case OKDATA: case ERRDATA: - ms->flags &= ~MAGIC_COMPRESS; if (urv == ERRDATA) - prv = file_printf(ms, "%s ERROR: %s", - methodname(i), newbuf); + prv = format_decompression_error(ms, i, newbuf); else - prv = file_buffer(ms, -1, name, newbuf, nsz); + prv = file_buffer(ms, -1, NULL, name, newbuf, nsz); if (prv == -1) goto error; rv = 1; @@ -247,8 +311,11 @@ file_zmagic(struct magic_set *ms, int fd, const char *name, * XXX: If file_buffer fails here, we overwrite * the compressed text. FIXME. */ - if (file_buffer(ms, -1, NULL, buf, nbytes) == -1) + if (file_buffer(ms, -1, NULL, NULL, buf, nbytes) == -1) { + if (file_pop_buffer(ms, pb) != NULL) + abort(); goto error; + } if ((rbuf = file_pop_buffer(ms, pb)) != NULL) { if (file_printf(ms, "%s", rbuf) == -1) { free(rbuf); @@ -272,9 +339,9 @@ file_zmagic(struct magic_set *ms, int fd, const char *name, out: DPRINTF("rv = %d\n", rv); -#ifdef HAVE_SIGNAL_H - (void)signal(SIGPIPE, osigpipe); -#endif + if (sa_saved && sig_act.sa_handler != SIG_IGN) + (void)sigaction(SIGPIPE, &sig_act, NULL); + free(newbuf); ms->flags |= MAGIC_COMPRESS; DPRINTF("Zmagic returns %d\n", rv); @@ -350,7 +417,7 @@ sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__))) (void)ioctl(fd, FIONREAD, &t); } - if (t > 0 && (size_t)t < n) { + if (t > 0 && CAST(size_t, t) < n) { n = t; rn = n; } @@ -394,7 +461,9 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf, #else { int te; + mode_t ou = umask(0); tfd = mkstemp(buf); + (void)umask(ou); te = errno; (void)unlink(buf); errno = te; @@ -406,11 +475,11 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf, return -1; } - if (swrite(tfd, startbuf, nbytes) != (ssize_t)nbytes) + if (swrite(tfd, startbuf, nbytes) != CAST(ssize_t, nbytes)) r = 1; else { while ((r = sread(fd, buf, sizeof(buf), 1)) > 0) - if (swrite(tfd, buf, (size_t)r) != r) + if (swrite(tfd, buf, CAST(size_t, r)) != r) break; } @@ -435,7 +504,7 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf, return -1; } (void)close(tfd); - if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) { + if (lseek(fd, CAST(off_t, 0), SEEK_SET) == CAST(off_t, -1)) { file_badseek(ms); return -1; } @@ -492,7 +561,7 @@ uncompresszlib(const unsigned char *old, unsigned char **newch, int rc; z_stream z; - if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL) + if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL) return makeerror(newch, n, "No buffer, %s", strerror(errno)); z.next_in = CCAST(Bytef *, old); @@ -512,22 +581,106 @@ uncompresszlib(const unsigned char *old, unsigned char **newch, if (rc != Z_OK && rc != Z_STREAM_END) goto err; - *n = (size_t)z.total_out; + *n = CAST(size_t, z.total_out); rc = inflateEnd(&z); if (rc != Z_OK) goto err; - + + /* let's keep the nul-terminate tradition */ + (*newch)[*n] = '\0'; + + return OKDATA; +err: + strlcpy(RCAST(char *, *newch), z.msg ? z.msg : zError(rc), bytes_max); + *n = strlen(RCAST(char *, *newch)); + return ERRDATA; +} +#endif + +#ifdef BUILTIN_BZLIB +private int +uncompressbzlib(const unsigned char *old, unsigned char **newch, + size_t bytes_max, size_t *n) +{ + int rc; + bz_stream bz; + + memset(&bz, 0, sizeof(bz)); + rc = BZ2_bzDecompressInit(&bz, 0, 0); + if (rc != BZ_OK) + goto err; + + if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL) + return makeerror(newch, n, "No buffer, %s", strerror(errno)); + + bz.next_in = CCAST(char *, RCAST(const char *, old)); + bz.avail_in = CAST(uint32_t, *n); + bz.next_out = RCAST(char *, *newch); + bz.avail_out = CAST(unsigned int, bytes_max); + + rc = BZ2_bzDecompress(&bz); + if (rc != BZ_OK && rc != BZ_STREAM_END) + goto err; + + /* Assume byte_max is within 32bit */ + /* assert(bz.total_out_hi32 == 0); */ + *n = CAST(size_t, bz.total_out_lo32); + rc = BZ2_bzDecompressEnd(&bz); + if (rc != BZ_OK) + goto err; + + /* let's keep the nul-terminate tradition */ + (*newch)[*n] = '\0'; + + return OKDATA; +err: + snprintf(RCAST(char *, *newch), bytes_max, "bunzip error %d", rc); + *n = strlen(RCAST(char *, *newch)); + return ERRDATA; +} +#endif + +#ifdef BUILTIN_XZLIB +private int +uncompressxzlib(const unsigned char *old, unsigned char **newch, + size_t bytes_max, size_t *n) +{ + int rc; + lzma_stream xz; + + memset(&xz, 0, sizeof(xz)); + rc = lzma_auto_decoder(&xz, UINT64_MAX, 0); + if (rc != LZMA_OK) + goto err; + + if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL) + return makeerror(newch, n, "No buffer, %s", strerror(errno)); + + xz.next_in = CCAST(const uint8_t *, old); + xz.avail_in = CAST(uint32_t, *n); + xz.next_out = RCAST(uint8_t *, *newch); + xz.avail_out = CAST(unsigned int, bytes_max); + + rc = lzma_code(&xz, LZMA_RUN); + if (rc != LZMA_OK && rc != LZMA_STREAM_END) + goto err; + + *n = CAST(size_t, xz.total_out); + + lzma_end(&xz); + /* let's keep the nul-terminate tradition */ (*newch)[*n] = '\0'; return OKDATA; err: - strlcpy((char *)*newch, z.msg ? z.msg : zError(rc), bytes_max); - *n = strlen((char *)*newch); + snprintf(RCAST(char *, *newch), bytes_max, "unxz error %d", rc); + *n = strlen(RCAST(char *, *newch)); return ERRDATA; } #endif + static int makeerror(unsigned char **buf, size_t *len, const char *fmt, ...) { @@ -543,7 +696,7 @@ makeerror(unsigned char **buf, size_t *len, const char *fmt, ...) *len = 0; return NODATA; } - *buf = (unsigned char *)msg; + *buf = RCAST(unsigned char *, msg); *len = strlen(msg); return ERRDATA; } @@ -565,52 +718,42 @@ closep(int *fd) closefd(fd, i); } -static void -copydesc(int i, int *fd) +static int +copydesc(int i, int fd) { - int j = fd[i == STDIN_FILENO ? 0 : 1]; - if (j == i) - return; - if (dup2(j, i) == -1) { - DPRINTF("dup(%d, %d) failed (%s)\n", j, i, strerror(errno)); + if (fd == i) + return 0; /* "no dup was necessary" */ + if (dup2(fd, i) == -1) { + DPRINTF("dup(%d, %d) failed (%s)\n", fd, i, strerror(errno)); exit(1); } - closep(fd); + return 1; } -static void -writechild(int fdp[3][2], const void *old, size_t n) +static pid_t +writechild(int fd, const void *old, size_t n) { - int status; + pid_t pid; - closefd(fdp[STDIN_FILENO], 0); - /* + /* * fork again, to avoid blocking because both * pipes filled */ - switch (fork()) { - case 0: /* child */ - closefd(fdp[STDOUT_FILENO], 0); - if (swrite(fdp[STDIN_FILENO][1], old, n) != (ssize_t)n) { - DPRINTF("Write failed (%s)\n", strerror(errno)); - exit(1); - } - exit(0); - /*NOTREACHED*/ - - case -1: + pid = fork(); + if (pid == -1) { DPRINTF("Fork failed (%s)\n", strerror(errno)); exit(1); - /*NOTREACHED*/ - - default: /* parent */ - if (wait(&status) == -1) { - DPRINTF("Wait failed (%s)\n", strerror(errno)); + } + if (pid == 0) { + /* child */ + if (swrite(fd, old, n) != CAST(ssize_t, n)) { + DPRINTF("Write failed (%s)\n", strerror(errno)); exit(1); } - DPRINTF("Grandchild wait return %#x\n", status); + exit(0); } - closefd(fdp[STDIN_FILENO], 1); + /* parent */ + return pid; } static ssize_t @@ -620,17 +763,17 @@ filter_error(unsigned char *ubuf, ssize_t n) char *buf; ubuf[n] = '\0'; - buf = (char *)ubuf; - while (isspace((unsigned char)*buf)) + buf = RCAST(char *, ubuf); + while (isspace(CAST(unsigned char, *buf))) buf++; DPRINTF("Filter error[[[%s]]]\n", buf); - if ((p = strchr((char *)buf, '\n')) != NULL) + if ((p = strchr(CAST(char *, buf), '\n')) != NULL) *p = '\0'; - if ((p = strchr((char *)buf, ';')) != NULL) + if ((p = strchr(CAST(char *, buf), ';')) != NULL) *p = '\0'; - if ((p = strrchr((char *)buf, ':')) != NULL) { + if ((p = strrchr(CAST(char *, buf), ':')) != NULL) { ++p; - while (isspace((unsigned char)*p)) + while (isspace(CAST(unsigned char, *p))) p++; n = strlen(p); memmove(ubuf, p, CAST(size_t, n + 1)); @@ -644,12 +787,24 @@ filter_error(unsigned char *ubuf, ssize_t n) private const char * methodname(size_t method) { + switch (method) { #ifdef BUILTIN_DECOMPRESS - /* FIXME: This doesn't cope with bzip2 */ - if (method == 2 || compr[method].maglen == 0) - return "zlib"; + case METH_FROZEN: + case METH_ZLIB: + return "zlib"; #endif - return compr[method].argv[0]; +#ifdef BUILTIN_BZLIB + case METH_BZIP: + return "bzlib"; +#endif +#ifdef BUILTIN_XZLIB + case METH_XZ: + case METH_LZMA: + return "xzlib"; +#endif + default: + return compr[method].argv[0]; + } } private int @@ -657,17 +812,32 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old, unsigned char **newch, size_t* n) { int fdp[3][2]; - int status, rv; + int status, rv, w; + pid_t pid; + pid_t writepid = -1; size_t i; ssize_t r; + switch (method) { #ifdef BUILTIN_DECOMPRESS - /* FIXME: This doesn't cope with bzip2 */ - if (method == 2) + case METH_FROZEN: return uncompressgzipped(old, newch, bytes_max, n); - if (compr[method].maglen == 0) + case METH_ZLIB: return uncompresszlib(old, newch, bytes_max, n, 1); #endif +#ifdef BUILTIN_BZLIB + case METH_BZIP: + return uncompressbzlib(old, newch, bytes_max, n); +#endif +#ifdef BUILTIN_XZLIB + case METH_XZ: + case METH_LZMA: + return uncompressxzlib(old, newch, bytes_max, n); +#endif + default: + break; + } + (void)fflush(stdout); (void)fflush(stderr); @@ -681,43 +851,68 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old, return makeerror(newch, n, "Cannot create pipe, %s", strerror(errno)); } - switch (fork()) { - case 0: /* child */ + + /* For processes with large mapped virtual sizes, vfork + * may be _much_ faster (10-100 times) than fork. + */ + pid = vfork(); + if (pid == -1) { + return makeerror(newch, n, "Cannot vfork, %s", + strerror(errno)); + } + if (pid == 0) { + /* child */ + /* Note: we are after vfork, do not modify memory + * in a way which confuses parent. In particular, + * do not modify fdp[i][j]. + */ if (fd != -1) { - fdp[STDIN_FILENO][0] = fd; - (void) lseek(fd, (off_t)0, SEEK_SET); + (void) lseek(fd, CAST(off_t, 0), SEEK_SET); + if (copydesc(STDIN_FILENO, fd)) + (void) close(fd); + } else { + if (copydesc(STDIN_FILENO, fdp[STDIN_FILENO][0])) + (void) close(fdp[STDIN_FILENO][0]); + if (fdp[STDIN_FILENO][1] > 2) + (void) close(fdp[STDIN_FILENO][1]); } - - for (i = 0; i < __arraycount(fdp); i++) - copydesc(CAST(int, i), fdp[i]); +///FIXME: if one of the fdp[i][j] is 0 or 1, this can bomb spectacularly + if (copydesc(STDOUT_FILENO, fdp[STDOUT_FILENO][1])) + (void) close(fdp[STDOUT_FILENO][1]); + if (fdp[STDOUT_FILENO][0] > 2) + (void) close(fdp[STDOUT_FILENO][0]); + + if (copydesc(STDERR_FILENO, fdp[STDERR_FILENO][1])) + (void) close(fdp[STDERR_FILENO][1]); + if (fdp[STDERR_FILENO][0] > 2) + (void) close(fdp[STDERR_FILENO][0]); (void)execvp(compr[method].argv[0], - (char *const *)(intptr_t)compr[method].argv); - dprintf(STDERR_FILENO, "exec `%s' failed, %s", + RCAST(char *const *, RCAST(intptr_t, compr[method].argv))); + dprintf(STDERR_FILENO, "exec `%s' failed, %s", compr[method].argv[0], strerror(errno)); - exit(1); - /*NOTREACHED*/ - case -1: - return makeerror(newch, n, "Cannot fork, %s", - strerror(errno)); - - default: /* parent */ - for (i = 1; i < __arraycount(fdp); i++) - closefd(fdp[i], 1); - - /* Write the buffer data to the child, if we don't have fd */ - if (fd == -1) - writechild(fdp, old, *n); + _exit(1); /* _exit(), not exit(), because of vfork */ + } + /* parent */ + /* Close write sides of child stdout/err pipes */ + for (i = 1; i < __arraycount(fdp); i++) + closefd(fdp[i], 1); + /* Write the buffer data to child stdin, if we don't have fd */ + if (fd == -1) { + closefd(fdp[STDIN_FILENO], 0); + writepid = writechild(fdp[STDIN_FILENO][1], old, *n); + closefd(fdp[STDIN_FILENO], 1); + } - *newch = CAST(unsigned char *, malloc(bytes_max + 1)); - if (*newch == NULL) { - rv = makeerror(newch, n, "No buffer, %s", - strerror(errno)); - goto err; - } - rv = OKDATA; - if ((r = sread(fdp[STDOUT_FILENO][0], *newch, bytes_max, 0)) > 0) - break; + *newch = CAST(unsigned char *, malloc(bytes_max + 1)); + if (*newch == NULL) { + rv = makeerror(newch, n, "No buffer, %s", + strerror(errno)); + goto err; + } + rv = OKDATA; + r = sread(fdp[STDOUT_FILENO][0], *newch, bytes_max, 0); + if (r <= 0) { DPRINTF("Read stdout failed %d (%s)\n", fdp[STDOUT_FILENO][0], r != -1 ? strerror(errno) : "no data"); @@ -726,7 +921,7 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old, (r = sread(fdp[STDERR_FILENO][0], *newch, bytes_max, 0)) > 0) { r = filter_error(*newch, r); - break; + goto ok; } free(*newch); if (r == 0) @@ -736,7 +931,7 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old, rv = makeerror(newch, n, "No data"); goto err; } - +ok: *n = r; /* NUL terminate, as every buffer is handled here. */ (*newch)[*n] = '\0'; @@ -744,7 +939,10 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old, closefd(fdp[STDIN_FILENO], 1); closefd(fdp[STDOUT_FILENO], 0); closefd(fdp[STDERR_FILENO], 0); - if (wait(&status) == -1) { + + w = waitpid(pid, &status, 0); +wait_err: + if (w == -1) { free(*newch); rv = makeerror(newch, n, "Wait failed, %s", strerror(errno)); DPRINTF("Child wait return %#x\n", status); @@ -753,10 +951,19 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old, } else if (WEXITSTATUS(status) != 0) { DPRINTF("Child exited (%#x)\n", WEXITSTATUS(status)); } + if (writepid > 0) { + /* _After_ we know decompressor has exited, our input writer + * definitely will exit now (at worst, writing fails in it, + * since output fd is closed now on the reading size). + */ + w = waitpid(writepid, &status, 0); + writepid = -1; + goto wait_err; + } + + closefd(fdp[STDIN_FILENO], 0); //why? it is already closed here! + DPRINTF("Returning %p n=%" SIZE_T_FORMAT "u rv=%d\n", *newch, *n, rv); - closefd(fdp[STDIN_FILENO], 0); - DPRINTF("Returning %p n=%zu rv=%d\n", *newch, *n, rv); - return rv; } #endif diff --git a/deps/libmagic/src/ctime_r.c b/deps/libmagic/src/ctime_r.c index ca7ad2f..eff9f07 100644 --- a/deps/libmagic/src/ctime_r.c +++ b/deps/libmagic/src/ctime_r.c @@ -1,8 +1,8 @@ -/* $File: ctime_r.c,v 1.1 2012/05/15 17:14:36 christos Exp $ */ +/* $File$ */ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: ctime_r.c,v 1.1 2012/05/15 17:14:36 christos Exp $") +FILE_RCSID("@(#)$File: ascmagic.c,v 1.84 2011/12/08 12:38:24 rrt Exp $") #endif /* lint */ #include #include diff --git a/deps/libmagic/src/der.c b/deps/libmagic/src/der.c index e7ca16e..11f5e08 100644 --- a/deps/libmagic/src/der.c +++ b/deps/libmagic/src/der.c @@ -35,8 +35,11 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: der.c,v 1.12 2017/02/10 18:14:01 christos Exp $") +FILE_RCSID("@(#)$File: der.c,v 1.19 2020/02/17 16:01:15 christos Exp $") #endif +#else +#define SIZE_T_FORMAT "z" +#define CAST(a, b) ((a)(b)) #endif #include @@ -47,11 +50,6 @@ FILE_RCSID("@(#)$File: der.c,v 1.12 2017/02/10 18:14:01 christos Exp $") #include #include -// XXX: addition by mscdex -#ifdef _MSC_VER -#define __func__ __FUNCTION__ -#endif - #ifndef TEST_DER #include "magic.h" #include "der.h" @@ -61,7 +59,7 @@ FILE_RCSID("@(#)$File: der.c,v 1.12 2017/02/10 18:14:01 christos Exp $") #include #endif -#define DER_BAD ((uint32_t)-1) +#define DER_BAD CAST(uint32_t, -1) #define DER_CLASS_UNIVERSAL 0 #define DER_CLASS_APPLICATION 1 @@ -91,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 @@ -108,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 @@ -180,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 @@ -190,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; @@ -204,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 (*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); @@ -228,12 +240,18 @@ 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: + return snprintf(buf, blen, "%.*s", len, RCAST(const char *, q)); case DER_TAG_UTCTIME: - return snprintf(buf, blen, "%.*s", len, (const char *)q); + 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; } - + for (uint32_t i = 0; i < len; i++) { uint32_t z = i << 1; if (z < blen - 2) @@ -248,20 +266,27 @@ 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 %zu %u\n", __func__, ms->offset, offs, m->offset)); + } + 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 %zu %u\n", __func__, ms->offset, offs, tlen)); + } + DPRINTF(("%s2: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset, + offs, tlen)); offs += ms->offset + m->offset; DPRINTF(("cont_level = %d\n", m->cont_level)); #ifdef DEBUG_DER for (size_t i = 0; i < m->cont_level; i++) - printf("cont_level[%zu] = %u\n", i, ms->c.li[i].off); + printf("cont_level[%" SIZE_T_FORMAT "u] = %u\n", i, + ms->c.li[i].off); #endif if (m->cont_level != 0) { if (offs + tlen > nbytes) @@ -282,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) @@ -309,22 +343,23 @@ der_cmp(struct magic_set *ms, struct magic *m) s++; goto val; default: - if (!isdigit((unsigned char)*s)) + if (!isdigit(CAST(unsigned char, *s))) return 0; slen = 0; do slen = slen * 10 + *s - '0'; - while (isdigit((unsigned char)*++s)); + while (isdigit(CAST(unsigned char, *++s))); if ((ms->flags & MAGIC_DEBUG) != 0) - fprintf(stderr, "%s: len %zu %u\n", __func__, - slen, tlen); + fprintf(stderr, "%s: len %" SIZE_T_FORMAT "u %u\n", + __func__, slen, tlen); if (tlen != slen) return 0; goto again; } val: - DPRINTF(("%s: before data %zu %u\n", __func__, offs, tlen)); + DPRINTF(("%s: before data %" SIZE_T_FORMAT "u %u\n", __func__, offs, + tlen)); der_data(buf, sizeof(buf), tag, b + offs, tlen); if ((ms->flags & MAGIC_DEBUG) != 0) fprintf(stderr, "%s: data %s %s\n", __func__, buf, s); @@ -343,12 +378,14 @@ 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: break; } - + for (uint32_t i = 0; i < len; i++) printf("%.2x", d[i]); printf("\n"); @@ -366,14 +403,15 @@ 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; uint32_t len = getlength(p, &x, ep - p + x); - - printf("%zu %zu-%zu %c,%c,%s,%u:", level, ox, x, + + printf("%" SIZE_T_FORMAT "u %" SIZE_T_FORMAT "u-%" + SIZE_T_FORMAT "u %c,%c,%s,%u:", level, ox, x, der_class[c], der_type[t], der_tag(buf, sizeof(buf), tag), len); q = p + x; diff --git a/deps/libmagic/src/dprintf.c b/deps/libmagic/src/dprintf.c index 425bacd..027a64f 100644 --- a/deps/libmagic/src/dprintf.c +++ b/deps/libmagic/src/dprintf.c @@ -2,7 +2,7 @@ * Copyright (c) Ian F. Darwin 1986-1995. * Software written by Ian F. Darwin and others; * maintained 1995-present by Christos Zoulas and others. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -28,14 +28,11 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: dprintf.c,v 1.1 2015/11/13 15:36:14 christos Exp $") +FILE_RCSID("@(#)$File: dprintf.c,v 1.2 2018/09/09 20:33:28 christos Exp $") #endif /* lint */ #include -// XXX: change by mscdex -#ifndef _MSC_VER -# include -#endif +#include #include #include diff --git a/deps/libmagic/src/elfclass.h b/deps/libmagic/src/elfclass.h index 5360b0b..936d8dc 100644 --- a/deps/libmagic/src/elfclass.h +++ b/deps/libmagic/src/elfclass.h @@ -1,7 +1,7 @@ /* * Copyright (c) Christos Zoulas 2008. * All Rights Reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -11,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -41,8 +41,8 @@ return toomany(ms, "program headers", phnum); flags |= FLAGS_IS_CORE; if (dophn_core(ms, clazz, swap, fd, - (off_t)elf_getu(swap, elfhdr.e_phoff), phnum, - (size_t)elf_getu16(swap, elfhdr.e_phentsize), + CAST(off_t, elf_getu(swap, elfhdr.e_phoff)), phnum, + CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)), fsize, &flags, ¬ecount) == -1) return -1; break; @@ -56,8 +56,8 @@ if (shnum > ms->elf_shnum_max) return toomany(ms, "section", shnum); if (dophn_exec(ms, clazz, swap, fd, - (off_t)elf_getu(swap, elfhdr.e_phoff), phnum, - (size_t)elf_getu16(swap, elfhdr.e_phentsize), + CAST(off_t, elf_getu(swap, elfhdr.e_phoff)), phnum, + CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)), fsize, shnum, &flags, ¬ecount) == -1) return -1; /*FALLTHROUGH*/ @@ -66,10 +66,10 @@ if (shnum > ms->elf_shnum_max) return toomany(ms, "section headers", shnum); if (doshn(ms, clazz, swap, fd, - (off_t)elf_getu(swap, elfhdr.e_shoff), shnum, - (size_t)elf_getu16(swap, elfhdr.e_shentsize), + CAST(off_t, elf_getu(swap, elfhdr.e_shoff)), shnum, + CAST(size_t, elf_getu16(swap, elfhdr.e_shentsize)), fsize, elf_getu16(swap, elfhdr.e_machine), - (int)elf_getu16(swap, elfhdr.e_shstrndx), + CAST(int, elf_getu16(swap, elfhdr.e_shstrndx)), &flags, ¬ecount) == -1) return -1; break; diff --git a/deps/libmagic/src/encoding.c b/deps/libmagic/src/encoding.c index 3c116cd..c3f3343 100644 --- a/deps/libmagic/src/encoding.c +++ b/deps/libmagic/src/encoding.c @@ -35,12 +35,11 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: encoding.c,v 1.13 2015/06/04 19:16:28 christos Exp $") +FILE_RCSID("@(#)$File: encoding.c,v 1.21 2019/06/08 20:49:14 christos Exp $") #endif /* lint */ #include "magic.h" #include -#include #include @@ -49,6 +48,7 @@ private int looks_utf8_with_BOM(const unsigned char *, size_t, unichar *, size_t *); private int looks_utf7(const unsigned char *, size_t, unichar *, size_t *); private int looks_ucs16(const unsigned char *, size_t, unichar *, size_t *); +private int looks_ucs32(const unsigned char *, size_t, unichar *, size_t *); private int looks_latin1(const unsigned char *, size_t, unichar *, size_t *); private int looks_extended(const unsigned char *, size_t, unichar *, size_t *); private void from_ebcdic(const unsigned char *, size_t, unsigned char *); @@ -66,11 +66,21 @@ private void from_ebcdic(const unsigned char *, size_t, unsigned char *); * ubuf, and the number of characters converted in ulen. */ protected int -file_encoding(struct magic_set *ms, const unsigned char *buf, size_t nbytes, unichar **ubuf, size_t *ulen, const char **code, const char **code_mime, const char **type) +file_encoding(struct magic_set *ms, const struct buffer *b, unichar **ubuf, + size_t *ulen, const char **code, const char **code_mime, const char **type) { + const unsigned char *buf = CAST(const unsigned char *, b->fbuf); + size_t nbytes = b->flen; size_t mlen; int rv = 1, ucs_type; unsigned char *nbuf = NULL; + unichar *udefbuf; + size_t udeflen; + + if (ubuf == NULL) + ubuf = &udefbuf; + if (ulen == NULL) + ulen = &udeflen; *type = "text"; *ulen = 0; @@ -78,12 +88,13 @@ file_encoding(struct magic_set *ms, const unsigned char *buf, size_t nbytes, uni *code_mime = "binary"; mlen = (nbytes + 1) * sizeof((*ubuf)[0]); - if ((*ubuf = CAST(unichar *, calloc((size_t)1, mlen))) == NULL) { + if ((*ubuf = CAST(unichar *, calloc(CAST(size_t, 1), mlen))) == NULL) { file_oomem(ms, mlen); goto done; } mlen = (nbytes + 1) * sizeof(nbuf[0]); - if ((nbuf = CAST(unsigned char *, calloc((size_t)1, mlen))) == NULL) { + if ((nbuf = CAST(unsigned char *, + calloc(CAST(size_t, 1), mlen))) == NULL) { file_oomem(ms, mlen); goto done; } @@ -106,6 +117,15 @@ file_encoding(struct magic_set *ms, const unsigned char *buf, size_t nbytes, uni DPRINTF(("utf8 %" SIZE_T_FORMAT "u\n", *ulen)); *code = "UTF-8 Unicode"; *code_mime = "utf-8"; + } else if ((ucs_type = looks_ucs32(buf, nbytes, *ubuf, ulen)) != 0) { + if (ucs_type == 1) { + *code = "Little-endian UTF-32 Unicode"; + *code_mime = "utf-32le"; + } else { + *code = "Big-endian UTF-32 Unicode"; + *code_mime = "utf-32be"; + } + DPRINTF(("ucs32 %" SIZE_T_FORMAT "u\n", *ulen)); } else if ((ucs_type = looks_ucs16(buf, nbytes, *ubuf, ulen)) != 0) { if (ucs_type == 1) { *code = "Little-endian UTF-16 Unicode"; @@ -144,6 +164,8 @@ file_encoding(struct magic_set *ms, const unsigned char *buf, size_t nbytes, uni done: free(nbuf); + if (ubuf == &udefbuf) + free(udefbuf); return rv; } @@ -398,7 +420,7 @@ looks_utf7(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen) } private int -looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf, +looks_ucs16(const unsigned char *bf, size_t nbytes, unichar *ubf, size_t *ulen) { int bigend; @@ -407,9 +429,9 @@ looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf, if (nbytes < 2) return 0; - if (buf[0] == 0xff && buf[1] == 0xfe) + if (bf[0] == 0xff && bf[1] == 0xfe) bigend = 0; - else if (buf[0] == 0xfe && buf[1] == 0xff) + else if (bf[0] == 0xfe && bf[1] == 0xff) bigend = 1; else return 0; @@ -420,20 +442,64 @@ looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf, /* XXX fix to properly handle chars > 65536 */ if (bigend) - ubuf[(*ulen)++] = buf[i + 1] + 256 * buf[i]; + ubf[(*ulen)++] = bf[i + 1] + | (CAST(unichar, bf[i]) << 8); else - ubuf[(*ulen)++] = buf[i] + 256 * buf[i + 1]; + ubf[(*ulen)++] = bf[i] + | (CAST(unichar, bf[i + 1]) << 8); - if (ubuf[*ulen - 1] == 0xfffe) + if (ubf[*ulen - 1] == 0xfffe) return 0; - if (ubuf[*ulen - 1] < 128 && - text_chars[(size_t)ubuf[*ulen - 1]] != T) + if (ubf[*ulen - 1] < 128 && + text_chars[CAST(size_t, ubf[*ulen - 1])] != T) return 0; } return 1 + bigend; } +private int +looks_ucs32(const unsigned char *bf, size_t nbytes, unichar *ubf, + size_t *ulen) +{ + int bigend; + size_t i; + + if (nbytes < 4) + return 0; + + if (bf[0] == 0xff && bf[1] == 0xfe && bf[2] == 0 && bf[3] == 0) + bigend = 0; + else if (bf[0] == 0 && bf[1] == 0 && bf[2] == 0xfe && bf[3] == 0xff) + bigend = 1; + else + return 0; + + *ulen = 0; + + for (i = 4; i + 3 < nbytes; i += 4) { + /* XXX fix to properly handle chars > 65536 */ + + if (bigend) + ubf[(*ulen)++] = CAST(unichar, bf[i + 3]) + | (CAST(unichar, bf[i + 2]) << 8) + | (CAST(unichar, bf[i + 1]) << 16) + | (CAST(unichar, bf[i]) << 24); + else + ubf[(*ulen)++] = CAST(unichar, bf[i + 0]) + | (CAST(unichar, bf[i + 1]) << 8) + | (CAST(unichar, bf[i + 2]) << 16) + | (CAST(unichar, bf[i + 3]) << 24); + + if (ubf[*ulen - 1] == 0xfffe) + return 0; + if (ubf[*ulen - 1] < 128 && + text_chars[CAST(size_t, ubf[*ulen - 1])] != T) + return 0; + } + + return 1 + bigend; +} #undef F #undef T #undef I diff --git a/deps/libmagic/src/file.c b/deps/libmagic/src/file.c index 861a824..c3bd597 100644 --- a/deps/libmagic/src/file.c +++ b/deps/libmagic/src/file.c @@ -32,16 +32,13 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: file.c,v 1.172 2016/10/24 15:21:07 christos Exp $") +FILE_RCSID("@(#)$File: file.c,v 1.185 2020/02/13 17:19:53 christos Exp $") #endif /* lint */ #include "magic.h" #include -// XXX: change by mscdex -#ifdef HAVE_UNISTD_H #include -#endif #include #ifdef RESTORE_TIME # if (__COHERENT__ >= 0x420) @@ -54,38 +51,40 @@ FILE_RCSID("@(#)$File: file.c,v 1.172 2016/10/24 15:21:07 christos Exp $") # endif # endif #endif -// XXX: change by mscdex #ifdef HAVE_UNISTD_H #include /* for read() */ #endif -#ifdef HAVE_LOCALE_H -#include -#endif #ifdef HAVE_WCHAR_H #include #endif #if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION) -#include -#ifndef HAVE_GETOPT_LONG -int getopt_long(int argc, char * const *argv, const char *optstring, const struct option *longopts, int *longindex); -#endif -#else -#include "mygetopt.h" +# include +# ifndef HAVE_GETOPT_LONG +int getopt_long(int, char * const *, const char *, + const struct option *, int *); +# endif +# else +# include "mygetopt.h" #endif #ifdef S_IFLNK -#define FILE_FLAGS "-bcEhikLlNnprsvzZ0" +# define IFLNK_h "h" +# define IFLNK_L "L" #else -#define FILE_FLAGS "-bcEiklNnprsvzZ0" +# define IFLNK_h "" +# define IFLNK_L "" #endif +#define FILE_FLAGS "bcCdE" IFLNK_h "ik" IFLNK_L "lNnprsSvzZ0" +#define OPTSTRING "bcCde:Ef:F:hiklLm:nNpP:rsSvzZ0" + # define USAGE \ - "Usage: %s [" FILE_FLAGS \ - "] [--apple] [--extension] [--mime-encoding] [--mime-type]\n" \ - " [-e testname] [-F separator] [-f namefile] [-m magicfiles] " \ - "file ...\n" \ - " %s -C [-m magicfiles]\n" \ + "Usage: %s [-" FILE_FLAGS "] [--apple] [--extension] [--mime-encoding]\n" \ + " [--mime-type] [-e ] [-F ] " \ + " [-f ]\n" \ + " [-m ] [-P ] ...\n" \ + " %s -C [-m ]\n" \ " %s [--help]\n" private int /* Global command-line options */ @@ -109,8 +108,7 @@ private const struct option long_options[] = { #undef OPT #undef OPT_LONGONLY {0, 0, NULL, 0} -}; -#define OPTSTRING "bcCde:Ef:F:hiklLm:nNpP:rsvzZ0" + }; private const struct { const char *name; @@ -120,10 +118,12 @@ private const struct { { "ascii", MAGIC_NO_CHECK_ASCII }, { "cdf", MAGIC_NO_CHECK_CDF }, { "compress", MAGIC_NO_CHECK_COMPRESS }, + { "csv", MAGIC_NO_CHECK_CSV }, { "elf", MAGIC_NO_CHECK_ELF }, { "encoding", MAGIC_NO_CHECK_ENCODING }, { "soft", MAGIC_NO_CHECK_SOFT }, { "tar", MAGIC_NO_CHECK_TAR }, + { "json", MAGIC_NO_CHECK_JSON }, { "text", MAGIC_NO_CHECK_TEXT }, /* synonym for ascii */ { "tokens", MAGIC_NO_CHECK_TOKENS }, /* OBSOLETE: ignored for backwards compatibility */ }; @@ -132,17 +132,17 @@ private struct { const char *name; int tag; size_t value; + int set; } pm[] = { - { "indir", MAGIC_PARAM_INDIR_MAX, 0 }, - { "name", MAGIC_PARAM_NAME_MAX, 0 }, - { "elf_phnum", MAGIC_PARAM_ELF_PHNUM_MAX, 0 }, - { "elf_shnum", MAGIC_PARAM_ELF_SHNUM_MAX, 0 }, - { "elf_notes", MAGIC_PARAM_ELF_NOTES_MAX, 0 }, - { "regex", MAGIC_PARAM_REGEX_MAX, 0 }, - { "bytes", MAGIC_PARAM_BYTES_MAX, 0 }, + { "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 }, }; -private char *progname; /* used throughout */ private int posixly; #ifdef __dead @@ -172,14 +172,16 @@ main(int argc, char *argv[]) size_t i; int action = 0, didsomefiles = 0, errflg = 0; int flags = 0, e = 0; +#ifdef HAVE_LIBSECCOMP + int sandbox = 1; +#endif struct magic_set *magic = NULL; int longindex; const char *magicfile = NULL; /* where the magic is */ + char *progname; /* makes islower etc work for other langs */ -#ifdef HAVE_SETLOCALE (void)setlocale(LC_CTYPE, ""); -#endif #ifdef __EMX__ /* sh-like wildcard expansion! Shouldn't hurt at least ... */ @@ -191,6 +193,9 @@ main(int argc, char *argv[]) else progname = argv[0]; + file_setprogname(progname); + + #ifdef S_IFLNK posixly = getenv("POSIXLY_CORRECT") != NULL; flags |= posixly ? MAGIC_SYMLINK : 0; @@ -232,11 +237,11 @@ main(int argc, char *argv[]) flags |= MAGIC_ERROR; break; case 'e': - for (i = 0; i < sizeof(nv) / sizeof(nv[0]); i++) + for (i = 0; i < __arraycount(nv); i++) if (strcmp(nv[i].name, optarg) == 0) break; - if (i == sizeof(nv) / sizeof(nv[0])) + if (i == __arraycount(nv)) errflg++; else flags |= nv[i].value; @@ -287,12 +292,21 @@ main(int argc, char *argv[]) case 's': flags |= MAGIC_DEVICES; break; + case 'S': +#ifdef HAVE_LIBSECCOMP + sandbox = 0; +#endif + break; case 'v': if (magicfile == NULL) magicfile = magic_getpath(magicfile, action); - (void)fprintf(stdout, "%s-%s\n", progname, VERSION); + (void)fprintf(stdout, "%s-%s\n", file_getprogname(), + VERSION); (void)fprintf(stdout, "magic file from %s\n", - magicfile); + magicfile); +#ifdef HAVE_LIBSECCOMP + (void)fprintf(stdout, "seccomp support included\n"); +#endif return 0; case 'z': flags |= MAGIC_COMPRESS; @@ -321,10 +335,19 @@ main(int argc, char *argv[]) if (e) return e; +#ifdef HAVE_LIBSECCOMP +#if 0 + if (sandbox && enable_sandbox_basic() == -1) +#else + if (sandbox && enable_sandbox_full() == -1) +#endif + file_err(EXIT_FAILURE, "SECCOMP initialisation failed"); +#endif /* HAVE_LIBSECCOMP */ + if (MAGIC_VERSION != magic_version()) - (void)fprintf(stderr, "%s: compiled magic version [%d] " + file_warnx("Compiled magic version [%d] " "does not match with shared library magic version [%d]\n", - progname, MAGIC_VERSION, magic_version()); + MAGIC_VERSION, magic_version()); switch(action) { case FILE_CHECK: @@ -336,8 +359,7 @@ main(int argc, char *argv[]) */ magic = magic_open(flags|MAGIC_CHECK); if (magic == NULL) { - (void)fprintf(stderr, "%s: %s\n", progname, - strerror(errno)); + file_warn("Can't create magic"); return 1; } @@ -356,8 +378,7 @@ main(int argc, char *argv[]) abort(); } if (c == -1) { - (void)fprintf(stderr, "%s: %s\n", progname, - magic_error(magic)); + file_warnx("%s", magic_error(magic)); e = 1; goto out; } @@ -375,7 +396,8 @@ main(int argc, char *argv[]) } else { size_t j, wid, nw; - for (wid = 0, j = (size_t)optind; j < (size_t)argc; j++) { + for (wid = 0, j = CAST(size_t, optind); j < CAST(size_t, argc); + j++) { nw = file_mbswidth(argv[j]); if (nw > wid) wid = nw; @@ -403,13 +425,10 @@ applyparam(magic_t magic) size_t i; for (i = 0; i < __arraycount(pm); i++) { - if (pm[i].value == 0) + if (!pm[i].set) continue; - if (magic_setparam(magic, pm[i].tag, &pm[i].value) == -1) { - (void)fprintf(stderr, "%s: Can't set %s %s\n", progname, - pm[i].name, strerror(errno)); - exit(1); - } + if (magic_setparam(magic, pm[i].tag, &pm[i].value) == -1) + file_err(EXIT_FAILURE, "Can't set %s", pm[i].name); } } @@ -426,11 +445,11 @@ setparam(const char *p) if (strncmp(p, pm[i].name, s - p) != 0) continue; pm[i].value = atoi(s + 1); + pm[i].set = 1; return; } badparm: - (void)fprintf(stderr, "%s: Unknown param %s\n", progname, p); - exit(1); + file_errx(EXIT_FAILURE, "Unknown param %s", p); } private struct magic_set * @@ -441,17 +460,16 @@ load(const char *magicfile, int flags) const char *e; if (magic == NULL) { - (void)fprintf(stderr, "%s: %s\n", progname, strerror(errno)); + file_warn("Can't create magic"); return NULL; } if (magic_load(magic, magicfile) == -1) { - (void)fprintf(stderr, "%s: %s\n", - progname, magic_error(magic)); + file_warn("%s", magic_error(magic)); magic_close(magic); return NULL; } if ((e = magic_error(magic)) != NULL) - (void)fprintf(stderr, "%s: Warning: %s\n", progname, e); + file_warn("%s", e); return magic; } @@ -473,8 +491,7 @@ unwrap(struct magic_set *ms, const char *fn) wid = 1; } else { if ((f = fopen(fn, "r")) == NULL) { - (void)fprintf(stderr, "%s: Cannot open `%s' (%s).\n", - progname, fn, strerror(errno)); + file_warn("Cannot open `%s'", fn); return 1; } @@ -517,9 +534,8 @@ process(struct magic_set *ms, const char *inname, int wid) (void)putc('\0', stdout); if (nulsep < 2) { (void)printf("%s", separator); - (void)printf("%*s ", - (int) (nopad ? 0 : (wid - file_mbswidth(inname))), - ""); + (void)printf("%*s ", CAST(int, nopad ? 0 + : (wid - file_mbswidth(inname))), ""); } } @@ -546,8 +562,8 @@ file_mbswidth(const char *s) while (n > 0) { bytesconsumed = mbrtowc(&nextchar, s, n, &state); - if (bytesconsumed == (size_t)(-1) || - bytesconsumed == (size_t)(-2)) { + if (bytesconsumed == CAST(size_t, -1) || + bytesconsumed == CAST(size_t, -2)) { /* Something went wrong, return something reasonable */ return old_n; } @@ -574,8 +590,9 @@ file_mbswidth(const char *s) private void usage(void) { - (void)fprintf(stderr, USAGE, progname, progname, progname); - exit(1); + const char *pn = file_getprogname(); + (void)fprintf(stderr, USAGE, pn, pn, pn); + exit(EXIT_FAILURE); } private void @@ -605,13 +622,13 @@ docprint(const char *opts, int def) for (sp = p - 1; sp > opts && *sp == ' '; sp--) continue; - fprintf(stdout, "%.*s", (int)(p - opts), opts); + fprintf(stdout, "%.*s", CAST(int, p - opts), opts); comma = 0; for (i = 0; i < __arraycount(nv); i++) { fprintf(stdout, "%s%s", comma++ ? ", " : "", nv[i].name); - if (i && i % 5 == 0) { - fprintf(stdout, ",\n%*s", (int)(p - sp - 1), ""); + if (i && i % 5 == 0 && i != __arraycount(nv) - 1) { + fprintf(stdout, ",\n%*s", CAST(int, p - sp - 1), ""); comma = 0; } } @@ -635,6 +652,81 @@ help(void) #include "file_opts.h" #undef OPT #undef OPT_LONGONLY - fprintf(stdout, "\nReport bugs to http://bugs.gw.com/\n"); - exit(0); + fprintf(stdout, "\nReport bugs to https://bugs.astron.com/\n"); + exit(EXIT_SUCCESS); +} + +private const char *file_progname; + +protected void +file_setprogname(const char *progname) +{ + file_progname = progname; +} + +protected const char * +file_getprogname(void) +{ + return file_progname; +} + +protected void +file_err(int e, const char *fmt, ...) +{ + va_list ap; + int se = errno; + + va_start(ap, fmt); + fprintf(stderr, "%s: ", file_progname); + vfprintf(stderr, fmt, ap); + va_end(ap); + if (se) + fprintf(stderr, " (%s)\n", strerror(se)); + else + fputc('\n', stderr); + exit(e); +} + +protected void +file_errx(int e, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "%s: ", file_progname); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + exit(e); +} + +protected void +file_warn(const char *fmt, ...) +{ + va_list ap; + int se = errno; + + va_start(ap, fmt); + fprintf(stderr, "%s: ", file_progname); + vfprintf(stderr, fmt, ap); + va_end(ap); + if (se) + fprintf(stderr, " (%s)\n", strerror(se)); + else + fputc('\n', stderr); + errno = se; +} + +protected void +file_warnx(const char *fmt, ...) +{ + va_list ap; + int se = errno; + + va_start(ap, fmt); + fprintf(stderr, "%s: ", file_progname); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + errno = se; } diff --git a/deps/libmagic/src/file.h b/deps/libmagic/src/file.h index 9930710..3021fb3 100644 --- a/deps/libmagic/src/file.h +++ b/deps/libmagic/src/file.h @@ -27,7 +27,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$File: file.h,v 1.183 2017/08/28 13:39:18 christos Exp $ + * @(#)$File: file.h,v 1.213 2020/03/08 21:30:06 christos Exp $ */ #ifndef __file_h__ @@ -40,39 +40,8 @@ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS #endif - -// XXX: change by mscdex -#ifdef _MSC_VER -typedef unsigned int mode_t; -# ifdef _WIN64 - typedef __int64 ssize_t; - typedef unsigned __int64 size_t; -# else - typedef _W64 int ssize_t; - typedef _W64 unsigned int size_t; -# endif -# include -# define access _access -# define lseek _lseek -# define read _read -# define X_OK 1 /* MS access() doesn't check for execute permission. */ -# define W_OK 2 /* Check for write permission */ -# define R_OK 4 /* Check for read permission */ -# include -# include -# undef S_IFLNK -# undef S_IFSOCK -# ifndef S_IFFIFO -# ifdef _S_IFIFO -# define S_IFFIFO _S_IFIFO -# else -# define S_IFFIFO 0 -# endif -# endif -# define strtoull _strtoui64 -# define STDIN_FILENO 0 -#else -# include +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS #endif #ifdef WIN32 @@ -100,8 +69,7 @@ typedef unsigned int mode_t; #include #include #include -// XXX: change by mscdex -#ifndef _MSC_VER +#ifndef WIN32 #include #endif /* Do this here and now, because struct stat gets re-defined on solaris */ @@ -165,21 +133,34 @@ typedef unsigned int mode_t; #ifndef FILE_BYTES_MAX # define FILE_BYTES_MAX (1024 * 1024) /* how much of the file to look at */ #endif +#define FILE_BADSIZE CAST(size_t, ~0ul) #define MAXMAGIS 8192 /* max entries in any one magic file or directory */ #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 15 +#define FILE_MAGICSIZE 376 + +#define FILE_GUID_SIZE sizeof("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX") #define FILE_LOAD 0 #define FILE_CHECK 1 #define FILE_COMPILE 2 #define FILE_LIST 3 +struct buffer { + int fd; + struct stat st; + const void *fbuf; + size_t flen; + off_t eoff; + void *ebuf; + size_t elen; +}; + union VALUETYPE { uint8_t b; uint16_t h; @@ -190,6 +171,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; }; @@ -263,7 +245,8 @@ 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_NAMES_SIZE 50 /* size of array to contain all names */ #define IS_STRING(t) \ ((t) == FILE_STRING || \ @@ -322,7 +305,7 @@ struct magic { #endif /* ENABLE_CONDITIONALS */ /* Word 4 */ - uint32_t offset; /* offset to magic number */ + int32_t offset; /* offset to magic number */ /* Word 5 */ int32_t in_offset; /* offset from indirection */ /* Word 6 */ @@ -404,7 +387,7 @@ struct mlist { #define CCAST(T, b) const_cast(b) #else #define CAST(T, b) ((T)(b)) -#define RCAST(T, b) ((T)(b)) +#define RCAST(T, b) ((T)(uintptr_t)(b)) #define CCAST(T, b) ((T)(uintptr_t)(b)) #endif @@ -427,15 +410,19 @@ struct magic_set { } c; struct out { char *buf; /* Accumulation buffer */ + size_t blen; /* Length of buffer */ char *pbuf; /* Printable buffer */ } o; - uint32_t offset; + 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; int flags; /* Control magic tests. */ int event_flags; /* Note things that happened. */ #define EVENT_HAD_ERR 0x01 const char *file; size_t line; /* current magic line number */ + mode_t mode; /* copy of current stat mode */ /* data for searches */ struct { @@ -469,37 +456,42 @@ 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_buffer(struct magic_set *, int, const char *, const void *, - size_t); +protected int file_default(struct magic_set *, size_t); +protected int file_buffer(struct magic_set *, int, struct stat *, const char *, + const void *, size_t); protected int file_fsmagic(struct magic_set *, const char *, struct stat *); 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))); protected int file_reset(struct magic_set *, int); -protected int file_tryelf(struct magic_set *, int, const unsigned char *, - size_t); -protected int file_trycdf(struct magic_set *, int, const unsigned char *, - size_t); +protected int file_tryelf(struct magic_set *, const struct buffer *); +protected int file_trycdf(struct magic_set *, const struct buffer *); #if HAVE_FORK -protected int file_zmagic(struct magic_set *, int, const char *, - const unsigned char *, size_t); +protected int file_zmagic(struct magic_set *, const struct buffer *, + const char *); #endif -protected int file_ascmagic(struct magic_set *, const unsigned char *, size_t, +protected int file_ascmagic(struct magic_set *, const struct buffer *, int); protected int file_ascmagic_with_encoding(struct magic_set *, - const unsigned char *, size_t, unichar *, size_t, const char *, - const char *, int); -protected int file_encoding(struct magic_set *, const unsigned char *, size_t, + const struct buffer *, unichar *, size_t, const char *, const char *, int); +protected int file_encoding(struct magic_set *, const struct buffer *, unichar **, size_t *, const char **, const char **, const char **); -protected int file_is_tar(struct magic_set *, const unsigned char *, size_t); -protected int file_softmagic(struct magic_set *, const unsigned char *, size_t, +protected int file_is_json(struct magic_set *, const struct buffer *); +protected int file_is_csv(struct magic_set *, const struct buffer *, int); +protected int file_is_tar(struct magic_set *, const struct buffer *); +protected int file_softmagic(struct magic_set *, const struct buffer *, uint16_t *, uint16_t *, int, int); protected int file_apprentice(struct magic_set *, const char *, int); protected int buffer_apprentice(struct magic_set *, struct magic **, @@ -524,17 +516,22 @@ 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 char * file_printable(char *, size_t, 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 *, size_t); #endif /* __EMX__ */ -#if defined(HAVE_LOCALE_H) +protected void buffer_init(struct buffer *, int, const struct stat *, + const void *, size_t); +protected void buffer_fini(struct buffer *); +protected int buffer_fill(const struct buffer *); + #include -#endif #if defined(HAVE_XLOCALE_H) #include #endif @@ -560,6 +557,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; @@ -571,17 +569,6 @@ extern const char *file_names[]; extern const size_t file_nnames; #endif -#ifndef HAVE_STRERROR -extern int sys_nerr; -extern char *sys_errlist[]; -#define strerror(e) \ - (((e) >= 0 && (e) < sys_nerr) ? sys_errlist[(e)] : "Unknown error") -#endif - -#ifndef HAVE_STRTOUL -#define strtoul(a, b, c) strtol(a, b, c) -#endif - #ifndef HAVE_PREAD ssize_t pread(int, void *, size_t, off_t); #endif @@ -621,10 +608,33 @@ struct tm *gmtime_r(const time_t *, struct tm *); struct tm *localtime_r(const time_t *, struct tm *); #endif #ifndef HAVE_FMTCHECK -const char *fmtcheck(const char *, const char *) +const char *fmtcheck(const char *, const char *) __attribute__((__format_arg__(2))); #endif +#ifdef HAVE_LIBSECCOMP +// basic filter +// this mode should not interfere with normal operations +// only some dangerous syscalls are blacklisted +int enable_sandbox_basic(void); + +// enhanced filter +// this mode allows only the necessary syscalls used during normal operation +// extensive testing required !!! +int enable_sandbox_full(void); +#endif + +protected const char *file_getprogname(void); +protected void file_setprogname(const char *); +protected void file_err(int, const char *, ...) + __attribute__((__format__(__printf__, 2, 3), __noreturn__)); +protected void file_errx(int, const char *, ...) + __attribute__((__format__(__printf__, 2, 3), __noreturn__)); +protected void file_warn(const char *, ...) + __attribute__((__format__(__printf__, 1, 2))); +protected void file_warnx(const char *, ...) + __attribute__((__format__(__printf__, 1, 2))); + #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK) #define QUICK #endif @@ -632,6 +642,9 @@ const char *fmtcheck(const char *, const char *) #ifndef O_BINARY #define O_BINARY 0 #endif +#ifndef O_NONBLOCK +#define O_NONBLOCK 0 +#endif #ifndef __cplusplus #if defined(__GNUC__) && (__GNUC__ >= 3) diff --git a/deps/libmagic/src/file_opts.h b/deps/libmagic/src/file_opts.h index 52ace18..4f894cc 100644 --- a/deps/libmagic/src/file_opts.h +++ b/deps/libmagic/src/file_opts.h @@ -4,7 +4,10 @@ * The first column specifies the short name, if any, or 0 if none. * The second column specifies the long name. * The third column specifies whether it takes a parameter. - * The fourth column is the documentation. + * The fourth colums specifies whether is is marked as "default" + * if POSIXLY_CORRECT is defined: 1, + * if POSIXLY_CORRECT is not defined: 2. + * The fifth column is the documentation. * * N.B. The long options' order must correspond to the code in file.c, * and OPTSTRING must be kept up-to-date with the short options. @@ -54,5 +57,6 @@ OPT('P', "parameter", 1, 0, " set file engine parameter limits\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") diff --git a/deps/libmagic/src/fmtcheck.c b/deps/libmagic/src/fmtcheck.c index 486aa08..fcad436 100644 --- a/deps/libmagic/src/fmtcheck.c +++ b/deps/libmagic/src/fmtcheck.c @@ -235,7 +235,7 @@ fmtcheck(const char *f1, const char *f2) EFT f1t, f2t; if (!f1) return f2; - + f1p = f1; f1t = FMTCHECK_START; f2p = f2; diff --git a/deps/libmagic/src/fsmagic.c b/deps/libmagic/src/fsmagic.c index f84a10e..5204f20 100644 --- a/deps/libmagic/src/fsmagic.c +++ b/deps/libmagic/src/fsmagic.c @@ -2,7 +2,7 @@ * Copyright (c) Ian F. Darwin 1986-1995. * Software written by Ian F. Darwin and others; * maintained 1995-present by Christos Zoulas and others. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: fsmagic.c,v 1.77 2017/05/24 19:17:50 christos Exp $") +FILE_RCSID("@(#)$File: fsmagic.c,v 1.81 2019/07/16 13:30:32 christos Exp $") #endif /* lint */ #include "magic.h" @@ -46,18 +46,19 @@ FILE_RCSID("@(#)$File: fsmagic.c,v 1.77 2017/05/24 19:17:50 christos Exp $") # include # define HAVE_MAJOR #endif -#ifdef MAJOR_IN_SYSMACROS +#ifdef HAVE_SYS_SYSMACROS_H # include +#endif +#ifdef MAJOR_IN_SYSMACROS # define HAVE_MAJOR #endif -#ifdef major /* Might be defined in sys/types.h. */ +#if defined(major) && !defined(HAVE_MAJOR) +/* Might be defined in sys/types.h. */ # define HAVE_MAJOR #endif #ifdef WIN32 # define WIN32_LEAN_AND_MEAN # include -// XXX: change by mscdex -# define S_IFIFO _S_IFIFO #endif #ifndef HAVE_MAJOR @@ -79,7 +80,7 @@ bad_link(struct magic_set *ms, int err, char *buf) file_error(ms, err, "broken symbolic link to %s", buf); return -1; - } + } if (file_printf(ms, "broken symbolic link to %s", buf) == -1) return -1; } @@ -176,17 +177,17 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) return -1; #endif #ifdef S_ISGID - if (sb->st_mode & S_ISGID) + if (sb->st_mode & S_ISGID) if (file_printf(ms, "%ssetgid", COMMA) == -1) return -1; #endif #ifdef S_ISVTX - if (sb->st_mode & S_ISVTX) + if (sb->st_mode & S_ISVTX) if (file_printf(ms, "%ssticky", COMMA) == -1) return -1; #endif } - + switch (sb->st_mode & S_IFMT) { case S_IFDIR: if (mime) { @@ -198,7 +199,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) break; #ifdef S_IFCHR case S_IFCHR: - /* + /* * If -s has been specified, treat character special files * like ordinary files. Otherwise, just report that they * are block special files and go on to the next file. @@ -233,7 +234,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) #endif #ifdef S_IFBLK case S_IFBLK: - /* + /* * If -s has been specified, treat block special files * like ordinary files. Otherwise, just report that they * are block special files and go on to the next file. @@ -310,6 +311,15 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) buf[nch] = '\0'; /* readlink(2) does not do this */ /* If broken symlink, say so and quit early. */ +#ifdef __linux__ + /* + * linux procfs/devfs makes symlinks like pipe:[3515864880] + * that we can't stat their readlink output, so stat the + * original filename instead. + */ + if (stat(fn, &tstatbuf) < 0) + return bad_link(ms, errno, buf); +#else if (*buf == '/') { if (stat(buf, &tstatbuf) < 0) return bad_link(ms, errno, buf); @@ -322,7 +332,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) } else { if (tmp - fn + 1 > BUFSIZ) { if (ms->flags & MAGIC_ERROR) { - file_error(ms, 0, + file_error(ms, 0, "path too long: `%s'", buf); return -1; } @@ -347,6 +357,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) if (stat(tmp, &tstatbuf) < 0) return bad_link(ms, errno, buf); } +#endif /* Otherwise, handle it. */ if ((ms->flags & MAGIC_SYMLINK) != 0) { @@ -414,5 +425,11 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) if (file_printf(ms, " ") == -1) return -1; } + /* + * If we were looking for extensions or apple (silent) it is not our + * job to print here, so don't count this as a match. + */ + if (ret == 1 && silent) + return 0; return ret; } diff --git a/deps/libmagic/src/funcs.c b/deps/libmagic/src/funcs.c index d7a18f4..09b965e 100644 --- a/deps/libmagic/src/funcs.c +++ b/deps/libmagic/src/funcs.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: funcs.c,v 1.93 2017/08/28 13:39:18 christos Exp $") +FILE_RCSID("@(#)$File: funcs.c,v 1.115 2020/02/20 15:50:20 christos Exp $") #endif /* lint */ #include "magic.h" @@ -42,14 +42,83 @@ FILE_RCSID("@(#)$File: funcs.c,v 1.93 2017/08/28 13:39:18 christos Exp $") #if defined(HAVE_WCTYPE_H) #include #endif -#if defined(HAVE_LIMITS_H) #include -#endif #ifndef SIZE_MAX #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. */ @@ -58,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); @@ -74,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; } @@ -105,15 +190,14 @@ 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_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno); + file_clearbuf(ms); + (void)file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno); } if (ms->o.buf && *ms->o.buf) - file_printf(ms, " "); - file_vprintf(ms, f, va); + (void)file_printf(ms, " "); + (void)file_vprintf(ms, f, va); if (error > 0) - file_printf(ms, " (%s)", strerror(error)); + (void)file_printf(ms, " (%s)", strerror(error)); ms->event_flags |= EVENT_HAD_ERR; ms->error = error; } @@ -162,34 +246,70 @@ file_badread(struct magic_set *ms) #ifndef COMPILE_ONLY +protected int +file_separator(struct magic_set *ms) +{ + return file_printf(ms, "\n- "); +} + static int checkdone(struct magic_set *ms, int *rv) { if ((ms->flags & MAGIC_CONTINUE) == 0) return 1; - if (file_printf(ms, "\n- ") == -1) + if (file_separator(ms) == -1) *rv = -1; return 0; } +protected int +file_default(struct magic_set *ms, size_t nb) +{ + if (ms->flags & MAGIC_MIME) { + if ((ms->flags & MAGIC_MIME_TYPE) && + file_printf(ms, "application/%s", + nb ? "octet-stream" : "x-empty") == -1) + return -1; + return 1; + } + if (ms->flags & MAGIC_APPLE) { + if (file_printf(ms, "UNKNUNKN") == -1) + return -1; + return 1; + } + if (ms->flags & MAGIC_EXTENSION) { + if (file_printf(ms, "???") == -1) + return -1; + return 1; + } + return 0; +} + +/* + * The magic detection functions return: + * 1: found + * 0: not found + * -1: error + */ /*ARGSUSED*/ protected int -file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__unused__)), +file_buffer(struct magic_set *ms, int fd, struct stat *st, + const char *inname __attribute__ ((__unused__)), const void *buf, size_t nb) { int m = 0, rv = 0, looks_text = 0; - const unsigned char *ubuf = CAST(const unsigned char *, buf); - unichar *u8buf = NULL; - size_t ulen; const char *code = NULL; const char *code_mime = "binary"; - const char *type = "application/octet-stream"; const char *def = "data"; const char *ftype = NULL; + char *rbuf = NULL; + struct buffer b; + + buffer_init(&b, fd, st, buf, nb); + ms->mode = b.st.st_mode; if (nb == 0) { def = "empty"; - type = "application/x-empty"; goto simple; } else if (nb == 1) { def = "very short file (no magic)"; @@ -197,13 +317,13 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u } if ((ms->flags & MAGIC_NO_CHECK_ENCODING) == 0) { - looks_text = file_encoding(ms, ubuf, nb, &u8buf, &ulen, + looks_text = file_encoding(ms, &b, NULL, 0, &code, &code_mime, &ftype); } #ifdef __EMX__ if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) { - m = file_os2_apptype(ms, inname, buf, nb); + m = file_os2_apptype(ms, inname, &b); if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "[try os2_apptype %d]\n", m); switch (m) { @@ -219,7 +339,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u #if HAVE_FORK /* try compression stuff */ if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0) { - m = file_zmagic(ms, fd, inname, ubuf, nb); + m = file_zmagic(ms, &b, inname); if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "[try zmagic %d]\n", m); if (m) { @@ -229,7 +349,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u #endif /* Check if we have a tar file */ if ((ms->flags & MAGIC_NO_CHECK_TAR) == 0) { - m = file_is_tar(ms, ubuf, nb); + m = file_is_tar(ms, &b); if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "[try tar %d]\n", m); if (m) { @@ -238,9 +358,31 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u } } + /* Check if we have a JSON file */ + if ((ms->flags & MAGIC_NO_CHECK_JSON) == 0) { + m = file_is_json(ms, &b); + if ((ms->flags & MAGIC_DEBUG) != 0) + (void)fprintf(stderr, "[try json %d]\n", m); + if (m) { + if (checkdone(ms, &rv)) + goto done; + } + } + + /* Check if we have a CSV file */ + if ((ms->flags & MAGIC_NO_CHECK_CSV) == 0) { + m = file_is_csv(ms, &b, looks_text); + if ((ms->flags & MAGIC_DEBUG) != 0) + (void)fprintf(stderr, "[try csv %d]\n", m); + if (m) { + if (checkdone(ms, &rv)) + goto done; + } + } + /* Check if we have a CDF file */ if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) { - m = file_trycdf(ms, fd, ubuf, nb); + m = file_trycdf(ms, &b); if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "[try cdf %d]\n", m); if (m) { @@ -248,32 +390,43 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u goto done; } } +#ifdef BUILTIN_ELF + if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && nb > 5 && fd != -1) { + file_pushbuf_t *pb; + /* + * We matched something in the file, so this + * *might* be an ELF file, and the file is at + * least 5 bytes long, so if it's an ELF file + * it has at least one byte past the ELF magic + * number - try extracting information from the + * ELF headers that cannot easily be extracted + * with rules in the magic file. We we don't + * print the information yet. + */ + if ((pb = file_push_buffer(ms)) == NULL) + return -1; + + rv = file_tryelf(ms, &b); + rbuf = file_pop_buffer(ms, pb); + if (rv == -1) { + free(rbuf); + rbuf = NULL; + } + if ((ms->flags & MAGIC_DEBUG) != 0) + (void)fprintf(stderr, "[try elf %d]\n", m); + } +#endif /* try soft magic tests */ if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) { - m = file_softmagic(ms, ubuf, nb, NULL, NULL, BINTEST, - looks_text); + m = file_softmagic(ms, &b, NULL, NULL, BINTEST, looks_text); if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "[try softmagic %d]\n", m); + if (m == 1 && rbuf) { + if (file_printf(ms, "%s", rbuf) == -1) + goto done; + } if (m) { -#ifdef BUILTIN_ELF - if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 && - nb > 5 && fd != -1) { - /* - * We matched something in the file, so this - * *might* be an ELF file, and the file is at - * least 5 bytes long, so if it's an ELF file - * it has at least one byte past the ELF magic - * number - try extracting information from the - * ELF headers that cannot easily * be - * extracted with rules in the magic file. - */ - m = file_tryelf(ms, fd, ubuf, nb); - if ((ms->flags & MAGIC_DEBUG) != 0) - (void)fprintf(stderr, "[try elf %d]\n", - m); - } -#endif if (checkdone(ms, &rv)) goto done; } @@ -282,31 +435,22 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u /* try text properties */ if ((ms->flags & MAGIC_NO_CHECK_TEXT) == 0) { - m = file_ascmagic(ms, ubuf, nb, looks_text); + m = file_ascmagic(ms, &b, looks_text); if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "[try ascmagic %d]\n", m); if (m) { - if (checkdone(ms, &rv)) - goto done; + goto done; } } simple: /* give up */ - m = 1; - if (ms->flags & MAGIC_MIME) { - if ((ms->flags & MAGIC_MIME_TYPE) && - file_printf(ms, "%s", type) == -1) - rv = -1; - } else if (ms->flags & MAGIC_APPLE) { - if (file_printf(ms, "UNKNUNKN") == -1) - rv = -1; - } else if (ms->flags & MAGIC_EXTENSION) { - if (file_printf(ms, "???") == -1) - rv = -1; - } else { - if (file_printf(ms, "%s", def) == -1) - rv = -1; + if (m == 0) { + m = 1; + rv = file_default(ms, nb); + if (rv == 0) + if (file_printf(ms, "%s", def) == -1) + rv = -1; } done: if ((ms->flags & MAGIC_MIME_ENCODING) != 0) { @@ -319,7 +463,8 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u #if HAVE_FORK done_encoding: #endif - free(u8buf); + free(rbuf); + buffer_fini(&b); if (rv) return rv; @@ -334,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; @@ -350,9 +492,9 @@ file_reset(struct magic_set *ms, int checkloaded) #define OCTALIFY(n, o) \ /*LINTED*/ \ (void)(*(n)++ = '\\', \ - *(n)++ = (((uint32_t)*(o) >> 6) & 3) + '0', \ - *(n)++ = (((uint32_t)*(o) >> 3) & 7) + '0', \ - *(n)++ = (((uint32_t)*(o) >> 0) & 7) + '0', \ + *(n)++ = ((CAST(uint32_t, *(o)) >> 6) & 3) + '0', \ + *(n)++ = ((CAST(uint32_t, *(o)) >> 3) & 7) + '0', \ + *(n)++ = ((CAST(uint32_t, *(o)) >> 0) & 7) + '0', \ (o)++) protected const char * @@ -398,9 +540,9 @@ file_getbuffer(struct magic_set *ms) while (op < eop) { bytesconsumed = mbrtowc(&nextchar, op, - (size_t)(eop - op), &state); - if (bytesconsumed == (size_t)(-1) || - bytesconsumed == (size_t)(-2)) { + CAST(size_t, eop - op), &state); + if (bytesconsumed == CAST(size_t, -1) || + bytesconsumed == CAST(size_t, -2)) { mb_conv = 0; break; } @@ -423,7 +565,7 @@ file_getbuffer(struct magic_set *ms) #endif for (np = ms->o.pbuf, op = ms->o.buf; *op;) { - if (isprint((unsigned char)*op)) { + if (isprint(CAST(unsigned char, *op))) { *np++ = *op++; } else { OCTALIFY(np, op); @@ -459,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 @@ -497,7 +639,11 @@ file_regcomp(file_regex_t *rx, const char *pat, int flags) rx->old_lc_ctype = uselocale(rx->c_lc_ctype); assert(rx->old_lc_ctype != NULL); #else - rx->old_lc_ctype = setlocale(LC_CTYPE, "C"); + rx->old_lc_ctype = setlocale(LC_CTYPE, NULL); + assert(rx->old_lc_ctype != NULL); + rx->old_lc_ctype = strdup(rx->old_lc_ctype); + assert(rx->old_lc_ctype != NULL); + (void)setlocale(LC_CTYPE, "C"); #endif rx->pat = pat; @@ -510,7 +656,8 @@ file_regexec(file_regex_t *rx, const char *str, size_t nmatch, { assert(rx->rc == 0); /* XXX: force initialization because glibc does not always do this */ - memset(pmatch, 0, nmatch * sizeof(*pmatch)); + if (nmatch != 0) + memset(pmatch, 0, nmatch * sizeof(*pmatch)); return regexec(&rx->rx, str, nmatch, pmatch, eflags); } @@ -524,6 +671,7 @@ file_regfree(file_regex_t *rx) freelocale(rx->c_lc_ctype); #else (void)setlocale(LC_CTYPE, rx->old_lc_ctype); + free(rx->old_lc_ctype); #endif } @@ -549,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; @@ -571,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); @@ -581,12 +732,13 @@ file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb) * convert string to ascii printable format. */ protected char * -file_printable(char *buf, size_t bufsiz, const char *str) +file_printable(char *buf, size_t bufsiz, const char *str, size_t slen) { - char *ptr, *eptr; - const unsigned char *s = (const unsigned char *)str; + char *ptr, *eptr = buf + bufsiz - 1; + const unsigned char *s = RCAST(const unsigned char *, str); + const unsigned char *es = s + slen; - for (ptr = buf, eptr = ptr + bufsiz - 1; ptr < eptr && *s; s++) { + for (ptr = buf; ptr < eptr && s < es && *s; s++) { if (isprint(*s)) { *ptr++ = *s; continue; @@ -601,3 +753,33 @@ file_printable(char *buf, size_t bufsiz, const char *str) *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]); +} diff --git a/deps/libmagic/src/getline.c b/deps/libmagic/src/getline.c index 67bd006..b00de01 100644 --- a/deps/libmagic/src/getline.c +++ b/deps/libmagic/src/getline.c @@ -33,10 +33,7 @@ #if !HAVE_GETLINE #include #include -// XXX: change by mscdex -#ifdef HAVE_UNISTD_H #include -#endif #include #include diff --git a/deps/libmagic/src/getopt_long.c b/deps/libmagic/src/getopt_long.c index d357dc3..43c4245 100644 --- a/deps/libmagic/src/getopt_long.c +++ b/deps/libmagic/src/getopt_long.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: getopt_long.c,v 1.6 2009/02/13 18:48:05 christos Exp $") +FILE_RCSID("@(#)$File: getopt_long.c,v 1.7 2018/09/09 20:33:28 christos Exp $") #endif /* lint */ #include @@ -124,7 +124,7 @@ gcd(a, b) b = c; c = a % b; } - + return b; } @@ -223,7 +223,7 @@ getopt_internal(nargc, nargv, options) place = EMSG; if (IN_ORDER) { /* - * GNU extension: + * GNU extension: * return non-option as argument to option 1 */ optarg = nargv[optind++]; @@ -269,7 +269,7 @@ getopt_internal(nargc, nargv, options) } if (optchar == 'W' && oli[1] == ';') { /* -W long-option */ /* XXX: what if no long options provided (called by getopt)? */ - if (*place) + if (*place) return -2; if (++optind >= nargc) { /* no arg */ @@ -404,7 +404,7 @@ getopt_long(nargc, nargv, options, long_options, idx) has_equal++; } else current_argv_len = strlen(current_argv); - + for (i = 0; long_options[i].name; i++) { /* find matching long option */ if (strncmp(current_argv, long_options[i].name, @@ -488,7 +488,7 @@ getopt_long(nargc, nargv, options, long_options, idx) if (long_options[match].flag) { *long_options[match].flag = long_options[match].val; retval = 0; - } else + } else retval = long_options[match].val; if (idx) *idx = match; diff --git a/deps/libmagic/src/gmtime_r.c b/deps/libmagic/src/gmtime_r.c index 469ec65..7e27ed6 100644 --- a/deps/libmagic/src/gmtime_r.c +++ b/deps/libmagic/src/gmtime_r.c @@ -1,8 +1,8 @@ -/* $File: gmtime_r.c,v 1.2 2015/07/11 14:41:37 christos Exp $ */ +/* $File: gmtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $ */ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: gmtime_r.c,v 1.2 2015/07/11 14:41:37 christos Exp $") +FILE_RCSID("@(#)$File: gmtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $") #endif /* lint */ #include #include diff --git a/deps/libmagic/src/is_csv.c b/deps/libmagic/src/is_csv.c new file mode 100644 index 0000000..0081088 --- /dev/null +++ b/deps/libmagic/src/is_csv.c @@ -0,0 +1,197 @@ +/*- + * Copyright (c) 2019 Christos Zoulas + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Parse CSV object serialization format (RFC-4180, RFC-7111) + */ + +#ifndef TEST +#include "file.h" + +#ifndef lint +FILE_RCSID("@(#)$File: is_csv.c,v 1.4 2019/06/26 20:31:31 christos Exp $") +#endif + +#include +#include "magic.h" +#else +#include +#endif + + +#ifdef DEBUG +#include +#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__) +#else +#define DPRINTF(fmt, ...) +#endif + +/* + * if CSV_LINES == 0: + * check all the lines in the buffer + * otherwise: + * check only up-to the number of lines specified + * + * the last line count is always ignored if it does not end in CRLF + */ +#ifndef CSV_LINES +#define CSV_LINES 10 +#endif + +static int csv_parse(const unsigned char *, const unsigned char *); + +static const unsigned char * +eatquote(const unsigned char *uc, const unsigned char *ue) +{ + int quote = 0; + + while (uc < ue) { + unsigned char c = *uc++; + if (c != '"') { + // We already got one, done. + if (quote) { + return --uc; + } + continue; + } + if (quote) { + // quote-quote escapes + quote = 0; + continue; + } + // first quote + quote = 1; + } + return ue; +} + +static int +csv_parse(const unsigned char *uc, const unsigned char *ue) +{ + size_t nf = 0, tf = 0, nl = 0; + + while (uc < ue) { + unsigned char c; + switch (c = *uc++) { + case '"': + // Eat until the matching quote + uc = eatquote(uc, ue); + break; + case ',': + nf++; + break; + case '\n': + DPRINTF("%zu %zu %zu\n", nl, nf, tf); + nl++; +#if CSV_LINES + if (nl == CSV_LINES) + return tf != 0 && tf == nf; +#endif + if (tf == 0) { + // First time and no fields, give up + if (nf == 0) + return 0; + // First time, set the number of fields + tf = nf; + } else if (tf != nf) { + // Field number mismatch, we are done. + return 0; + } + nf = 0; + break; + default: + break; + } + } + return tf && nl > 2; +} + +#ifndef TEST +int +file_is_csv(struct magic_set *ms, const struct buffer *b, int looks_text) +{ + const unsigned char *uc = CAST(const unsigned char *, b->fbuf); + const unsigned char *ue = uc + b->flen; + int mime = ms->flags & MAGIC_MIME; + + if (!looks_text) + return 0; + + if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) != 0) + return 0; + + if (!csv_parse(uc, ue)) + return 0; + + if (mime == MAGIC_MIME_ENCODING) + return 1; + + if (mime) { + if (file_printf(ms, "application/csv") == -1) + return -1; + return 1; + } + + if (file_printf(ms, "CSV text") == -1) + return -1; + + return 1; +} + +#else + +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int fd, rv; + struct stat st; + unsigned char *p; + + if ((fd = open(argv[1], O_RDONLY)) == -1) + err(EXIT_FAILURE, "Can't open `%s'", argv[1]); + + if (fstat(fd, &st) == -1) + err(EXIT_FAILURE, "Can't stat `%s'", argv[1]); + + if ((p = malloc(st.st_size)) == NULL) + err(EXIT_FAILURE, "Can't allocate %jd bytes", + (intmax_t)st.st_size); + if (read(fd, p, st.st_size) != st.st_size) + err(EXIT_FAILURE, "Can't read %jd bytes", + (intmax_t)st.st_size); + printf("is csv %d\n", csv_parse(p, p + st.st_size)); + return 0; +} +#endif diff --git a/deps/libmagic/src/is_json.c b/deps/libmagic/src/is_json.c new file mode 100644 index 0000000..206ec37 --- /dev/null +++ b/deps/libmagic/src/is_json.c @@ -0,0 +1,462 @@ +/*- + * Copyright (c) 2018 Christos Zoulas + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Parse JSON object serialization format (RFC-7159) + */ + +#ifndef TEST +#include "file.h" + +#ifndef lint +FILE_RCSID("@(#)$File: is_json.c,v 1.13 2019/03/02 01:08:10 christos Exp $") +#endif + +#include +#include "magic.h" +#endif + +#ifdef DEBUG +#include +#define DPRINTF(a, b, c) \ + printf("%s [%.2x/%c] %.20s\n", (a), *(b), *(b), (const char *)(c)) +#else +#define DPRINTF(a, b, c) do { } while (/*CONSTCOND*/0) +#endif + +#define JSON_ARRAY 0 +#define JSON_CONSTANT 1 +#define JSON_NUMBER 2 +#define JSON_OBJECT 3 +#define JSON_STRING 4 +#define JSON_ARRAYN 5 +#define JSON_MAX 6 + +/* + * if JSON_COUNT != 0: + * count all the objects, require that we have the whole data file + * otherwise: + * stop if we find an object or an array + */ +#ifndef JSON_COUNT +#define JSON_COUNT 0 +#endif + +static int json_parse(const unsigned char **, const unsigned char *, size_t *, + size_t); + +static int +json_isspace(const unsigned char uc) +{ + switch (uc) { + case ' ': + case '\n': + case '\r': + case '\t': + return 1; + default: + return 0; + } +} + +static int +json_isdigit(unsigned char uc) +{ + switch (uc) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return 1; + default: + return 0; + } +} + +static int +json_isxdigit(unsigned char uc) +{ + if (json_isdigit(uc)) + return 1; + switch (uc) { + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + return 1; + default: + return 0; + } +} + +static const unsigned char * +json_skip_space(const unsigned char *uc, const unsigned char *ue) +{ + while (uc < ue && json_isspace(*uc)) + uc++; + return uc; +} + +static int +json_parse_string(const unsigned char **ucp, const unsigned char *ue) +{ + const unsigned char *uc = *ucp; + size_t i; + + DPRINTF("Parse string: ", uc, *ucp); + while (uc < ue) { + switch (*uc++) { + case '\0': + goto out; + case '\\': + if (uc == ue) + goto out; + switch (*uc++) { + case '\0': + goto out; + case '"': + case '\\': + case '/': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + continue; + case 'u': + if (ue - uc < 4) { + uc = ue; + goto out; + } + for (i = 0; i < 4; i++) + if (!json_isxdigit(*uc++)) + goto out; + continue; + default: + goto out; + } + case '"': + *ucp = uc; + return 1; + default: + continue; + } + } +out: + DPRINTF("Bad string: ", uc, *ucp); + *ucp = uc; + return 0; +} + +static int +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 (!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]++; + *ucp = uc + 1; + return 1; + default: + goto out; + } + } +out: + DPRINTF("Bad array: ", uc, *ucp); + *ucp = uc; + return 0; +} + +static int +json_parse_object(const unsigned char **ucp, const unsigned char *ue, + size_t *st, size_t lvl) +{ + const unsigned char *uc = *ucp; + DPRINTF("Parse object: ", uc, *ucp); + while (uc < ue) { + uc = json_skip_space(uc, ue); + if (uc == ue) + goto out; + if (*uc++ != '"') { + DPRINTF("not string", uc, *ucp); + goto out; + } + DPRINTF("next field", uc, *ucp); + if (!json_parse_string(&uc, ue)) { + DPRINTF("not string", uc, *ucp); + goto out; + } + uc = json_skip_space(uc, ue); + if (uc == ue) + goto out; + if (*uc++ != ':') { + DPRINTF("not colon", uc, *ucp); + goto out; + } + if (!json_parse(&uc, ue, st, lvl + 1)) { + DPRINTF("not json", uc, *ucp); + goto out; + } + if (uc == ue) + goto out; + switch (*uc++) { + case ',': + continue; + case '}': /* { */ + *ucp = uc; + DPRINTF("Good object: ", uc, *ucp); + return 1; + default: + *ucp = uc - 1; + DPRINTF("not more", uc, *ucp); + goto out; + } + } +out: + DPRINTF("Bad object: ", uc, *ucp); + *ucp = uc; + return 0; +} + +static int +json_parse_number(const unsigned char **ucp, const unsigned char *ue) +{ + const unsigned char *uc = *ucp; + int got = 0; + + DPRINTF("Parse number: ", uc, *ucp); + if (uc == ue) + return 0; + if (*uc == '-') + uc++; + + for (; uc < ue; uc++) { + if (!json_isdigit(*uc)) + break; + got = 1; + } + if (uc == ue) + goto out; + if (*uc == '.') + uc++; + for (; uc < ue; uc++) { + if (!json_isdigit(*uc)) + break; + got = 1; + } + if (uc == ue) + goto out; + if (got && (*uc == 'e' || *uc == 'E')) { + uc++; + got = 0; + if (uc == ue) + goto out; + if (*uc == '+' || *uc == '-') + uc++; + for (; uc < ue; uc++) { + if (!json_isdigit(*uc)) + break; + got = 1; + } + } +out: + if (!got) + DPRINTF("Bad number: ", uc, *ucp); + else + DPRINTF("Good number: ", uc, *ucp); + *ucp = uc; + return got; +} + +static int +json_parse_const(const unsigned char **ucp, const unsigned char *ue, + const char *str, size_t len) +{ + const unsigned char *uc = *ucp; + + DPRINTF("Parse const: ", uc, *ucp); + for (len--; uc < ue && --len;) { + if (*uc++ == *++str) + continue; + } + if (len) + DPRINTF("Bad const: ", uc, *ucp); + *ucp = uc; + return len == 0; +} + +static int +json_parse(const unsigned char **ucp, const unsigned char *ue, + size_t *st, size_t lvl) +{ + const unsigned char *uc; + int rv = 0; + int t; + + uc = json_skip_space(*ucp, ue); + if (uc == ue) + goto out; + + // Avoid recursion + if (lvl > 20) + return 0; +#if JSON_COUNT + /* bail quickly if not counting */ + if (lvl > 1 && (st[JSON_OBJECT] || st[JSON_ARRAYN])) + return 1; +#endif + + DPRINTF("Parse general: ", uc, *ucp); + switch (*uc++) { + case '"': + rv = json_parse_string(&uc, ue); + t = JSON_STRING; + break; + case '[': + rv = json_parse_array(&uc, ue, st, lvl + 1); + t = JSON_ARRAY; + break; + case '{': /* '}' */ + rv = json_parse_object(&uc, ue, st, lvl + 1); + t = JSON_OBJECT; + break; + case 't': + rv = json_parse_const(&uc, ue, "true", sizeof("true")); + t = JSON_CONSTANT; + break; + case 'f': + rv = json_parse_const(&uc, ue, "false", sizeof("false")); + t = JSON_CONSTANT; + break; + case 'n': + rv = json_parse_const(&uc, ue, "null", sizeof("null")); + t = JSON_CONSTANT; + break; + default: + --uc; + rv = json_parse_number(&uc, ue); + t = JSON_NUMBER; + break; + } + if (rv) + st[t]++; + uc = json_skip_space(uc, ue); +out: + *ucp = uc; + DPRINTF("End general: ", uc, *ucp); + if (lvl == 0) + return rv && (st[JSON_ARRAYN] || st[JSON_OBJECT]); + return rv; +} + +#ifndef TEST +int +file_is_json(struct magic_set *ms, const struct buffer *b) +{ + const unsigned char *uc = CAST(const unsigned char *, b->fbuf); + const unsigned char *ue = uc + b->flen; + size_t st[JSON_MAX]; + int mime = ms->flags & MAGIC_MIME; + + + if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) != 0) + return 0; + + memset(st, 0, sizeof(st)); + + if (!json_parse(&uc, ue, st, 0)) + return 0; + + if (mime == MAGIC_MIME_ENCODING) + return 1; + if (mime) { + if (file_printf(ms, "application/json") == -1) + return -1; + return 1; + } + if (file_printf(ms, "JSON data") == -1) + return -1; +#if JSON_COUNT +#define P(n) st[n], st[n] > 1 ? "s" : "" + if (file_printf(ms, " (%" SIZE_T_FORMAT "u object%s, %" SIZE_T_FORMAT + "u array%s, %" SIZE_T_FORMAT "u string%s, %" SIZE_T_FORMAT + "u constant%s, %" SIZE_T_FORMAT "u number%s, %" SIZE_T_FORMAT + "u >1array%s)", + P(JSON_OBJECT), P(JSON_ARRAY), P(JSON_STRING), P(JSON_CONSTANT), + P(JSON_NUMBER), P(JSON_ARRAYN)) + == -1) + return -1; +#endif + return 1; +} + +#else + +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int fd, rv; + struct stat st; + unsigned char *p; + size_t stats[JSON_MAX]; + + if ((fd = open(argv[1], O_RDONLY)) == -1) + err(EXIT_FAILURE, "Can't open `%s'", argv[1]); + + if (fstat(fd, &st) == -1) + err(EXIT_FAILURE, "Can't stat `%s'", argv[1]); + + if ((p = malloc(st.st_size)) == NULL) + err(EXIT_FAILURE, "Can't allocate %jd bytes", + (intmax_t)st.st_size); + if (read(fd, p, st.st_size) != st.st_size) + err(EXIT_FAILURE, "Can't read %jd bytes", + (intmax_t)st.st_size); + memset(stats, 0, sizeof(stats)); + printf("is json %d\n", json_parse((const unsigned char **)&p, + p + st.st_size, stats, 0)); + return 0; +} +#endif diff --git a/deps/libmagic/src/is_tar.c b/deps/libmagic/src/is_tar.c index 1953a7f..82b0805 100644 --- a/deps/libmagic/src/is_tar.c +++ b/deps/libmagic/src/is_tar.c @@ -40,7 +40,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: is_tar.c,v 1.39 2017/03/17 20:45:01 christos Exp $") +FILE_RCSID("@(#)$File: is_tar.c,v 1.44 2019/02/20 02:35:27 christos Exp $") #endif #include "magic.h" @@ -53,15 +53,17 @@ FILE_RCSID("@(#)$File: is_tar.c,v 1.39 2017/03/17 20:45:01 christos Exp $") private int is_tar(const unsigned char *, size_t); private int from_oct(const char *, size_t); /* Decode octal number */ -static const char tartype[][32] = { - "tar archive", +static const char tartype[][32] = { /* should be equal to messages */ + "tar archive", /* found in ../magic/Magdir/archive */ "POSIX tar archive", - "POSIX tar archive (GNU)", + "POSIX tar archive (GNU)", /* */ }; protected int -file_is_tar(struct magic_set *ms, const unsigned char *buf, size_t nbytes) +file_is_tar(struct magic_set *ms, const struct buffer *b) { + const unsigned char *buf = CAST(const unsigned char *, b->fbuf); + size_t nbytes = b->flen; /* * Do the tar test first, because if the first file in the tar * archive starts with a dot, we can confuse it with an nroff file. @@ -76,9 +78,13 @@ file_is_tar(struct magic_set *ms, const unsigned char *buf, size_t nbytes) if (tar < 1 || tar > 3) return 0; + if (mime == MAGIC_MIME_ENCODING) + return 1; + if (file_printf(ms, "%s", mime ? "application/x-tar" : tartype[tar - 1]) == -1) return -1; + return 1; } @@ -92,7 +98,8 @@ file_is_tar(struct magic_set *ms, const unsigned char *buf, size_t nbytes) private int is_tar(const unsigned char *buf, size_t nbytes) { - const union record *header = (const union record *)(const void *)buf; + const union record *header = RCAST(const union record *, + RCAST(const void *, buf)); size_t i; int sum, recsum; const unsigned char *p, *ep; @@ -141,7 +148,7 @@ from_oct(const char *where, size_t digs) if (digs == 0) return -1; - while (isspace((unsigned char)*where)) { /* Skip spaces */ + while (isspace(CAST(unsigned char, *where))) { /* Skip spaces */ where++; if (digs-- == 0) return -1; /* All blank field */ @@ -152,7 +159,7 @@ from_oct(const char *where, size_t digs) digs--; } - if (digs > 0 && *where && !isspace((unsigned char)*where)) + if (digs > 0 && *where && !isspace(CAST(unsigned char, *where))) return -1; /* Ended on non-(space/NUL) */ return value; diff --git a/deps/libmagic/src/localtime_r.c b/deps/libmagic/src/localtime_r.c index b0d996d..35c3b40 100644 --- a/deps/libmagic/src/localtime_r.c +++ b/deps/libmagic/src/localtime_r.c @@ -1,8 +1,8 @@ -/* $File: localtime_r.c,v 1.2 2015/07/11 14:41:37 christos Exp $ */ +/* $File: localtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $ */ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: localtime_r.c,v 1.2 2015/07/11 14:41:37 christos Exp $") +FILE_RCSID("@(#)$File: localtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $") #endif /* lint */ #include #include diff --git a/deps/libmagic/src/magic.c b/deps/libmagic/src/magic.c index 91c9d82..da5baf1 100644 --- a/deps/libmagic/src/magic.c +++ b/deps/libmagic/src/magic.c @@ -25,8 +25,7 @@ * SUCH DAMAGE. */ -// XXX: change by mscdex -#ifdef _MSC_VER +#ifdef WIN32 #include #include #endif @@ -34,23 +33,18 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: magic.c,v 1.102 2017/08/28 13:39:18 christos Exp $") +FILE_RCSID("@(#)$File: magic.c,v 1.111 2019/05/07 02:27:11 christos Exp $") #endif /* lint */ #include "magic.h" #include -// XXX: change by mscdex -#ifdef HAVE_UNISTD_H #include -#endif #include #ifdef QUICK #include #endif -#ifdef HAVE_LIMITS_H #include /* for PIPE_BUF */ -#endif #if defined(HAVE_UTIMES) # include @@ -318,7 +312,8 @@ magic_load_buffers(struct magic_set *ms, void **bufs, size_t *sizes, { if (ms == NULL) return -1; - return buffer_apprentice(ms, (struct magic **)bufs, sizes, nbufs); + return buffer_apprentice(ms, RCAST(struct magic **, bufs), + sizes, nbufs); } #endif @@ -411,7 +406,8 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd) struct stat sb; ssize_t nbytes = 0; /* number of bytes read from a datafile */ int ispipe = 0; - off_t pos = (off_t)-1; + int okstat = 0; + off_t pos = CAST(off_t, -1); if (file_reset(ms, 1) == -1) goto out; @@ -439,25 +435,13 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd) if (fd == STDIN_FILENO) _setmode(STDIN_FILENO, O_BINARY); #endif - - if (inname == NULL) { - if (fstat(fd, &sb) == 0 && S_ISFIFO(sb.st_mode)) - ispipe = 1; - else - pos = lseek(fd, (off_t)0, SEEK_CUR); - } else { - int flags = O_RDONLY|O_BINARY; - int okstat = stat(inname, &sb) == 0; - - if (okstat && S_ISFIFO(sb.st_mode)) { -#ifdef O_NONBLOCK - flags |= O_NONBLOCK; -#endif - ispipe = 1; - } - + if (inname != NULL) { + int flags = O_RDONLY|O_BINARY|O_NONBLOCK; errno = 0; if ((fd = open(inname, flags)) < 0) { + okstat = stat(inname, &sb) == 0; + if (okstat && S_ISFIFO(sb.st_mode)) + ispipe = 1; #ifdef WIN32 /* * Can't stat, can't open. It may have been opened in @@ -476,24 +460,29 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd) rv = 0; goto done; } -#ifdef O_NONBLOCK - if ((flags = fcntl(fd, F_GETFL)) != -1) { - flags &= ~O_NONBLOCK; - (void)fcntl(fd, F_SETFL, flags); - } -#endif + } + + if (fd != -1) { + if (!okstat) + okstat = fstat(fd, &sb) == 0; + if (okstat && S_ISFIFO(sb.st_mode)) + ispipe = 1; + if (inname == NULL) + pos = lseek(fd, CAST(off_t, 0), SEEK_CUR); } /* * try looking at the first ms->bytes_max bytes */ if (ispipe) { - ssize_t r = 0; + if (fd != -1) { + ssize_t r = 0; - while ((r = sread(fd, (void *)&buf[nbytes], - (size_t)(ms->bytes_max - nbytes), 1)) > 0) { - nbytes += r; - if (r < PIPE_BUF) break; + while ((r = sread(fd, RCAST(void *, &buf[nbytes]), + CAST(size_t, ms->bytes_max - nbytes), 1)) > 0) { + nbytes += r; + if (r < PIPE_BUF) break; + } } if (nbytes == 0 && inname) { @@ -504,14 +493,14 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd) goto done; } - } else { + } else if (fd != -1) { /* Windows refuses to read from a big console buffer. */ size_t howmany = #if defined(WIN32) - _isatty(fd) ? 8 * 1024 : + _isatty(fd) ? 8 * 1024 : #endif - ms->bytes_max; - if ((nbytes = read(fd, (char *)buf, howmany)) == -1) { + ms->bytes_max; + if ((nbytes = read(fd, RCAST(void *, buf), howmany)) == -1) { if (inname == NULL && fd != STDIN_FILENO) file_error(ms, errno, "cannot read fd %d", fd); else @@ -522,13 +511,13 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd) } (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */ - if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1) + if (file_buffer(ms, fd, okstat ? &sb : NULL, inname, buf, CAST(size_t, nbytes)) == -1) goto done; rv = 0; done: free(buf); if (fd != -1) { - if (pos != (off_t)-1) + if (pos != CAST(off_t, -1)) (void)lseek(fd, pos, SEEK_SET); close_and_restore(ms, inname, fd, &sb); } @@ -548,7 +537,7 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb) * The main work is done here! * We have the file name and/or the data buffer to be identified. */ - if (file_buffer(ms, -1, NULL, buf, nb) == -1) { + if (file_buffer(ms, -1, NULL, NULL, buf, nb) == -1) { return NULL; } return file_getbuffer(ms); @@ -602,27 +591,29 @@ magic_version(void) public int magic_setparam(struct magic_set *ms, int param, const void *val) { + if (ms == NULL) + return -1; switch (param) { case MAGIC_PARAM_INDIR_MAX: - ms->indir_max = (uint16_t)*(const size_t *)val; + ms->indir_max = CAST(uint16_t, *CAST(const size_t *, val)); return 0; case MAGIC_PARAM_NAME_MAX: - ms->name_max = (uint16_t)*(const size_t *)val; + ms->name_max = CAST(uint16_t, *CAST(const size_t *, val)); return 0; case MAGIC_PARAM_ELF_PHNUM_MAX: - ms->elf_phnum_max = (uint16_t)*(const size_t *)val; + ms->elf_phnum_max = CAST(uint16_t, *CAST(const size_t *, val)); return 0; case MAGIC_PARAM_ELF_SHNUM_MAX: - ms->elf_shnum_max = (uint16_t)*(const size_t *)val; + ms->elf_shnum_max = CAST(uint16_t, *CAST(const size_t *, val)); return 0; case MAGIC_PARAM_ELF_NOTES_MAX: - ms->elf_notes_max = (uint16_t)*(const size_t *)val; + ms->elf_notes_max = CAST(uint16_t, *CAST(const size_t *, val)); return 0; case MAGIC_PARAM_REGEX_MAX: - ms->elf_notes_max = (uint16_t)*(const size_t *)val; + ms->regex_max = CAST(uint16_t, *CAST(const size_t *, val)); return 0; case MAGIC_PARAM_BYTES_MAX: - ms->bytes_max = *(const size_t *)val; + ms->bytes_max = *CAST(const size_t *, val); return 0; default: errno = EINVAL; @@ -633,27 +624,29 @@ magic_setparam(struct magic_set *ms, int param, const void *val) public int magic_getparam(struct magic_set *ms, int param, void *val) { + if (ms == NULL) + return -1; switch (param) { case MAGIC_PARAM_INDIR_MAX: - *(size_t *)val = ms->indir_max; + *CAST(size_t *, val) = ms->indir_max; return 0; case MAGIC_PARAM_NAME_MAX: - *(size_t *)val = ms->name_max; + *CAST(size_t *, val) = ms->name_max; return 0; case MAGIC_PARAM_ELF_PHNUM_MAX: - *(size_t *)val = ms->elf_phnum_max; + *CAST(size_t *, val) = ms->elf_phnum_max; return 0; case MAGIC_PARAM_ELF_SHNUM_MAX: - *(size_t *)val = ms->elf_shnum_max; + *CAST(size_t *, val) = ms->elf_shnum_max; return 0; case MAGIC_PARAM_ELF_NOTES_MAX: - *(size_t *)val = ms->elf_notes_max; + *CAST(size_t *, val) = ms->elf_notes_max; return 0; case MAGIC_PARAM_REGEX_MAX: - *(size_t *)val = ms->regex_max; + *CAST(size_t *, val) = ms->regex_max; return 0; case MAGIC_PARAM_BYTES_MAX: - *(size_t *)val = ms->bytes_max; + *CAST(size_t *, val) = ms->bytes_max; return 0; default: errno = EINVAL; diff --git a/deps/libmagic/src/magic.h b/deps/libmagic/src/magic.h index 2d707d5..a6dccc2 100644 --- a/deps/libmagic/src/magic.h +++ b/deps/libmagic/src/magic.h @@ -56,8 +56,10 @@ #define MAGIC_NO_CHECK_ELF 0x0010000 /* Don't check for elf details */ #define MAGIC_NO_CHECK_TEXT 0x0020000 /* Don't check for text files */ #define MAGIC_NO_CHECK_CDF 0x0040000 /* Don't check for cdf files */ +#define MAGIC_NO_CHECK_CSV 0x0080000 /* Don't check for CSV files */ #define MAGIC_NO_CHECK_TOKENS 0x0100000 /* Don't check tokens */ #define MAGIC_NO_CHECK_ENCODING 0x0200000 /* Don't check text encodings */ +#define MAGIC_NO_CHECK_JSON 0x0400000 /* Don't check for JSON files */ /* No built-in tests; only consult the magic file */ #define MAGIC_NO_CHECK_BUILTIN ( \ @@ -67,9 +69,11 @@ MAGIC_NO_CHECK_APPTYPE | \ MAGIC_NO_CHECK_ELF | \ MAGIC_NO_CHECK_TEXT | \ + MAGIC_NO_CHECK_CSV | \ MAGIC_NO_CHECK_CDF | \ MAGIC_NO_CHECK_TOKENS | \ MAGIC_NO_CHECK_ENCODING | \ + MAGIC_NO_CHECK_JSON | \ 0 \ ) @@ -96,7 +100,7 @@ b\22no_check_cdf\0\ b\23no_check_reserved0\0\ b\24no_check_tokens\0\ b\25no_check_encoding\0\ -b\26no_check_reserved1\0\ +b\26no_check_json\0\ b\27no_check_reserved2\0\ b\30extension\0\ b\31transp_compression\0\ @@ -109,7 +113,7 @@ b\31transp_compression\0\ #define MAGIC_NO_CHECK_FORTRAN 0x000000 /* Don't check ascii/fortran */ #define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */ -#define MAGIC_VERSION 532 /* This implementation */ +#define MAGIC_VERSION 538 /* This implementation */ #ifdef __cplusplus diff --git a/deps/libmagic/src/mygetopt.h b/deps/libmagic/src/mygetopt.h index ef87525..d766762 100644 --- a/deps/libmagic/src/mygetopt.h +++ b/deps/libmagic/src/mygetopt.h @@ -64,5 +64,5 @@ struct option { int getopt_long(int, char * const *, const char *, const struct option *, int *); - + #endif /* !_GETOPT_H_ */ diff --git a/deps/libmagic/src/pread.c b/deps/libmagic/src/pread.c index 0de518f..3ab52d1 100644 --- a/deps/libmagic/src/pread.c +++ b/deps/libmagic/src/pread.c @@ -1,12 +1,9 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: pread.c,v 1.3 2014/09/15 19:11:25 christos Exp $") +FILE_RCSID("@(#)$File: pread.c,v 1.2 2013/04/02 16:23:07 christos Exp $") #endif /* lint */ #include -// XXX: change by mscdex -#if HAVE_UNISTD_H #include -#endif ssize_t pread(int fd, void *buf, size_t len, off_t off) { diff --git a/deps/libmagic/src/print.c b/deps/libmagic/src/print.c index 0b91863..5045db1 100644 --- a/deps/libmagic/src/print.c +++ b/deps/libmagic/src/print.c @@ -2,7 +2,7 @@ * Copyright (c) Ian F. Darwin 1986-1995. * Software written by Ian F. Darwin and others; * maintained 1995-present by Christos Zoulas and others. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -12,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: print.c,v 1.82 2017/02/10 18:14:01 christos Exp $") +FILE_RCSID("@(#)$File: print.c,v 1.87 2020/03/08 21:30:06 christos Exp $") #endif /* lint */ #include @@ -43,8 +43,6 @@ FILE_RCSID("@(#)$File: print.c,v 1.82 2017/02/10 18:14:01 christos Exp $") #endif #include -#define SZOF(a) (sizeof(a) / sizeof(a[0])) - #include "cdf.h" #ifndef COMPILE_ONLY @@ -52,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); @@ -65,9 +63,9 @@ file_mdump(struct magic *m) if (m->in_op & FILE_OPINVERSE) (void) fputc('~', stderr); (void) fprintf(stderr, "%c%u),", - ((size_t)(m->in_op & FILE_OPS_MASK) < - SZOF(optyp)) ? optyp[m->in_op & FILE_OPS_MASK] : '?', - m->in_offset); + (CAST(size_t, m->in_op & FILE_OPS_MASK) < + __arraycount(optyp)) ? + optyp[m->in_op & FILE_OPS_MASK] : '?', m->in_offset); } (void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "", /* Note: type is unsigned */ @@ -78,16 +76,16 @@ file_mdump(struct magic *m) if (IS_STRING(m->type)) { if (m->str_flags) { (void) fputc('/', stderr); - if (m->str_flags & STRING_COMPACT_WHITESPACE) + if (m->str_flags & STRING_COMPACT_WHITESPACE) (void) fputc(CHAR_COMPACT_WHITESPACE, stderr); - if (m->str_flags & STRING_COMPACT_OPTIONAL_WHITESPACE) + if (m->str_flags & STRING_COMPACT_OPTIONAL_WHITESPACE) (void) fputc(CHAR_COMPACT_OPTIONAL_WHITESPACE, stderr); - if (m->str_flags & STRING_IGNORE_LOWERCASE) + if (m->str_flags & STRING_IGNORE_LOWERCASE) (void) fputc(CHAR_IGNORE_LOWERCASE, stderr); - if (m->str_flags & STRING_IGNORE_UPPERCASE) + if (m->str_flags & STRING_IGNORE_UPPERCASE) (void) fputc(CHAR_IGNORE_UPPERCASE, stderr); - if (m->str_flags & REGEX_OFFSET_START) + if (m->str_flags & REGEX_OFFSET_START) (void) fputc(CHAR_REGEX_OFFSET_START, stderr); if (m->str_flags & STRING_TEXTTEST) (void) fputc(CHAR_TEXTTEST, stderr); @@ -112,14 +110,15 @@ file_mdump(struct magic *m) (void) fprintf(stderr, "/%u", m->str_range); } else { - if ((size_t)(m->mask_op & FILE_OPS_MASK) < SZOF(optyp)) + if (CAST(size_t, m->mask_op & FILE_OPS_MASK) < + __arraycount(optyp)) (void) fputc(optyp[m->mask_op & FILE_OPS_MASK], stderr); else (void) fputc('?', stderr); - + if (m->num_mask) { (void) fprintf(stderr, "%.8llx", - (unsigned long long)m->num_mask); + CAST(unsigned long long, m->num_mask)); } } (void) fprintf(stderr, ",%c", m->reln); @@ -141,7 +140,7 @@ file_mdump(struct magic *m) case FILE_LEQUAD: case FILE_QUAD: (void) fprintf(stderr, "%" INT64_T_FORMAT "d", - (unsigned long long)m->value.q); + CAST(long long, m->value.q)); break; case FILE_PSTRING: case FILE_STRING: @@ -149,39 +148,43 @@ file_mdump(struct magic *m) case FILE_BESTRING16: case FILE_LESTRING16: case FILE_SEARCH: - file_showstr(stderr, m->value.s, (size_t)m->vallen); + file_showstr(stderr, m->value.s, + CAST(size_t, m->vallen)); break; case FILE_DATE: case FILE_LEDATE: 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 +204,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; @@ -217,11 +226,11 @@ file_magwarn(struct magic_set *ms, const char *f, ...) va_list va; /* cuz we use stdout for most, stderr here */ - (void) fflush(stdout); + (void) fflush(stdout); if (ms->file) (void) fprintf(stderr, "%s, %lu: ", ms->file, - (unsigned long)ms->line); + CAST(unsigned long, ms->line)); (void) fprintf(stderr, "Warning: "); va_start(va, f); (void) vfprintf(stderr, f, va); @@ -230,7 +239,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; @@ -243,7 +252,7 @@ file_fmttime(uint64_t v, int flags, char *buf) } else { // XXX: perhaps detect and print something if overflow // on 32 bit time_t? - t = (time_t)v; + t = CAST(time_t, v); } if (flags & FILE_T_LOCAL) { @@ -260,5 +269,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; } diff --git a/deps/libmagic/src/readcdf.c b/deps/libmagic/src/readcdf.c index 3d251d4..7622c7b 100644 --- a/deps/libmagic/src/readcdf.c +++ b/deps/libmagic/src/readcdf.c @@ -26,15 +26,12 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: readcdf.c,v 1.65 2017/04/08 20:58:03 christos Exp $") +FILE_RCSID("@(#)$File: readcdf.c,v 1.74 2019/09/11 15:46:30 christos Exp $") #endif #include #include -// XXX: change by mscdex -#ifdef HAVE_UNISTD_H -# include -#endif +#include #include #include #include @@ -42,10 +39,6 @@ FILE_RCSID("@(#)$File: readcdf.c,v 1.65 2017/04/08 20:58:03 christos Exp $") #include "cdf.h" #include "magic.h" -#ifndef __arraycount -#define __arraycount(a) (sizeof(a) / sizeof(a[0])) -#endif - #define NOTMIME(ms) (((ms)->flags & MAGIC_MIME) == 0) static const struct nv { @@ -127,7 +120,11 @@ cdf_app_to_mime(const char *vbuf, const struct nv *nv) old_lc_ctype = uselocale(c_lc_ctype); assert(old_lc_ctype != NULL); #else - char *old_lc_ctype = setlocale(LC_CTYPE, "C"); + char *old_lc_ctype = setlocale(LC_CTYPE, NULL); + assert(old_lc_ctype != NULL); + old_lc_ctype = strdup(old_lc_ctype); + assert(old_lc_ctype != NULL); + (void)setlocale(LC_CTYPE, "C"); #endif for (i = 0; nv[i].pattern != NULL; i++) if (strcasestr(vbuf, nv[i].pattern) != NULL) { @@ -141,7 +138,8 @@ cdf_app_to_mime(const char *vbuf, const struct nv *nv) (void)uselocale(old_lc_ctype); freelocale(c_lc_ctype); #else - setlocale(LC_CTYPE, old_lc_ctype); + (void)setlocale(LC_CTYPE, old_lc_ctype); + free(old_lc_ctype); #endif return rv; } @@ -150,118 +148,118 @@ private int cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, size_t count, const cdf_directory_t *root_storage) { - size_t i; - cdf_timestamp_t tp; - struct timespec ts; - char buf[64]; - const char *str = NULL; - const char *s, *e; - int len; - - if (!NOTMIME(ms) && root_storage) + size_t i; + cdf_timestamp_t tp; + struct timespec ts; + char buf[64]; + const char *str = NULL; + const char *s, *e; + int len; + + if (!NOTMIME(ms) && root_storage) str = cdf_clsid_to_mime(root_storage->d_storage_uuid, clsid2mime); - for (i = 0; i < count; i++) { - cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); - switch (info[i].pi_type) { - case CDF_NULL: - break; - case CDF_SIGNED16: - if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf, - info[i].pi_s16) == -1) - return -1; - break; - case CDF_SIGNED32: - if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf, - info[i].pi_s32) == -1) - return -1; - break; - case CDF_UNSIGNED32: - if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf, - info[i].pi_u32) == -1) - return -1; - break; - case CDF_FLOAT: - if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf, - info[i].pi_f) == -1) - return -1; - break; - case CDF_DOUBLE: - if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf, - info[i].pi_d) == -1) - return -1; - break; - case CDF_LENGTH32_STRING: - case CDF_LENGTH32_WSTRING: - len = info[i].pi_str.s_len; - if (len > 1) { - char vbuf[1024]; - size_t j, k = 1; - - if (info[i].pi_type == CDF_LENGTH32_WSTRING) - k++; - s = info[i].pi_str.s_buf; + for (i = 0; i < count; i++) { + cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); + switch (info[i].pi_type) { + case CDF_NULL: + break; + case CDF_SIGNED16: + if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf, + info[i].pi_s16) == -1) + return -1; + break; + case CDF_SIGNED32: + if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf, + info[i].pi_s32) == -1) + return -1; + break; + case CDF_UNSIGNED32: + if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf, + info[i].pi_u32) == -1) + return -1; + break; + case CDF_FLOAT: + if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf, + info[i].pi_f) == -1) + return -1; + break; + case CDF_DOUBLE: + if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf, + info[i].pi_d) == -1) + return -1; + break; + case CDF_LENGTH32_STRING: + case CDF_LENGTH32_WSTRING: + len = info[i].pi_str.s_len; + if (len > 1) { + char vbuf[1024]; + size_t j, k = 1; + + if (info[i].pi_type == CDF_LENGTH32_WSTRING) + k++; + s = info[i].pi_str.s_buf; e = info[i].pi_str.s_buf + len; - for (j = 0; s < e && j < sizeof(vbuf) + for (j = 0; s < e && j < sizeof(vbuf) && len--; s += k) { - if (*s == '\0') - break; - if (isprint((unsigned char)*s)) - vbuf[j++] = *s; - } - if (j == sizeof(vbuf)) - --j; - vbuf[j] = '\0'; - if (NOTMIME(ms)) { - if (vbuf[0]) { - if (file_printf(ms, ", %s: %s", - buf, vbuf) == -1) - return -1; - } - } else if (str == NULL && info[i].pi_id == + if (*s == '\0') + break; + if (isprint(CAST(unsigned char, *s))) + vbuf[j++] = *s; + } + if (j == sizeof(vbuf)) + --j; + vbuf[j] = '\0'; + if (NOTMIME(ms)) { + if (vbuf[0]) { + if (file_printf(ms, ", %s: %s", + buf, vbuf) == -1) + return -1; + } + } else if (str == NULL && info[i].pi_id == CDF_PROPERTY_NAME_OF_APPLICATION) { str = cdf_app_to_mime(vbuf, app2mime); } } - break; - case CDF_FILETIME: - tp = info[i].pi_tp; - if (tp != 0) { + break; + case CDF_FILETIME: + tp = info[i].pi_tp; + if (tp != 0) { char tbuf[64]; - if (tp < 1000000000000000LL) { - cdf_print_elapsed_time(tbuf, - sizeof(tbuf), tp); - if (NOTMIME(ms) && file_printf(ms, - ", %s: %s", buf, tbuf) == -1) - return -1; - } else { - char *c, *ec; - cdf_timestamp_to_timespec(&ts, tp); - c = cdf_ctime(&ts.tv_sec, tbuf); - if (c != NULL && + if (tp < 1000000000000000LL) { + cdf_print_elapsed_time(tbuf, + sizeof(tbuf), tp); + if (NOTMIME(ms) && file_printf(ms, + ", %s: %s", buf, tbuf) == -1) + return -1; + } else { + char *c, *ec; + cdf_timestamp_to_timespec(&ts, tp); + c = cdf_ctime(&ts.tv_sec, tbuf); + if (c != NULL && (ec = strchr(c, '\n')) != NULL) *ec = '\0'; - if (NOTMIME(ms) && file_printf(ms, - ", %s: %s", buf, c) == -1) - return -1; - } - } - break; - case CDF_CLIPBOARD: - break; - default: - return -1; - } - } - if (!NOTMIME(ms)) { + if (NOTMIME(ms) && file_printf(ms, + ", %s: %s", buf, c) == -1) + return -1; + } + } + break; + case CDF_CLIPBOARD: + break; + default: + return -1; + } + } + if (ms->flags & MAGIC_MIME_TYPE) { if (str == NULL) return 0; - if (file_printf(ms, "application/%s", str) == -1) - return -1; - } - return 1; + if (file_printf(ms, "application/%s", str) == -1) + return -1; + } + return 1; } private int @@ -273,7 +271,7 @@ cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h, char buf[256]; cdf_catalog_entry_t *ce; - if (NOTMIME(ms)) { + if (NOTMIME(ms)) { if (file_printf(ms, "Microsoft Thumbs.db [") == -1) return -1; if (cdf_unpack_catalog(h, sst, &cat) == -1) @@ -288,7 +286,7 @@ cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h, return -1; } free(cat); - } else { + } else if (ms->flags & MAGIC_MIME_TYPE) { if (file_printf(ms, "application/CDFV2") == -1) return -1; } @@ -299,44 +297,44 @@ private int cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, const cdf_stream_t *sst, const cdf_directory_t *root_storage) { - cdf_summary_info_header_t si; - cdf_property_info_t *info; - size_t count; - int m; + cdf_summary_info_header_t si; + cdf_property_info_t *info; + size_t count; + int m; - if (cdf_unpack_summary_info(sst, h, &si, &info, &count) == -1) - return -1; + if (cdf_unpack_summary_info(sst, h, &si, &info, &count) == -1) + return -1; - if (NOTMIME(ms)) { + if (NOTMIME(ms)) { const char *str; - if (file_printf(ms, "Composite Document File V2 Document") + if (file_printf(ms, "Composite Document File V2 Document") == -1) - return -1; - - if (file_printf(ms, ", %s Endian", - si.si_byte_order == 0xfffe ? "Little" : "Big") == -1) - return -2; - switch (si.si_os) { - case 2: - if (file_printf(ms, ", Os: Windows, Version %d.%d", - si.si_os_version & 0xff, - (uint32_t)si.si_os_version >> 8) == -1) - return -2; - break; - case 1: - if (file_printf(ms, ", Os: MacOS, Version %d.%d", - (uint32_t)si.si_os_version >> 8, - si.si_os_version & 0xff) == -1) - return -2; - break; - default: - if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os, - si.si_os_version & 0xff, - (uint32_t)si.si_os_version >> 8) == -1) - return -2; - break; - } + return -1; + + if (file_printf(ms, ", %s Endian", + si.si_byte_order == 0xfffe ? "Little" : "Big") == -1) + return -2; + switch (si.si_os) { + case 2: + if (file_printf(ms, ", Os: Windows, Version %d.%d", + si.si_os_version & 0xff, + CAST(uint32_t, si.si_os_version) >> 8) == -1) + return -2; + break; + case 1: + if (file_printf(ms, ", Os: MacOS, Version %d.%d", + CAST(uint32_t, si.si_os_version) >> 8, + si.si_os_version & 0xff) == -1) + return -2; + break; + default: + if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os, + si.si_os_version & 0xff, + CAST(uint32_t, si.si_os_version) >> 8) == -1) + return -2; + break; + } if (root_storage) { str = cdf_clsid_to_mime(root_storage->d_storage_uuid, clsid2desc); @@ -347,20 +345,20 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, } } - m = cdf_file_property_info(ms, info, count, root_storage); - free(info); + m = cdf_file_property_info(ms, info, count, root_storage); + free(info); - return m == -1 ? -2 : m; + return m == -1 ? -2 : m; } #ifdef notdef private char * format_clsid(char *buf, size_t len, const uint64_t uuid[2]) { - snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4" + snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.12" PRIx64, (uuid[0] >> 32) & (uint64_t)0x000000000ffffffffULL, (uuid[0] >> 16) & (uint64_t)0x0000000000000ffffULL, - (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffULL, + (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffULL, (uuid[1] >> 48) & (uint64_t)0x0000000000000ffffULL, (uuid[1] >> 0) & (uint64_t)0x0000fffffffffffffULL); return buf; @@ -398,10 +396,10 @@ cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info, size_t j, k; #ifdef CDF_DEBUG - cdf_dump_summary_info(h, scn); + cdf_dump_summary_info(h, scn); #endif - if ((i = cdf_file_summary_info(ms, h, scn, root_storage)) < 0) { - *expn = "Can't expand summary_info"; + if ((i = cdf_file_summary_info(ms, h, scn, root_storage)) < 0) { + *expn = "Can't expand summary_info"; return i; } if (i == 1) @@ -409,7 +407,7 @@ cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info, for (j = 0; str == NULL && j < dir->dir_len; j++) { d = &dir->dir_tab[j]; for (k = 0; k < sizeof(name); k++) - name[k] = (char)cdf_tole2(d->d_name[k]); + name[k] = CAST(char, cdf_tole2(d->d_name[k])); str = cdf_app_to_mime(name, NOTMIME(ms) ? name2desc : name2mime); } @@ -419,7 +417,7 @@ cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info, return -1; i = 1; } - } else { + } else if (ms->flags & MAGIC_MIME_TYPE) { if (str == NULL) str = "vnd.ms-office"; if (file_printf(ms, "application/%s", str) == -1) @@ -439,7 +437,7 @@ private struct sinfo { const char *sections[5]; const int types[5]; } sectioninfo[] = { - { "Encrypted", "encrypted", + { "Encrypted", "encrypted", { "EncryptedPackage", "EncryptedSummary", NULL, NULL, NULL, @@ -451,7 +449,7 @@ private struct sinfo { }, }, - { "QuickBooks", "quickbooks", + { "QuickBooks", "quickbooks", { #if 0 "TaxForms", "PDFTaxForms", "modulesInBackup", @@ -530,7 +528,7 @@ cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir) if (NOTMIME(ms)) { if (file_printf(ms, "CDFV2 %s", si->name) == -1) return -1; - } else { + } else if (ms->flags & MAGIC_MIME_TYPE) { if (file_printf(ms, "application/%s", si->mime) == -1) return -1; } @@ -540,58 +538,60 @@ cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir) } protected int -file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, - size_t nbytes) +file_trycdf(struct magic_set *ms, const struct buffer *b) { - cdf_info_t info; - cdf_header_t h; - cdf_sat_t sat, ssat; - cdf_stream_t sst, scn; - cdf_dir_t dir; - int i; - const char *expn = ""; - const cdf_directory_t *root_storage; - - scn.sst_tab = NULL; - info.i_fd = fd; - info.i_buf = buf; - info.i_len = nbytes; - if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) - return 0; - if (cdf_read_header(&info, &h) == -1) - return 0; + int fd = b->fd; + const unsigned char *buf = CAST(const unsigned char *, b->fbuf); + size_t nbytes = b->flen; + cdf_info_t info; + cdf_header_t h; + cdf_sat_t sat, ssat; + cdf_stream_t sst, scn; + cdf_dir_t dir; + int i; + const char *expn = ""; + const cdf_directory_t *root_storage; + + scn.sst_tab = NULL; + info.i_fd = fd; + info.i_buf = buf; + info.i_len = nbytes; + if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) + return 0; + if (cdf_read_header(&info, &h) == -1) + return 0; #ifdef CDF_DEBUG - cdf_dump_header(&h); + cdf_dump_header(&h); #endif - if ((i = cdf_read_sat(&info, &h, &sat)) == -1) { - expn = "Can't read SAT"; - goto out0; - } + if ((i = cdf_read_sat(&info, &h, &sat)) == -1) { + expn = "Can't read SAT"; + goto out0; + } #ifdef CDF_DEBUG - cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h)); + cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h)); #endif - if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) { - expn = "Can't read SSAT"; - goto out1; - } + if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) { + expn = "Can't read SSAT"; + goto out1; + } #ifdef CDF_DEBUG - cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h)); + cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h)); #endif - if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) { - expn = "Can't read directory"; - goto out2; - } + if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) { + expn = "Can't read directory"; + goto out2; + } - if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst, + if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst, &root_storage)) == -1) { - expn = "Cannot read short stream"; - goto out3; - } + expn = "Cannot read short stream"; + goto out3; + } #ifdef CDF_DEBUG - cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir); + cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir); #endif #ifdef notdef if (root_storage) { @@ -615,7 +615,7 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, if (file_printf(ms, "Hangul (Korean) Word Processor File 5.x") == -1) return -1; - } else { + } else if (ms->flags & MAGIC_MIME_TYPE) { if (file_printf(ms, "application/x-hwp") == -1) return -1; } @@ -626,10 +626,10 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, } } - if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir, - &scn)) == -1) { - if (errno != ESRCH) { - expn = "Cannot read summary info"; + if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir, + &scn)) == -1) { + if (errno != ESRCH) { + expn = "Cannot read summary info"; } } else { i = cdf_check_summary_info(ms, &info, &h, @@ -656,25 +656,26 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, cdf_zero_stream(&scn); cdf_zero_stream(&sst); out3: - free(dir.dir_tab); + free(dir.dir_tab); out2: - free(ssat.sat_tab); + free(ssat.sat_tab); out1: - free(sat.sat_tab); + free(sat.sat_tab); out0: - if (i == -1) { - if (NOTMIME(ms)) { + /* If we handled it already, return */ + if (i != -1) + return i; + /* Provide a default handler */ + if (NOTMIME(ms)) { if (file_printf(ms, "Composite Document File V2 Document") == -1) - return -1; - if (*expn) - if (file_printf(ms, ", %s", expn) == -1) return -1; - } else { + if (*expn) + if (file_printf(ms, ", %s", expn) == -1) + return -1; + } else if (ms->flags & MAGIC_MIME_TYPE) { if (file_printf(ms, "application/CDFV2") == -1) - return -1; - } - i = 1; + return -1; } - return i; + return 1; } diff --git a/deps/libmagic/src/readelf.c b/deps/libmagic/src/readelf.c index 5f425c9..9d1d1ad 100644 --- a/deps/libmagic/src/readelf.c +++ b/deps/libmagic/src/readelf.c @@ -1,7 +1,7 @@ /* * Copyright (c) Christos Zoulas 2003. * All Rights Reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -11,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: readelf.c,v 1.138 2017/08/27 07:55:02 christos Exp $") +FILE_RCSID("@(#)$File: readelf.c,v 1.170 2020/02/20 15:50:20 christos Exp $") #endif #ifdef BUILTIN_ELF @@ -62,15 +62,14 @@ private uint64_t getu64(int, uint64_t); #define MAX_PHNUM 128 #define MAX_SHNUM 32768 -#define SIZE_UNKNOWN ((off_t)-1) +#define SIZE_UNKNOWN CAST(off_t, -1) private int toomany(struct magic_set *ms, const char *name, uint16_t num) { - if (file_printf(ms, ", too many %s (%u)", name, num - ) == -1) + if (file_printf(ms, ", too many %s (%u)", name, num) == -1) return -1; - return 0; + return 1; } private uint16_t @@ -86,7 +85,7 @@ getu16(int swap, uint16_t value) retval.c[0] = tmpval.c[1]; retval.c[1] = tmpval.c[0]; - + return retval.ui; } else return value; @@ -107,7 +106,7 @@ getu32(int swap, uint32_t value) retval.c[1] = tmpval.c[2]; retval.c[2] = tmpval.c[1]; retval.c[3] = tmpval.c[0]; - + return retval.ui; } else return value; @@ -132,7 +131,7 @@ getu64(int swap, uint64_t value) retval.c[5] = tmpval.c[2]; retval.c[6] = tmpval.c[1]; retval.c[7] = tmpval.c[0]; - + return retval.ui; } else return value; @@ -143,54 +142,55 @@ getu64(int swap, uint64_t value) #define elf_getu64(swap, value) getu64(swap, value) #define xsh_addr (clazz == ELFCLASS32 \ - ? (void *)&sh32 \ - : (void *)&sh64) + ? CAST(void *, &sh32) \ + : CAST(void *, &sh64)) #define xsh_sizeof (clazz == ELFCLASS32 \ ? sizeof(sh32) \ : sizeof(sh64)) -#define xsh_size (size_t)(clazz == ELFCLASS32 \ +#define xsh_size CAST(size_t, (clazz == ELFCLASS32 \ ? elf_getu32(swap, sh32.sh_size) \ - : elf_getu64(swap, sh64.sh_size)) -#define xsh_offset (off_t)(clazz == ELFCLASS32 \ + : elf_getu64(swap, sh64.sh_size))) +#define xsh_offset CAST(off_t, (clazz == ELFCLASS32 \ ? elf_getu32(swap, sh32.sh_offset) \ - : elf_getu64(swap, sh64.sh_offset)) + : elf_getu64(swap, sh64.sh_offset))) #define xsh_type (clazz == ELFCLASS32 \ ? elf_getu32(swap, sh32.sh_type) \ : elf_getu32(swap, sh64.sh_type)) #define xsh_name (clazz == ELFCLASS32 \ ? elf_getu32(swap, sh32.sh_name) \ : elf_getu32(swap, sh64.sh_name)) + #define xph_addr (clazz == ELFCLASS32 \ - ? (void *) &ph32 \ - : (void *) &ph64) + ? CAST(void *, &ph32) \ + : CAST(void *, &ph64)) #define xph_sizeof (clazz == ELFCLASS32 \ ? sizeof(ph32) \ : sizeof(ph64)) #define xph_type (clazz == ELFCLASS32 \ ? elf_getu32(swap, ph32.p_type) \ : elf_getu32(swap, ph64.p_type)) -#define xph_offset (off_t)(clazz == ELFCLASS32 \ +#define xph_offset CAST(off_t, (clazz == ELFCLASS32 \ ? elf_getu32(swap, ph32.p_offset) \ - : elf_getu64(swap, ph64.p_offset)) -#define xph_align (size_t)((clazz == ELFCLASS32 \ - ? (off_t) (ph32.p_align ? \ - elf_getu32(swap, ph32.p_align) : 4) \ - : (off_t) (ph64.p_align ? \ - elf_getu64(swap, ph64.p_align) : 4))) -#define xph_vaddr (size_t)((clazz == ELFCLASS32 \ - ? (off_t) (ph32.p_vaddr ? \ - elf_getu32(swap, ph32.p_vaddr) : 4) \ - : (off_t) (ph64.p_vaddr ? \ - elf_getu64(swap, ph64.p_vaddr) : 4))) -#define xph_filesz (size_t)((clazz == ELFCLASS32 \ + : elf_getu64(swap, ph64.p_offset))) +#define xph_align CAST(size_t, (clazz == ELFCLASS32 \ + ? CAST(off_t, (ph32.p_align ? \ + elf_getu32(swap, ph32.p_align) : 4))\ + : CAST(off_t, (ph64.p_align ? \ + elf_getu64(swap, ph64.p_align) : 4)))) +#define xph_vaddr CAST(size_t, (clazz == ELFCLASS32 \ + ? CAST(off_t, (ph32.p_vaddr ? \ + elf_getu32(swap, ph32.p_vaddr) : 4))\ + : CAST(off_t, (ph64.p_vaddr ? \ + elf_getu64(swap, ph64.p_vaddr) : 4)))) +#define xph_filesz CAST(size_t, (clazz == ELFCLASS32 \ ? elf_getu32(swap, ph32.p_filesz) \ : elf_getu64(swap, ph64.p_filesz))) -#define xnh_addr (clazz == ELFCLASS32 \ - ? (void *)&nh32 \ - : (void *)&nh64) -#define xph_memsz (size_t)((clazz == ELFCLASS32 \ +#define xph_memsz CAST(size_t, ((clazz == ELFCLASS32 \ ? elf_getu32(swap, ph32.p_memsz) \ - : elf_getu64(swap, ph64.p_memsz))) + : elf_getu64(swap, ph64.p_memsz)))) +#define xnh_addr (clazz == ELFCLASS32 \ + ? CAST(void *, &nh32) \ + : CAST(void *, &nh64)) #define xnh_sizeof (clazz == ELFCLASS32 \ ? sizeof(nh32) \ : sizeof(nh64)) @@ -203,24 +203,36 @@ getu64(int swap, uint64_t value) #define xnh_descsz (clazz == ELFCLASS32 \ ? elf_getu32(swap, nh32.n_descsz) \ : elf_getu32(swap, nh64.n_descsz)) -#define prpsoffsets(i) (clazz == ELFCLASS32 \ - ? prpsoffsets32[i] \ - : prpsoffsets64[i]) + +#define xdh_addr (clazz == ELFCLASS32 \ + ? CAST(void *, &dh32) \ + : CAST(void *, &dh64)) +#define xdh_sizeof (clazz == ELFCLASS32 \ + ? sizeof(dh32) \ + : sizeof(dh64)) +#define xdh_tag (clazz == ELFCLASS32 \ + ? elf_getu32(swap, dh32.d_tag) \ + : elf_getu64(swap, dh64.d_tag)) +#define xdh_val (clazz == ELFCLASS32 \ + ? elf_getu32(swap, dh32.d_un.d_val) \ + : elf_getu64(swap, dh64.d_un.d_val)) + #define xcap_addr (clazz == ELFCLASS32 \ - ? (void *)&cap32 \ - : (void *)&cap64) + ? CAST(void *, &cap32) \ + : CAST(void *, &cap64)) #define xcap_sizeof (clazz == ELFCLASS32 \ - ? sizeof cap32 \ - : sizeof cap64) + ? sizeof(cap32) \ + : sizeof(cap64)) #define xcap_tag (clazz == ELFCLASS32 \ ? elf_getu32(swap, cap32.c_tag) \ : elf_getu64(swap, cap64.c_tag)) #define xcap_val (clazz == ELFCLASS32 \ ? elf_getu32(swap, cap32.c_un.c_val) \ : elf_getu64(swap, cap64.c_un.c_val)) + #define xauxv_addr (clazz == ELFCLASS32 \ - ? (void *)&auxv32 \ - : (void *)&auxv64) + ? CAST(void *, &auxv32) \ + : CAST(void *, &auxv64)) #define xauxv_sizeof (clazz == ELFCLASS32 \ ? sizeof(auxv32) \ : sizeof(auxv64)) @@ -231,6 +243,10 @@ getu64(int swap, uint64_t value) ? elf_getu32(swap, auxv32.a_v) \ : elf_getu64(swap, auxv64.a_v)) +#define prpsoffsets(i) (clazz == ELFCLASS32 \ + ? prpsoffsets32[i] \ + : prpsoffsets64[i]) + #ifdef ELFCORE /* * Try larger offsets first to avoid false matches @@ -246,7 +262,10 @@ static const size_t prpsoffsets32[] = { 84, /* SunOS 5.x (short name) */ 44, /* Linux (command line) */ - 28, /* Linux 2.0.36 (short name) */ + 28, /* Linux (short name) */ + + 48, /* Linux PowerPC (command line) */ + 32, /* Linux PowerPC (short name) */ 8, /* FreeBSD */ }; @@ -266,8 +285,8 @@ static const size_t prpsoffsets64[] = { 16, /* FreeBSD, 64-bit */ }; -#define NOFFSETS32 (sizeof prpsoffsets32 / sizeof prpsoffsets32[0]) -#define NOFFSETS64 (sizeof prpsoffsets64 / sizeof prpsoffsets64[0]) +#define NOFFSETS32 __arraycount(prpsoffsets32) +#define NOFFSETS64 __arraycount(prpsoffsets64) #define NOFFSETS (clazz == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64) @@ -310,18 +329,19 @@ private const char os_style_names[][8] = { "NetBSD", }; -#define FLAGS_CORE_STYLE 0x003 +#define FLAGS_CORE_STYLE 0x0003 -#define FLAGS_DID_CORE 0x004 -#define FLAGS_DID_OS_NOTE 0x008 -#define FLAGS_DID_BUILD_ID 0x010 -#define FLAGS_DID_CORE_STYLE 0x020 -#define FLAGS_DID_NETBSD_PAX 0x040 -#define FLAGS_DID_NETBSD_MARCH 0x080 -#define FLAGS_DID_NETBSD_CMODEL 0x100 -#define FLAGS_DID_NETBSD_UNKNOWN 0x200 -#define FLAGS_IS_CORE 0x400 -#define FLAGS_DID_AUXV 0x800 +#define FLAGS_DID_CORE 0x0004 +#define FLAGS_DID_OS_NOTE 0x0008 +#define FLAGS_DID_BUILD_ID 0x0010 +#define FLAGS_DID_CORE_STYLE 0x0020 +#define FLAGS_DID_NETBSD_PAX 0x0040 +#define FLAGS_DID_NETBSD_MARCH 0x0080 +#define FLAGS_DID_NETBSD_CMODEL 0x0100 +#define FLAGS_DID_NETBSD_EMULATION 0x0200 +#define FLAGS_DID_NETBSD_UNKNOWN 0x0400 +#define FLAGS_IS_CORE 0x0800 +#define FLAGS_DID_AUXV 0x1000 private int dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, @@ -335,6 +355,11 @@ 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 (num == 0) { + if (file_printf(ms, ", no program header") == -1) + return -1; + return 0; + } if (size != xph_sizeof) { if (file_printf(ms, ", corrupted program header size") == -1) return -1; @@ -345,7 +370,8 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, * Loop through all the program headers. */ for ( ; num; num--) { - if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) { + if (pread(fd, xph_addr, xph_sizeof, off) < + CAST(ssize_t, xph_sizeof)) { file_badread(ms); return -1; } @@ -370,9 +396,9 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, } offset = 0; for (;;) { - if (offset >= (size_t)bufsize) + if (offset >= CAST(size_t, bufsize)) break; - offset = donote(ms, nbuf, offset, (size_t)bufsize, + offset = donote(ms, nbuf, offset, CAST(size_t, bufsize), clazz, swap, 4, flags, notecount, fd, ph_off, ph_num, fsize); if (offset == 0) @@ -384,15 +410,15 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, } #endif -static void +static int do_note_netbsd_version(struct magic_set *ms, int swap, void *v) { uint32_t desc; - (void)memcpy(&desc, v, sizeof(desc)); + memcpy(&desc, v, sizeof(desc)); desc = elf_getu32(swap, desc); if (file_printf(ms, ", for NetBSD") == -1) - return; + return -1; /* * The version number used to be stuck as 199905, and was thus * basically content-free. Newer versions of NetBSD have fixed @@ -412,96 +438,98 @@ do_note_netbsd_version(struct magic_set *ms, int swap, void *v) uint32_t ver_maj = desc / 100000000; if (file_printf(ms, " %u.%u", ver_maj, ver_min) == -1) - return; + return -1; if (ver_rel == 0 && ver_patch != 0) { if (file_printf(ms, ".%u", ver_patch) == -1) - return; + return -1; } else if (ver_rel != 0) { while (ver_rel > 26) { if (file_printf(ms, "Z") == -1) - return; + return -1; ver_rel -= 26; } if (file_printf(ms, "%c", 'A' + ver_rel - 1) == -1) - return; + return -1; } } + return 0; } -static void +static int do_note_freebsd_version(struct magic_set *ms, int swap, void *v) { uint32_t desc; - (void)memcpy(&desc, v, sizeof(desc)); + memcpy(&desc, v, sizeof(desc)); desc = elf_getu32(swap, desc); if (file_printf(ms, ", for FreeBSD") == -1) - return; + return -1; /* * Contents is __FreeBSD_version, whose relation to OS * versions is defined by a huge table in the Porter's * Handbook. This is the general scheme: - * + * * Releases: * Mmp000 (before 4.10) * Mmi0p0 (before 5.0) * Mmm0p0 - * + * * Development branches: * Mmpxxx (before 4.6) * Mmp1xx (before 4.10) * Mmi1xx (before 5.0) * M000xx (pre-M.0) * Mmm1xx - * + * * M = major version * m = minor version * i = minor version increment (491000 -> 4.10) * p = patchlevel * x = revision - * + * * The first release of FreeBSD to use ELF by default * was version 3.0. */ if (desc == 460002) { if (file_printf(ms, " 4.6.2") == -1) - return; + return -1; } else if (desc < 460100) { if (file_printf(ms, " %d.%d", desc / 100000, desc / 10000 % 10) == -1) - return; + return -1; if (desc / 1000 % 10 > 0) if (file_printf(ms, ".%d", desc / 1000 % 10) == -1) - return; + return -1; if ((desc % 1000 > 0) || (desc % 100000 == 0)) if (file_printf(ms, " (%d)", desc) == -1) - return; + return -1; } else if (desc < 500000) { if (file_printf(ms, " %d.%d", desc / 100000, desc / 10000 % 10 + desc / 1000 % 10) == -1) - return; + return -1; if (desc / 100 % 10 > 0) { if (file_printf(ms, " (%d)", desc) == -1) - return; + return -1; } else if (desc / 10 % 10 > 0) { if (file_printf(ms, ".%d", desc / 10 % 10) == -1) - return; + return -1; } } else { if (file_printf(ms, " %d.%d", desc / 100000, desc / 1000 % 100) == -1) - return; + return -1; if ((desc / 100 % 10 > 0) || (desc % 100000 / 100 == 0)) { if (file_printf(ms, " (%d)", desc) == -1) - return; + return -1; } else if (desc / 10 % 10 > 0) { if (file_printf(ms, ".%d", desc / 10 % 10) == -1) - return; + return -1; } } + return 0; } private int @@ -510,7 +538,7 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, int swap __attribute__((__unused__)), uint32_t namesz, uint32_t descsz, size_t noff, size_t doff, int *flags) { - if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 && + if (namesz == 4 && strcmp(RCAST(char *, &nbuf[noff]), "GNU") == 0 && type == NT_GNU_BUILD_ID && (descsz >= 4 && descsz <= 20)) { uint8_t desc[20]; const char *btype; @@ -531,11 +559,20 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, break; } if (file_printf(ms, ", BuildID[%s]=", btype) == -1) - return 1; - (void)memcpy(desc, &nbuf[doff], descsz); + return -1; + memcpy(desc, &nbuf[doff], descsz); for (i = 0; i < descsz; i++) if (file_printf(ms, "%02x", desc[i]) == -1) - return 1; + return -1; + return 1; + } + if (namesz == 4 && strcmp(RCAST(char *, &nbuf[noff]), "Go") == 0 && + type == NT_GO_BUILD_ID && descsz < 128) { + 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; } return 0; @@ -546,88 +583,95 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, int swap, uint32_t namesz, uint32_t descsz, size_t noff, size_t doff, int *flags) { - if (namesz == 5 && strcmp((char *)&nbuf[noff], "SuSE") == 0 && - type == NT_GNU_VERSION && descsz == 2) { - *flags |= FLAGS_DID_OS_NOTE; - file_printf(ms, ", for SuSE %d.%d", nbuf[doff], nbuf[doff + 1]); + const char *name = RCAST(const char *, &nbuf[noff]); + + if (namesz == 5 && strcmp(name, "SuSE") == 0 && + type == NT_GNU_VERSION && descsz == 2) { + *flags |= FLAGS_DID_OS_NOTE; + if (file_printf(ms, ", for SuSE %d.%d", nbuf[doff], + nbuf[doff + 1]) == -1) + return -1; return 1; } - if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 && + if (namesz == 4 && strcmp(name, "GNU") == 0 && type == NT_GNU_VERSION && descsz == 16) { uint32_t desc[4]; - (void)memcpy(desc, &nbuf[doff], sizeof(desc)); + memcpy(desc, &nbuf[doff], sizeof(desc)); *flags |= FLAGS_DID_OS_NOTE; if (file_printf(ms, ", for GNU/") == -1) - return 1; + return -1; switch (elf_getu32(swap, desc[0])) { case GNU_OS_LINUX: if (file_printf(ms, "Linux") == -1) - return 1; + return -1; break; case GNU_OS_HURD: if (file_printf(ms, "Hurd") == -1) - return 1; + return -1; break; case GNU_OS_SOLARIS: if (file_printf(ms, "Solaris") == -1) - return 1; + return -1; break; case GNU_OS_KFREEBSD: if (file_printf(ms, "kFreeBSD") == -1) - return 1; + return -1; break; case GNU_OS_KNETBSD: if (file_printf(ms, "kNetBSD") == -1) - return 1; + return -1; break; default: if (file_printf(ms, "") == -1) - return 1; + return -1; } if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]), elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1) - return 1; + return -1; return 1; } - if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) { + if (namesz == 7 && strcmp(name, "NetBSD") == 0) { if (type == NT_NETBSD_VERSION && descsz == 4) { *flags |= FLAGS_DID_OS_NOTE; - do_note_netbsd_version(ms, swap, &nbuf[doff]); + if (do_note_netbsd_version(ms, swap, &nbuf[doff]) == -1) + return -1; return 1; } } - if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) { + if (namesz == 8 && strcmp(name, "FreeBSD") == 0) { if (type == NT_FREEBSD_VERSION && descsz == 4) { *flags |= FLAGS_DID_OS_NOTE; - do_note_freebsd_version(ms, swap, &nbuf[doff]); + if (do_note_freebsd_version(ms, swap, &nbuf[doff]) + == -1) + return -1; return 1; } } - if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 && + if (namesz == 8 && strcmp(name, "OpenBSD") == 0 && type == NT_OPENBSD_VERSION && descsz == 4) { *flags |= FLAGS_DID_OS_NOTE; if (file_printf(ms, ", for OpenBSD") == -1) - return 1; + return -1; /* Content of note is always 0 */ return 1; } - if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 && + if (namesz == 10 && strcmp(name, "DragonFly") == 0 && type == NT_DRAGONFLY_VERSION && descsz == 4) { uint32_t desc; *flags |= FLAGS_DID_OS_NOTE; if (file_printf(ms, ", for DragonFly") == -1) - return 1; - (void)memcpy(&desc, &nbuf[doff], sizeof(desc)); + return -1; + memcpy(&desc, &nbuf[doff], sizeof(desc)); desc = elf_getu32(swap, desc); if (file_printf(ms, " %d.%d.%d", desc / 100000, desc / 10000 % 10, desc % 10000) == -1) - return 1; + return -1; return 1; } return 0; @@ -638,7 +682,9 @@ do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, int swap, uint32_t namesz, uint32_t descsz, size_t noff, size_t doff, int *flags) { - if (namesz == 4 && strcmp((char *)&nbuf[noff], "PaX") == 0 && + const char *name = RCAST(const char *, &nbuf[noff]); + + if (namesz == 4 && strcmp(name, "PaX") == 0 && type == NT_NETBSD_PAX && descsz == 4) { static const char *pax[] = { "+mprotect", @@ -653,18 +699,18 @@ do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, int did = 0; *flags |= FLAGS_DID_NETBSD_PAX; - (void)memcpy(&desc, &nbuf[doff], sizeof(desc)); + memcpy(&desc, &nbuf[doff], sizeof(desc)); desc = elf_getu32(swap, desc); if (desc && file_printf(ms, ", PaX: ") == -1) - return 1; + return -1; for (i = 0; i < __arraycount(pax); i++) { - if (((1 << (int)i) & desc) == 0) + if (((1 << CAST(int, i)) & desc) == 0) continue; if (file_printf(ms, "%s%s", did++ ? "," : "", pax[i]) == -1) - return 1; + return -1; } return 1; } @@ -677,6 +723,9 @@ 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; /* * Sigh. The 2.0.36 kernel in Debian 2.1, at @@ -692,16 +741,16 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, * doesn't include the terminating null in the * name.... */ - if ((namesz == 4 && strncmp((char *)&nbuf[noff], "CORE", 4) == 0) || - (namesz == 5 && strcmp((char *)&nbuf[noff], "CORE") == 0)) { + if ((namesz == 4 && strncmp(name, "CORE", 4) == 0) || + (namesz == 5 && strcmp(name, "CORE") == 0)) { os_style = OS_STYLE_SVR4; - } + } - if ((namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0)) { + if ((namesz == 8 && strcmp(name, "FreeBSD") == 0)) { os_style = OS_STYLE_FREEBSD; } - if ((namesz >= 11 && strncmp((char *)&nbuf[noff], "NetBSD-CORE", 11) + if ((namesz >= 11 && strncmp(name, "NetBSD-CORE", 11) == 0)) { os_style = OS_STYLE_NETBSD; } @@ -709,7 +758,7 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, if (os_style != -1 && (*flags & FLAGS_DID_CORE_STYLE) == 0) { if (file_printf(ms, ", %s-style", os_style_names[os_style]) == -1) - return 1; + return -1; *flags |= FLAGS_DID_CORE_STYLE; *flags |= os_style; } @@ -720,26 +769,48 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, char sbuf[512]; struct NetBSD_elfcore_procinfo pi; memset(&pi, 0, sizeof(pi)); - memcpy(&pi, nbuf + doff, descsz); + memcpy(&pi, nbuf + doff, MIN(descsz, sizeof(pi))); if (file_printf(ms, ", from '%.31s', pid=%u, uid=%u, " "gid=%u, nlwps=%u, lwp=%u (signal %u/code %u)", file_printable(sbuf, sizeof(sbuf), - CAST(char *, pi.cpi_name)), - elf_getu32(swap, pi.cpi_pid), + RCAST(char *, pi.cpi_name), sizeof(pi.cpi_name)), + elf_getu32(swap, CAST(uint32_t, pi.cpi_pid)), elf_getu32(swap, pi.cpi_euid), elf_getu32(swap, pi.cpi_egid), elf_getu32(swap, pi.cpi_nlwps), - elf_getu32(swap, pi.cpi_siglwp), + elf_getu32(swap, CAST(uint32_t, pi.cpi_siglwp)), elf_getu32(swap, pi.cpi_signo), elf_getu32(swap, pi.cpi_sigcode)) == -1) - return 1; + return -1; *flags |= FLAGS_DID_CORE; return 1; } break; + case OS_STYLE_FREEBSD: + if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) { + size_t argoff, pidoff; + + if (clazz == ELFCLASS32) + argoff = 4 + 4 + 17; + else + argoff = 4 + 4 + 8 + 17; + if (file_printf(ms, ", from '%.80s'", nbuf + doff + + argoff) == -1) + return -1; + pidoff = argoff + 81 + 2; + if (doff + pidoff + 4 <= size) { + if (file_printf(ms, ", pid=%u", + elf_getu32(swap, *RCAST(uint32_t *, (nbuf + + doff + pidoff)))) == -1) + return -1; + } + *flags |= FLAGS_DID_CORE; + } + break; + default: if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) { size_t i, j; @@ -822,9 +893,10 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, i = k; } - cname = (unsigned char *) - &nbuf[doff + prpsoffsets(i)]; - for (cp = cname; *cp && isprint(*cp); cp++) + cname = CAST(unsigned char *, + &nbuf[doff + prpsoffsets(i)]); + for (cp = cname; cp < nbuf + size && *cp + && isprint(*cp); cp++) continue; /* * Linux apparently appends a space at the end @@ -832,9 +904,11 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, */ while (cp > cname && isspace(cp[-1])) cp--; - if (file_printf(ms, ", from '%.*s'", - (int)(cp - cname), cname) == -1) - return 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; @@ -860,7 +934,8 @@ get_offset_from_virtaddr(struct magic_set *ms, int swap, int clazz, int fd, * virtual address in which the "virtaddr" belongs to. */ for ( ; num; num--) { - if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) { + if (pread(fd, xph_addr, xph_sizeof, off) < + CAST(ssize_t, xph_sizeof)) { file_badread(ms); return -1; } @@ -890,7 +965,8 @@ get_string_on_virtaddr(struct magic_set *ms, offset = get_offset_from_virtaddr(ms, swap, clazz, fd, ph_off, ph_num, fsize, virtaddr); - if ((buflen = pread(fd, buf, CAST(size_t, buflen), offset)) <= 0) { + if (offset < 0 || + (buflen = pread(fd, buf, CAST(size_t, buflen), offset)) <= 0) { file_badread(ms); return 0; } @@ -899,7 +975,7 @@ get_string_on_virtaddr(struct magic_set *ms, /* We expect only printable characters, so return if buffer contains * non-printable character before the '\0' or just '\0'. */ - for (bptr = buf; *bptr && isprint((unsigned char)*bptr); bptr++) + for (bptr = buf; *bptr && isprint(CAST(unsigned char, *bptr)); bptr++) continue; if (*bptr != '\0') return 0; @@ -908,6 +984,7 @@ get_string_on_virtaddr(struct magic_set *ms, } +/*ARGSUSED*/ private int do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, int swap, uint32_t namesz __attribute__((__unused__)), @@ -951,7 +1028,7 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, nval = 0; for (size_t off = 0; off + elsize <= descsz; off += elsize) { - (void)memcpy(xauxv_addr, &nbuf[doff + off], xauxv_sizeof); + memcpy(xauxv_addr, &nbuf[doff + off], xauxv_sizeof); /* Limit processing to 50 vector entries to prevent DoS */ if (nval++ >= 50) { file_error(ms, 0, "Too many ELF Auxv elements"); @@ -1000,13 +1077,13 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, if (buflen == 0) continue; - + if (file_printf(ms, ", %s: '%s'", tag, buf) == -1) - return 0; + return -1; } else { - if (file_printf(ms, ", %s: %d", tag, (int) xauxv_val) - == -1) - return 0; + if (file_printf(ms, ", %s: %d", tag, + CAST(int, xauxv_val)) == -1) + return -1; } } return 1; @@ -1015,6 +1092,38 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, #endif } +private size_t +dodynamic(struct magic_set *ms, void *vbuf, size_t offset, size_t size, + int clazz, int swap) +{ + Elf32_Dyn dh32; + Elf64_Dyn dh64; + unsigned char *dbuf = CAST(unsigned char *, vbuf); + + if (xdh_sizeof + offset > size) { + /* + * We're out of note headers. + */ + return xdh_sizeof + offset; + } + + memcpy(xdh_addr, &dbuf[offset], xdh_sizeof); + offset += xdh_sizeof; + + switch (xdh_tag) { + case DT_FLAGS_1: + if (xdh_val & DF_1_PIE) + ms->mode |= 0111; + else + ms->mode &= ~0111; + break; + default: + break; + } + return offset; +} + + private size_t donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, int clazz, int swap, size_t align, int *flags, uint16_t *notecount, @@ -1024,6 +1133,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) @@ -1036,8 +1146,11 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, */ return xnh_sizeof + offset; } + /*XXX: GCC */ + memset(&nh32, 0, sizeof(nh32)); + memset(&nh64, 0, sizeof(nh64)); - (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof); + memcpy(xnh_addr, &nbuf[offset], xnh_sizeof); offset += xnh_sizeof; namesz = xnh_namesz; @@ -1051,14 +1164,16 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, } if (namesz & 0x80000000) { - (void)file_printf(ms, ", bad note name size %#lx", - (unsigned long)namesz); + if (file_printf(ms, ", bad note name size %#lx", + CAST(unsigned long, namesz)) == -1) + return -1; return 0; } if (descsz & 0x80000000) { - (void)file_printf(ms, ", bad note description size %#lx", - (unsigned long)descsz); + if (file_printf(ms, ", bad note description size %#lx", + CAST(unsigned long, descsz)) == -1) + return -1; return 0; } @@ -1092,7 +1207,7 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, namesz, descsz, noff, doff, flags)) return offset; } - + if ((*flags & FLAGS_DID_NETBSD_PAX) == 0) { if (do_pax_note(ms, nbuf, xnh_type, swap, namesz, descsz, noff, doff, flags)) @@ -1112,27 +1227,25 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, return offset; } - if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) { + if (namesz == 7 && strcmp(RCAST(char *, &nbuf[noff]), "NetBSD") == 0) { + int descw, flag; + const char *str, *tag; if (descsz > 100) descsz = 100; switch (xnh_type) { case NT_NETBSD_VERSION: return offset; case NT_NETBSD_MARCH: - if (*flags & FLAGS_DID_NETBSD_MARCH) - return offset; - *flags |= FLAGS_DID_NETBSD_MARCH; - if (file_printf(ms, ", compiled for: %.*s", - (int)descsz, (const char *)&nbuf[doff]) == -1) - return offset; + flag = FLAGS_DID_NETBSD_MARCH; + tag = "compiled for"; break; case NT_NETBSD_CMODEL: - if (*flags & FLAGS_DID_NETBSD_CMODEL) - return offset; - *flags |= FLAGS_DID_NETBSD_CMODEL; - if (file_printf(ms, ", compiler model: %.*s", - (int)descsz, (const char *)&nbuf[doff]) == -1) - return offset; + flag = FLAGS_DID_NETBSD_CMODEL; + tag = "compiler model"; + break; + case NT_NETBSD_EMULATION: + flag = FLAGS_DID_NETBSD_EMULATION; + tag = "emulation:"; break; default: if (*flags & FLAGS_DID_NETBSD_UNKNOWN) @@ -1140,8 +1253,16 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, *flags |= FLAGS_DID_NETBSD_UNKNOWN; if (file_printf(ms, ", note=%u", xnh_type) == -1) return offset; - break; + return offset; } + + if (*flags & flag) + return offset; + str = RCAST(const char *, &nbuf[doff]); + descw = CAST(int, descsz); + *flags |= flag; + file_printf(ms, ", %s: %s", tag, + file_copystr(buf, sizeof(buf), descw, str)); return offset; } @@ -1214,6 +1335,11 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, char name[50]; ssize_t namesize; + if (num == 0) { + if (file_printf(ms, ", no section header") == -1) + return -1; + return 0; + } if (size != xsh_sizeof) { if (file_printf(ms, ", corrupted section header size") == -1) return -1; @@ -1222,16 +1348,24 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, /* Read offset of name section to be able to read section names later */ if (pread(fd, xsh_addr, xsh_sizeof, CAST(off_t, (off + size * strtab))) - < (ssize_t)xsh_sizeof) { + < CAST(ssize_t, xsh_sizeof)) { if (file_printf(ms, ", missing section headers") == -1) return -1; return 0; } name_off = xsh_offset; + if (fsize != SIZE_UNKNOWN && fsize < name_off) { + if (file_printf(ms, ", too large section header offset %jd", + (intmax_t)name_off) == -1) + return -1; + return 0; + } + for ( ; num; num--) { /* Read the name of this section. */ - if ((namesize = pread(fd, name, sizeof(name) - 1, name_off + xsh_name)) == -1) { + if ((namesize = pread(fd, name, sizeof(name) - 1, + name_off + xsh_name)) == -1) { file_badread(ms); return -1; } @@ -1241,7 +1375,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, stripped = 0; } - if (pread(fd, xsh_addr, xsh_sizeof, off) < (ssize_t)xsh_sizeof) { + if (pread(fd, xsh_addr, xsh_sizeof, off) < + CAST(ssize_t, xsh_sizeof)) { file_badread(ms); return -1; } @@ -1267,16 +1402,17 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, /* Things we can determine when we seek */ switch (xsh_type) { case SHT_NOTE: - if ((uintmax_t)(xsh_size + xsh_offset) > - (uintmax_t)fsize) { + if (CAST(uintmax_t, (xsh_size + xsh_offset)) > + CAST(uintmax_t, fsize)) { if (file_printf(ms, ", note offset/size %#" INTMAX_T_FORMAT "x+%#" INTMAX_T_FORMAT "x exceeds" " file size %#" INTMAX_T_FORMAT "x", - (uintmax_t)xsh_offset, (uintmax_t)xsh_size, - (uintmax_t)fsize) == -1) + CAST(uintmax_t, xsh_offset), + CAST(uintmax_t, xsh_size), + CAST(uintmax_t, fsize)) == -1) return -1; - return 0; + return 0; } if ((nbuf = malloc(xsh_size)) == NULL) { file_error(ms, errno, "Cannot allocate memory" @@ -1284,7 +1420,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, return -1; } if (pread(fd, nbuf, xsh_size, xsh_offset) < - (ssize_t)xsh_size) { + CAST(ssize_t, xsh_size)) { file_badread(ms); free(nbuf); return -1; @@ -1292,9 +1428,9 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, noff = 0; for (;;) { - if (noff >= (off_t)xsh_size) + if (noff >= CAST(off_t, xsh_size)) break; - noff = donote(ms, nbuf, (size_t)noff, + noff = donote(ms, nbuf, CAST(size_t, noff), xsh_size, clazz, swap, 4, flags, notecount, fd, 0, 0, 0); if (noff == 0) @@ -1316,7 +1452,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, if (nbadcap > 5) break; - if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) { + if (lseek(fd, xsh_offset, SEEK_SET) + == CAST(off_t, -1)) { file_badseek(ms); return -1; } @@ -1325,11 +1462,12 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, Elf32_Cap cap32; Elf64_Cap cap64; char cbuf[/*CONSTCOND*/ - MAX(sizeof cap32, sizeof cap64)]; - if ((coff += xcap_sizeof) > (off_t)xsh_size) + MAX(sizeof(cap32), sizeof(cap64))]; + if ((coff += xcap_sizeof) > + CAST(off_t, xsh_size)) break; - if (read(fd, cbuf, (size_t)xcap_sizeof) != - (ssize_t)xcap_sizeof) { + if (read(fd, cbuf, CAST(size_t, xcap_sizeof)) != + CAST(ssize_t, xcap_sizeof)) { file_badread(ms); return -1; } @@ -1359,11 +1497,11 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, return -1; break; } - // gnu attributes + // gnu attributes #endif break; } - (void)memcpy(xcap_addr, cbuf, xcap_sizeof); + memcpy(xcap_addr, cbuf, xcap_sizeof); switch (xcap_tag) { case CA_SUNW_NULL: break; @@ -1378,8 +1516,9 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, ", with unknown capability " "%#" INT64_T_FORMAT "x = %#" INT64_T_FORMAT "x", - (unsigned long long)xcap_tag, - (unsigned long long)xcap_val) == -1) + CAST(unsigned long long, xcap_tag), + CAST(unsigned long long, xcap_val)) + == -1) return -1; if (nbadcap++ > 2) coff = xsh_size; @@ -1432,12 +1571,12 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, if (file_printf(ms, " unknown hardware capability %#" INT64_T_FORMAT "x", - (unsigned long long)cap_hw1) == -1) + CAST(unsigned long long, cap_hw1)) == -1) return -1; } else { if (file_printf(ms, " hardware capability %#" INT64_T_FORMAT "x", - (unsigned long long)cap_hw1) == -1) + CAST(unsigned long long, cap_hw1)) == -1) return -1; } } @@ -1454,7 +1593,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, if (file_printf(ms, ", with unknown software capability %#" INT64_T_FORMAT "x", - (unsigned long long)cap_sf1) == -1) + CAST(unsigned long long, cap_sf1)) == -1) return -1; } return 0; @@ -1473,20 +1612,28 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, Elf32_Phdr ph32; Elf64_Phdr ph64; const char *linking_style = "statically"; - const char *interp = ""; unsigned char nbuf[BUFSIZ]; char ibuf[BUFSIZ]; + char interp[BUFSIZ]; ssize_t bufsize; size_t offset, align, len; - + + if (num == 0) { + if (file_printf(ms, ", no program header") == -1) + return -1; + return 0; + } if (size != xph_sizeof) { if (file_printf(ms, ", corrupted program header size") == -1) return -1; return 0; } + interp[0] = '\0'; for ( ; num; num--) { - if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) { + int doread; + if (pread(fd, xph_addr, xph_sizeof, off) < + CAST(ssize_t, xph_sizeof)) { file_badread(ms); return -1; } @@ -1498,30 +1645,26 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, /* Things we can determine before we seek */ switch (xph_type) { case PT_DYNAMIC: - linking_style = "dynamically"; + doread = 1; break; case PT_NOTE: if (sh_num) /* Did this through section headers */ continue; if (((align = xph_align) & 0x80000000UL) != 0 || align < 4) { - if (file_printf(ms, + if (file_printf(ms, ", invalid note alignment %#lx", - (unsigned long)align) == -1) + CAST(unsigned long, align)) == -1) return -1; align = 4; } /*FALLTHROUGH*/ case PT_INTERP: - len = xph_filesz < sizeof(nbuf) ? xph_filesz - : sizeof(nbuf); - bufsize = pread(fd, nbuf, len, xph_offset); - if (bufsize == -1) { - file_badread(ms); - return -1; - } + linking_style = "dynamically"; + doread = 1; break; default: + doread = 0; if (fsize != SIZE_UNKNOWN && xph_offset > fsize) { /* Maybe warn here? */ continue; @@ -1529,14 +1672,39 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, break; } + if (doread) { + len = xph_filesz < sizeof(nbuf) ? xph_filesz + : sizeof(nbuf); + bufsize = pread(fd, nbuf, len, xph_offset); + if (bufsize == -1) { + file_badread(ms); + return -1; + } + } else + len = 0; + /* Things we can determine when we seek */ switch (xph_type) { + case PT_DYNAMIC: + offset = 0; + // Let DF_1 determine if we are PIE or not. + ms->mode &= ~0111; + for (;;) { + if (offset >= CAST(size_t, bufsize)) + break; + offset = dodynamic(ms, nbuf, offset, + CAST(size_t, bufsize), clazz, swap); + if (offset == 0) + break; + } + break; + case PT_INTERP: if (bufsize && nbuf[0]) { nbuf[bufsize - 1] = '\0'; - interp = (const char *)nbuf; + memcpy(interp, nbuf, CAST(size_t, bufsize)); } else - interp = "*empty*"; + strlcpy(interp, "*empty*", sizeof(interp)); break; case PT_NOTE: /* @@ -1545,10 +1713,10 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, */ offset = 0; for (;;) { - if (offset >= (size_t)bufsize) + if (offset >= CAST(size_t, bufsize)) break; offset = donote(ms, nbuf, offset, - (size_t)bufsize, clazz, swap, align, + CAST(size_t, bufsize), clazz, swap, align, flags, notecount, fd, 0, 0, 0); if (offset == 0) break; @@ -1563,23 +1731,27 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, return -1; if (interp[0]) if (file_printf(ms, ", interpreter %s", - file_printable(ibuf, sizeof(ibuf), interp)) == -1) + file_printable(ibuf, sizeof(ibuf), interp, sizeof(interp))) + == -1) return -1; return 0; } protected int -file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf, - size_t nbytes) +file_tryelf(struct magic_set *ms, const struct buffer *b) { + int fd = b->fd; + const unsigned char *buf = CAST(const unsigned char *, b->fbuf); + size_t nbytes = b->flen; union { int32_t l; - char c[sizeof (int32_t)]; + char c[sizeof(int32_t)]; } u; int clazz; int swap; struct stat st; + const struct stat *stp; off_t fsize; int flags = 0; Elf32_Ehdr elf32hdr; @@ -1593,7 +1765,8 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf, * file locations and thus file(1) cannot determine it from easily. * Instead we traverse thru all section headers until a symbol table * one is found or else the binary is stripped. - * Return immediately if it's not ELF (so we avoid pipe2file unless needed). + * Return immediately if it's not ELF (so we avoid pipe2file unless + * needed). */ if (buf[EI_MAG0] != ELFMAG0 || (buf[EI_MAG1] != ELFMAG1 && buf[EI_MAG1] != OLFMAG1) @@ -1603,15 +1776,29 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf, /* * If we cannot seek, it must be a pipe, socket or fifo. */ - if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE)) + if((lseek(fd, CAST(off_t, 0), SEEK_SET) == CAST(off_t, -1)) + && (errno == ESPIPE)) fd = file_pipe2file(ms, fd, buf, nbytes); - if (fstat(fd, &st) == -1) { - file_badread(ms); + if (fd == -1) { + file_badread(ms); return -1; } - if (S_ISREG(st.st_mode) || st.st_size != 0) - fsize = st.st_size; + + stp = &b->st; + /* + * b->st.st_size != 0 if previous fstat() succeeded, + * which is likely, we can avoid extra stat() call. + */ + if (b->st.st_size == 0) { + stp = &st; + if (fstat(fd, &st) == -1) { + file_badread(ms); + return -1; + } + } + if (S_ISREG(stp->st_mode) || stp->st_size != 0) + fsize = stp->st_size; else fsize = SIZE_UNKNOWN; diff --git a/deps/libmagic/src/readelf.h b/deps/libmagic/src/readelf.h index ef880b9..809d3f7 100644 --- a/deps/libmagic/src/readelf.h +++ b/deps/libmagic/src/readelf.h @@ -1,7 +1,7 @@ /* * Copyright (c) Christos Zoulas 2003. * All Rights Reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -11,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -304,7 +304,7 @@ typedef struct { #define GNU_OS_KNETBSD 4 /* - * GNU Hardware capability information + * GNU Hardware capability information * word[0]: Number of entries * word[1]: Bitmask of enabled entries * Followed by a byte id, and a NUL terminated string per entry @@ -313,7 +313,7 @@ typedef struct { /* * GNU Build ID generated by ld - * 160 bit SHA1 [default] + * 160 bit SHA1 [default] * 128 bit md5 or uuid */ #define NT_GNU_BUILD_ID 3 @@ -355,6 +355,15 @@ typedef struct { */ #define NT_NETBSD_CMODEL 6 +/* + * Golang-specific note type + * name: Go\0\0 + * namesz: 4 + * desc: base-64 build id. + * descsz: < 128 + */ +#define NT_GO_BUILD_ID 4 + /* * FreeBSD specific notes */ @@ -430,4 +439,107 @@ typedef struct { #define AV_386_SSE4_1 0x00800000 #define AV_386_SSE4_2 0x01000000 +/* + * Dynamic Section structure array + */ +typedef struct { + Elf32_Word d_tag; /* entry tag value */ + union { + Elf32_Addr d_ptr; + Elf32_Word d_val; + } d_un; +} Elf32_Dyn; + +typedef struct { + Elf64_Xword d_tag; /* entry tag value */ + union { + Elf64_Addr d_ptr; + Elf64_Xword d_val; + } d_un; +} Elf64_Dyn; + +/* d_tag */ +#define DT_NULL 0 /* Marks end of dynamic array */ +#define DT_NEEDED 1 /* Name of needed library (DT_STRTAB offset) */ +#define DT_PLTRELSZ 2 /* Size, in bytes, of relocations in PLT */ +#define DT_PLTGOT 3 /* Address of PLT and/or GOT */ +#define DT_HASH 4 /* Address of symbol hash table */ +#define DT_STRTAB 5 /* Address of string table */ +#define DT_SYMTAB 6 /* Address of symbol table */ +#define DT_RELA 7 /* Address of Rela relocation table */ +#define DT_RELASZ 8 /* Size, in bytes, of DT_RELA table */ +#define DT_RELAENT 9 /* Size, in bytes, of one DT_RELA entry */ +#define DT_STRSZ 10 /* Size, in bytes, of DT_STRTAB table */ +#define DT_SYMENT 11 /* Size, in bytes, of one DT_SYMTAB entry */ +#define DT_INIT 12 /* Address of initialization function */ +#define DT_FINI 13 /* Address of termination function */ +#define DT_SONAME 14 /* Shared object name (DT_STRTAB offset) */ +#define DT_RPATH 15 /* Library search path (DT_STRTAB offset) */ +#define DT_SYMBOLIC 16 /* Start symbol search within local object */ +#define DT_REL 17 /* Address of Rel relocation table */ +#define DT_RELSZ 18 /* Size, in bytes, of DT_REL table */ +#define DT_RELENT 19 /* Size, in bytes, of one DT_REL entry */ +#define DT_PLTREL 20 /* Type of PLT relocation entries */ +#define DT_DEBUG 21 /* Used for debugging; unspecified */ +#define DT_TEXTREL 22 /* Relocations might modify non-writable seg */ +#define DT_JMPREL 23 /* Address of relocations associated with PLT */ +#define DT_BIND_NOW 24 /* Process all relocations at load-time */ +#define DT_INIT_ARRAY 25 /* Address of initialization function array */ +#define DT_FINI_ARRAY 26 /* Size, in bytes, of DT_INIT_ARRAY array */ +#define DT_INIT_ARRAYSZ 27 /* Address of termination function array */ +#define DT_FINI_ARRAYSZ 28 /* Size, in bytes, of DT_FINI_ARRAY array*/ +#define DT_RUNPATH 29 /* overrides DT_RPATH */ +#define DT_FLAGS 30 /* Encodes ORIGIN, SYMBOLIC, TEXTREL, BIND_NOW, STATIC_TLS */ +#define DT_ENCODING 31 /* ??? */ +#define DT_PREINIT_ARRAY 32 /* Address of pre-init function array */ +#define DT_PREINIT_ARRAYSZ 33 /* Size, in bytes, of DT_PREINIT_ARRAY array */ +#define DT_NUM 34 + +#define DT_LOOS 0x60000000 /* Operating system specific range */ +#define DT_VERSYM 0x6ffffff0 /* Symbol versions */ +#define DT_FLAGS_1 0x6ffffffb /* ELF dynamic flags */ +#define DT_VERDEF 0x6ffffffc /* Versions defined by file */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of versions defined by file */ +#define DT_VERNEED 0x6ffffffe /* Versions needed by file */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of versions needed by file */ +#define DT_HIOS 0x6fffffff +#define DT_LOPROC 0x70000000 /* Processor-specific range */ +#define DT_HIPROC 0x7fffffff + +/* Flag values for DT_FLAGS */ +#define DF_ORIGIN 0x00000001 /* uses $ORIGIN */ +#define DF_SYMBOLIC 0x00000002 /* */ +#define DF_TEXTREL 0x00000004 /* */ +#define DF_BIND_NOW 0x00000008 /* */ +#define DF_STATIC_TLS 0x00000010 /* */ + +/* Flag values for DT_FLAGS_1 */ +#define DF_1_NOW 0x00000001 /* Same as DF_BIND_NOW */ +#define DF_1_GLOBAL 0x00000002 /* Unused */ +#define DF_1_GROUP 0x00000004 /* Is member of group */ +#define DF_1_NODELETE 0x00000008 /* Cannot be deleted from process */ +#define DF_1_LOADFLTR 0x00000010 /* Immediate loading of filters */ +#define DF_1_INITFIRST 0x00000020 /* init/fini takes priority */ +#define DF_1_NOOPEN 0x00000040 /* Do not allow loading on dlopen() */ +#define DF_1_ORIGIN 0x00000080 /* Require $ORIGIN processing */ +#define DF_1_DIRECT 0x00000100 /* Enable direct bindings */ +#define DF_1_INTERPOSE 0x00000400 /* Is an interposer */ +#define DF_1_NODEFLIB 0x00000800 /* Ignore default library search path */ +#define DF_1_NODUMP 0x00001000 /* Cannot be dumped with dldump(3C) */ +#define DF_1_CONFALT 0x00002000 /* Configuration alternative */ +#define DF_1_ENDFILTEE 0x00004000 /* Filtee ends filter's search */ +#define DF_1_DISPRELDNE 0x00008000 /* Did displacement relocation */ +#define DF_1_DISPRELPND 0x00010000 /* Pending displacement relocation */ +#define DF_1_NODIRECT 0x00020000 /* Has non-direct bindings */ +#define DF_1_IGNMULDEF 0x00040000 /* Used internally */ +#define DF_1_NOKSYMS 0x00080000 /* Used internally */ +#define DF_1_NOHDR 0x00100000 /* Used internally */ +#define DF_1_EDITED 0x00200000 /* Has been modified since build */ +#define DF_1_NORELOC 0x00400000 /* Used internally */ +#define DF_1_SYMINTPOSE 0x00800000 /* Has individual symbol interposers */ +#define DF_1_GLOBAUDIT 0x01000000 /* Require global auditing */ +#define DF_1_SINGLETON 0x02000000 /* Has singleton symbols */ +#define DF_1_STUB 0x04000000 /* Stub */ +#define DF_1_PIE 0x08000000 /* Position Independent Executable */ + #endif diff --git a/deps/libmagic/src/softmagic.c b/deps/libmagic/src/softmagic.c index b9e9753..8ad2765 100644 --- a/deps/libmagic/src/softmagic.c +++ b/deps/libmagic/src/softmagic.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: softmagic.c,v 1.249 2017/06/19 18:30:25 christos Exp $") +FILE_RCSID("@(#)$File: softmagic.c,v 1.291 2020/03/08 21:30:06 christos Exp $") #endif /* lint */ #include "magic.h" @@ -44,14 +44,18 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.249 2017/06/19 18:30:25 christos Exp $") #include "der.h" private int match(struct magic_set *, struct magic *, uint32_t, - const unsigned char *, size_t, size_t, int, int, int, uint16_t *, - uint16_t *, int *, int *, int *); -private int mget(struct magic_set *, const unsigned char *, - struct magic *, size_t, size_t, unsigned int, int, int, int, uint16_t *, - uint16_t *, int *, int *, int *); + const struct buffer *, size_t, int, int, int, uint16_t *, + uint16_t *, int *, int *, int *, int *); +private int mget(struct magic_set *, struct magic *, const struct buffer *, + const unsigned char *, size_t, + size_t, unsigned int, int, int, int, uint16_t *, + uint16_t *, int *, int *, int *, int *); +private int msetoffset(struct magic_set *, struct magic *, struct buffer *, + const struct buffer *, size_t, unsigned int); private int magiccheck(struct magic_set *, struct magic *); private int32_t mprint(struct magic_set *, struct magic *); -private int moffset(struct magic_set *, struct magic *, size_t, int32_t *); +private int moffset(struct magic_set *, struct magic *, const struct buffer *, + int32_t *); private void mdebug(uint32_t, const char *, size_t); private int mcopy(struct magic_set *, union VALUETYPE *, int, int, const unsigned char *, uint32_t, size_t, struct magic *); @@ -63,24 +67,46 @@ private int cvt_16(union VALUETYPE *, const struct magic *); private int cvt_32(union VALUETYPE *, const struct magic *); private int cvt_64(union VALUETYPE *, const struct magic *); -#define OFFSET_OOB(n, o, i) ((n) < (uint32_t)(o) || (i) > ((n) - (o))) -#define BE64(p) (((uint64_t)(p)->hq[0]<<56)|((uint64_t)(p)->hq[1]<<48)| \ - ((uint64_t)(p)->hq[2]<<40)|((uint64_t)(p)->hq[3]<<32)| \ - ((uint64_t)(p)->hq[4]<<24)|((uint64_t)(p)->hq[5]<<16)| \ - ((uint64_t)(p)->hq[6]<<8)|((uint64_t)(p)->hq[7])) -#define LE64(p) (((uint64_t)(p)->hq[7]<<56)|((uint64_t)(p)->hq[6]<<48)| \ - ((uint64_t)(p)->hq[5]<<40)|((uint64_t)(p)->hq[4]<<32)| \ - ((uint64_t)(p)->hq[3]<<24)|((uint64_t)(p)->hq[2]<<16)| \ - ((uint64_t)(p)->hq[1]<<8)|((uint64_t)(p)->hq[0])) -#define LE32(p) (((uint32_t)(p)->hl[3]<<24)|((uint32_t)(p)->hl[2]<<16)| \ - ((uint32_t)(p)->hl[1]<<8)|((uint32_t)(p)->hl[0])) -#define BE32(p) (((uint32_t)(p)->hl[0]<<24)|((uint32_t)(p)->hl[1]<<16)| \ - ((uint32_t)(p)->hl[2]<<8)|((uint32_t)(p)->hl[3])) -#define ME32(p) (((uint32_t)(p)->hl[1]<<24)|((uint32_t)(p)->hl[0]<<16)| \ - ((uint32_t)(p)->hl[3]<<8)|((uint32_t)(p)->hl[2])) -#define BE16(p) (((uint16_t)(p)->hs[0]<<8)|((uint16_t)(p)->hs[1])) -#define LE16(p) (((uint16_t)(p)->hs[1]<<8)|((uint16_t)(p)->hs[0])) -#define SEXT(s,v,p) ((s)?(intmax_t)(int##v##_t)(p):(intmax_t)(uint##v##_t)(p)) +#define OFFSET_OOB(n, o, i) ((n) < CAST(uint32_t, (o)) || (i) > ((n) - (o))) +#define BE64(p) ( \ + (CAST(uint64_t, (p)->hq[0])<<56)| \ + (CAST(uint64_t, (p)->hq[1])<<48)| \ + (CAST(uint64_t, (p)->hq[2])<<40)| \ + (CAST(uint64_t, (p)->hq[3])<<32)| \ + (CAST(uint64_t, (p)->hq[4])<<24)| \ + (CAST(uint64_t, (p)->hq[5])<<16)| \ + (CAST(uint64_t, (p)->hq[6])<<8)| \ + (CAST(uint64_t, (p)->hq[7]))) +#define LE64(p) ( \ + (CAST(uint64_t, (p)->hq[7])<<56)| \ + (CAST(uint64_t, (p)->hq[6])<<48)| \ + (CAST(uint64_t, (p)->hq[5])<<40)| \ + (CAST(uint64_t, (p)->hq[4])<<32)| \ + (CAST(uint64_t, (p)->hq[3])<<24)| \ + (CAST(uint64_t, (p)->hq[2])<<16)| \ + (CAST(uint64_t, (p)->hq[1])<<8)| \ + (CAST(uint64_t, (p)->hq[0]))) +#define LE32(p) ( \ + (CAST(uint32_t, (p)->hl[3])<<24)| \ + (CAST(uint32_t, (p)->hl[2])<<16)| \ + (CAST(uint32_t, (p)->hl[1])<<8)| \ + (CAST(uint32_t, (p)->hl[0]))) +#define BE32(p) ( \ + (CAST(uint32_t, (p)->hl[0])<<24)| \ + (CAST(uint32_t, (p)->hl[1])<<16)| \ + (CAST(uint32_t, (p)->hl[2])<<8)| \ + (CAST(uint32_t, (p)->hl[3]))) +#define ME32(p) ( \ + (CAST(uint32_t, (p)->hl[1])<<24)| \ + (CAST(uint32_t, (p)->hl[0])<<16)| \ + (CAST(uint32_t, (p)->hl[3])<<8)| \ + (CAST(uint32_t, (p)->hl[2]))) + +#define BE16(p) ((CAST(uint16_t, (p)->hs[0])<<8)|(CAST(uint16_t, (p)->hs[1]))) +#define LE16(p) ((CAST(uint16_t, (p)->hs[1])<<8)|(CAST(uint16_t, (p)->hs[0]))) +#define SEXT(s,v,p) ((s) ? \ + CAST(intmax_t, CAST(int##v##_t, p)) : \ + CAST(intmax_t, CAST(uint##v##_t, p))) /* * softmagic - lookup one file in parsed, in-memory copy of database @@ -88,7 +114,7 @@ private int cvt_64(union VALUETYPE *, const struct magic *); */ /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ protected int -file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, +file_softmagic(struct magic_set *ms, const struct buffer *b, uint16_t *indir_count, uint16_t *name_count, int mode, int text) { struct mlist *ml; @@ -105,9 +131,9 @@ file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, } for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next) - if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode, + if ((rv = match(ms, ml->magic, ml->nmagic, b, 0, mode, text, 0, indir_count, name_count, - &printed_something, &need_separator, NULL)) != 0) + &printed_something, &need_separator, NULL, NULL)) != 0) return rv; return 0; @@ -118,18 +144,23 @@ file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, #define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__) private const char * __attribute__((__format_arg__(3))) -file_fmtcheck(struct magic_set *ms, const struct magic *m, const char *def, +file_fmtcheck(struct magic_set *ms, const char *desc, const char *def, const char *file, size_t line) { - const char *ptr = fmtcheck(m->desc, def); + const char *ptr; + + if (strchr(desc, '%') == NULL) + return desc; + + ptr = fmtcheck(desc, def); if (ptr == def) file_magerror(ms, "%s, %" SIZE_T_FORMAT "u: format `%s' does not match" - " with `%s'", file, line, m->desc, def); + " with `%s'", file, line, desc, def); return ptr; } #else -#define F(a, b, c) fmtcheck((b)->desc, (c)) +#define F(a, b, c) fmtcheck((b), (c)) #endif /* @@ -161,18 +192,27 @@ file_fmtcheck(struct magic_set *ms, const struct magic *m, const char *def, */ private int match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, - const unsigned char *s, size_t nbytes, size_t offset, int mode, int text, + const struct buffer *b, size_t offset, int mode, int text, int flip, uint16_t *indir_count, uint16_t *name_count, - int *printed_something, int *need_separator, int *returnval) + int *printed_something, int *need_separator, int *returnval, + int *found_match) { uint32_t magindex = 0; unsigned int cont_level = 0; - int returnvalv = 0, e; /* if a match is found it is set to 1*/ + int found_matchv = 0; /* if a match is found it is set to 1*/ + int returnvalv = 0, e; int firstline = 1; /* a flag to print X\n X\n- X */ + struct buffer bb; int print = (ms->flags & MAGIC_NODESC) == 0; + /* + * returnval can be 0 if a match is found, but there was no + * annotation to be printed. + */ if (returnval == NULL) returnval = &returnvalv; + if (found_match == NULL) + found_match = &found_matchv; if (file_check_mem(ms, cont_level) == -1) return -1; @@ -196,21 +236,26 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, continue; /* Skip to next top-level test*/ } - ms->offset = m->offset; + if (msetoffset(ms, m, &bb, b, offset, cont_level) == -1) + goto flush; ms->line = m->lineno; /* if main entry matches, print it... */ - switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text, - flip, indir_count, name_count, - printed_something, need_separator, returnval)) { + switch (mget(ms, m, b, CAST(const unsigned char *, bb.fbuf), + bb.flen, offset, cont_level, + mode, text, flip, indir_count, name_count, + printed_something, need_separator, returnval, found_match)) + { case -1: return -1; case 0: flush = m->reln != '!'; break; default: - if (m->type == FILE_INDIRECT) + if (m->type == FILE_INDIRECT) { + *found_match = 1; *returnval = 1; + } switch (magiccheck(ms, m)) { case -1: @@ -232,7 +277,11 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, goto flush; } - if ((e = handle_annotation(ms, m, firstline)) != 0) { + if (*m->desc) + *found_match = 1; + + if ((e = handle_annotation(ms, m, firstline)) != 0) + { *need_separator = 1; *printed_something = 1; *returnval = 1; @@ -243,18 +292,17 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, * If we are going to print something, we'll need to print * a blank before we print something else. */ - if (*m->desc) { + if (print && *m->desc) { *need_separator = 1; *printed_something = 1; + *returnval = 1; if (print_sep(ms, firstline) == -1) return -1; + if (mprint(ms, m) == -1) + return -1; } - - if (print && mprint(ms, m) == -1) - return -1; - - switch (moffset(ms, m, nbytes, &ms->c.li[cont_level].off)) { + switch (moffset(ms, m, &bb, &ms->c.li[cont_level].off)) { case -1: case 0: goto flush; @@ -280,8 +328,16 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, */ cont_level = m->cont_level; } - ms->offset = m->offset; + 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; } @@ -293,9 +349,11 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, continue; } #endif - switch (mget(ms, s, m, nbytes, offset, cont_level, mode, - text, flip, indir_count, name_count, - printed_something, need_separator, returnval)) { + switch (mget(ms, m, b, CAST(const unsigned char *, + bb.fbuf), bb.flen, offset, + cont_level, mode, text, flip, indir_count, + name_count, printed_something, need_separator, + returnval, found_match)) { case -1: return -1; case 0: @@ -304,8 +362,10 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, flush = 1; break; default: - if (m->type == FILE_INDIRECT) + if (m->type == FILE_INDIRECT) { + *found_match = 1; *returnval = 1; + } flush = 0; break; } @@ -330,43 +390,48 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, } else ms->c.li[cont_level].got_match = 1; - if ((e = handle_annotation(ms, m, firstline)) != 0) { + if (*m->desc) + *found_match = 1; + + if ((e = handle_annotation(ms, m, firstline)) + != 0) { *need_separator = 1; *printed_something = 1; *returnval = 1; return e; } - /* - * If we are going to print something, - * make sure that we have a separator first. - */ - if (*m->desc) { + if (print && *m->desc) { + /* + * This continuation matched. Print + * its message, with a blank before it + * if the previous item printed and + * this item isn't empty. + */ + /* + * If we are going to print something, + * make sure that we have a separator + * first. + */ if (!*printed_something) { *printed_something = 1; if (print_sep(ms, firstline) == -1) return -1; } - } - /* - * This continuation matched. Print - * its message, with a blank before it - * if the previous item printed and - * this item isn't empty. - */ - /* space if previous printed */ - if (*need_separator - && ((m->flag & NOSPACE) == 0) - && *m->desc) { - if (print && - file_printf(ms, " ") == -1) - return -1; + /* space if previous printed */ + if (*need_separator + && (m->flag & NOSPACE) == 0) { + if (file_printf(ms, " ") == -1) + return -1; + } + *returnval = 1; *need_separator = 0; + if (mprint(ms, m) == -1) + return -1; + *need_separator = 1; } - if (print && mprint(ms, m) == -1) - return -1; - switch (moffset(ms, m, nbytes, + switch (moffset(ms, m, &bb, &ms->c.li[cont_level].off)) { case -1: case 0: @@ -377,9 +442,6 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, break; } - if (*m->desc) - *need_separator = 1; - /* * If we see any continuations * at a higher level, @@ -392,11 +454,13 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, } if (*printed_something) { firstline = 0; - if (print) - *returnval = 1; } - if ((ms->flags & MAGIC_CONTINUE) == 0 && *printed_something) { + if (*found_match) { + if ((ms->flags & MAGIC_CONTINUE) == 0) return *returnval; /* don't keep searching */ + // So that we print a separator + *printed_something = 0; + firstline = 0; } cont_level = 0; } @@ -404,27 +468,30 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, } private int -check_fmt(struct magic_set *ms, struct magic *m) +check_fmt(struct magic_set *ms, const char *fmt) { file_regex_t rx; int rc, rv = -1; - if (strchr(m->desc, '%') == NULL) + if (strchr(fmt, '%') == NULL) return 0; rc = file_regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB); if (rc) { file_regerror(&rx, rc, ms); } else { - rc = file_regexec(&rx, m->desc, 0, 0, 0); + rc = file_regexec(&rx, fmt, 0, 0, 0); rv = !rc; } file_regfree(&rx); return rv; } -#ifndef HAVE_STRNDUP -char * strndup(const char *, size_t); +#if !defined(HAVE_STRNDUP) || defined(__aiws__) +# ifdef __aiws__ +# define strndup aix_strndup /* aix is broken */ +# endif +char *strndup(const char *, size_t); char * strndup(const char *str, size_t n) @@ -442,6 +509,61 @@ strndup(const char *str, size_t n) } #endif /* HAVE_STRNDUP */ +static int +varexpand(struct magic_set *ms, char *buf, size_t len, const char *str) +{ + const char *ptr, *sptr, *e, *t, *ee, *et; + size_t l; + + for (sptr = str; (ptr = strstr(sptr, "${")) != NULL;) { + l = CAST(size_t, ptr - sptr); + if (l >= len) + return -1; + memcpy(buf, sptr, l); + buf += l; + len -= l; + ptr += 2; + if (!*ptr || ptr[1] != '?') + return -1; + for (et = t = ptr + 2; *et && *et != ':'; et++) + continue; + if (*et != ':') + return -1; + for (ee = e = et + 1; *ee && *ee != '}'; ee++) + continue; + if (*ee != '}') + return -1; + switch (*ptr) { + case 'x': + if (ms->mode & 0111) { + ptr = t; + l = et - t; + } else { + ptr = e; + l = ee - e; + } + break; + default: + return -1; + } + if (l >= len) + return -1; + memcpy(buf, ptr, l); + buf += l; + len -= l; + sptr = ee + 1; + } + + l = strlen(sptr); + if (l >= len) + return -1; + + memcpy(buf, sptr, l); + buf[l] = '\0'; + return 0; +} + + private int32_t mprint(struct magic_set *ms, struct magic *m) { @@ -449,24 +571,30 @@ mprint(struct magic_set *ms, struct magic *m) float vf; double vd; int64_t t = 0; - char buf[128], tbuf[26], sbuf[512]; + char buf[128], tbuf[26], sbuf[512], ebuf[512]; + const char *desc; union VALUETYPE *p = &ms->ms_value; + if (varexpand(ms, ebuf, sizeof(ebuf), m->desc) == -1) + desc = m->desc; + else + desc = ebuf; + switch (m->type) { case FILE_BYTE: - v = file_signextend(ms, m, (uint64_t)p->b); - switch (check_fmt(ms, m)) { + v = file_signextend(ms, m, CAST(uint64_t, p->b)); + switch (check_fmt(ms, desc)) { case -1: return -1; case 1: (void)snprintf(buf, sizeof(buf), "%d", - (unsigned char)v); - if (file_printf(ms, F(ms, m, "%s"), buf) == -1) + CAST(unsigned char, v)); + if (file_printf(ms, F(ms, desc, "%s"), buf) == -1) return -1; break; default: - if (file_printf(ms, F(ms, m, "%d"), - (unsigned char) v) == -1) + if (file_printf(ms, F(ms, desc, "%d"), + CAST(unsigned char, v)) == -1) return -1; break; } @@ -476,19 +604,19 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_SHORT: case FILE_BESHORT: case FILE_LESHORT: - v = file_signextend(ms, m, (uint64_t)p->h); - switch (check_fmt(ms, m)) { + v = file_signextend(ms, m, CAST(uint64_t, p->h)); + switch (check_fmt(ms, desc)) { case -1: return -1; case 1: (void)snprintf(buf, sizeof(buf), "%u", - (unsigned short)v); - if (file_printf(ms, F(ms, m, "%s"), buf) == -1) + CAST(unsigned short, v)); + if (file_printf(ms, F(ms, desc, "%s"), buf) == -1) return -1; break; default: - if (file_printf(ms, F(ms, m, "%u"), - (unsigned short) v) == -1) + if (file_printf(ms, F(ms, desc, "%u"), + CAST(unsigned short, v)) == -1) return -1; break; } @@ -499,17 +627,19 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BELONG: case FILE_LELONG: case FILE_MELONG: - v = file_signextend(ms, m, (uint64_t)p->l); - switch (check_fmt(ms, m)) { + v = file_signextend(ms, m, CAST(uint64_t, p->l)); + switch (check_fmt(ms, desc)) { case -1: return -1; case 1: - (void)snprintf(buf, sizeof(buf), "%u", (uint32_t) v); - if (file_printf(ms, F(ms, m, "%s"), buf) == -1) + (void)snprintf(buf, sizeof(buf), "%u", + CAST(uint32_t, v)); + if (file_printf(ms, F(ms, desc, "%s"), buf) == -1) return -1; break; default: - if (file_printf(ms, F(ms, m, "%u"), (uint32_t) v) == -1) + if (file_printf(ms, F(ms, desc, "%u"), + CAST(uint32_t, v)) == -1) return -1; break; } @@ -520,18 +650,18 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BEQUAD: case FILE_LEQUAD: v = file_signextend(ms, m, p->q); - switch (check_fmt(ms, m)) { + switch (check_fmt(ms, desc)) { case -1: return -1; case 1: (void)snprintf(buf, sizeof(buf), "%" INT64_T_FORMAT "u", - (unsigned long long)v); - if (file_printf(ms, F(ms, m, "%s"), buf) == -1) + CAST(unsigned long long, v)); + if (file_printf(ms, F(ms, desc, "%s"), buf) == -1) return -1; break; default: - if (file_printf(ms, F(ms, m, "%" INT64_T_FORMAT "u"), - (unsigned long long) v) == -1) + if (file_printf(ms, F(ms, desc, "%" INT64_T_FORMAT "u"), + CAST(unsigned long long, v)) == -1) return -1; break; } @@ -543,9 +673,9 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BESTRING16: case FILE_LESTRING16: if (m->reln == '=' || m->reln == '!') { - if (file_printf(ms, F(ms, m, "%s"), - file_printable(sbuf, sizeof(sbuf), m->value.s)) - == -1) + if (file_printf(ms, F(ms, desc, "%s"), + file_printable(sbuf, sizeof(sbuf), m->value.s, + sizeof(m->value.s))) == -1) return -1; t = ms->offset + m->vallen; } @@ -560,23 +690,28 @@ mprint(struct magic_set *ms, struct magic *m) if (m->str_flags & STRING_TRIM) { char *last; - while (isspace((unsigned char)*str)) + while (isspace(CAST(unsigned char, *str))) str++; last = str; while (*last) last++; --last; - while (isspace((unsigned char)*last)) + while (isspace(CAST(unsigned char, *last))) last--; *++last = '\0'; } - if (file_printf(ms, F(ms, m, "%s"), - file_printable(sbuf, sizeof(sbuf), str)) == -1) + if (file_printf(ms, F(ms, desc, "%s"), + file_printable(sbuf, sizeof(sbuf), str, + 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; @@ -584,8 +719,8 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BEDATE: case FILE_LEDATE: case FILE_MEDATE: - if (file_printf(ms, F(ms, m, "%s"), - file_fmttime(p->l, 0, tbuf)) == -1) + if (file_printf(ms, F(ms, desc, "%s"), + file_fmttime(tbuf, sizeof(tbuf), p->l, 0)) == -1) return -1; t = ms->offset + sizeof(uint32_t); break; @@ -594,8 +729,8 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BELDATE: case FILE_LELDATE: case FILE_MELDATE: - if (file_printf(ms, F(ms, m, "%s"), - file_fmttime(p->l, FILE_T_LOCAL, tbuf)) == -1) + if (file_printf(ms, F(ms, desc, "%s"), + file_fmttime(tbuf, sizeof(tbuf), p->l, FILE_T_LOCAL)) == -1) return -1; t = ms->offset + sizeof(uint32_t); break; @@ -603,8 +738,8 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_QDATE: case FILE_BEQDATE: case FILE_LEQDATE: - if (file_printf(ms, F(ms, m, "%s"), - file_fmttime(p->q, 0, tbuf)) == -1) + if (file_printf(ms, F(ms, desc, "%s"), + file_fmttime(tbuf, sizeof(tbuf), p->q, 0)) == -1) return -1; t = ms->offset + sizeof(uint64_t); break; @@ -612,8 +747,8 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_QLDATE: case FILE_BEQLDATE: case FILE_LEQLDATE: - if (file_printf(ms, F(ms, m, "%s"), - file_fmttime(p->q, FILE_T_LOCAL, tbuf)) == -1) + if (file_printf(ms, F(ms, desc, "%s"), + file_fmttime(tbuf, sizeof(tbuf), p->q, FILE_T_LOCAL)) == -1) return -1; t = ms->offset + sizeof(uint64_t); break; @@ -621,8 +756,9 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_QWDATE: case FILE_BEQWDATE: case FILE_LEQWDATE: - if (file_printf(ms, F(ms, m, "%s"), - file_fmttime(p->q, FILE_T_WINDOWS, tbuf)) == -1) + if (file_printf(ms, F(ms, desc, "%s"), + file_fmttime(tbuf, sizeof(tbuf), p->q, FILE_T_WINDOWS)) + == -1) return -1; t = ms->offset + sizeof(uint64_t); break; @@ -631,16 +767,16 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BEFLOAT: case FILE_LEFLOAT: vf = p->f; - switch (check_fmt(ms, m)) { + switch (check_fmt(ms, desc)) { case -1: return -1; case 1: (void)snprintf(buf, sizeof(buf), "%g", vf); - if (file_printf(ms, F(ms, m, "%s"), buf) == -1) + if (file_printf(ms, F(ms, desc, "%s"), buf) == -1) return -1; break; default: - if (file_printf(ms, F(ms, m, "%g"), vf) == -1) + if (file_printf(ms, F(ms, desc, "%g"), vf) == -1) return -1; break; } @@ -651,16 +787,16 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BEDOUBLE: case FILE_LEDOUBLE: vd = p->d; - switch (check_fmt(ms, m)) { + switch (check_fmt(ms, desc)) { case -1: return -1; case 1: (void)snprintf(buf, sizeof(buf), "%g", vd); - if (file_printf(ms, F(ms, m, "%s"), buf) == -1) + if (file_printf(ms, F(ms, desc, "%s"), buf) == -1) return -1; break; default: - if (file_printf(ms, F(ms, m, "%g"), vd) == -1) + if (file_printf(ms, F(ms, desc, "%g"), vd) == -1) return -1; break; } @@ -672,13 +808,14 @@ mprint(struct magic_set *ms, struct magic *m) char *cp; int rval; - cp = strndup((const char *)ms->search.s, ms->search.rm_len); + cp = strndup(RCAST(const char *, ms->search.s), + ms->search.rm_len); if (cp == NULL) { file_oomem(ms, ms->search.rm_len); return -1; } - rval = file_printf(ms, F(ms, m, "%s"), - file_printable(sbuf, sizeof(sbuf), cp)); + rval = file_printf(ms, F(ms, desc, "%s"), + file_printable(sbuf, sizeof(sbuf), cp, ms->search.rm_len)); free(cp); if (rval == -1) @@ -704,8 +841,15 @@ mprint(struct magic_set *ms, struct magic *m) t = ms->offset; break; case FILE_DER: - if (file_printf(ms, F(ms, m, "%s"), - file_printable(sbuf, sizeof(sbuf), ms->ms_value.s)) == -1) + if (file_printf(ms, F(ms, desc, "%s"), + file_printable(sbuf, sizeof(sbuf), ms->ms_value.s, + sizeof(ms->ms_value.s))) == -1) + 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; @@ -713,12 +857,14 @@ mprint(struct magic_set *ms, struct magic *m) file_magerror(ms, "invalid m->type (%d) in mprint()", m->type); return -1; } - return (int32_t)t; + return CAST(int32_t, t); } private int -moffset(struct magic_set *ms, struct magic *m, size_t nbytes, int32_t *op) +moffset(struct magic_set *ms, struct magic *m, const struct buffer *b, + int32_t *op) { + size_t nbytes = b->flen; int32_t o; switch (m->type) { @@ -757,8 +903,12 @@ moffset(struct magic_set *ms, struct magic *m, size_t nbytes, int32_t *op) 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 += (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; @@ -822,29 +972,31 @@ moffset(struct magic_set *ms, struct magic *m, size_t nbytes, int32_t *op) break; case FILE_DER: - { - o = der_offs(ms, m, nbytes); - if (o == -1 || (size_t)o > nbytes) { - if ((ms->flags & MAGIC_DEBUG) != 0) { - (void)fprintf(stderr, - "Bad DER offset %d nbytes=%zu", - 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; break; } - if ((size_t)o > nbytes) { + if (CAST(size_t, o) > nbytes) { #if 0 - file_error(ms, 0, "Offset out of range %zu > %zu", - (size_t)o, nbytes); + file_error(ms, 0, "Offset out of range %" SIZE_T_FORMAT + "u > %" SIZE_T_FORMAT "u", (size_t)o, nbytes); #endif return -1; } @@ -914,36 +1066,36 @@ cvt_flip(int type, int flip) return type; } } -#define DO_CVT(fld, cast) \ +#define DO_CVT(fld, type) \ if (m->num_mask) \ switch (m->mask_op & FILE_OPS_MASK) { \ case FILE_OPAND: \ - p->fld &= cast m->num_mask; \ + p->fld &= CAST(type, m->num_mask); \ break; \ case FILE_OPOR: \ - p->fld |= cast m->num_mask; \ + p->fld |= CAST(type, m->num_mask); \ break; \ case FILE_OPXOR: \ - p->fld ^= cast m->num_mask; \ + p->fld ^= CAST(type, m->num_mask); \ break; \ case FILE_OPADD: \ - p->fld += cast m->num_mask; \ + p->fld += CAST(type, m->num_mask); \ break; \ case FILE_OPMINUS: \ - p->fld -= cast m->num_mask; \ + p->fld -= CAST(type, m->num_mask); \ break; \ case FILE_OPMULTIPLY: \ - p->fld *= cast m->num_mask; \ + p->fld *= CAST(type, m->num_mask); \ break; \ case FILE_OPDIVIDE: \ - if (cast m->num_mask == 0) \ + if (CAST(type, m->num_mask) == 0) \ return -1; \ - p->fld /= cast m->num_mask; \ + p->fld /= CAST(type, m->num_mask); \ break; \ case FILE_OPMODULO: \ - if (cast m->num_mask == 0) \ + if (CAST(type, m->num_mask) == 0) \ return -1; \ - p->fld %= cast m->num_mask; \ + p->fld %= CAST(type, m->num_mask); \ break; \ } \ if (m->mask_op & FILE_OPINVERSE) \ @@ -952,61 +1104,61 @@ cvt_flip(int type, int flip) private int cvt_8(union VALUETYPE *p, const struct magic *m) { - DO_CVT(b, (uint8_t)); + DO_CVT(b, uint8_t); return 0; } private int cvt_16(union VALUETYPE *p, const struct magic *m) { - DO_CVT(h, (uint16_t)); + DO_CVT(h, uint16_t); return 0; } private int cvt_32(union VALUETYPE *p, const struct magic *m) { - DO_CVT(l, (uint32_t)); + DO_CVT(l, uint32_t); return 0; } private int cvt_64(union VALUETYPE *p, const struct magic *m) { - DO_CVT(q, (uint64_t)); + DO_CVT(q, uint64_t); return 0; } -#define DO_CVT2(fld, cast) \ +#define DO_CVT2(fld, type) \ if (m->num_mask) \ switch (m->mask_op & FILE_OPS_MASK) { \ case FILE_OPADD: \ - p->fld += cast m->num_mask; \ + p->fld += CAST(type, m->num_mask); \ break; \ case FILE_OPMINUS: \ - p->fld -= cast m->num_mask; \ + p->fld -= CAST(type, m->num_mask); \ break; \ case FILE_OPMULTIPLY: \ - p->fld *= cast m->num_mask; \ + p->fld *= CAST(type, m->num_mask); \ break; \ case FILE_OPDIVIDE: \ - if (cast m->num_mask == 0) \ + if (CAST(type, m->num_mask) == 0) \ return -1; \ - p->fld /= cast m->num_mask; \ + p->fld /= CAST(type, m->num_mask); \ break; \ } \ private int cvt_float(union VALUETYPE *p, const struct magic *m) { - DO_CVT2(f, (float)); + DO_CVT2(f, float); return 0; } private int cvt_double(union VALUETYPE *p, const struct magic *m) { - DO_CVT2(d, (double)); + DO_CVT2(d, double); return 0; } @@ -1050,9 +1202,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) { /* @@ -1062,7 +1220,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) * string by p->s, so we need to deduct sz. * Because we can use one of the bytes of the length * after we shifted as NUL termination. - */ + */ len = sz; } while (len--) @@ -1071,14 +1229,14 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) return 1; } case FILE_BESHORT: - p->h = (short)BE16(p); + p->h = CAST(short, BE16(p)); if (cvt_16(p, m) == -1) goto out; return 1; case FILE_BELONG: case FILE_BEDATE: case FILE_BELDATE: - p->l = (int32_t)BE32(p); + p->l = CAST(int32_t, BE32(p)); if (cvt_32(p, m) == -1) goto out; return 1; @@ -1086,19 +1244,19 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) case FILE_BEQDATE: case FILE_BEQLDATE: case FILE_BEQWDATE: - p->q = (uint64_t)BE64(p); + p->q = CAST(uint64_t, BE64(p)); if (cvt_64(p, m) == -1) goto out; return 1; case FILE_LESHORT: - p->h = (short)LE16(p); + p->h = CAST(short, LE16(p)); if (cvt_16(p, m) == -1) goto out; return 1; case FILE_LELONG: case FILE_LEDATE: case FILE_LELDATE: - p->l = (int32_t)LE32(p); + p->l = CAST(int32_t, LE32(p)); if (cvt_32(p, m) == -1) goto out; return 1; @@ -1106,14 +1264,14 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) case FILE_LEQDATE: case FILE_LEQLDATE: case FILE_LEQWDATE: - p->q = (uint64_t)LE64(p); + p->q = CAST(uint64_t, LE64(p)); if (cvt_64(p, m) == -1) goto out; return 1; case FILE_MELONG: case FILE_MEDATE: case FILE_MELDATE: - p->l = (int32_t)ME32(p); + p->l = CAST(int32_t, ME32(p)); if (cvt_32(p, m) == -1) goto out; return 1; @@ -1136,7 +1294,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) goto out; return 1; case FILE_BEDOUBLE: - p->q = BE64(p); + p->q = BE64(p); if (cvt_double(p, m) == -1) goto out; return 1; @@ -1152,6 +1310,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); @@ -1227,12 +1386,14 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, || (b = CAST(const char *, memchr(c, '\r', CAST(size_t, (end - c)))))); lines--, b++) { - last = b; if (b < end - 1 && b[0] == '\r' && b[1] == '\n') b++; + if (b < end - 1 && b[0] == '\n') + b++; + last = b; } if (lines) - last = RCAST(const char *, s) + bytecnt; + last = end; ms->search.s = buf; ms->search.s_len = last - buf; @@ -1292,7 +1453,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, * might even cause problems */ if (nbytes < sizeof(*p)) - (void)memset(((char *)(void *)p) + nbytes, '\0', + (void)memset(RCAST(char *, RCAST(void *, p)) + nbytes, '\0', sizeof(*p) - nbytes); return 0; } @@ -1333,16 +1494,64 @@ do_ops(struct magic *m, intmax_t lhs, intmax_t off) if (m->in_op & FILE_OPINVERSE) offset = ~offset; - return (uint32_t)offset; + return CAST(uint32_t, offset); } private int -mget(struct magic_set *ms, const unsigned char *s, struct magic *m, - size_t nbytes, size_t o, unsigned int cont_level, int mode, int text, - int flip, uint16_t *indir_count, uint16_t *name_count, - int *printed_something, int *need_separator, int *returnval) +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) { + if (cont_level > 0) { + if (m->flag & (OFFADD|INDIROFFADD)) + goto normal; +#if 0 + file_error(ms, 0, "negative offset %d at continuation" + "level %u", m->offset, cont_level); + return -1; +#endif + } + if (buffer_fill(b) == -1) + return -1; + if (o != 0) { + // Not yet! + file_magerror(ms, "non zero offset %" SIZE_T_FORMAT + "u at level %u", o, cont_level); + return -1; + } + if (CAST(size_t, -m->offset) > b->elen) + return -1; + buffer_init(bb, -1, NULL, b->ebuf, b->elen); + ms->eoffset = ms->offset = CAST(int32_t, b->elen + m->offset); + } else { + 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->eoffset = 0; + } else { + ms->offset = ms->eoffset + m->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); + } + return 0; +} + +private int +mget(struct magic_set *ms, struct magic *m, const struct buffer *b, + const unsigned char *s, size_t nbytes, size_t o, unsigned int cont_level, + int mode, int text, int flip, uint16_t *indir_count, uint16_t *name_count, + int *printed_something, int *need_separator, int *returnval, + int *found_match) { uint32_t offset = ms->offset; + struct buffer bb; intmax_t lhs; file_pushbuf_t *pb; int rv, oneed_separator, in_type; @@ -1362,8 +1571,10 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, return -1; } - if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o), - (uint32_t)nbytes, m) == -1) + + + if (mcopy(ms, p, m->type, m->flag & INDIR, s, + CAST(uint32_t, offset + o), CAST(uint32_t, nbytes), m) == -1) return -1; if ((ms->flags & MAGIC_DEBUG) != 0) { @@ -1372,7 +1583,8 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, "u, il=%hu, nc=%hu)\n", m->type, m->flag, offset, o, nbytes, *indir_count, *name_count); - mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE)); + mdebug(offset, RCAST(char *, RCAST(void *, p)), + sizeof(union VALUETYPE)); #ifndef COMPILE_ONLY file_mdump(m); #endif @@ -1383,36 +1595,65 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, const int sgn = m->in_op & FILE_OPSIGNED; if (m->in_op & FILE_OPINDIRECT) { const union VALUETYPE *q = CAST(const union VALUETYPE *, - ((const void *)(s + offset + off))); - if (OFFSET_OOB(nbytes, offset + off, sizeof(*q))) - return 0; - switch (cvt_flip(m->in_type, flip)) { + RCAST(const void *, s + offset + off)); + int op; + switch (op = cvt_flip(m->in_type, flip)) { case FILE_BYTE: + if (OFFSET_OOB(nbytes, offset + off, 1)) + return 0; off = SEXT(sgn,8,q->b); break; case FILE_SHORT: + if (OFFSET_OOB(nbytes, offset + off, 2)) + return 0; off = SEXT(sgn,16,q->h); break; case FILE_BESHORT: + if (OFFSET_OOB(nbytes, offset + off, 2)) + return 0; off = SEXT(sgn,16,BE16(q)); break; case FILE_LESHORT: + if (OFFSET_OOB(nbytes, offset + off, 2)) + return 0; off = SEXT(sgn,16,LE16(q)); break; case FILE_LONG: + if (OFFSET_OOB(nbytes, offset + off, 4)) + return 0; off = SEXT(sgn,32,q->l); break; case FILE_BELONG: case FILE_BEID3: + if (OFFSET_OOB(nbytes, offset + off, 4)) + return 0; off = SEXT(sgn,32,BE32(q)); break; case FILE_LEID3: case FILE_LELONG: + if (OFFSET_OOB(nbytes, offset + off, 4)) + return 0; off = SEXT(sgn,32,LE32(q)); break; case FILE_MELONG: + if (OFFSET_OOB(nbytes, offset + off, 4)) + return 0; off = SEXT(sgn,32,ME32(q)); break; + case FILE_BEQUAD: + if (OFFSET_OOB(nbytes, offset + off, 8)) + return 0; + off = SEXT(sgn,64,BE64(q)); + break; + case FILE_LEQUAD: + if (OFFSET_OOB(nbytes, offset + off, 8)) + return 0; + off = SEXT(sgn,64,LE64(q)); + break; + default: + 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); @@ -1444,7 +1685,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, return 0; lhs = BE32(p); if (in_type == FILE_BEID3) - lhs = cvt_id3(ms, (uint32_t)lhs); + lhs = cvt_id3(ms, CAST(uint32_t, lhs)); offset = do_ops(m, SEXT(sgn,32,lhs), off); break; case FILE_LELONG: @@ -1453,7 +1694,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, return 0; lhs = LE32(p); if (in_type == FILE_LEID3) - lhs = cvt_id3(ms, (uint32_t)lhs); + lhs = cvt_id3(ms, CAST(uint32_t, lhs)); offset = do_ops(m, SEXT(sgn,32,lhs), off); break; case FILE_MELONG: @@ -1466,12 +1707,30 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, return 0; offset = do_ops(m, SEXT(sgn,32,p->l), off); break; - default: + case FILE_LEQUAD: + if (OFFSET_OOB(nbytes, offset, 8)) + return 0; + offset = do_ops(m, SEXT(sgn,64,LE64(p)), off); break; + case FILE_BEQUAD: + if (OFFSET_OOB(nbytes, offset, 8)) + return 0; + offset = do_ops(m, SEXT(sgn,64,BE64(p)), off); + break; + default: + 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, @@ -1486,7 +1745,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, ms->offset = offset; if ((ms->flags & MAGIC_DEBUG) != 0) { - mdebug(offset, (char *)(void *)p, + mdebug(offset, RCAST(char *, RCAST(void *, p)), sizeof(union VALUETYPE)); #ifndef COMPILE_ONLY file_mdump(m); @@ -1534,6 +1793,11 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, return 0; break; + case FILE_GUID: + if (OFFSET_OOB(nbytes, offset, 16)) + return 0; + break; + case FILE_STRING: case FILE_PSTRING: case FILE_SEARCH: @@ -1559,7 +1823,10 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, return -1; (*indir_count)++; - rv = file_softmagic(ms, s + offset, nbytes - offset, + bb = *b; + bb.fbuf = s + offset; + bb.flen = nbytes - offset; + rv = file_softmagic(ms, &bb, indir_count, name_count, BINTEST, text); if ((ms->flags & MAGIC_DEBUG) != 0) @@ -1571,7 +1838,8 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, if (rv == 1) { if ((ms->flags & MAGIC_NODESC) == 0 && - file_printf(ms, F(ms, m, "%u"), offset) == -1) { + file_printf(ms, F(ms, m->desc, "%u"), offset) == -1) + { free(rbuf); return -1; } @@ -1599,12 +1867,13 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, oneed_separator = *need_separator; if (m->flag & NOSPACE) *need_separator = 0; - rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o, + rv = match(ms, ml.magic, ml.nmagic, b, offset + o, mode, text, flip, indir_count, name_count, - printed_something, need_separator, returnval); + printed_something, need_separator, returnval, found_match); + (*name_count)--; if (rv != 1) *need_separator = oneed_separator; - return 1; + return rv; case FILE_NAME: if (ms->flags & MAGIC_NODESC) @@ -1632,8 +1901,8 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags) * the ctype functions will work correctly without extra * casting. */ - const unsigned char *a = (const unsigned char *)s1; - const unsigned char *b = (const unsigned char *)s2; + const unsigned char *a = RCAST(const unsigned char *, s1); + const unsigned char *b = RCAST(const unsigned char *, s2); const unsigned char *eb = b + len; uint64_t v; @@ -1828,13 +2097,15 @@ magiccheck(struct magic_set *ms, struct magic *m) case FILE_STRING: case FILE_PSTRING: l = 0; - v = file_strncmp(m->value.s, p->s, (size_t)m->vallen, m->str_flags); + v = file_strncmp(m->value.s, p->s, CAST(size_t, m->vallen), + m->str_flags); break; case FILE_BESTRING16: case FILE_LESTRING16: l = 0; - v = file_strncmp16(m->value.s, p->s, (size_t)m->vallen, m->str_flags); + v = file_strncmp16(m->value.s, p->s, CAST(size_t, m->vallen), + m->str_flags); break; case FILE_SEARCH: { /* search ms->search.s for the string m->value.s */ @@ -1847,6 +2118,22 @@ magiccheck(struct magic_set *ms, struct magic *m) slen = MIN(m->vallen, sizeof(m->value.s)); l = 0; v = 0; +#ifdef HAVE_MEMMEM + if (slen > 0 && m->str_flags == 0) { + const char *found; + idx = m->str_range + slen; + if (m->str_range == 0 || ms->search.s_len < idx) + idx = ms->search.s_len; + found = CAST(const char *, memmem(ms->search.s, idx, + m->value.s, slen)); + if (!found) + return 0; + idx = found - ms->search.s; + ms->search.offset += idx; + ms->search.rm_len = ms->search.s_len - idx; + break; + } +#endif for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) { if (slen + idx > ms->search.s_len) @@ -1876,7 +2163,7 @@ magiccheck(struct magic_set *ms, struct magic *m) ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0)); if (rc) { file_regerror(&rx, rc, ms); - v = (uint64_t)-1; + v = CAST(uint64_t, -1); } else { regmatch_t pmatch; size_t slen = ms->search.s_len; @@ -1897,15 +2184,15 @@ magiccheck(struct magic_set *ms, struct magic *m) search = CCAST(char *, ""); copy = NULL; } - rc = file_regexec(&rx, (const char *)search, + rc = file_regexec(&rx, RCAST(const char *, search), 1, &pmatch, 0); free(copy); switch (rc) { case 0: - ms->search.s += (int)pmatch.rm_so; - ms->search.offset += (size_t)pmatch.rm_so; - ms->search.rm_len = - (size_t)(pmatch.rm_eo - pmatch.rm_so); + ms->search.s += CAST(int, pmatch.rm_so); + ms->search.offset += CAST(size_t, pmatch.rm_so); + ms->search.rm_len = CAST(size_t, + pmatch.rm_eo - pmatch.rm_so); v = 0; break; @@ -1915,12 +2202,12 @@ magiccheck(struct magic_set *ms, struct magic *m) default: file_regerror(&rx, rc, ms); - v = (uint64_t)-1; + v = CAST(uint64_t, -1); break; } } file_regfree(&rx); - if (v == (uint64_t)-1) + if (v == CAST(uint64_t, -1)) return -1; break; } @@ -1938,6 +2225,8 @@ magiccheck(struct magic_set *ms, struct magic *m) return 0; } return matched; + case FILE_GUID: + return memcmp(m->value.guid, p->guid, sizeof(p->guid)) == 0; default: file_magerror(ms, "invalid type %d in magiccheck()", m->type); return -1; @@ -1949,7 +2238,7 @@ magiccheck(struct magic_set *ms, struct magic *m) case 'x': if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%" INT64_T_FORMAT - "u == *any* = 1\n", (unsigned long long)v); + "u == *any* = 1\n", CAST(unsigned long long, v)); matched = 1; break; @@ -1957,16 +2246,18 @@ magiccheck(struct magic_set *ms, struct magic *m) matched = v != l; if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%" INT64_T_FORMAT "u != %" - INT64_T_FORMAT "u = %d\n", (unsigned long long)v, - (unsigned long long)l, matched); + INT64_T_FORMAT "u = %d\n", + CAST(unsigned long long, v), + CAST(unsigned long long, l), matched); break; case '=': matched = v == l; if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%" INT64_T_FORMAT "u == %" - INT64_T_FORMAT "u = %d\n", (unsigned long long)v, - (unsigned long long)l, matched); + INT64_T_FORMAT "u = %d\n", + CAST(unsigned long long, v), + CAST(unsigned long long, l), matched); break; case '>': @@ -1975,15 +2266,16 @@ magiccheck(struct magic_set *ms, struct magic *m) if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%" INT64_T_FORMAT "u > %" INT64_T_FORMAT "u = %d\n", - (unsigned long long)v, - (unsigned long long)l, matched); + CAST(unsigned long long, v), + CAST(unsigned long long, l), matched); } else { - matched = (int64_t) v > (int64_t) l; + matched = CAST(int64_t, v) > CAST(int64_t, l); if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%" INT64_T_FORMAT "d > %" INT64_T_FORMAT "d = %d\n", - (long long)v, (long long)l, matched); + CAST(long long, v), + CAST(long long, l), matched); } break; @@ -1993,15 +2285,16 @@ magiccheck(struct magic_set *ms, struct magic *m) if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%" INT64_T_FORMAT "u < %" INT64_T_FORMAT "u = %d\n", - (unsigned long long)v, - (unsigned long long)l, matched); + CAST(unsigned long long, v), + CAST(unsigned long long, l), matched); } else { - matched = (int64_t) v < (int64_t) l; + matched = CAST(int64_t, v) < CAST(int64_t, l); if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%" INT64_T_FORMAT "d < %" INT64_T_FORMAT "d = %d\n", - (long long)v, (long long)l, matched); + CAST(long long, v), + CAST(long long, l), matched); } break; @@ -2010,8 +2303,9 @@ magiccheck(struct magic_set *ms, struct magic *m) if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %" INT64_T_FORMAT "x) == %" INT64_T_FORMAT - "x) = %d\n", (unsigned long long)v, - (unsigned long long)l, (unsigned long long)l, + "x) = %d\n", CAST(unsigned long long, v), + CAST(unsigned long long, l), + CAST(unsigned long long, l), matched); break; @@ -2020,9 +2314,9 @@ magiccheck(struct magic_set *ms, struct magic *m) if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %" INT64_T_FORMAT "x) != %" INT64_T_FORMAT - "x) = %d\n", (unsigned long long)v, - (unsigned long long)l, (unsigned long long)l, - matched); + "x) = %d\n", CAST(unsigned long long, v), + CAST(unsigned long long, l), + CAST(unsigned long long, l), matched); break; default: @@ -2038,23 +2332,29 @@ private int handle_annotation(struct magic_set *ms, struct magic *m, int firstline) { if ((ms->flags & MAGIC_APPLE) && m->apple[0]) { - if (!firstline && file_printf(ms, "\n- ") == -1) + if (print_sep(ms, firstline) == -1) return -1; if (file_printf(ms, "%.8s", m->apple) == -1) return -1; return 1; } if ((ms->flags & MAGIC_EXTENSION) && m->ext[0]) { - if (!firstline && file_printf(ms, "\n- ") == -1) + if (print_sep(ms, firstline) == -1) return -1; if (file_printf(ms, "%s", m->ext) == -1) return -1; return 1; } if ((ms->flags & MAGIC_MIME_TYPE) && m->mimetype[0]) { - if (!firstline && file_printf(ms, "\n- ") == -1) + char buf[1024]; + const char *p; + if (print_sep(ms, firstline) == -1) return -1; - if (file_printf(ms, "%s", m->mimetype) == -1) + if (varexpand(ms, buf, sizeof(buf), m->mimetype) == -1) + p = m->mimetype; + else + p = buf; + if (file_printf(ms, "%s", p) == -1) return -1; return 1; } @@ -2064,13 +2364,11 @@ handle_annotation(struct magic_set *ms, struct magic *m, int firstline) private int print_sep(struct magic_set *ms, int firstline) { -// if (ms->flags & MAGIC_NODESC) -// return 0; if (firstline) return 0; /* * we found another match * put a newline and '-' to do some simple formatting */ - return file_printf(ms, "\n- "); + return file_separator(ms); } diff --git a/deps/libmagic/src/tar.h b/deps/libmagic/src/tar.h index 854d455..c3d0297 100644 --- a/deps/libmagic/src/tar.h +++ b/deps/libmagic/src/tar.h @@ -32,7 +32,7 @@ * * Created 25 August 1985 by John Gilmore, ihnp4!hoptoad!gnu. * - * $File: tar.h,v 1.13 2010/11/30 14:58:53 rrt Exp $ # checkin only + * $File: tar.h,v 1.12 2008/02/07 00:58:52 christos Exp $ # checkin only */ /* diff --git a/deps/libmagic/src/vasprintf.c b/deps/libmagic/src/vasprintf.c index 9548fd8..49d33d4 100644 --- a/deps/libmagic/src/vasprintf.c +++ b/deps/libmagic/src/vasprintf.c @@ -1,27 +1,653 @@ -// XXX: change by mscdex -// from mingw-w64-crt project +/* + * Copyright (c) Ian F. Darwin 1986-1995. + * Software written by Ian F. Darwin and others; + * maintained 1995-present by Christos Zoulas and others. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/*########################################################################### + # # + # vasprintf # + # # + # Copyright (c) 2002-2005 David TAILLANDIER # + # # + ###########################################################################*/ -#include -#include +/* + +This software is distributed under the "modified BSD licence". + +This software is also released with GNU license (GPL) in another file (same +source-code, only license differ). + + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. Redistributions in binary +form must reproduce the above copyright notice, this list of conditions and +the following disclaimer in the documentation and/or other materials +provided with the distribution. The name of the author may not be used to +endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +==================== + +Hacked from xnprintf version of 26th February 2005 to provide only +vasprintf by Reuben Thomas . + +==================== + + +'printf' function family use the following format string: + +%[flag][width][.prec][modifier]type + +%% is the escape sequence to print a '%' +% followed by an unknown format will print the characters without +trying to do any interpretation + +flag: none + - # (blank) +width: n 0n * +prec: none .0 .n .* +modifier: F N L h l ll z t ('F' and 'N' are ms-dos/16-bit specific) +type: d i o u x X f e g E G c s p n + + +The function needs to allocate memory to store the full text before to +actually writing it. i.e if you want to fnprintf() 1000 characters, the +functions will allocate 1000 bytes. +This behaviour can be modified: you have to customise the code to flush the +internal buffer (writing to screen or file) when it reach a given size. Then +the buffer can have a shorter length. But what? If you really need to write +HUGE string, don't use printf! +During the process, some other memory is allocated (1024 bytes minimum) +to handle the output of partial sprintf() calls. If you have only 10000 bytes +free in memory, you *may* not be able to nprintf() an 8000 bytes-long text. + +note: if a buffer overflow occurs, exit() is called. This situation should +never appear ... but if you want to be *really* sure, you have to modify the +code to handle those situations (only one place to modify). +A buffer overflow can only occur if your sprintf() do strange things or when +you use strange formats. + +*/ +#include "file.h" + +#ifndef lint +FILE_RCSID("@(#)$File: vasprintf.c,v 1.17 2019/11/15 21:03:14 christos Exp $") +#endif /* lint */ + +#include +#include #include -#include - -int vasprintf(char ** ret, const char * format, va_list ap) { - int len; - /* Get Length */ - len = _vsnprintf(NULL, 0, format, ap); - if (len < 0) - return -1; - /* +1 for \0 terminator. */ - *ret = malloc(len + 1); - /* Check malloc fail*/ - if (!*ret) { - errno = ENOMEM; - return -1; - } - /* Write String */ - _vsnprintf(*ret, len + 1, format, ap); - /* Terminate explicitly */ - (*ret)[len] = '\0'; - return len; +#include +#include +#include +#include + +#define ALLOC_CHUNK 2048 +#define ALLOC_SECURITY_MARGIN 1024 /* big value because some platforms have very big 'G' exponent */ +#if ALLOC_CHUNK < ALLOC_SECURITY_MARGIN +# error !!! ALLOC_CHUNK < ALLOC_SECURITY_MARGIN !!! +#endif +/* note: to have some interest, ALLOC_CHUNK should be much greater than ALLOC_SECURITY_MARGIN */ + +/* + * To save a lot of push/pop, every variable are stored into this + * structure, which is passed among nearly every sub-functions. + */ +typedef struct { + const char * src_string; /* current position into intput string */ + char * buffer_base; /* output buffer */ + char * dest_string; /* current position into output string */ + size_t buffer_len; /* length of output buffer */ + size_t real_len; /* real current length of output text */ + size_t pseudo_len; /* total length of output text if it were not limited in size */ + size_t maxlen; + va_list vargs; /* pointer to current position into vargs */ + char * sprintf_string; + FILE * fprintf_file; +} xprintf_struct; + +/* + * Realloc buffer if needed + * Return value: 0 = ok + * EOF = not enought memory + */ +static int realloc_buff(xprintf_struct *s, size_t len) +{ + char * ptr; + + if (len + ALLOC_SECURITY_MARGIN + s->real_len > s->buffer_len) { + len += s->real_len + ALLOC_CHUNK; + ptr = (char *)realloc((void *)(s->buffer_base), len); + if (ptr == NULL) { + s->buffer_base = NULL; + return EOF; + } + + s->dest_string = ptr + (size_t)(s->dest_string - s->buffer_base); + s->buffer_base = ptr; + s->buffer_len = len; + + (s->buffer_base)[s->buffer_len - 1] = 1; /* overflow marker */ + } + + return 0; +} + +/* + * Prints 'usual' characters up to next '%' + * or up to end of text + */ +static int usual_char(xprintf_struct * s) +{ + size_t len; + + len = strcspn(s->src_string, "%"); /* reachs the next '%' or end of input string */ + /* note: 'len' is never 0 because the presence of '%' */ + /* or end-of-line is checked in the calling function */ + + if (realloc_buff(s,len) == EOF) + return EOF; + + memcpy(s->dest_string, s->src_string, len); + s->src_string += len; + s->dest_string += len; + s->real_len += len; + s->pseudo_len += len; + + return 0; +} + +/* + * Return value: 0 = ok + * EOF = error + */ +static int print_it(xprintf_struct *s, size_t approx_len, + const char *format_string, ...) +{ + va_list varg; + int vsprintf_len; + size_t len; + + if (realloc_buff(s,approx_len) == EOF) + return EOF; + + va_start(varg, format_string); + vsprintf_len = vsprintf(s->dest_string, format_string, varg); + va_end(varg); + + /* Check for overflow */ + assert((s->buffer_base)[s->buffer_len - 1] == 1); + + if (vsprintf_len == EOF) /* must be done *after* overflow-check */ + return EOF; + + s->pseudo_len += vsprintf_len; + len = strlen(s->dest_string); + s->real_len += len; + s->dest_string += len; + + return 0; +} + +/* + * Prints a string (%s) + * We need special handling because: + * a: the length of the string is unknown + * b: when .prec is used, we must not access any extra byte of the + * string (of course, if the original sprintf() does... what the + * hell, not my problem) + * + * Return value: 0 = ok + * EOF = error + */ +static int type_s(xprintf_struct *s, int width, int prec, + const char *format_string, const char *arg_string) +{ + size_t string_len; + + if (arg_string == NULL) + return print_it(s, (size_t)6, "(null)", 0); + + /* hand-made strlen() whitch stops when 'prec' is reached. */ + /* if 'prec' is -1 then it is never reached. */ + string_len = 0; + while (arg_string[string_len] != 0 && (size_t)prec != string_len) + string_len++; + + if (width != -1 && string_len < (size_t)width) + string_len = (size_t)width; + + return print_it(s, string_len, format_string, arg_string); +} + +/* + * Read a serie of digits. Stop when non-digit is found. + * Return value: the value read (between 0 and 32767). + * Note: no checks are made against overflow. If the string contain a big + * number, then the return value won't be what we want (but, in this case, + * the programmer don't know whatr he wants, then no problem). + */ +static int getint(const char **string) +{ + int i = 0; + + while (isdigit((unsigned char)**string) != 0) { + i = i * 10 + (**string - '0'); + (*string)++; + } + + if (i < 0 || i > 32767) + i = 32767; /* if we have i==-10 this is not because the number is */ + /* negative; this is because the number is big */ + return i; +} + +/* + * Read a part of the format string. A part is 'usual characters' (ie "blabla") + * or '%%' escape sequence (to print a single '%') or any combination of + * format specifier (ie "%i" or "%10.2d"). + * After the current part is managed, the function returns to caller with + * everything ready to manage the following part. + * The caller must ensure than the string is not empty, i.e. the first byte + * is not zero. + * + * Return value: 0 = ok + * EOF = error + */ +static int dispatch(xprintf_struct *s) +{ + const char *initial_ptr; + char format_string[24]; /* max length may be something like "% +-#032768.32768Ld" */ + char *format_ptr; + int flag_plus, flag_minus, flag_space, flag_sharp, flag_zero; + int width, prec, modifier, approx_width; + char type; + /* most of those variables are here to rewrite the format string */ + +#define SRCTXT (s->src_string) +#define DESTTXT (s->dest_string) + + /* incoherent format string. Characters after the '%' will be printed with the next call */ +#define INCOHERENT() do {SRCTXT=initial_ptr; return 0;} while (0) /* do/while to avoid */ +#define INCOHERENT_TEST() do {if(*SRCTXT==0) INCOHERENT();} while (0) /* a null statement */ + + /* 'normal' text */ + if (*SRCTXT != '%') + return usual_char(s); + + /* we then have a '%' */ + SRCTXT++; + /* don't check for end-of-string ; this is done later */ + + /* '%%' escape sequence */ + if (*SRCTXT == '%') { + if (realloc_buff(s, (size_t)1) == EOF) /* because we can have "%%%%%%%%..." */ + return EOF; + *DESTTXT = '%'; + DESTTXT++; + SRCTXT++; + (s->real_len)++; + (s->pseudo_len)++; + return 0; + } + + /* '%' managing */ + initial_ptr = SRCTXT; /* save current pointer in case of incorrect */ + /* 'decoding'. Points just after the '%' so the '%' */ + /* won't be printed in any case, as required. */ + + /* flag */ + flag_plus = flag_minus = flag_space = flag_sharp = flag_zero = 0; + + for (;; SRCTXT++) { + if (*SRCTXT == ' ') + flag_space = 1; + else if (*SRCTXT == '+') + flag_plus = 1; + else if (*SRCTXT == '-') + flag_minus = 1; + else if (*SRCTXT == '#') + flag_sharp = 1; + else if (*SRCTXT == '0') + flag_zero = 1; + else + break; + } + + INCOHERENT_TEST(); /* here is the first test for end of string */ + + /* width */ + if (*SRCTXT == '*') { /* width given by next argument */ + SRCTXT++; + width = va_arg(s->vargs, int); + if ((size_t)width > 0x3fffU) /* 'size_t' to check against negative values too */ + width = 0x3fff; + } else if (isdigit((unsigned char)*SRCTXT)) /* width given as ASCII number */ + width = getint(&SRCTXT); + else + width = -1; /* no width specified */ + + INCOHERENT_TEST(); + + /* .prec */ + if (*SRCTXT == '.') { + SRCTXT++; + if (*SRCTXT == '*') { /* .prec given by next argument */ + SRCTXT++; + prec = va_arg(s->vargs, int); + if ((size_t)prec >= 0x3fffU) /* 'size_t' to check against negative values too */ + prec = 0x3fff; + } else { /* .prec given as ASCII number */ + if (isdigit((unsigned char)*SRCTXT) == 0) + INCOHERENT(); + prec = getint(&SRCTXT); + } + INCOHERENT_TEST(); + } else + prec = -1; /* no .prec specified */ + + /* modifier */ + switch (*SRCTXT) { + case 'L': + case 'h': + case 'l': + case 'z': + case 't': + modifier = *SRCTXT; + SRCTXT++; + if (modifier=='l' && *SRCTXT=='l') { + SRCTXT++; + modifier = 'L'; /* 'll' == 'L' long long == long double */ + } /* only for compatibility ; not portable */ + INCOHERENT_TEST(); + break; + default: + modifier = -1; /* no modifier specified */ + break; + } + + /* type */ + type = *SRCTXT; + if (strchr("diouxXfegEGcspn",type) == NULL) + INCOHERENT(); /* unknown type */ + SRCTXT++; + + /* rewrite format-string */ + format_string[0] = '%'; + format_ptr = &(format_string[1]); + + if (flag_plus) { + *format_ptr = '+'; + format_ptr++; + } + if (flag_minus) { + *format_ptr = '-'; + format_ptr++; + } + if (flag_space) { + *format_ptr = ' '; + format_ptr++; + } + if (flag_sharp) { + *format_ptr = '#'; + format_ptr++; + } + if (flag_zero) { + *format_ptr = '0'; + format_ptr++; + } /* '0' *must* be the last one */ + + if (width != -1) { + sprintf(format_ptr, "%i", width); + format_ptr += strlen(format_ptr); + } + + if (prec != -1) { + *format_ptr = '.'; + format_ptr++; + sprintf(format_ptr, "%i", prec); + format_ptr += strlen(format_ptr); + } + + if (modifier != -1) { + if (modifier == 'L' && strchr("diouxX",type) != NULL) { + *format_ptr = 'l'; + format_ptr++; + *format_ptr = 'l'; + format_ptr++; + } else { + *format_ptr = modifier; + format_ptr++; + } + } + + *format_ptr = type; + format_ptr++; + *format_ptr = 0; + + /* vague approximation of minimal length if width or prec are specified */ + approx_width = width + prec; + if (approx_width < 0) /* because width == -1 and/or prec == -1 */ + approx_width = 0; + + switch (type) { + /* int */ + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + switch (modifier) { + case -1 : + return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, int)); + case 'L': + return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, long long int)); + case 'l': + return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, long int)); + case 'h': + return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, int)); + case 'z': + return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, size_t)); + case 't': + return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, ptrdiff_t)); + /* 'int' instead of 'short int' because default promotion is 'int' */ + default: + INCOHERENT(); + } + + /* char */ + case 'c': + if (modifier != -1) + INCOHERENT(); + return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, int)); + /* 'int' instead of 'char' because default promotion is 'int' */ + + /* math */ + case 'e': + case 'f': + case 'g': + case 'E': + case 'G': + switch (modifier) { + case -1 : /* because of default promotion, no modifier means 'l' */ + case 'l': + return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, double)); + case 'L': + return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, long double)); + default: + INCOHERENT(); + } + + /* string */ + case 's': + return type_s(s, width, prec, format_string, va_arg(s->vargs, const char*)); + + /* pointer */ + case 'p': + if (modifier == -1) + return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, void *)); + INCOHERENT(); + + /* store */ + case 'n': + if (modifier == -1) { + int * p; + p = va_arg(s->vargs, int *); + if (p != NULL) { + *p = s->pseudo_len; + return 0; + } + return EOF; + } + INCOHERENT(); + + } /* switch */ + + INCOHERENT(); /* unknown type */ + +#undef INCOHERENT +#undef INCOHERENT_TEST +#undef SRCTXT +#undef DESTTXT +} + +/* + * Return value: number of *virtually* written characters + * EOF = error + */ +static int core(xprintf_struct *s) +{ + size_t save_len; + char *dummy_base; + + /* basic checks */ + if ((int)(s->maxlen) <= 0) /* 'int' to check against some conversion */ + return EOF; /* error for example if value is (int)-10 */ + s->maxlen--; /* because initial maxlen counts final 0 */ + /* note: now 'maxlen' _can_ be zero */ + + if (s->src_string == NULL) + s->src_string = "(null)"; + + /* struct init and memory allocation */ + s->buffer_base = NULL; + s->buffer_len = 0; + s->real_len = 0; + s->pseudo_len = 0; + if (realloc_buff(s, (size_t)0) == EOF) + return EOF; + s->dest_string = s->buffer_base; + + /* process source string */ + for (;;) { + /* up to end of source string */ + if (*(s->src_string) == 0) { + *(s->dest_string) = '\0'; /* final NUL */ + break; + } + + if (dispatch(s) == EOF) + goto free_EOF; + + /* up to end of dest string */ + if (s->real_len >= s->maxlen) { + (s->buffer_base)[s->maxlen] = '\0'; /* final NUL */ + break; + } + } + + /* for (v)asnprintf */ + dummy_base = s->buffer_base; + + dummy_base = s->buffer_base + s->real_len; + save_len = s->real_len; + + /* process the remaining of source string to compute 'pseudo_len'. We + * overwrite again and again, starting at 'dummy_base' because we don't + * need the text, only char count. */ + while(*(s->src_string) != 0) { /* up to end of source string */ + s->real_len = 0; + s->dest_string = dummy_base; + if (dispatch(s) == EOF) + goto free_EOF; + } + + s->buffer_base = (char *)realloc((void *)(s->buffer_base), save_len + 1); + if (s->buffer_base == NULL) + return EOF; /* should rarely happen because we shrink the buffer */ + return s->pseudo_len; + + free_EOF: + free(s->buffer_base); + return EOF; +} + +int vasprintf(char **ptr, const char *format_string, va_list vargs) +{ + xprintf_struct s; + int retval; + + s.src_string = format_string; +#ifdef va_copy + va_copy (s.vargs, vargs); +#else +# ifdef __va_copy + __va_copy (s.vargs, vargs); +# else +# ifdef WIN32 + s.vargs = vargs; +# else + memcpy (&s.vargs, &vargs, sizeof (s.va_args)); +# endif /* WIN32 */ +# endif /* __va_copy */ +#endif /* va_copy */ + s.maxlen = (size_t)INT_MAX; + + retval = core(&s); + va_end(s.vargs); + if (retval == EOF) { + *ptr = NULL; + return EOF; + } + + *ptr = s.buffer_base; + return retval; } diff --git a/magic/magic.mgc b/magic/magic.mgc index 2fdc46d0a66f6f1c3599434d6ff69c508b87f2cb..ad4a53f3321c55b7c92a04febe3d6ed7e8e25cac 100644 GIT binary patch delta 351908 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 z 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 +*4NLbFPF9kikq1*}_@R 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

D{qEUmDi1}Cy~PPk4> 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 LlVNY+??G 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

L6Gfs7xk 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 From 51ad6176bc5ebf139e921afad40182ccbed7f82f Mon Sep 17 00:00:00 2001 From: Vlad Seryakov Date: Wed, 27 Mar 2024 14:08:26 -0400 Subject: [PATCH 2/2] fix Sonoma compilation, bump minor --- binding.gyp | 6 +++--- package.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/binding.gyp b/binding.gyp index 8280a81..be3593e 100644 --- a/binding.gyp +++ b/binding.gyp @@ -18,12 +18,12 @@ 'dependencies': [ 'deps/libmagic/libmagic.gyp:libmagic', ], - 'conditions': [ + '_conditions': [ ['OS=="mac"', { 'xcode_settings': { - 'MACOSX_DEPLOYMENT_TARGET': '10.7', + 'MACOSX_DEPLOYMENT_TARGET': '10.15', 'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0', - 'CLANG_CXX_LANGUAGE_STANDARD': 'gnu++1y', # -std=gnu++1y + 'CLANG_CXX_LANGUAGE_STANDARD': 'c++17', # -std=gnu++1y 'CLANG_CXX_LIBRARY': 'libc++', } }], diff --git a/package.json b/package.json index 68a8afa..af649d2 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,18 @@ { "name": "mmmagic", - "version": "0.5.3", + "version": "0.5.4", "author": "Brian White ", "description": "An async libmagic binding for node.js for detecting content types by data inspection", "main": "./lib/index", "dependencies": { - "nan": "^2.13.2" + "nan": "^2.17.0" }, "scripts": { "install": "node-gyp rebuild", "test": "node test/test.js" }, "engines": { - "node": ">=4.0.0" + "node": ">=20.0.0" }, "keywords": [ "magic",