Update libmagic to 5.45 (#13369)

* Update libmagic to 5.45

This also cleans up magicdata.patch: changes that are already in upstream file
were removed from that patch file.

There are five (expected) test output changes.
All these were also checked with the file command.

  - bug77961.phpt changes because there's now an early error-return in the
    `if (ts == FILE_BADSIZE) {` branch.
  - cve-2014-1943.phpt and cve-2014-1943-mb.phpt change because now the crafted
    data is recognised as a simh file.
  - bug71434.phpt now properly recognises it as a Python file.
  - ext/fileinfo/tests/finfo_file_basic.phpt more specific mime type.

* Adjust memory requirement for s390x fileinfo run

The larger database causes a higher memory usage.
Similar to 962c082a5b.

* [ci skip] NEWS
This commit is contained in:
Niels Dossche 2024-02-13 21:11:57 +01:00 committed by GitHub
parent 686916652e
commit b7c5813c98
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 213163 additions and 177632 deletions

3
NEWS
View file

@ -32,6 +32,9 @@ PHP NEWS
. Handle OOM more consistently. (nielsdos) . Handle OOM more consistently. (nielsdos)
. Implemented "Improve callbacks in ext/dom and ext/xsl" RFC. (nielsdos) . Implemented "Improve callbacks in ext/dom and ext/xsl" RFC. (nielsdos)
- Fileinfo:
. Update to libmagic 5.45. (nielsdos)
- FPM: - FPM:
. Implement GH-12385 (flush headers without body when calling flush()). . Implement GH-12385 (flush headers without body when calling flush()).
(nielsdos) (nielsdos)

View file

@ -10,7 +10,7 @@ if test "$PHP_FILEINFO" != "no"; then
libmagic/apprentice.c libmagic/apptype.c libmagic/ascmagic.c \ libmagic/apprentice.c libmagic/apptype.c libmagic/ascmagic.c \
libmagic/cdf.c libmagic/cdf_time.c libmagic/compress.c \ libmagic/cdf.c libmagic/cdf_time.c libmagic/compress.c \
libmagic/encoding.c libmagic/fsmagic.c libmagic/funcs.c \ libmagic/encoding.c libmagic/fsmagic.c libmagic/funcs.c \
libmagic/is_json.c libmagic/is_tar.c libmagic/magic.c libmagic/print.c \ libmagic/is_json.c libmagic/is_tar.c libmagic/is_simh.c libmagic/magic.c libmagic/print.c \
libmagic/readcdf.c libmagic/softmagic.c libmagic/der.c \ libmagic/readcdf.c libmagic/softmagic.c libmagic/der.c \
libmagic/buffer.c libmagic/is_csv.c" libmagic/buffer.c libmagic/is_csv.c"

View file

@ -6,7 +6,7 @@ if (PHP_FILEINFO != 'no') {
LIBMAGIC_SOURCES=" apprentice.c apptype.c ascmagic.c \ LIBMAGIC_SOURCES=" apprentice.c apptype.c ascmagic.c \
cdf.c cdf_time.c compress.c \ cdf.c cdf_time.c compress.c \
encoding.c fsmagic.c funcs.c \ encoding.c fsmagic.c funcs.c \
is_json.c is_tar.c magic.c print.c \ is_json.c is_tar.c is_simh.c magic.c print.c \
readcdf.c softmagic.c der.c \ readcdf.c softmagic.c der.c \
strcasestr.c buffer.c is_csv.c"; strcasestr.c buffer.c is_csv.c";

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
VERSION=5.43 VERSION=5.45
if [[ ! -d libmagic.orig ]]; then if [[ ! -d libmagic.orig ]]; then
mkdir libmagic.orig mkdir libmagic.orig
wget -O - ftp://ftp.astron.com/pub/file/file-$VERSION.tar.gz \ wget -O - ftp://ftp.astron.com/pub/file/file-$VERSION.tar.gz \

File diff suppressed because it is too large Load diff

View file

@ -32,7 +32,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: apprentice.c,v 1.326 2022/09/13 18:46:07 christos Exp $") FILE_RCSID("@(#)$File: apprentice.c,v 1.342 2023/07/17 14:38:35 christos Exp $")
#endif /* lint */ #endif /* lint */
#include "magic.h" #include "magic.h"
@ -114,25 +114,24 @@ const size_t file_nformats = FILE_NAMES_SIZE;
const char *file_names[FILE_NAMES_SIZE]; const char *file_names[FILE_NAMES_SIZE];
const size_t file_nnames = FILE_NAMES_SIZE; const size_t file_nnames = FILE_NAMES_SIZE;
private int getvalue(struct magic_set *ms, struct magic *, const char **, int); file_private int getvalue(struct magic_set *ms, struct magic *, const char **, int);
private int hextoint(int); file_private int hextoint(int);
private const char *getstr(struct magic_set *, struct magic *, const char *, file_private const char *getstr(struct magic_set *, struct magic *, const char *,
int); int);
private int parse(struct magic_set *, struct magic_entry *, const char *, file_private int parse(struct magic_set *, struct magic_entry *, const char *,
size_t, int); size_t, int);
private void eatsize(const char **); file_private void eatsize(const char **);
private int apprentice_1(struct magic_set *, const char *, int); file_private int apprentice_1(struct magic_set *, const char *, int);
private ssize_t apprentice_magic_strength_1(const struct magic *); file_private ssize_t apprentice_magic_strength_1(const struct magic *);
private size_t apprentice_magic_strength(const struct magic *, size_t); file_private int apprentice_sort(const void *, const void *);
private int apprentice_sort(const void *, const void *); file_private void apprentice_list(struct mlist *, int );
private void apprentice_list(struct mlist *, int ); file_private struct magic_map *apprentice_load(struct magic_set *,
private struct magic_map *apprentice_load(struct magic_set *,
const char *, int); const char *, int);
private struct mlist *mlist_alloc(void); file_private struct mlist *mlist_alloc(void);
private void mlist_free_all(struct magic_set *); file_private void mlist_free_all(struct magic_set *);
private void mlist_free(struct mlist *); file_private void mlist_free(struct mlist *);
private void byteswap(struct magic *, uint32_t); file_private void byteswap(struct magic *, uint32_t);
private void bs1(struct magic *); file_private void bs1(struct magic *);
#if defined(HAVE_BYTESWAP_H) #if defined(HAVE_BYTESWAP_H)
#define swap2(x) bswap_16(x) #define swap2(x) bswap_16(x)
@ -143,34 +142,34 @@ private void bs1(struct magic *);
#define swap4(x) bswap32(x) #define swap4(x) bswap32(x)
#define swap8(x) bswap64(x) #define swap8(x) bswap64(x)
#else #else
private uint16_t swap2(uint16_t); file_private uint16_t swap2(uint16_t);
private uint32_t swap4(uint32_t); file_private uint32_t swap4(uint32_t);
private uint64_t swap8(uint64_t); file_private uint64_t swap8(uint64_t);
#endif #endif
private char *mkdbname(struct magic_set *, const char *, int); file_private char *mkdbname(struct magic_set *, const char *, int);
private struct magic_map *apprentice_map(struct magic_set *, const char *); file_private struct magic_map *apprentice_map(struct magic_set *, const char *);
private void apprentice_unmap(struct magic_map *); file_private void apprentice_unmap(struct magic_map *);
private int apprentice_compile(struct magic_set *, struct magic_map *, file_private int apprentice_compile(struct magic_set *, struct magic_map *,
const char *); const char *);
private int check_format_type(const char *, int, const char **); file_private int check_format_type(const char *, int, const char **);
private int check_format(struct magic_set *, struct magic *); file_private int check_format(struct magic_set *, struct magic *);
private int get_op(char); file_private int get_op(char);
private int parse_mime(struct magic_set *, struct magic_entry *, const char *, file_private int parse_mime(struct magic_set *, struct magic_entry *, const char *,
size_t); size_t);
private int parse_strength(struct magic_set *, struct magic_entry *, file_private int parse_strength(struct magic_set *, struct magic_entry *,
const char *, size_t); const char *, size_t);
private int parse_apple(struct magic_set *, struct magic_entry *, const char *, file_private int parse_apple(struct magic_set *, struct magic_entry *, const char *,
size_t); size_t);
private int parse_ext(struct magic_set *, struct magic_entry *, const char *, file_private int parse_ext(struct magic_set *, struct magic_entry *, const char *,
size_t); size_t);
private size_t magicsize = sizeof(struct magic); file_private size_t magicsize = sizeof(struct magic);
private const char usg_hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc"; file_private const char usg_hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc";
private struct { file_private struct {
const char *name; const char *name;
size_t len; size_t len;
int (*fun)(struct magic_set *, struct magic_entry *, const char *, int (*fun)(struct magic_set *, struct magic_entry *, const char *,
@ -314,7 +313,7 @@ static const struct type_tbl_s special_tbl[] = {
# undef XX # undef XX
# undef XX_NULL # undef XX_NULL
private int file_private int
get_type(const struct type_tbl_s *tbl, const char *l, const char **t) get_type(const struct type_tbl_s *tbl, const char *l, const char **t)
{ {
const struct type_tbl_s *p; const struct type_tbl_s *p;
@ -329,7 +328,7 @@ get_type(const struct type_tbl_s *tbl, const char *l, const char **t)
return p->type; return p->type;
} }
private off_t file_private off_t
maxoff_t(void) { maxoff_t(void) {
if (/*CONSTCOND*/sizeof(off_t) == sizeof(int)) if (/*CONSTCOND*/sizeof(off_t) == sizeof(int))
return CAST(off_t, INT_MAX); return CAST(off_t, INT_MAX);
@ -338,7 +337,7 @@ maxoff_t(void) {
return 0x7fffffff; return 0x7fffffff;
} }
private int file_private int
get_standard_integer_type(const char *l, const char **t) get_standard_integer_type(const char *l, const char **t)
{ {
int type; int type;
@ -423,7 +422,7 @@ get_standard_integer_type(const char *l, const char **t)
return type; return type;
} }
private void file_private void
init_file_tables(void) init_file_tables(void)
{ {
static int done = 0; static int done = 0;
@ -441,7 +440,7 @@ init_file_tables(void)
assert(p - type_tbl == FILE_NAMES_SIZE); assert(p - type_tbl == FILE_NAMES_SIZE);
} }
private int file_private int
add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx) add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx)
{ {
struct mlist *ml; struct mlist *ml;
@ -464,12 +463,11 @@ add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx)
/* /*
* Handle one file or directory. * Handle one file or directory.
*/ */
private int file_private int
apprentice_1(struct magic_set *ms, const char *fn, int action) apprentice_1(struct magic_set *ms, const char *fn, int action)
{ {
struct magic_map *map; struct magic_map *map;
#ifndef COMPILE_ONLY #ifndef COMPILE_ONLY
struct mlist *ml;
size_t i; size_t i;
#endif #endif
@ -491,7 +489,7 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
map = apprentice_map(ms, fn); map = apprentice_map(ms, fn);
if (map == NULL) { if (map == NULL) {
if (ms->flags & MAGIC_CHECK) if (ms->flags & MAGIC_CHECK)
file_magwarn(ms, "using regular magic file `%s'", fn); file_magwarn(NULL, "using regular magic file `%s'", fn);
map = apprentice_load(ms, fn, action); map = apprentice_load(ms, fn, action);
if (map == NULL) if (map == NULL)
return -1; return -1;
@ -504,7 +502,7 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
apprentice_unmap(map); apprentice_unmap(map);
else else
mlist_free_all(ms); mlist_free_all(ms);
file_oomem(ms, sizeof(*ml)); file_oomem(ms, sizeof(*ms->mlist[0]));
return -1; return -1;
} }
} }
@ -524,7 +522,7 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
#endif /* COMPILE_ONLY */ #endif /* COMPILE_ONLY */
} }
protected void file_protected void
file_ms_free(struct magic_set *ms) file_ms_free(struct magic_set *ms)
{ {
size_t i; size_t i;
@ -547,14 +545,14 @@ file_ms_free(struct magic_set *ms)
efree(ms); efree(ms);
} }
protected struct magic_set * file_protected struct magic_set *
file_ms_alloc(int flags) file_ms_alloc(int flags)
{ {
struct magic_set *ms; struct magic_set *ms;
size_t i, len; size_t i, len;
if ((ms = CAST(struct magic_set *, ecalloc(CAST(size_t, 1u), if ((ms = CAST(struct magic_set *, ecalloc(CAST(size_t, 1u),
sizeof(struct magic_set)))) == NULL) sizeof(*ms)))) == NULL)
return NULL; return NULL;
if (magic_setflags(ms, flags) == -1) { if (magic_setflags(ms, flags) == -1) {
@ -578,6 +576,7 @@ file_ms_alloc(int flags)
ms->indir_max = FILE_INDIR_MAX; ms->indir_max = FILE_INDIR_MAX;
ms->name_max = FILE_NAME_MAX; ms->name_max = FILE_NAME_MAX;
ms->elf_shnum_max = FILE_ELF_SHNUM_MAX; ms->elf_shnum_max = FILE_ELF_SHNUM_MAX;
ms->elf_shsize_max = FILE_ELF_SHSIZE_MAX;
ms->elf_phnum_max = FILE_ELF_PHNUM_MAX; ms->elf_phnum_max = FILE_ELF_PHNUM_MAX;
ms->elf_notes_max = FILE_ELF_NOTES_MAX; ms->elf_notes_max = FILE_ELF_NOTES_MAX;
ms->regex_max = FILE_REGEX_MAX; ms->regex_max = FILE_REGEX_MAX;
@ -589,11 +588,11 @@ file_ms_alloc(int flags)
#endif #endif
return ms; return ms;
free: free:
free(ms); efree(ms);
return NULL; return NULL;
} }
private void file_private void
apprentice_unmap(struct magic_map *map) apprentice_unmap(struct magic_map *map)
{ {
if (map == NULL) if (map == NULL)
@ -613,7 +612,7 @@ apprentice_unmap(struct magic_map *map)
efree(map); efree(map);
} }
private struct mlist * file_private struct mlist *
mlist_alloc(void) mlist_alloc(void)
{ {
struct mlist *mlist; struct mlist *mlist;
@ -624,7 +623,7 @@ mlist_alloc(void)
return mlist; return mlist;
} }
private void file_private void
mlist_free_all(struct magic_set *ms) mlist_free_all(struct magic_set *ms)
{ {
size_t i; size_t i;
@ -635,7 +634,7 @@ mlist_free_all(struct magic_set *ms)
} }
} }
private void file_private void
mlist_free_one(struct mlist *ml) mlist_free_one(struct mlist *ml)
{ {
if (ml->map) if (ml->map)
@ -643,7 +642,7 @@ mlist_free_one(struct mlist *ml)
efree(ml); efree(ml);
} }
private void file_private void
mlist_free(struct mlist *mlist) mlist_free(struct mlist *mlist)
{ {
struct mlist *ml, *next; struct mlist *ml, *next;
@ -660,7 +659,7 @@ mlist_free(struct mlist *mlist)
} }
/* const char *fn: list of magic files and directories */ /* const char *fn: list of magic files and directories */
protected int file_protected int
file_apprentice(struct magic_set *ms, const char *fn, int action) file_apprentice(struct magic_set *ms, const char *fn, int action)
{ {
char *p, *mfn; char *p, *mfn;
@ -698,7 +697,7 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
for (i = 0; i < MAGIC_SETS; i++) { for (i = 0; i < MAGIC_SETS; i++) {
mlist_free(ms->mlist[i]); mlist_free(ms->mlist[i]);
if ((ms->mlist[i] = mlist_alloc()) == NULL) { if ((ms->mlist[i] = mlist_alloc()) == NULL) {
file_oomem(ms, sizeof(*ms->mlist[i])); file_oomem(ms, sizeof(*ms->mlist[0]));
for (j = 0; j < i; j++) { for (j = 0; j < i; j++) {
mlist_free(ms->mlist[j]); mlist_free(ms->mlist[j]);
ms->mlist[j] = NULL; ms->mlist[j] = NULL;
@ -766,7 +765,7 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
* - regular characters or escaped magic characters count 1 * - regular characters or escaped magic characters count 1
* - 0 length expressions count as one * - 0 length expressions count as one
*/ */
private size_t file_private size_t
nonmagic(const char *str) nonmagic(const char *str)
{ {
const char *p; const char *p;
@ -806,7 +805,7 @@ nonmagic(const char *str)
} }
private size_t file_private size_t
typesize(int type) typesize(int type)
{ {
switch (type) { switch (type) {
@ -876,7 +875,7 @@ typesize(int type)
/* /*
* Get weight of this magic entry, for sorting purposes. * Get weight of this magic entry, for sorting purposes.
*/ */
private ssize_t file_private ssize_t
apprentice_magic_strength_1(const struct magic *m) apprentice_magic_strength_1(const struct magic *m)
{ {
#define MULT 10U #define MULT 10U
@ -886,8 +885,8 @@ apprentice_magic_strength_1(const struct magic *m)
switch (m->type) { switch (m->type) {
case FILE_DEFAULT: /* make sure this sorts last */ case FILE_DEFAULT: /* make sure this sorts last */
if (m->factor_op != FILE_FACTOR_OP_NONE) { if (m->factor_op != FILE_FACTOR_OP_NONE) {
fprintf(stderr, "Bad factor_op %d", m->factor_op); file_magwarn(NULL, "Usupported factor_op in default %d",
abort(); m->factor_op);
} }
return 0; return 0;
@ -1013,8 +1012,8 @@ apprentice_magic_strength_1(const struct magic *m)
/*ARGSUSED*/ /*ARGSUSED*/
private size_t file_protected size_t
apprentice_magic_strength(const struct magic *m, file_magic_strength(const struct magic *m,
size_t nmagic __attribute__((__unused__))) size_t nmagic __attribute__((__unused__)))
{ {
ssize_t val = apprentice_magic_strength_1(m); ssize_t val = apprentice_magic_strength_1(m);
@ -1074,13 +1073,13 @@ apprentice_magic_strength(const struct magic *m,
/* /*
* Sort callback for sorting entries by "strength" (basically length) * Sort callback for sorting entries by "strength" (basically length)
*/ */
private int file_private int
apprentice_sort(const void *a, const void *b) apprentice_sort(const void *a, const void *b)
{ {
const struct magic_entry *ma = CAST(const struct magic_entry *, a); const struct magic_entry *ma = CAST(const struct magic_entry *, a);
const struct magic_entry *mb = CAST(const struct magic_entry *, b); const struct magic_entry *mb = CAST(const struct magic_entry *, b);
size_t sa = apprentice_magic_strength(ma->mp, ma->cont_count); size_t sa = file_magic_strength(ma->mp, ma->cont_count);
size_t sb = apprentice_magic_strength(mb->mp, mb->cont_count); size_t sb = file_magic_strength(mb->mp, mb->cont_count);
if (sa == sb) if (sa == sb)
return 0; return 0;
else if (sa > sb) else if (sa > sb)
@ -1092,7 +1091,7 @@ apprentice_sort(const void *a, const void *b)
/* /*
* Shows sorted patterns list in the order which is used for the matching * Shows sorted patterns list in the order which is used for the matching
*/ */
private void file_private void
apprentice_list(struct mlist *mlist, int mode) apprentice_list(struct mlist *mlist, int mode)
{ {
uint32_t magindex, descindex, mimeindex, lineindex; uint32_t magindex, descindex, mimeindex, lineindex;
@ -1113,18 +1112,20 @@ apprentice_list(struct mlist *mlist, int mode)
* description/mimetype. * description/mimetype.
*/ */
lineindex = descindex = mimeindex = magindex; lineindex = descindex = mimeindex = magindex;
for (magindex++; magindex < ml->nmagic && for (; magindex + 1 < ml->nmagic &&
ml->magic[magindex].cont_level != 0; magindex++) { ml->magic[magindex + 1].cont_level != 0;
magindex++) {
uint32_t mi = magindex + 1;
if (*ml->magic[descindex].desc == '\0' if (*ml->magic[descindex].desc == '\0'
&& *ml->magic[magindex].desc) && *ml->magic[mi].desc)
descindex = magindex; descindex = mi;
if (*ml->magic[mimeindex].mimetype == '\0' if (*ml->magic[mimeindex].mimetype == '\0'
&& *ml->magic[magindex].mimetype) && *ml->magic[mi].mimetype)
mimeindex = magindex; mimeindex = mi;
} }
printf("Strength = %3" SIZE_T_FORMAT "u@%u: %s [%s]\n", printf("Strength = %3" SIZE_T_FORMAT "u@%u: %s [%s]\n",
apprentice_magic_strength(m, ml->nmagic - magindex), file_magic_strength(m, ml->nmagic - magindex),
ml->magic[lineindex].lineno, ml->magic[lineindex].lineno,
ml->magic[descindex].desc, ml->magic[descindex].desc,
ml->magic[mimeindex].mimetype); ml->magic[mimeindex].mimetype);
@ -1132,7 +1133,7 @@ apprentice_list(struct mlist *mlist, int mode)
} }
} }
private void file_private void
set_test_type(struct magic *mstart, struct magic *m) set_test_type(struct magic *mstart, struct magic *m)
{ {
switch (m->type) { switch (m->type) {
@ -1223,7 +1224,7 @@ set_test_type(struct magic *mstart, struct magic *m)
} }
} }
private int file_private int
addentry(struct magic_set *ms, struct magic_entry *me, addentry(struct magic_set *ms, struct magic_entry *me,
struct magic_entry_set *mset) struct magic_entry_set *mset)
{ {
@ -1252,7 +1253,7 @@ addentry(struct magic_set *ms, struct magic_entry *me,
/* /*
* Load and parse one file. * Load and parse one file.
*/ */
private void file_private void
load_1(struct magic_set *ms, int action, const char *fn, int *errs, load_1(struct magic_set *ms, int action, const char *fn, int *errs,
struct magic_entry_set *mset) struct magic_entry_set *mset)
{ {
@ -1345,14 +1346,14 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
* parse a file or directory of files * parse a file or directory of files
* const char *fn: name of magic file or directory * const char *fn: name of magic file or directory
*/ */
private int file_private int
cmpstrp(const void *p1, const void *p2) cmpstrp(const void *p1, const void *p2)
{ {
return strcmp(*RCAST(char *const *, p1), *RCAST(char *const *, p2)); return strcmp(*RCAST(char *const *, p1), *RCAST(char *const *, p2));
} }
private uint32_t file_private uint32_t
set_text_binary(struct magic_set *ms, struct magic_entry *me, uint32_t nme, set_text_binary(struct magic_set *ms, struct magic_entry *me, uint32_t nme,
uint32_t starttest) uint32_t starttest)
{ {
@ -1385,7 +1386,7 @@ set_text_binary(struct magic_set *ms, struct magic_entry *me, uint32_t nme,
return i; return i;
} }
private void file_private void
set_last_default(struct magic_set *ms, struct magic_entry *me, uint32_t nme) set_last_default(struct magic_set *ms, struct magic_entry *me, uint32_t nme)
{ {
uint32_t i; uint32_t i;
@ -1406,7 +1407,7 @@ set_last_default(struct magic_set *ms, struct magic_entry *me, uint32_t nme)
} }
} }
private int file_private int
coalesce_entries(struct magic_set *ms, struct magic_entry *me, uint32_t nme, coalesce_entries(struct magic_set *ms, struct magic_entry *me, uint32_t nme,
struct magic **ma, uint32_t *nma) struct magic **ma, uint32_t *nma)
{ {
@ -1438,7 +1439,7 @@ coalesce_entries(struct magic_set *ms, struct magic_entry *me, uint32_t nme,
return 0; return 0;
} }
private void file_private void
magic_entry_free(struct magic_entry *me, uint32_t nme) magic_entry_free(struct magic_entry *me, uint32_t nme)
{ {
uint32_t i; uint32_t i;
@ -1449,7 +1450,7 @@ magic_entry_free(struct magic_entry *me, uint32_t nme)
efree(me); efree(me);
} }
private struct magic_map * file_private struct magic_map *
apprentice_load(struct magic_set *ms, const char *fn, int action) apprentice_load(struct magic_set *ms, const char *fn, int action)
{ {
int errs = 0; int errs = 0;
@ -1539,7 +1540,7 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
i = set_text_binary(ms, mset[j].me, mset[j].count, i); i = set_text_binary(ms, mset[j].me, mset[j].count, i);
} }
if (mset[j].me) if (mset[j].me)
qsort(mset[j].me, mset[j].count, sizeof(*mset[j].me), qsort(mset[j].me, mset[j].count, sizeof(*mset[0].me),
apprentice_sort); apprentice_sort);
/* /*
@ -1573,7 +1574,7 @@ out:
/* /*
* extend the sign bit if the comparison is to be signed * extend the sign bit if the comparison is to be signed
*/ */
protected uint64_t file_protected uint64_t
file_signextend(struct magic_set *ms, struct magic *m, uint64_t v) file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
{ {
if (!(m->flag & UNSIGNED)) { if (!(m->flag & UNSIGNED)) {
@ -1659,7 +1660,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
return v; return v;
} }
private int file_private int
string_modifier_check(struct magic_set *ms, struct magic *m) string_modifier_check(struct magic_set *ms, struct magic *m)
{ {
if ((ms->flags & MAGIC_CHECK) == 0) if ((ms->flags & MAGIC_CHECK) == 0)
@ -1718,7 +1719,7 @@ string_modifier_check(struct magic_set *ms, struct magic *m)
return 0; return 0;
} }
private int file_private int
get_op(char c) get_op(char c)
{ {
switch (c) { switch (c) {
@ -1744,7 +1745,7 @@ get_op(char c)
} }
#ifdef ENABLE_CONDITIONALS #ifdef ENABLE_CONDITIONALS
private int file_private int
get_cond(const char *l, const char **t) get_cond(const char *l, const char **t)
{ {
static const struct cond_tbl_s { static const struct cond_tbl_s {
@ -1770,7 +1771,7 @@ get_cond(const char *l, const char **t)
return p->cond; return p->cond;
} }
private int file_private int
check_cond(struct magic_set *ms, int cond, uint32_t cont_level) check_cond(struct magic_set *ms, int cond, uint32_t cont_level)
{ {
int last_cond; int last_cond;
@ -1814,7 +1815,7 @@ check_cond(struct magic_set *ms, int cond, uint32_t cont_level)
} }
#endif /* ENABLE_CONDITIONALS */ #endif /* ENABLE_CONDITIONALS */
private int file_private int
parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp) parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp)
{ {
const char *l = *lp; const char *l = *lp;
@ -1835,7 +1836,7 @@ parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp)
return 0; return 0;
} }
private void file_private void
parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp, parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp,
int op) int op)
{ {
@ -1852,7 +1853,7 @@ parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp,
*lp = l; *lp = l;
} }
private int file_private int
parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp) parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp)
{ {
const char *l = *lp; const char *l = *lp;
@ -1959,7 +1960,7 @@ out:
/* /*
* parse one line from magic file, put into magic[index++] if valid * parse one line from magic file, put into magic[index++] if valid
*/ */
private int file_private int
parse(struct magic_set *ms, struct magic_entry *me, const char *line, parse(struct magic_set *ms, struct magic_entry *me, const char *line,
size_t lineno, int action) size_t lineno, int action)
{ {
@ -2376,13 +2377,14 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
* if valid * if valid
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
private int file_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__))) size_t len __attribute__((__unused__)))
{ {
const char *l = line; const char *l = line;
char *el; char *el;
unsigned long factor; unsigned long factor;
char sbuf[512];
struct magic *m = &me->mp[0]; struct magic *m = &me->mp[0];
if (m->factor_op != FILE_FACTOR_OP_NONE) { if (m->factor_op != FILE_FACTOR_OP_NONE) {
@ -2393,12 +2395,15 @@ parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line,
} }
if (m->type == FILE_NAME) { if (m->type == FILE_NAME) {
file_magwarn(ms, "%s: Strength setting is not supported in " file_magwarn(ms, "%s: Strength setting is not supported in "
"\"name\" magic entries", m->value.s); "\"name\" magic entries",
file_printable(ms, sbuf, sizeof(sbuf), m->value.s,
sizeof(m->value.s)));
return -1; return -1;
} }
EATAB; EATAB;
switch (*l) { switch (*l) {
case FILE_FACTOR_OP_NONE: case FILE_FACTOR_OP_NONE:
break;
case FILE_FACTOR_OP_PLUS: case FILE_FACTOR_OP_PLUS:
case FILE_FACTOR_OP_MINUS: case FILE_FACTOR_OP_MINUS:
case FILE_FACTOR_OP_TIMES: case FILE_FACTOR_OP_TIMES:
@ -2432,15 +2437,16 @@ out:
return -1; return -1;
} }
private int file_private int
goodchar(unsigned char x, const char *extra) goodchar(unsigned char x, const char *extra)
{ {
return (isascii(x) && isalnum(x)) || strchr(extra, x); return (isascii(x) && isalnum(x)) || strchr(extra, x);
} }
private int file_private int
parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line, parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
size_t llen, zend_off_t off, size_t len, const char *name, const char *extra, int nt) size_t llen, zend_off_t off, size_t len, const char *name, const char *extra,
int nt)
{ {
size_t i; size_t i;
const char *l = line; const char *l = line;
@ -2490,7 +2496,7 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
* Parse an Apple CREATOR/TYPE annotation from magic file and put it into * Parse an Apple CREATOR/TYPE annotation from magic file and put it into
* magic[index - 1] * magic[index - 1]
*/ */
private int file_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) size_t len)
{ {
@ -2502,20 +2508,22 @@ parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line,
/* /*
* Parse a comma-separated list of extensions * Parse a comma-separated list of extensions
*/ */
private int file_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) size_t len)
{ {
return parse_extra(ms, me, line, len, return parse_extra(ms, me, line, len,
CAST(off_t, offsetof(struct magic, ext)), CAST(off_t, offsetof(struct magic, ext)),
sizeof(me->mp[0].ext), "EXTENSION", ",!+-/@?_$&", 0); /* & for b&w */ sizeof(me->mp[0].ext), "EXTENSION", ",!+-/@?_$&~", 0);
/* & for b&w */
/* ~ for journal~ */
} }
/* /*
* parse a MIME annotation line from magic file, put into magic[index - 1] * parse a MIME annotation line from magic file, put into magic[index - 1]
* if valid * if valid
*/ */
private int file_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) size_t len)
{ {
@ -2524,7 +2532,7 @@ parse_mime(struct magic_set *ms, struct magic_entry *me, const char *line,
sizeof(me->mp[0].mimetype), "MIME", "+-/.$?:{}", 1); sizeof(me->mp[0].mimetype), "MIME", "+-/.$?:{}", 1);
} }
private int file_private int
check_format_type(const char *ptr, int type, const char **estr) check_format_type(const char *ptr, int type, const char **estr)
{ {
int quad = 0, h; int quad = 0, h;
@ -2708,6 +2716,7 @@ check_format_type(const char *ptr, int type, const char **estr)
} }
invalid: invalid:
*estr = "not valid"; *estr = "not valid";
return -1;
toolong: toolong:
*estr = "too long"; *estr = "too long";
return -1; return -1;
@ -2717,7 +2726,7 @@ toolong:
* Check that the optional printf format in description matches * Check that the optional printf format in description matches
* the type of the magic. * the type of the magic.
*/ */
private int file_private int
check_format(struct magic_set *ms, struct magic *m) check_format(struct magic_set *ms, struct magic *m)
{ {
char *ptr; char *ptr;
@ -2773,11 +2782,12 @@ check_format(struct magic_set *ms, struct magic *m)
* pointer, according to the magic type. Update the string pointer to point * 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. * just after the number read. Return 0 for success, non-zero for failure.
*/ */
private int file_private int
getvalue(struct magic_set *ms, struct magic *m, const char **p, int action) getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
{ {
char *ep; char *ep;
uint64_t ull; uint64_t ull;
int y;
switch (m->type) { switch (m->type) {
case FILE_BESTRING16: case FILE_BESTRING16:
@ -2851,6 +2861,7 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
m->value.q = file_signextend(ms, m, ull); m->value.q = file_signextend(ms, m, ull);
if (*p == ep) { if (*p == ep) {
file_magwarn(ms, "Unparsable number `%s'", *p); file_magwarn(ms, "Unparsable number `%s'", *p);
return -1;
} else { } else {
size_t ts = typesize(m->type); size_t ts = typesize(m->type);
uint64_t x; uint64_t x;
@ -2860,32 +2871,38 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
file_magwarn(ms, file_magwarn(ms,
"Expected numeric type got `%s'", "Expected numeric type got `%s'",
type_tbl[m->type].name); type_tbl[m->type].name);
return -1;
} }
for (q = *p; isspace(CAST(unsigned char, *q)); q++) for (q = *p; isspace(CAST(unsigned char, *q)); q++)
continue; continue;
if (*q == '-') if (*q == '-' && ull != UINT64_MAX)
ull = -CAST(int64_t, ull); ull = -CAST(int64_t, ull);
switch (ts) { switch (ts) {
case 1: case 1:
x = CAST(uint64_t, ull & ~0xffULL); x = CAST(uint64_t, ull & ~0xffULL);
y = (x & ~0xffULL) != ~0xffULL;
break; break;
case 2: case 2:
x = CAST(uint64_t, ull & ~0xffffULL); x = CAST(uint64_t, ull & ~0xffffULL);
y = (x & ~0xffffULL) != ~0xffffULL;
break; break;
case 4: case 4:
x = CAST(uint64_t, ull & ~0xffffffffULL); x = CAST(uint64_t, ull & ~0xffffffffULL);
y = (x & ~0xffffffffULL) != ~0xffffffffULL;
break; break;
case 8: case 8:
x = 0; x = 0;
y = 0;
break; break;
default: default:
fprintf(stderr, "Bad width %zu", ts); fprintf(stderr, "Bad width %zu", ts);
abort(); abort();
} }
if (x) { if (x && y) {
file_magwarn(ms, "Overflow for numeric" file_magwarn(ms, "Overflow for numeric"
" type `%s' value %#" PRIx64, " type `%s' value %#" PRIx64,
type_tbl[m->type].name, ull); type_tbl[m->type].name, ull);
return -1;
} }
} }
if (errno == 0) { if (errno == 0) {
@ -2902,7 +2919,7 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
* Copy the converted version to "m->value.s", and the length in m->vallen. * Copy the converted version to "m->value.s", and the length in m->vallen.
* Return updated scan pointer as function result. Warn if set. * Return updated scan pointer as function result. Warn if set.
*/ */
private const char * file_private const char *
getstr(struct magic_set *ms, struct magic *m, const char *s, int warn) getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
{ {
const char *origs = s; const char *origs = s;
@ -3080,7 +3097,7 @@ out:
/* Single hex char to int; -1 if not a hex char. */ /* Single hex char to int; -1 if not a hex char. */
private int file_private int
hextoint(int c) hextoint(int c)
{ {
if (!isascii(CAST(unsigned char, c))) if (!isascii(CAST(unsigned char, c)))
@ -3098,7 +3115,7 @@ hextoint(int c)
/* /*
* Print a string containing C character escapes. * Print a string containing C character escapes.
*/ */
protected void file_protected void
file_showstr(FILE *fp, const char *s, size_t len) file_showstr(FILE *fp, const char *s, size_t len)
{ {
char c; char c;
@ -3158,7 +3175,7 @@ file_showstr(FILE *fp, const char *s, size_t len)
/* /*
* eatsize(): Eat the size spec from a number [eg. 10UL] * eatsize(): Eat the size spec from a number [eg. 10UL]
*/ */
private void file_private void
eatsize(const char **p) eatsize(const char **p)
{ {
const char *l = *p; const char *l = *p;
@ -3185,7 +3202,7 @@ eatsize(const char **p)
* handle a compiled file. * handle a compiled file.
*/ */
private struct magic_map * file_private struct magic_map *
apprentice_map(struct magic_set *ms, const char *fn) apprentice_map(struct magic_set *ms, const char *fn)
{ {
uint32_t *ptr; uint32_t *ptr;
@ -3331,7 +3348,7 @@ error:
/* /*
* handle an mmaped file. * handle an mmaped file.
*/ */
private int file_private int
apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn) apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn)
{ {
static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS; static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS;
@ -3385,11 +3402,11 @@ out:
return rv; return rv;
} }
private const char ext[] = ".mgc"; file_private const char ext[] = ".mgc";
/* /*
* make a dbname * make a dbname
*/ */
private char * file_private char *
mkdbname(struct magic_set *ms, const char *fn, int strip) mkdbname(struct magic_set *ms, const char *fn, int strip)
{ {
const char *p, *q; const char *p, *q;
@ -3437,7 +3454,7 @@ mkdbname(struct magic_set *ms, const char *fn, int strip)
/* /*
* Byteswap an mmap'ed file if needed * Byteswap an mmap'ed file if needed
*/ */
private void file_private void
byteswap(struct magic *magic, uint32_t nmagic) byteswap(struct magic *magic, uint32_t nmagic)
{ {
uint32_t i; uint32_t i;
@ -3449,7 +3466,7 @@ byteswap(struct magic *magic, uint32_t nmagic)
/* /*
* swap a short * swap a short
*/ */
private uint16_t file_private uint16_t
swap2(uint16_t sv) swap2(uint16_t sv)
{ {
uint16_t rv; uint16_t rv;
@ -3463,7 +3480,7 @@ swap2(uint16_t sv)
/* /*
* swap an int * swap an int
*/ */
private uint32_t file_private uint32_t
swap4(uint32_t sv) swap4(uint32_t sv)
{ {
uint32_t rv; uint32_t rv;
@ -3479,7 +3496,7 @@ swap4(uint32_t sv)
/* /*
* swap a quad * swap a quad
*/ */
private uint64_t file_private uint64_t
swap8(uint64_t sv) swap8(uint64_t sv)
{ {
uint64_t rv; uint64_t rv;
@ -3508,7 +3525,7 @@ swap8(uint64_t sv)
} }
#endif #endif
protected uintmax_t file_protected uintmax_t
file_varint2uintmax_t(const unsigned char *us, int t, size_t *l) file_varint2uintmax_t(const unsigned char *us, int t, size_t *l)
{ {
uintmax_t x = 0; uintmax_t x = 0;
@ -3541,7 +3558,7 @@ file_varint2uintmax_t(const unsigned char *us, int t, size_t *l)
/* /*
* byteswap a single magic entry * byteswap a single magic entry
*/ */
private void file_private void
bs1(struct magic *m) bs1(struct magic *m)
{ {
m->cont_level = swap2(m->cont_level); m->cont_level = swap2(m->cont_level);
@ -3558,7 +3575,7 @@ bs1(struct magic *m)
} }
} }
protected size_t file_protected size_t
file_pstring_length_size(struct magic_set *ms, const struct magic *m) file_pstring_length_size(struct magic_set *ms, const struct magic *m)
{ {
switch (m->str_flags & PSTRING_LEN) { switch (m->str_flags & PSTRING_LEN) {
@ -3577,7 +3594,7 @@ file_pstring_length_size(struct magic_set *ms, const struct magic *m)
return FILE_BADSIZE; return FILE_BADSIZE;
} }
} }
protected size_t file_protected size_t
file_pstring_get_length(struct magic_set *ms, const struct magic *m, file_pstring_get_length(struct magic_set *ms, const struct magic *m,
const char *ss) const char *ss)
{ {
@ -3630,7 +3647,7 @@ file_pstring_get_length(struct magic_set *ms, const struct magic *m,
return len; return len;
} }
protected int file_protected int
file_magicfind(struct magic_set *ms, const char *name, struct mlist *v) file_magicfind(struct magic_set *ms, const char *name, struct mlist *v)
{ {
uint32_t i, j; uint32_t i, j;

View file

@ -1,6 +1,6 @@
/* /*
* Adapted from: apptype.c, Written by Eberhard Mattes and put into the * Adapted from: apptype.c, Written by Eberhard Mattes and put into the
* public domain * file_public domain
* *
* Notes: 1. Qualify the filename so that DosQueryAppType does not do extraneous * Notes: 1. Qualify the filename so that DosQueryAppType does not do extraneous
* searches. * searches.
@ -27,7 +27,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: apptype.c,v 1.14 2018/09/09 20:33:28 christos Exp $") FILE_RCSID("@(#)$File: apptype.c,v 1.17 2022/12/26 17:31:14 christos Exp $")
#endif /* lint */ #endif /* lint */
#include <stdlib.h> #include <stdlib.h>
@ -41,7 +41,7 @@ FILE_RCSID("@(#)$File: apptype.c,v 1.14 2018/09/09 20:33:28 christos Exp $")
#include <os2.h> #include <os2.h>
typedef ULONG APPTYPE; typedef ULONG APPTYPE;
protected int file_protected int
file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf, file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf,
size_t nb) size_t nb)
{ {
@ -116,7 +116,7 @@ file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf,
return -1; return -1;
} else if (type & FAPPTYP_DLL) { } else if (type & FAPPTYP_DLL) {
if (type & FAPPTYP_PROTDLL) if (type & FAPPTYP_PROTDLL)
if (file_printf(ms, "protected ") == -1) if (file_printf(ms, "file_protected ") == -1)
return -1; return -1;
if (file_printf(ms, "DLL") == -1) if (file_printf(ms, "DLL") == -1)
return -1; return -1;

View file

@ -35,7 +35,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: ascmagic.c,v 1.110 2021/12/06 15:33:00 christos Exp $") FILE_RCSID("@(#)$File: ascmagic.c,v 1.116 2023/05/21 16:08:50 christos Exp $")
#endif /* lint */ #endif /* lint */
#include "magic.h" #include "magic.h"
@ -50,15 +50,15 @@ FILE_RCSID("@(#)$File: ascmagic.c,v 1.110 2021/12/06 15:33:00 christos Exp $")
#define ISSPC(x) ((x) == ' ' || (x) == '\t' || (x) == '\r' || (x) == '\n' \ #define ISSPC(x) ((x) == ' ' || (x) == '\t' || (x) == '\r' || (x) == '\n' \
|| (x) == 0x85 || (x) == '\f') || (x) == 0x85 || (x) == '\f')
private unsigned char *encode_utf8(unsigned char *, size_t, file_unichar_t *, file_private unsigned char *encode_utf8(unsigned char *, size_t, file_unichar_t *,
size_t); size_t);
private size_t trim_nuls(const unsigned char *, size_t); file_private size_t trim_nuls(const unsigned char *, size_t);
/* /*
* Undo the NUL-termination kindly provided by process() * Undo the NUL-termination kindly provided by process()
* but leave at least one byte to look at * but leave at least one byte to look at
*/ */
private size_t file_private size_t
trim_nuls(const unsigned char *buf, size_t nbytes) trim_nuls(const unsigned char *buf, size_t nbytes)
{ {
while (nbytes > 1 && buf[nbytes - 1] == '\0') while (nbytes > 1 && buf[nbytes - 1] == '\0')
@ -67,7 +67,7 @@ trim_nuls(const unsigned char *buf, size_t nbytes)
return nbytes; return nbytes;
} }
protected int file_protected int
file_ascmagic(struct magic_set *ms, const struct buffer *b, int text) file_ascmagic(struct magic_set *ms, const struct buffer *b, int text)
{ {
file_unichar_t *ubuf = NULL; file_unichar_t *ubuf = NULL;
@ -101,7 +101,7 @@ file_ascmagic(struct magic_set *ms, const struct buffer *b, int text)
return rv; return rv;
} }
protected int file_protected int
file_ascmagic_with_encoding(struct magic_set *ms, const struct buffer *b, file_ascmagic_with_encoding(struct magic_set *ms, const struct buffer *b,
file_unichar_t *ubuf, size_t ulen, const char *code, const char *type, file_unichar_t *ubuf, size_t ulen, const char *code, const char *type,
int text) int text)
@ -121,10 +121,10 @@ file_ascmagic_with_encoding(struct magic_set *ms, const struct buffer *b,
int has_backspace = 0; int has_backspace = 0;
int seen_cr = 0; int seen_cr = 0;
int n_crlf = 0; size_t n_crlf = 0;
int n_lf = 0; size_t n_lf = 0;
int n_cr = 0; size_t n_cr = 0;
int n_nel = 0; size_t n_nel = 0;
int executable = 0; int executable = 0;
size_t last_line_end = CAST(size_t, -1); size_t last_line_end = CAST(size_t, -1);
@ -148,8 +148,10 @@ file_ascmagic_with_encoding(struct magic_set *ms, const struct buffer *b,
goto done; goto done;
} }
if ((utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen)) if ((utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen))
== NULL) == NULL) {
rv = 0;
goto done; goto done;
}
buffer_init(&bb, b->fd, &b->st, utf8_buf, buffer_init(&bb, b->fd, &b->st, utf8_buf,
CAST(size_t, utf8_end - utf8_buf)); CAST(size_t, utf8_end - utf8_buf));
@ -203,13 +205,6 @@ file_ascmagic_with_encoding(struct magic_set *ms, const struct buffer *b,
has_backspace = 1; has_backspace = 1;
} }
/* Beware, if the data has been truncated, the final CR could have
been followed by a LF. If we have ms->bytes_max bytes, it indicates
that the data might have been truncated, probably even before
this function was called. */
if (seen_cr && nbytes < ms->bytes_max)
n_cr++;
if (strcmp(type, "binary") == 0) { if (strcmp(type, "binary") == 0) {
rv = 0; rv = 0;
goto done; goto done;
@ -228,10 +223,9 @@ file_ascmagic_with_encoding(struct magic_set *ms, const struct buffer *b,
} }
if (need_separator && file_separator(ms) == -1) if (need_separator && file_separator(ms) == -1)
goto done; goto done;
} else {
if (file_printf(ms, "text/plain") == -1)
goto done;
} }
if (file_printf(ms, "text/plain") == -1)
goto done;
} }
} else { } else {
if (len) { if (len) {
@ -340,7 +334,7 @@ done:
* Encode Unicode string as UTF-8, returning pointer to character * Encode Unicode string as UTF-8, returning pointer to character
* after end of string, or NULL if an invalid character is found. * after end of string, or NULL if an invalid character is found.
*/ */
private unsigned char * file_private unsigned char *
encode_utf8(unsigned char *buf, size_t len, file_unichar_t *ubuf, size_t ulen) encode_utf8(unsigned char *buf, size_t len, file_unichar_t *ubuf, size_t ulen)
{ {
size_t i; size_t i;

View file

@ -27,7 +27,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: buffer.c,v 1.8 2020/02/16 15:52:49 christos Exp $") FILE_RCSID("@(#)$File: buffer.c,v 1.13 2023/07/02 12:48:39 christos Exp $")
#endif /* lint */ #endif /* lint */
#include "magic.h" #include "magic.h"
@ -58,6 +58,8 @@ void
buffer_fini(struct buffer *b) buffer_fini(struct buffer *b)
{ {
efree(b->ebuf); efree(b->ebuf);
b->ebuf = NULL;
b->elen = 0;
} }
int int
@ -71,8 +73,13 @@ buffer_fill(const struct buffer *bb)
if (!S_ISREG(b->st.st_mode)) if (!S_ISREG(b->st.st_mode))
goto out; goto out;
b->elen = CAST(size_t, b->st.st_size) < b->flen ? b->elen = CAST(size_t, b->st.st_size) < b->flen ?
CAST(size_t, b->st.st_size) : b->flen; CAST(size_t, b->st.st_size) : b->flen;
if (b->elen == 0) {
efree(b->ebuf);
b->ebuf = NULL;
return 0;
}
if ((b->ebuf = emalloc(b->elen)) == NULL) if ((b->ebuf = emalloc(b->elen)) == NULL)
goto out; goto out;

View file

@ -35,7 +35,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: cdf.c,v 1.121 2021/10/20 13:56:15 christos Exp $") FILE_RCSID("@(#)$File: cdf.c,v 1.123 2022/09/24 20:30:13 christos Exp $")
#endif #endif
#include <assert.h> #include <assert.h>

View file

@ -27,7 +27,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: cdf_time.c,v 1.20 2021/12/06 15:33:00 christos Exp $") FILE_RCSID("@(#)$File: cdf_time.c,v 1.24 2023/07/17 15:54:44 christos Exp $")
#endif #endif
#include <time.h> #include <time.h>
@ -157,7 +157,7 @@ cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timespec *ts)
return -1; return -1;
} }
*t = (ts->ts_nsec / 100) * CDF_TIME_PREC; *t = (ts->ts_nsec / 100) * CDF_TIME_PREC;
*t = tm.tm_sec; *t += tm.tm_sec;
*t += tm.tm_min * 60; *t += tm.tm_min * 60;
*t += tm.tm_hour * 60 * 60; *t += tm.tm_hour * 60 * 60;
*t += tm.tm_mday * 60 * 60 * 24; *t += tm.tm_mday * 60 * 60 * 24;
@ -168,7 +168,7 @@ cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timespec *ts)
char * char *
cdf_ctime(const time_t *sec, char *buf) cdf_ctime(const time_t *sec, char *buf)
{ {
char *ptr = ctime_r(sec, buf); char *ptr = *sec > MAX_CTIME ? NULL : ctime_r(sec, buf);
if (ptr != NULL) if (ptr != NULL)
return buf; return buf;
#ifdef WIN32 #ifdef WIN32

View file

@ -35,7 +35,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: compress.c,v 1.136 2022/09/13 16:08:34 christos Exp $") FILE_RCSID("@(#)$File: compress.c,v 1.157 2023/05/21 15:59:58 christos Exp $")
#endif #endif
#include "magic.h" #include "magic.h"
@ -80,6 +80,17 @@ typedef void (*sig_t)(int);
#include <lzma.h> #include <lzma.h>
#endif #endif
#if defined(HAVE_ZSTD_H) && defined(ZSTDLIBSUPPORT)
#define BUILTIN_ZSTDLIB
#include <zstd.h>
#include <zstd_errors.h>
#endif
#if defined(HAVE_LZLIB_H) && defined(LZLIBSUPPORT)
#define BUILTIN_LZLIB
#include <lzlib.h>
#endif
#ifdef DEBUG #ifdef DEBUG
int tty = -1; int tty = -1;
#define DPRINTF(...) do { \ #define DPRINTF(...) do { \
@ -135,7 +146,6 @@ lzmacmp(const unsigned char *buf)
} }
#define gzip_flags "-cd" #define gzip_flags "-cd"
#define lrzip_flags "-do"
#define lzip_flags gzip_flags #define lzip_flags gzip_flags
static const char *gzip_args[] = { static const char *gzip_args[] = {
@ -154,7 +164,7 @@ static const char *xz_args[] = {
"xz", "-cd", NULL "xz", "-cd", NULL
}; };
static const char *lrzip_args[] = { static const char *lrzip_args[] = {
"lrzip", lrzip_flags, NULL "lrzip", "-qdf", "-", NULL
}; };
static const char *lz4_args[] = { static const char *lz4_args[] = {
"lz4", "-cd", NULL "lz4", "-cd", NULL
@ -166,7 +176,7 @@ static const char *zstd_args[] = {
#define do_zlib NULL #define do_zlib NULL
#define do_bzlib NULL #define do_bzlib NULL
private const struct { file_private const struct {
union { union {
const char *magic; const char *magic;
int (*func)(const unsigned char *); int (*func)(const unsigned char *);
@ -178,6 +188,8 @@ private const struct {
#define METH_FROZEN 2 #define METH_FROZEN 2
#define METH_BZIP 7 #define METH_BZIP 7
#define METH_XZ 9 #define METH_XZ 9
#define METH_LZIP 8
#define METH_ZSTD 12
#define METH_LZMA 13 #define METH_LZMA 13
#define METH_ZLIB 14 #define METH_ZLIB 14
{ { .magic = "\037\235" }, 2, gzip_args, NULL }, /* 0, compressed */ { { .magic = "\037\235" }, 2, gzip_args, NULL }, /* 0, compressed */
@ -207,31 +219,39 @@ private const struct {
#define NODATA 1 #define NODATA 1
#define ERRDATA 2 #define ERRDATA 2
private ssize_t swrite(int, const void *, size_t); file_private ssize_t swrite(int, const void *, size_t);
#if HAVE_FORK #if HAVE_FORK
private size_t ncompr = __arraycount(compr); file_private size_t ncompr = __arraycount(compr);
private int uncompressbuf(int, size_t, size_t, const unsigned char *, file_private int uncompressbuf(int, size_t, size_t, int, const unsigned char *,
unsigned char **, size_t *); unsigned char **, size_t *);
#ifdef BUILTIN_DECOMPRESS #ifdef BUILTIN_DECOMPRESS
private int uncompresszlib(const unsigned char *, unsigned char **, size_t, file_private int uncompresszlib(const unsigned char *, unsigned char **, size_t,
size_t *, int);
file_private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
size_t *, int); size_t *, int);
private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
size_t *);
#endif #endif
#ifdef BUILTIN_BZLIB #ifdef BUILTIN_BZLIB
private int uncompressbzlib(const unsigned char *, unsigned char **, size_t, file_private int uncompressbzlib(const unsigned char *, unsigned char **, size_t,
size_t *); size_t *, int);
#endif #endif
#ifdef BUILTIN_XZLIB #ifdef BUILTIN_XZLIB
private int uncompressxzlib(const unsigned char *, unsigned char **, size_t, file_private int uncompressxzlib(const unsigned char *, unsigned char **, size_t,
size_t *); size_t *, int);
#endif
#ifdef BUILTIN_ZSTDLIB
file_private int uncompresszstd(const unsigned char *, unsigned char **, size_t,
size_t *, int);
#endif
#ifdef BUILTIN_LZLIB
file_private int uncompresslzlib(const unsigned char *, unsigned char **, size_t,
size_t *, int);
#endif #endif
static int makeerror(unsigned char **, size_t *, const char *, ...) static int makeerror(unsigned char **, size_t *, const char *, ...)
__attribute__((__format__(__printf__, 3, 4))); __attribute__((__format__(__printf__, 3, 4)));
private const char *methodname(size_t); file_private const char *methodname(size_t);
private int file_private int
format_decompression_error(struct magic_set *ms, size_t i, unsigned char *buf) format_decompression_error(struct magic_set *ms, size_t i, unsigned char *buf)
{ {
unsigned char *p; unsigned char *p;
@ -248,7 +268,7 @@ format_decompression_error(struct magic_set *ms, size_t i, unsigned char *buf)
methodname(i), buf); methodname(i), buf);
} }
protected int file_protected int
file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name) file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
{ {
unsigned char *newbuf = NULL; unsigned char *newbuf = NULL;
@ -290,7 +310,9 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
} }
nsz = nbytes; nsz = nbytes;
urv = uncompressbuf(fd, ms->bytes_max, i, buf, &newbuf, &nsz); efree(newbuf);
urv = uncompressbuf(fd, ms->bytes_max, i,
(ms->flags & MAGIC_NO_COMPRESS_FORK), buf, &newbuf, &nsz);
DPRINTF("uncompressbuf = %d, %s, %" SIZE_T_FORMAT "u\n", urv, DPRINTF("uncompressbuf = %d, %s, %" SIZE_T_FORMAT "u\n", urv,
(char *)newbuf, nsz); (char *)newbuf, nsz);
switch (urv) { switch (urv) {
@ -300,7 +322,8 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
if (urv == ERRDATA) if (urv == ERRDATA)
prv = format_decompression_error(ms, i, newbuf); prv = format_decompression_error(ms, i, newbuf);
else else
prv = file_buffer(ms, NULL, NULL, name, newbuf, nsz); prv = file_buffer(ms, NULL, NULL, name, newbuf,
nsz);
if (prv == -1) if (prv == -1)
goto error; goto error;
rv = 1; rv = 1;
@ -317,7 +340,8 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
* XXX: If file_buffer fails here, we overwrite * XXX: If file_buffer fails here, we overwrite
* the compressed text. FIXME. * the compressed text. FIXME.
*/ */
if (file_buffer(ms, NULL, NULL, NULL, buf, nbytes) == -1) { if (file_buffer(ms, NULL, NULL, NULL, buf, nbytes) == -1)
{
if (file_pop_buffer(ms, pb) != NULL) if (file_pop_buffer(ms, pb) != NULL)
abort(); abort();
goto error; goto error;
@ -358,7 +382,7 @@ out:
/* /*
* `safe' write for sockets and pipes. * `safe' write for sockets and pipes.
*/ */
private ssize_t file_private ssize_t
swrite(int fd, const void *buf, size_t n) swrite(int fd, const void *buf, size_t n)
{ {
ssize_t rv; ssize_t rv;
@ -383,11 +407,11 @@ swrite(int fd, const void *buf, size_t n)
/* /*
* `safe' read for sockets and pipes. * `safe' read for sockets and pipes.
*/ */
protected ssize_t file_protected ssize_t
sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__))) sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
{ {
ssize_t rv; ssize_t rv;
#ifdef FIONREAD #if defined(FIONREAD) && !defined(__MINGW32__)
int t = 0; int t = 0;
#endif #endif
size_t rn = n; size_t rn = n;
@ -395,7 +419,7 @@ sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
if (fd == STDIN_FILENO) if (fd == STDIN_FILENO)
goto nocheck; goto nocheck;
#ifdef FIONREAD #if defined(FIONREAD) && !defined(__MINGW32__)
if (canbepipe && (ioctl(fd, FIONREAD, &t) == -1 || t == 0)) { if (canbepipe && (ioctl(fd, FIONREAD, &t) == -1 || t == 0)) {
#ifdef FD_ZERO #ifdef FD_ZERO
ssize_t cnt; ssize_t cnt;
@ -448,7 +472,7 @@ nocheck:
return rn; return rn;
} }
protected int file_protected int
file_pipe2file(struct magic_set *ms, int fd, const void *startbuf, file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
size_t nbytes) size_t nbytes)
{ {
@ -540,13 +564,19 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
#define FCOMMENT (1 << 4) #define FCOMMENT (1 << 4)
private int file_private int
uncompressgzipped(const unsigned char *old, unsigned char **newch, uncompressgzipped(const unsigned char *old, unsigned char **newch,
size_t bytes_max, size_t *n) size_t bytes_max, size_t *n, int extra __attribute__((__unused__)))
{ {
unsigned char flg = old[3]; unsigned char flg;
size_t data_start = 10; size_t data_start = 10;
if (*n < 4) {
goto err;
}
flg = old[3];
if (flg & FEXTRA) { if (flg & FEXTRA) {
if (data_start + 1 >= *n) if (data_start + 1 >= *n)
goto err; goto err;
@ -575,16 +605,14 @@ err:
return makeerror(newch, n, "File too short"); return makeerror(newch, n, "File too short");
} }
private int file_private int
uncompresszlib(const unsigned char *old, unsigned char **newch, uncompresszlib(const unsigned char *old, unsigned char **newch,
size_t bytes_max, size_t *n, int zlib) size_t bytes_max, size_t *n, int zlib)
{ {
int rc; int rc;
z_stream z; z_stream z;
if ((*newch = CAST(unsigned char *, emalloc(bytes_max + 1))) == NULL) DPRINTF("builtin zlib decompression\n");
return makeerror(newch, n, "No buffer, %s", strerror(errno));
z.next_in = CCAST(Bytef *, old); z.next_in = CCAST(Bytef *, old);
z.avail_in = CAST(uint32_t, *n); z.avail_in = CAST(uint32_t, *n);
z.next_out = *newch; z.next_out = *newch;
@ -599,8 +627,10 @@ uncompresszlib(const unsigned char *old, unsigned char **newch,
goto err; goto err;
rc = inflate(&z, Z_SYNC_FLUSH); rc = inflate(&z, Z_SYNC_FLUSH);
if (rc != Z_OK && rc != Z_STREAM_END) if (rc != Z_OK && rc != Z_STREAM_END) {
inflateEnd(&z);
goto err; goto err;
}
*n = CAST(size_t, z.total_out); *n = CAST(size_t, z.total_out);
rc = inflateEnd(&z); rc = inflateEnd(&z);
@ -612,36 +642,34 @@ uncompresszlib(const unsigned char *old, unsigned char **newch,
return OKDATA; return OKDATA;
err: err:
strlcpy(RCAST(char *, *newch), z.msg ? z.msg : zError(rc), bytes_max); return makeerror(newch, n, "%s", z.msg ? z.msg : zError(rc));
*n = strlen(RCAST(char *, *newch));
return ERRDATA;
} }
#endif #endif
#ifdef BUILTIN_BZLIB #ifdef BUILTIN_BZLIB
private int file_private int
uncompressbzlib(const unsigned char *old, unsigned char **newch, uncompressbzlib(const unsigned char *old, unsigned char **newch,
size_t bytes_max, size_t *n) size_t bytes_max, size_t *n, int extra __attribute__((__unused__)))
{ {
int rc; int rc;
bz_stream bz; bz_stream bz;
DPRINTF("builtin bzlib decompression\n");
memset(&bz, 0, sizeof(bz)); memset(&bz, 0, sizeof(bz));
rc = BZ2_bzDecompressInit(&bz, 0, 0); rc = BZ2_bzDecompressInit(&bz, 0, 0);
if (rc != BZ_OK) if (rc != BZ_OK)
goto err; 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.next_in = CCAST(char *, RCAST(const char *, old));
bz.avail_in = CAST(uint32_t, *n); bz.avail_in = CAST(uint32_t, *n);
bz.next_out = RCAST(char *, *newch); bz.next_out = RCAST(char *, *newch);
bz.avail_out = CAST(unsigned int, bytes_max); bz.avail_out = CAST(unsigned int, bytes_max);
rc = BZ2_bzDecompress(&bz); rc = BZ2_bzDecompress(&bz);
if (rc != BZ_OK && rc != BZ_STREAM_END) if (rc != BZ_OK && rc != BZ_STREAM_END) {
BZ2_bzDecompressEnd(&bz);
goto err; goto err;
}
/* Assume byte_max is within 32bit */ /* Assume byte_max is within 32bit */
/* assert(bz.total_out_hi32 == 0); */ /* assert(bz.total_out_hi32 == 0); */
@ -655,36 +683,34 @@ uncompressbzlib(const unsigned char *old, unsigned char **newch,
return OKDATA; return OKDATA;
err: err:
snprintf(RCAST(char *, *newch), bytes_max, "bunzip error %d", rc); return makeerror(newch, n, "bunzip error %d", rc);
*n = strlen(RCAST(char *, *newch));
return ERRDATA;
} }
#endif #endif
#ifdef BUILTIN_XZLIB #ifdef BUILTIN_XZLIB
private int file_private int
uncompressxzlib(const unsigned char *old, unsigned char **newch, uncompressxzlib(const unsigned char *old, unsigned char **newch,
size_t bytes_max, size_t *n) size_t bytes_max, size_t *n, int extra __attribute__((__unused__)))
{ {
int rc; int rc;
lzma_stream xz; lzma_stream xz;
DPRINTF("builtin xzlib decompression\n");
memset(&xz, 0, sizeof(xz)); memset(&xz, 0, sizeof(xz));
rc = lzma_auto_decoder(&xz, UINT64_MAX, 0); rc = lzma_auto_decoder(&xz, UINT64_MAX, 0);
if (rc != LZMA_OK) if (rc != LZMA_OK)
goto err; 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.next_in = CCAST(const uint8_t *, old);
xz.avail_in = CAST(uint32_t, *n); xz.avail_in = CAST(uint32_t, *n);
xz.next_out = RCAST(uint8_t *, *newch); xz.next_out = RCAST(uint8_t *, *newch);
xz.avail_out = CAST(unsigned int, bytes_max); xz.avail_out = CAST(unsigned int, bytes_max);
rc = lzma_code(&xz, LZMA_RUN); rc = lzma_code(&xz, LZMA_RUN);
if (rc != LZMA_OK && rc != LZMA_STREAM_END) if (rc != LZMA_OK && rc != LZMA_STREAM_END) {
lzma_end(&xz);
goto err; goto err;
}
*n = CAST(size_t, xz.total_out); *n = CAST(size_t, xz.total_out);
@ -695,9 +721,115 @@ uncompressxzlib(const unsigned char *old, unsigned char **newch,
return OKDATA; return OKDATA;
err: err:
snprintf(RCAST(char *, *newch), bytes_max, "unxz error %d", rc); return makeerror(newch, n, "unxz error %d", rc);
*n = strlen(RCAST(char *, *newch)); }
return ERRDATA; #endif
#ifdef BUILTIN_ZSTDLIB
file_private int
uncompresszstd(const unsigned char *old, unsigned char **newch,
size_t bytes_max, size_t *n, int extra __attribute__((__unused__)))
{
size_t rc;
ZSTD_DStream *zstd;
ZSTD_inBuffer in;
ZSTD_outBuffer out;
DPRINTF("builtin zstd decompression\n");
if ((zstd = ZSTD_createDStream()) == NULL) {
return makeerror(newch, n, "No ZSTD decompression stream, %s",
strerror(errno));
}
rc = ZSTD_DCtx_reset(zstd, ZSTD_reset_session_only);
if (ZSTD_isError(rc))
goto err;
in.src = CCAST(const void *, old);
in.size = *n;
in.pos = 0;
out.dst = RCAST(void *, *newch);
out.size = bytes_max;
out.pos = 0;
rc = ZSTD_decompressStream(zstd, &out, &in);
if (ZSTD_isError(rc))
goto err;
*n = out.pos;
ZSTD_freeDStream(zstd);
/* let's keep the nul-terminate tradition */
(*newch)[*n] = '\0';
return OKDATA;
err:
ZSTD_freeDStream(zstd);
return makeerror(newch, n, "zstd error %d", ZSTD_getErrorCode(rc));
}
#endif
#ifdef BUILTIN_LZLIB
file_private int
uncompresslzlib(const unsigned char *old, unsigned char **newch,
size_t bytes_max, size_t *n, int extra __attribute__((__unused__)))
{
enum LZ_Errno err;
size_t old_remaining = *n;
size_t new_remaining = bytes_max;
size_t total_read = 0;
unsigned char *bufp;
struct LZ_Decoder *dec;
bufp = *newch;
DPRINTF("builtin lzlib decompression\n");
dec = LZ_decompress_open();
if (!dec) {
return makeerror(newch, n, "unable to allocate LZ_Decoder");
}
if (LZ_decompress_errno(dec) != LZ_ok)
goto err;
for (;;) {
// LZ_decompress_read() stops at member boundaries, so we may
// have more than one successful read after writing all data
// we have.
if (old_remaining > 0) {
int wr = LZ_decompress_write(dec, old, old_remaining);
if (wr < 0)
goto err;
old_remaining -= wr;
old += wr;
}
int rd = LZ_decompress_read(dec, bufp, new_remaining);
if (rd > 0) {
new_remaining -= rd;
bufp += rd;
total_read += rd;
}
if (rd < 0 || LZ_decompress_errno(dec) != LZ_ok)
goto err;
if (new_remaining == 0)
break;
if (old_remaining == 0 && rd == 0)
break;
}
LZ_decompress_close(dec);
*n = total_read;
/* let's keep the nul-terminate tradition */
*bufp = '\0';
return OKDATA;
err:
err = LZ_decompress_errno(dec);
LZ_decompress_close(dec);
return makeerror(newch, n, "lzlib error: %s", LZ_strerror(err));
} }
#endif #endif
@ -709,10 +841,13 @@ makeerror(unsigned char **buf, size_t *len, const char *fmt, ...)
va_list ap; va_list ap;
int rv; int rv;
DPRINTF("Makeerror %s\n", fmt);
free(*buf);
va_start(ap, fmt); va_start(ap, fmt);
rv = vasprintf(&msg, fmt, ap); rv = vasprintf(&msg, fmt, ap);
va_end(ap); va_end(ap);
if (rv < 0) { if (rv < 0) {
DPRINTF("Makeerror failed");
*buf = NULL; *buf = NULL;
*len = 0; *len = 0;
return NODATA; return NODATA;
@ -751,7 +886,7 @@ movedesc(void *v, int i, int fd)
#else #else
if (dup2(fd, i) == -1) { if (dup2(fd, i) == -1) {
DPRINTF("dup(%d, %d) failed (%s)\n", fd, i, strerror(errno)); DPRINTF("dup(%d, %d) failed (%s)\n", fd, i, strerror(errno));
exit(1); exit(EXIT_FAILURE);
} }
close(v ? fd : fd); close(v ? fd : fd);
#endif #endif
@ -808,15 +943,15 @@ writechild(int fd, const void *old, size_t n)
pid = fork(); pid = fork();
if (pid == -1) { if (pid == -1) {
DPRINTF("Fork failed (%s)\n", strerror(errno)); DPRINTF("Fork failed (%s)\n", strerror(errno));
exit(1); return -1;
} }
if (pid == 0) { if (pid == 0) {
/* child */ /* child */
if (swrite(fd, old, n) != CAST(ssize_t, n)) { if (swrite(fd, old, n) != CAST(ssize_t, n)) {
DPRINTF("Write failed (%s)\n", strerror(errno)); DPRINTF("Write failed (%s)\n", strerror(errno));
exit(1); exit(EXIT_FAILURE);
} }
exit(0); exit(EXIT_SUCCESS);
} }
/* parent */ /* parent */
return pid; return pid;
@ -850,7 +985,7 @@ filter_error(unsigned char *ubuf, ssize_t n)
return n; return n;
} }
private const char * file_private const char *
methodname(size_t method) methodname(size_t method)
{ {
switch (method) { switch (method) {
@ -867,45 +1002,80 @@ methodname(size_t method)
case METH_XZ: case METH_XZ:
case METH_LZMA: case METH_LZMA:
return "xzlib"; return "xzlib";
#endif
#ifdef BUILTIN_ZSTDLIB
case METH_ZSTD:
return "zstd";
#endif
#ifdef BUILTIN_LZLIB
case METH_LZIP:
return "lzlib";
#endif #endif
default: default:
return compr[method].argv[0]; return compr[method].argv[0];
} }
} }
private int file_private int (*
uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old, getdecompressor(size_t method))(const unsigned char *, unsigned char **, size_t,
unsigned char **newch, size_t* n) size_t *, int)
{
switch (method) {
#ifdef BUILTIN_DECOMPRESS
case METH_FROZEN:
return uncompressgzipped;
case METH_ZLIB:
return uncompresszlib;
#endif
#ifdef BUILTIN_BZLIB
case METH_BZIP:
return uncompressbzlib;
#endif
#ifdef BUILTIN_XZLIB
case METH_XZ:
case METH_LZMA:
return uncompressxzlib;
#endif
#ifdef BUILTIN_ZSTDLIB
case METH_ZSTD:
return uncompresszstd;
#endif
#ifdef BUILTIN_LZLIB
case METH_LZIP:
return uncompresslzlib;
#endif
default:
return NULL;
}
}
file_private int
uncompressbuf(int fd, size_t bytes_max, size_t method, int nofork,
const unsigned char *old, unsigned char **newch, size_t* n)
{ {
int fdp[3][2]; int fdp[3][2];
int status, rv, w; int status, rv, w;
pid_t pid; pid_t pid;
pid_t writepid = -1; pid_t writepid = -1;
size_t i; size_t i;
ssize_t r; ssize_t r, re;
char *const *args; char *const *args;
#ifdef HAVE_POSIX_SPAWNP #ifdef HAVE_POSIX_SPAWNP
posix_spawn_file_actions_t fa; posix_spawn_file_actions_t fa;
#endif #endif
int (*decompress)(const unsigned char *, unsigned char **,
size_t, size_t *, int) = getdecompressor(method);
switch (method) { *newch = CAST(unsigned char *, emalloc(bytes_max + 1));
#ifdef BUILTIN_DECOMPRESS if (*newch == NULL)
case METH_FROZEN: return makeerror(newch, n, "No buffer, %s", strerror(errno));
return uncompressgzipped(old, newch, bytes_max, n);
case METH_ZLIB: if (decompress) {
return uncompresszlib(old, newch, bytes_max, n, 1); if (nofork) {
#endif return makeerror(newch, n,
#ifdef BUILTIN_BZLIB "Fork is required to uncompress, but disabled");
case METH_BZIP: }
return uncompressbzlib(old, newch, bytes_max, n); return (*decompress)(old, newch, bytes_max, n, 1);
#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(stdout);
@ -920,7 +1090,7 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
* analyze two large compressed files, both will spawn * analyze two large compressed files, both will spawn
* an uncompressing child here, which writes out uncompressed data. * an uncompressing child here, which writes out uncompressed data.
* We read some portion, then close the pipe, then waitpid() the child. * We read some portion, then close the pipe, then waitpid() the child.
* If uncompressed data is larger, child shound get EPIPE and exit. * If uncompressed data is larger, child should get EPIPE and exit.
* However, with *parallel* calls OTHER child may unintentionally * However, with *parallel* calls OTHER child may unintentionally
* inherit pipe fds, thus keeping pipe open and making writes in * inherit pipe fds, thus keeping pipe open and making writes in
* our child block instead of failing with EPIPE! * our child block instead of failing with EPIPE!
@ -943,6 +1113,7 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
handledesc(&fa, fd, fdp); handledesc(&fa, fd, fdp);
DPRINTF("Executing %s\n", compr[method].argv[0]);
status = posix_spawnp(&pid, compr[method].argv[0], &fa, NULL, status = posix_spawnp(&pid, compr[method].argv[0], &fa, NULL,
args, NULL); args, NULL);
@ -968,11 +1139,12 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
* do not modify fdp[i][j]. * do not modify fdp[i][j].
*/ */
handledesc(NULL, fd, fdp); handledesc(NULL, fd, fdp);
DPRINTF("Executing %s\n", compr[method].argv[0]);
(void)execvp(compr[method].argv[0], args); (void)execvp(compr[method].argv[0], args);
dprintf(STDERR_FILENO, "exec `%s' failed, %s", dprintf(STDERR_FILENO, "exec `%s' failed, %s",
compr[method].argv[0], strerror(errno)); compr[method].argv[0], strerror(errno));
_exit(1); /* _exit(), not exit(), because of vfork */ _exit(EXIT_FAILURE); /* _exit(), not exit(), because of vfork */
} }
#endif #endif
/* parent */ /* parent */
@ -983,39 +1155,45 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
if (fd == -1) { if (fd == -1) {
closefd(fdp[STDIN_FILENO], 0); closefd(fdp[STDIN_FILENO], 0);
writepid = writechild(fdp[STDIN_FILENO][1], old, *n); writepid = writechild(fdp[STDIN_FILENO][1], old, *n);
if (writepid == (pid_t)-1) {
rv = makeerror(newch, n, "Write to child failed, %s",
strerror(errno));
DPRINTF("Write to child failed\n");
goto err;
}
closefd(fdp[STDIN_FILENO], 1); 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; rv = OKDATA;
errno = 0;
r = sread(fdp[STDOUT_FILENO][0], *newch, bytes_max, 0); r = sread(fdp[STDOUT_FILENO][0], *newch, bytes_max, 0);
if (r == 0 && errno == 0) DPRINTF("read got %zd\n", r);
goto ok; if (r < 0) {
if (r <= 0) {
DPRINTF("Read stdout failed %d (%s)\n", fdp[STDOUT_FILENO][0],
r != -1 ? strerror(errno) : "no data");
rv = ERRDATA; rv = ERRDATA;
if (r == 0 && DPRINTF("Read stdout failed %d (%s)\n", fdp[STDOUT_FILENO][0],
(r = sread(fdp[STDERR_FILENO][0], *newch, bytes_max, 0)) > 0) strerror(errno));
{
r = filter_error(*newch, r);
goto ok;
}
free(*newch);
if (r == 0)
rv = makeerror(newch, n, "Read failed, %s",
strerror(errno));
else
rv = makeerror(newch, n, "No data");
goto err; goto err;
} }
if (CAST(size_t, r) == bytes_max) {
/*
* close fd so that the child exits with sigpipe and ignore
* errors, otherwise we risk the child blocking and never
* exiting.
*/
DPRINTF("Closing stdout for bytes_max\n");
closefd(fdp[STDOUT_FILENO], 0);
goto ok;
}
if ((re = sread(fdp[STDERR_FILENO][0], *newch, bytes_max, 0)) > 0) {
DPRINTF("Got stuff from stderr %s\n", *newch);
rv = ERRDATA;
r = filter_error(*newch, r);
goto ok;
}
if (re == 0)
goto ok;
rv = makeerror(newch, n, "Read stderr failed, %s",
strerror(errno));
goto err;
ok: ok:
*n = r; *n = r;
/* NUL terminate, as every buffer is handled here. */ /* NUL terminate, as every buffer is handled here. */
@ -1028,7 +1206,6 @@ err:
w = waitpid(pid, &status, 0); w = waitpid(pid, &status, 0);
wait_err: wait_err:
if (w == -1) { if (w == -1) {
free(*newch);
rv = makeerror(newch, n, "Wait failed, %s", strerror(errno)); rv = makeerror(newch, n, "Wait failed, %s", strerror(errno));
DPRINTF("Child wait return %#x\n", status); DPRINTF("Child wait return %#x\n", status);
} else if (!WIFEXITED(status)) { } else if (!WIFEXITED(status)) {

View file

@ -35,7 +35,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: der.c,v 1.24 2022/07/30 18:08:36 christos Exp $") FILE_RCSID("@(#)$File: der.c,v 1.27 2022/09/24 20:30:13 christos Exp $")
#endif #endif
#else #else
#define SIZE_T_FORMAT "z" #define SIZE_T_FORMAT "z"
@ -272,7 +272,7 @@ der_offs(struct magic_set *ms, struct magic *m, size_t nbytes)
DPRINTF(("%s: bad tag 1\n", __func__)); DPRINTF(("%s: bad tag 1\n", __func__));
return -1; return -1;
} }
DPRINTF(("%s1: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset, DPRINTF(("%s1: %u %" SIZE_T_FORMAT "u %d\n", __func__, ms->offset,
offs, m->offset)); offs, m->offset));
uint32_t tlen = getlength(b, &offs, len); uint32_t tlen = getlength(b, &offs, len);
@ -280,7 +280,7 @@ der_offs(struct magic_set *ms, struct magic *m, size_t nbytes)
DPRINTF(("%s: bad tag 2\n", __func__)); DPRINTF(("%s: bad tag 2\n", __func__));
return -1; return -1;
} }
DPRINTF(("%s2: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset, DPRINTF(("%s2: %u %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset,
offs, tlen)); offs, tlen));
offs += ms->offset + m->offset; offs += ms->offset + m->offset;
@ -288,14 +288,14 @@ der_offs(struct magic_set *ms, struct magic *m, size_t nbytes)
#ifdef DEBUG_DER #ifdef DEBUG_DER
size_t i; size_t i;
for (i = 0; i < m->cont_level; i++) for (i = 0; i < m->cont_level; i++)
printf("cont_level[%" SIZE_T_FORMAT "u] = %u\n", i, printf("cont_level[%" SIZE_T_FORMAT "u] = %d\n", i,
ms->c.li[i].off); ms->c.li[i].off);
#endif #endif
if (m->cont_level != 0) { if (m->cont_level != 0) {
if (offs + tlen > nbytes) if (offs + tlen > nbytes)
return -1; return -1;
ms->c.li[m->cont_level - 1].off = CAST(int, offs + tlen); ms->c.li[m->cont_level - 1].off = CAST(int, offs + tlen);
DPRINTF(("cont_level[%u] = %u\n", m->cont_level - 1, DPRINTF(("cont_level[%u] = %d\n", m->cont_level - 1,
ms->c.li[m->cont_level - 1].off)); ms->c.li[m->cont_level - 1].off));
} }
return CAST(int32_t, offs); return CAST(int32_t, offs);
@ -318,7 +318,7 @@ der_cmp(struct magic_set *ms, struct magic *m)
return -1; return -1;
} }
DPRINTF(("%s1: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset, DPRINTF(("%s1: %d %" SIZE_T_FORMAT "u %d\n", __func__, ms->offset,
offs, m->offset)); offs, m->offset));
tlen = getlength(b, &offs, len); tlen = getlength(b, &offs, len);

View file

@ -35,7 +35,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: encoding.c,v 1.39 2022/09/13 18:46:07 christos Exp $") FILE_RCSID("@(#)$File: encoding.c,v 1.42 2022/12/26 17:31:14 christos Exp $")
#endif /* lint */ #endif /* lint */
#include "magic.h" #include "magic.h"
@ -43,21 +43,21 @@ FILE_RCSID("@(#)$File: encoding.c,v 1.39 2022/09/13 18:46:07 christos Exp $")
#include <stdlib.h> #include <stdlib.h>
private int looks_ascii(const unsigned char *, size_t, file_unichar_t *, file_private int looks_ascii(const unsigned char *, size_t, file_unichar_t *,
size_t *); size_t *);
private int looks_utf8_with_BOM(const unsigned char *, size_t, file_unichar_t *, file_private int looks_utf8_with_BOM(const unsigned char *, size_t, file_unichar_t *,
size_t *); size_t *);
private int looks_utf7(const unsigned char *, size_t, file_unichar_t *, file_private int looks_utf7(const unsigned char *, size_t, file_unichar_t *,
size_t *); size_t *);
private int looks_ucs16(const unsigned char *, size_t, file_unichar_t *, file_private int looks_ucs16(const unsigned char *, size_t, file_unichar_t *,
size_t *); size_t *);
private int looks_ucs32(const unsigned char *, size_t, file_unichar_t *, file_private int looks_ucs32(const unsigned char *, size_t, file_unichar_t *,
size_t *); size_t *);
private int looks_latin1(const unsigned char *, size_t, file_unichar_t *, file_private int looks_latin1(const unsigned char *, size_t, file_unichar_t *,
size_t *); size_t *);
private int looks_extended(const unsigned char *, size_t, file_unichar_t *, file_private int looks_extended(const unsigned char *, size_t, file_unichar_t *,
size_t *); size_t *);
private void from_ebcdic(const unsigned char *, size_t, unsigned char *); file_private void from_ebcdic(const unsigned char *, size_t, unsigned char *);
#ifdef DEBUG_ENCODING #ifdef DEBUG_ENCODING
#define DPRINTF(a) printf a #define DPRINTF(a) printf a
@ -71,7 +71,7 @@ private void from_ebcdic(const unsigned char *, size_t, unsigned char *);
* the text converted into one-file_unichar_t-per-character Unicode in * the text converted into one-file_unichar_t-per-character Unicode in
* ubuf, and the number of characters converted in ulen. * ubuf, and the number of characters converted in ulen.
*/ */
protected int file_protected int
file_encoding(struct magic_set *ms, const struct buffer *b, file_encoding(struct magic_set *ms, const struct buffer *b,
file_unichar_t **ubuf, size_t *ulen, const char **code, file_unichar_t **ubuf, size_t *ulen, const char **code,
const char **code_mime, const char **type) const char **code_mime, const char **type)
@ -237,7 +237,7 @@ file_encoding(struct magic_set *ms, const struct buffer *b,
#define I 2 /* character appears in ISO-8859 text */ #define I 2 /* character appears in ISO-8859 text */
#define X 3 /* character appears in non-ISO extended ASCII (Mac, IBM PC) */ #define X 3 /* character appears in non-ISO extended ASCII (Mac, IBM PC) */
private char text_chars[256] = { file_private char text_chars[256] = {
/* BEL BS HT LF VT FF CR */ /* BEL BS HT LF VT FF CR */
F, F, F, F, F, F, F, T, T, T, T, T, T, T, F, F, /* 0x0X */ F, F, F, F, F, F, F, T, T, T, T, T, T, T, F, F, /* 0x0X */
/* ESC */ /* ESC */
@ -260,7 +260,7 @@ private char text_chars[256] = {
}; };
#define LOOKS(NAME, COND) \ #define LOOKS(NAME, COND) \
private int \ file_private int \
looks_ ## NAME(const unsigned char *buf, size_t nbytes, file_unichar_t *ubuf, \ looks_ ## NAME(const unsigned char *buf, size_t nbytes, file_unichar_t *ubuf, \
size_t *ulen) \ size_t *ulen) \
{ \ { \
@ -346,7 +346,7 @@ struct accept_range {
{ LOCB, 0x8F }, { LOCB, 0x8F },
}; };
protected int file_protected int
file_looks_utf8(const unsigned char *buf, size_t nbytes, file_unichar_t *ubuf, file_looks_utf8(const unsigned char *buf, size_t nbytes, file_unichar_t *ubuf,
size_t *ulen) size_t *ulen)
{ {
@ -427,7 +427,7 @@ done:
* BOM, return -1; otherwise return the result of looks_utf8 on the * BOM, return -1; otherwise return the result of looks_utf8 on the
* rest of the text. * rest of the text.
*/ */
private int file_private int
looks_utf8_with_BOM(const unsigned char *buf, size_t nbytes, looks_utf8_with_BOM(const unsigned char *buf, size_t nbytes,
file_unichar_t *ubuf, size_t *ulen) file_unichar_t *ubuf, size_t *ulen)
{ {
@ -437,7 +437,7 @@ looks_utf8_with_BOM(const unsigned char *buf, size_t nbytes,
return -1; return -1;
} }
private int file_private int
looks_utf7(const unsigned char *buf, size_t nbytes, file_unichar_t *ubuf, looks_utf7(const unsigned char *buf, size_t nbytes, file_unichar_t *ubuf,
size_t *ulen) size_t *ulen)
{ {
@ -461,7 +461,7 @@ looks_utf7(const unsigned char *buf, size_t nbytes, file_unichar_t *ubuf,
#define UCS16_HISURR(c) ((c) >= 0xd800 && (c) <= 0xdbff) #define UCS16_HISURR(c) ((c) >= 0xd800 && (c) <= 0xdbff)
#define UCS16_LOSURR(c) ((c) >= 0xdc00 && (c) <= 0xdfff) #define UCS16_LOSURR(c) ((c) >= 0xdc00 && (c) <= 0xdfff)
private int file_private int
looks_ucs16(const unsigned char *bf, size_t nbytes, file_unichar_t *ubf, looks_ucs16(const unsigned char *bf, size_t nbytes, file_unichar_t *ubf,
size_t *ulen) size_t *ulen)
{ {
@ -521,7 +521,7 @@ looks_ucs16(const unsigned char *bf, size_t nbytes, file_unichar_t *ubf,
return 1 + bigend; return 1 + bigend;
} }
private int file_private int
looks_ucs32(const unsigned char *bf, size_t nbytes, file_unichar_t *ubf, looks_ucs32(const unsigned char *bf, size_t nbytes, file_unichar_t *ubf,
size_t *ulen) size_t *ulen)
{ {
@ -590,7 +590,7 @@ looks_ucs32(const unsigned char *bf, size_t nbytes, file_unichar_t *ubf,
* between old-style and internationalized examples of text. * between old-style and internationalized examples of text.
*/ */
private unsigned char ebcdic_to_ascii[] = { file_private unsigned char ebcdic_to_ascii[] = {
0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15, 0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15,
16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31, 16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31,
128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7, 128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7,
@ -624,7 +624,7 @@ private unsigned char ebcdic_to_ascii[] = {
* cases for the NEL character can be taken out of the code. * cases for the NEL character can be taken out of the code.
*/ */
private unsigned char ebcdic_1047_to_8859[] = { file_private unsigned char ebcdic_1047_to_8859[] = {
0x00,0x01,0x02,0x03,0x9C,0x09,0x86,0x7F,0x97,0x8D,0x8E,0x0B,0x0C,0x0D,0x0E,0x0F, 0x00,0x01,0x02,0x03,0x9C,0x09,0x86,0x7F,0x97,0x8D,0x8E,0x0B,0x0C,0x0D,0x0E,0x0F,
0x10,0x11,0x12,0x13,0x9D,0x0A,0x08,0x87,0x18,0x19,0x92,0x8F,0x1C,0x1D,0x1E,0x1F, 0x10,0x11,0x12,0x13,0x9D,0x0A,0x08,0x87,0x18,0x19,0x92,0x8F,0x1C,0x1D,0x1E,0x1F,
0x80,0x81,0x82,0x83,0x84,0x85,0x17,0x1B,0x88,0x89,0x8A,0x8B,0x8C,0x05,0x06,0x07, 0x80,0x81,0x82,0x83,0x84,0x85,0x17,0x1B,0x88,0x89,0x8A,0x8B,0x8C,0x05,0x06,0x07,
@ -647,7 +647,7 @@ private unsigned char ebcdic_1047_to_8859[] = {
/* /*
* Copy buf[0 ... nbytes-1] into out[], translating EBCDIC to ASCII. * Copy buf[0 ... nbytes-1] into out[], translating EBCDIC to ASCII.
*/ */
private void file_private void
from_ebcdic(const unsigned char *buf, size_t nbytes, unsigned char *out) from_ebcdic(const unsigned char *buf, size_t nbytes, unsigned char *out)
{ {
size_t i; size_t i;

View file

@ -27,7 +27,7 @@
*/ */
/* /*
* file.h - definitions for file(1) program * file.h - definitions for file(1) program
* @(#)$File: file.h,v 1.237 2022/09/10 13:21:42 christos Exp $ * @(#)$File: file.h,v 1.247 2023/07/27 19:40:22 christos Exp $
*/ */
#ifndef __file_h__ #ifndef __file_h__
@ -98,17 +98,17 @@
#define PATHSEP ':' #define PATHSEP ':'
#endif #endif
#define private static #define file_private static
#if HAVE_VISIBILITY && !defined(WIN32) #if HAVE_VISIBILITY && !defined(WIN32)
#define public __attribute__ ((__visibility__("default"))) #define file_public __attribute__ ((__visibility__("default")))
#ifndef protected #ifndef file_protected
#define protected __attribute__ ((__visibility__("hidden"))) #define file_protected __attribute__ ((__visibility__("hidden")))
#endif #endif
#else #else
#define public #define file_public
#ifndef protected #ifndef file_protected
#define protected #define file_protected
#endif #endif
#endif #endif
@ -148,6 +148,14 @@
# define FD_CLOEXEC 1 # define FD_CLOEXEC 1
#endif #endif
/*
* Dec 31, 23:59:59 9999
* we need to make sure that we don't exceed 9999 because some libc
* implementations like muslc crash otherwise
*/
#define MAX_CTIME CAST(time_t, 0x3afff487cfULL)
#define FILE_BADSIZE CAST(size_t, ~0ul) #define FILE_BADSIZE CAST(size_t, ~0ul)
#define MAXDESC 64 /* max len of text description/MIME type */ #define MAXDESC 64 /* max len of text description/MIME type */
#define MAXMIME 80 /* max len of text MIME type */ #define MAXMIME 80 /* max len of text MIME type */
@ -472,12 +480,14 @@ struct magic_set {
uint16_t regex_max; uint16_t regex_max;
size_t bytes_max; /* number of bytes to read from file */ size_t bytes_max; /* number of bytes to read from file */
size_t encoding_max; /* bytes to look for encoding */ size_t encoding_max; /* bytes to look for encoding */
size_t elf_shsize_max;
#ifndef FILE_BYTES_MAX #ifndef FILE_BYTES_MAX
# define FILE_BYTES_MAX (1024 * 1024) /* how much of the file to look at */ # define FILE_BYTES_MAX (7 * 1024 * 1024)/* how much of the file to look at */
#endif #endif /* above 0x6ab0f4 map offset for HelveticaNeue.dfont */
#define FILE_ELF_NOTES_MAX 256 #define FILE_ELF_NOTES_MAX 256
#define FILE_ELF_PHNUM_MAX 2048 #define FILE_ELF_PHNUM_MAX 2048
#define FILE_ELF_SHNUM_MAX 32768 #define FILE_ELF_SHNUM_MAX 32768
#define FILE_ELF_SHSIZE_MAX (128 * 1024 * 1024)
#define FILE_INDIR_MAX 50 #define FILE_INDIR_MAX 50
#define FILE_NAME_MAX 50 #define FILE_NAME_MAX 50
#define FILE_REGEX_MAX 8192 #define FILE_REGEX_MAX 8192
@ -497,90 +507,98 @@ typedef unsigned long file_unichar_t;
struct stat; struct stat;
#define FILE_T_LOCAL 1 #define FILE_T_LOCAL 1
#define FILE_T_WINDOWS 2 #define FILE_T_WINDOWS 2
protected const char *file_fmtdatetime(char *, size_t, uint64_t, int); file_protected const char *file_fmtdatetime(char *, size_t, uint64_t, int);
protected const char *file_fmtdate(char *, size_t, uint16_t); file_protected const char *file_fmtdate(char *, size_t, uint16_t);
protected const char *file_fmttime(char *, size_t, uint16_t); file_protected const char *file_fmttime(char *, size_t, uint16_t);
protected const char *file_fmtvarint(char *, size_t, const unsigned char *, file_protected const char *file_fmtvarint(char *, size_t, const unsigned char *,
int); int);
protected const char *file_fmtnum(char *, size_t, const char *, int); file_protected const char *file_fmtnum(char *, size_t, const char *, int);
protected struct magic_set *file_ms_alloc(int); file_protected struct magic_set *file_ms_alloc(int);
protected void file_ms_free(struct magic_set *); file_protected void file_ms_free(struct magic_set *);
protected int file_buffer(struct magic_set *, php_stream *, zend_stat_t *, const char *, const void *, file_protected int file_buffer(struct magic_set *, php_stream *, zend_stat_t *, const char *, const void *,
size_t); size_t);
protected int file_fsmagic(struct magic_set *, const char *, zend_stat_t *); file_protected int file_fsmagic(struct magic_set *, const char *, zend_stat_t *);
protected int file_pipe2file(struct magic_set *, int, const void *, size_t); file_protected int file_pipe2file(struct magic_set *, int, const void *,
protected int file_vprintf(struct magic_set *, const char *, va_list) size_t);
file_protected int file_vprintf(struct magic_set *, const char *, va_list)
__attribute__((__format__(__printf__, 2, 0))); __attribute__((__format__(__printf__, 2, 0)));
protected int file_separator(struct magic_set *); file_protected int file_separator(struct magic_set *);
protected char *file_copystr(char *, size_t, size_t, const char *); file_protected char *file_copystr(char *, size_t, size_t, const char *);
protected int file_checkfmt(char *, size_t, const char *); file_protected int file_checkfmt(char *, size_t, const char *);
protected size_t file_printedlen(const struct magic_set *); file_protected size_t file_printedlen(const struct magic_set *);
protected int file_print_guid(char *, size_t, const uint64_t *); file_protected int file_print_guid(char *, size_t, const uint64_t *);
protected int file_parse_guid(const char *, uint64_t *); file_protected int file_parse_guid(const char *, uint64_t *);
protected int file_replace(struct magic_set *, const char *, const char *); file_protected int file_replace(struct magic_set *, const char *, const char *);
protected int file_printf(struct magic_set *, const char *, ...) file_protected int file_printf(struct magic_set *, const char *, ...)
__attribute__((__format__(__printf__, 2, 3))); __attribute__((__format__(__printf__, 2, 3)));
protected int file_reset(struct magic_set *, int); file_protected int file_reset(struct magic_set *, int);
protected int file_tryelf(struct magic_set *, const struct buffer *); file_protected int file_tryelf(struct magic_set *, const struct buffer *);
protected int file_trycdf(struct magic_set *, const struct buffer *); file_protected int file_trycdf(struct magic_set *, const struct buffer *);
#ifdef PHP_FILEINFO_UNCOMPRESS #ifdef PHP_FILEINFO_UNCOMPRESS
protected int file_zmagic(struct magic_set *, const struct buffer *, file_protected int file_zmagic(struct magic_set *, const struct buffer *,
const char *); const char *);
#endif #endif
protected int file_ascmagic(struct magic_set *, const struct buffer *, file_protected int file_ascmagic(struct magic_set *, const struct buffer *,
int); int);
protected int file_ascmagic_with_encoding(struct magic_set *, file_protected int file_ascmagic_with_encoding(struct magic_set *,
const struct buffer *, file_unichar_t *, size_t, const char *, const char *, int); const struct buffer *, file_unichar_t *, size_t, const char *, const char *, int);
protected int file_encoding(struct magic_set *, const struct buffer *, file_protected int file_encoding(struct magic_set *, const struct buffer *,
file_unichar_t **, size_t *, const char **, const char **, const char **); file_unichar_t **, size_t *, const char **, const char **, const char **);
protected int file_is_json(struct magic_set *, const struct buffer *); file_protected int file_is_json(struct magic_set *, const struct buffer *);
protected int file_is_csv(struct magic_set *, const struct buffer *, int); file_protected int file_is_csv(struct magic_set *, const struct buffer *, int,
protected int file_is_tar(struct magic_set *, const struct buffer *); const char *);
protected int file_softmagic(struct magic_set *, const struct buffer *, file_protected int file_is_simh(struct magic_set *, const struct buffer *);
file_protected int file_is_tar(struct magic_set *, const struct buffer *);
file_protected int file_softmagic(struct magic_set *, const struct buffer *,
uint16_t *, uint16_t *, int, int); uint16_t *, uint16_t *, int, int);
protected int file_apprentice(struct magic_set *, const char *, int); file_protected int file_apprentice(struct magic_set *, const char *, int);
protected int buffer_apprentice(struct magic_set *, struct magic **, file_protected size_t file_magic_strength(const struct magic *, size_t);
file_protected int buffer_apprentice(struct magic_set *, struct magic **,
size_t *, size_t); size_t *, size_t);
protected int file_magicfind(struct magic_set *, const char *, struct mlist *); file_protected int file_magicfind(struct magic_set *, const char *,
protected uint64_t file_signextend(struct magic_set *, struct magic *, struct mlist *);
file_protected uint64_t file_signextend(struct magic_set *, struct magic *,
uint64_t); uint64_t);
protected uintmax_t file_varint2uintmax_t(const unsigned char *, int, size_t *); file_protected uintmax_t file_varint2uintmax_t(const unsigned char *, int,
protected void file_badread(struct magic_set *);
protected void file_badseek(struct magic_set *);
protected void file_oomem(struct magic_set *, size_t);
protected void file_error(struct magic_set *, int, const char *, ...)
__attribute__((__format__(__printf__, 3, 4)));
protected void file_magerror(struct magic_set *, const char *, ...)
__attribute__((__format__(__printf__, 2, 3)));
protected void file_magwarn(struct magic_set *, const char *, ...)
__attribute__((__format__(__printf__, 2, 3)));
protected void file_mdump(struct magic *);
protected void file_showstr(FILE *, const char *, size_t);
protected size_t file_mbswidth(struct magic_set *, const char *);
protected const char *file_getbuffer(struct magic_set *);
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, file_unichar_t *,
size_t *); size_t *);
protected size_t file_pstring_length_size(struct magic_set *,
file_protected void file_badread(struct magic_set *);
file_protected void file_badseek(struct magic_set *);
file_protected void file_oomem(struct magic_set *, size_t);
file_protected void file_error(struct magic_set *, int, const char *, ...)
__attribute__((__format__(__printf__, 3, 4)));
file_protected void file_magerror(struct magic_set *, const char *, ...)
__attribute__((__format__(__printf__, 2, 3)));
file_protected void file_magwarn(struct magic_set *, const char *, ...)
__attribute__((__format__(__printf__, 2, 3)));
file_protected void file_mdump(struct magic *);
file_protected void file_showstr(FILE *, const char *, size_t);
file_protected size_t file_mbswidth(struct magic_set *, const char *);
file_protected const char *file_getbuffer(struct magic_set *);
file_protected ssize_t sread(int, void *, size_t, int);
file_protected int file_check_mem(struct magic_set *, unsigned int);
file_protected int file_looks_utf8(const unsigned char *, size_t,
file_unichar_t *, size_t *);
file_protected size_t file_pstring_length_size(struct magic_set *,
const struct magic *); const struct magic *);
protected size_t file_pstring_get_length(struct magic_set *, file_protected size_t file_pstring_get_length(struct magic_set *,
const struct magic *, const char *); const struct magic *, const char *);
protected char * file_printable(struct magic_set *, char *, size_t, file_protected char * file_printable(struct magic_set *, char *, size_t,
const char *, size_t); const char *, size_t);
#ifdef __EMX__ #ifdef __EMX__
protected int file_os2_apptype(struct magic_set *, const char *, const void *, file_protected int file_os2_apptype(struct magic_set *, const char *,
size_t);
#endif /* __EMX__ */
protected int file_pipe_closexec(int *);
protected int file_clear_closexec(int);
protected char *file_strtrim(char *);
protected void buffer_init(struct buffer *, int, const zend_stat_t *,
const void *, size_t); const void *, size_t);
protected void buffer_fini(struct buffer *); #endif /* __EMX__ */
protected int buffer_fill(const struct buffer *); file_protected int file_pipe_closexec(int *);
file_protected int file_clear_closexec(int);
file_protected char *file_strtrim(char *);
file_protected void buffer_init(struct buffer *, int, const zend_stat_t *,
const void *, size_t);
file_protected void buffer_fini(struct buffer *);
file_protected int buffer_fill(const struct buffer *);
typedef struct { typedef struct {
char *buf; char *buf;
@ -588,8 +606,8 @@ typedef struct {
uint32_t offset; uint32_t offset;
} file_pushbuf_t; } file_pushbuf_t;
protected file_pushbuf_t *file_push_buffer(struct magic_set *); file_protected file_pushbuf_t *file_push_buffer(struct magic_set *);
protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *); file_protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
#ifndef COMPILE_ONLY #ifndef COMPILE_ONLY
extern const char *file_names[]; extern const char *file_names[];

View file

@ -32,7 +32,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: fsmagic.c,v 1.82 2022/04/11 18:14:41 christos Exp $") FILE_RCSID("@(#)$File: fsmagic.c,v 1.85 2022/12/26 17:31:14 christos Exp $")
#endif /* lint */ #endif /* lint */
#include "magic.h" #include "magic.h"
@ -71,7 +71,7 @@ FILE_RCSID("@(#)$File: fsmagic.c,v 1.82 2022/04/11 18:14:41 christos Exp $")
# undef S_IFIFO # undef S_IFIFO
#endif #endif
private int file_private int
handle_mime(struct magic_set *ms, int mime, const char *str) handle_mime(struct magic_set *ms, int mime, const char *str)
{ {
if ((mime & MAGIC_MIME_TYPE)) { if ((mime & MAGIC_MIME_TYPE)) {
@ -86,7 +86,7 @@ handle_mime(struct magic_set *ms, int mime, const char *str)
return 0; return 0;
} }
protected int file_protected int
file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb) file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb)
{ {
int ret, did = 0; int ret, did = 0;

View file

@ -27,7 +27,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: funcs.c,v 1.131 2022/09/13 18:46:07 christos Exp $") FILE_RCSID("@(#)$File: funcs.c,v 1.140 2023/05/21 17:08:34 christos Exp $")
#endif /* lint */ #endif /* lint */
#include "magic.h" #include "magic.h"
@ -51,7 +51,7 @@ FILE_RCSID("@(#)$File: funcs.c,v 1.131 2022/09/13 18:46:07 christos Exp $")
#define SIZE_MAX ((size_t)~0) #define SIZE_MAX ((size_t)~0)
#endif #endif
protected char * file_protected char *
file_copystr(char *buf, size_t blen, size_t width, const char *str) file_copystr(char *buf, size_t blen, size_t width, const char *str)
{ {
if (blen == 0) if (blen == 0)
@ -63,7 +63,7 @@ file_copystr(char *buf, size_t blen, size_t width, const char *str)
return buf; return buf;
} }
private void file_private void
file_clearbuf(struct magic_set *ms) file_clearbuf(struct magic_set *ms)
{ {
efree(ms->o.buf); efree(ms->o.buf);
@ -71,7 +71,7 @@ file_clearbuf(struct magic_set *ms)
ms->o.blen = 0; ms->o.blen = 0;
} }
private int file_private int
file_checkfield(char *msg, size_t mlen, const char *what, const char **pp) file_checkfield(char *msg, size_t mlen, const char *what, const char **pp)
{ {
const char *p = *pp; const char *p = *pp;
@ -90,7 +90,7 @@ file_checkfield(char *msg, size_t mlen, const char *what, const char **pp)
return 0; return 0;
} }
protected int file_protected int
file_checkfmt(char *msg, size_t mlen, const char *fmt) file_checkfmt(char *msg, size_t mlen, const char *fmt)
{ {
const char *p; const char *p;
@ -129,7 +129,7 @@ file_checkfmt(char *msg, size_t mlen, const char *fmt)
/* /*
* Like printf, only we append to a buffer. * Like printf, only we append to a buffer.
*/ */
protected int file_protected int
file_vprintf(struct magic_set *ms, const char *fmt, va_list ap) file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
{ {
size_t len; size_t len;
@ -166,7 +166,7 @@ file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
return 0; return 0;
} }
protected int file_protected int
file_printf(struct magic_set *ms, const char *fmt, ...) file_printf(struct magic_set *ms, const char *fmt, ...)
{ {
int rv; int rv;
@ -183,7 +183,7 @@ file_printf(struct magic_set *ms, const char *fmt, ...)
*/ */
/*VARARGS*/ /*VARARGS*/
__attribute__((__format__(__printf__, 3, 0))) __attribute__((__format__(__printf__, 3, 0)))
private void file_private void
file_error_core(struct magic_set *ms, int error, const char *f, va_list va, file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
size_t lineno) size_t lineno)
{ {
@ -204,7 +204,7 @@ file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
} }
/*VARARGS*/ /*VARARGS*/
protected void file_protected void
file_error(struct magic_set *ms, int error, const char *f, ...) file_error(struct magic_set *ms, int error, const char *f, ...)
{ {
va_list va; va_list va;
@ -217,7 +217,7 @@ file_error(struct magic_set *ms, int error, const char *f, ...)
* Print an error with magic line number. * Print an error with magic line number.
*/ */
/*VARARGS*/ /*VARARGS*/
protected void file_protected void
file_magerror(struct magic_set *ms, const char *f, ...) file_magerror(struct magic_set *ms, const char *f, ...)
{ {
va_list va; va_list va;
@ -226,20 +226,20 @@ file_magerror(struct magic_set *ms, const char *f, ...)
va_end(va); va_end(va);
} }
protected void file_protected void
file_oomem(struct magic_set *ms, size_t len) file_oomem(struct magic_set *ms, size_t len)
{ {
file_error(ms, errno, "cannot allocate %" SIZE_T_FORMAT "u bytes", file_error(ms, errno, "cannot allocate %" SIZE_T_FORMAT "u bytes",
len); len);
} }
protected void file_protected void
file_badseek(struct magic_set *ms) file_badseek(struct magic_set *ms)
{ {
file_error(ms, errno, "error seeking"); file_error(ms, errno, "error seeking");
} }
protected void file_protected void
file_badread(struct magic_set *ms) file_badread(struct magic_set *ms)
{ {
file_error(ms, errno, "error reading"); file_error(ms, errno, "error reading");
@ -248,7 +248,7 @@ file_badread(struct magic_set *ms)
#ifndef COMPILE_ONLY #ifndef COMPILE_ONLY
#define FILE_SEPARATOR "\n- " #define FILE_SEPARATOR "\n- "
protected int file_protected int
file_separator(struct magic_set *ms) file_separator(struct magic_set *ms)
{ {
return file_printf(ms, FILE_SEPARATOR); return file_printf(ms, FILE_SEPARATOR);
@ -283,7 +283,7 @@ checkdone(struct magic_set *ms, int *rv)
return 0; return 0;
} }
protected int file_protected int
file_default(struct magic_set *ms, size_t nb) file_default(struct magic_set *ms, size_t nb)
{ {
if (ms->flags & MAGIC_MIME) { if (ms->flags & MAGIC_MIME) {
@ -313,9 +313,9 @@ file_default(struct magic_set *ms, size_t nb)
* -1: error * -1: error
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
protected int file_protected int
file_buffer(struct magic_set *ms, php_stream *stream, zend_stat_t *st, file_buffer(struct magic_set *ms, php_stream *stream, zend_stat_t *st,
const char *inname, const char *inname __attribute__ ((__unused__)),
const void *buf, size_t nb) const void *buf, size_t nb)
{ {
int m = 0, rv = 0, looks_text = 0; int m = 0, rv = 0, looks_text = 0;
@ -406,7 +406,7 @@ file_buffer(struct magic_set *ms, php_stream *stream, zend_stat_t *st,
/* Check if we have a CSV file */ /* Check if we have a CSV file */
if ((ms->flags & MAGIC_NO_CHECK_CSV) == 0) { if ((ms->flags & MAGIC_NO_CHECK_CSV) == 0) {
m = file_is_csv(ms, &b, looks_text); m = file_is_csv(ms, &b, looks_text, code);
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
(void)fprintf(stderr, "[try csv %d]\n", m); (void)fprintf(stderr, "[try csv %d]\n", m);
if (m) { if (m) {
@ -415,6 +415,17 @@ file_buffer(struct magic_set *ms, php_stream *stream, zend_stat_t *st,
} }
} }
/* Check if we have a SIMH tape file */
if ((ms->flags & MAGIC_NO_CHECK_SIMH) == 0) {
m = file_is_simh(ms, &b);
if ((ms->flags & MAGIC_DEBUG) != 0)
(void)fprintf(stderr, "[try simh %d]\n", m);
if (m) {
if (checkdone(ms, &rv))
goto done;
}
}
/* Check if we have a CDF file */ /* Check if we have a CDF file */
if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) { if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) {
m = file_trycdf(ms, &b); m = file_trycdf(ms, &b);
@ -444,7 +455,7 @@ file_buffer(struct magic_set *ms, php_stream *stream, zend_stat_t *st,
rv = file_tryelf(ms, &b); rv = file_tryelf(ms, &b);
rbuf = file_pop_buffer(ms, pb); rbuf = file_pop_buffer(ms, pb);
if (rv == -1) { if (rv == -1) {
free(rbuf); efree(rbuf);
rbuf = NULL; rbuf = NULL;
} }
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
@ -508,7 +519,7 @@ simple:
} }
#endif #endif
protected int file_protected int
file_reset(struct magic_set *ms, int checkloaded) file_reset(struct magic_set *ms, int checkloaded)
{ {
if (checkloaded && ms->mlist[0] == NULL) { if (checkloaded && ms->mlist[0] == NULL) {
@ -533,7 +544,7 @@ file_reset(struct magic_set *ms, int checkloaded)
*(n)++ = ((CAST(uint32_t, *(o)) >> 0) & 7) + '0', \ *(n)++ = ((CAST(uint32_t, *(o)) >> 0) & 7) + '0', \
(o)++) (o)++)
protected const char * file_protected const char *
file_getbuffer(struct magic_set *ms) file_getbuffer(struct magic_set *ms)
{ {
char *pbuf, *op, *np; char *pbuf, *op, *np;
@ -611,7 +622,7 @@ file_getbuffer(struct magic_set *ms)
return ms->o.pbuf; return ms->o.pbuf;
} }
protected int file_protected int
file_check_mem(struct magic_set *ms, unsigned int level) file_check_mem(struct magic_set *ms, unsigned int level)
{ {
size_t len; size_t len;
@ -634,13 +645,13 @@ file_check_mem(struct magic_set *ms, unsigned int level)
return 0; return 0;
} }
protected size_t file_protected size_t
file_printedlen(const struct magic_set *ms) file_printedlen(const struct magic_set *ms)
{ {
return ms->o.blen; return ms->o.blen;
} }
protected int file_protected int
file_replace(struct magic_set *ms, const char *pat, const char *rep) file_replace(struct magic_set *ms, const char *pat, const char *rep)
{ {
zend_string *pattern; zend_string *pattern;
@ -668,7 +679,7 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep)
goto out; goto out;
} }
strncpy(ms->o.buf, ZSTR_VAL(res), ZSTR_LEN(res)); memcpy(ms->o.buf, ZSTR_VAL(res), ZSTR_LEN(res));
ms->o.buf[ZSTR_LEN(res)] = '\0'; ms->o.buf[ZSTR_LEN(res)] = '\0';
zend_string_release_ex(res, 0); zend_string_release_ex(res, 0);
@ -677,7 +688,7 @@ out:
return rep_cnt; return rep_cnt;
} }
protected file_pushbuf_t * file_protected file_pushbuf_t *
file_push_buffer(struct magic_set *ms) file_push_buffer(struct magic_set *ms)
{ {
file_pushbuf_t *pb; file_pushbuf_t *pb;
@ -699,7 +710,7 @@ file_push_buffer(struct magic_set *ms)
return pb; return pb;
} }
protected char * file_protected char *
file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb) file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
{ {
char *rbuf; char *rbuf;
@ -723,7 +734,7 @@ file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
/* /*
* convert string to ascii printable format. * convert string to ascii printable format.
*/ */
protected char * file_protected char *
file_printable(struct magic_set *ms, char *buf, size_t bufsiz, file_printable(struct magic_set *ms, char *buf, size_t bufsiz,
const char *str, size_t slen) const char *str, size_t slen)
{ {
@ -754,7 +765,7 @@ struct guid {
uint8_t data4[8]; uint8_t data4[8];
}; };
protected int file_protected int
file_parse_guid(const char *s, uint64_t *guid) file_parse_guid(const char *s, uint64_t *guid)
{ {
struct guid *g = CAST(struct guid *, CAST(void *, guid)); struct guid *g = CAST(struct guid *, CAST(void *, guid));
@ -779,7 +790,7 @@ file_parse_guid(const char *s, uint64_t *guid)
#endif #endif
} }
protected int file_protected int
file_print_guid(char *str, size_t len, const uint64_t *guid) file_print_guid(char *str, size_t len, const uint64_t *guid)
{ {
const struct guid *g = CAST(const struct guid *, const struct guid *g = CAST(const struct guid *,
@ -801,10 +812,12 @@ file_print_guid(char *str, size_t len, const uint64_t *guid)
} }
#if 0 #if 0
protected int file_protected int
file_pipe_closexec(int *fds) file_pipe_closexec(int *fds)
{ {
#ifdef HAVE_PIPE2 #ifdef __MINGW32__
return 0;
#elif defined(HAVE_PIPE2)
return pipe2(fds, O_CLOEXEC); return pipe2(fds, O_CLOEXEC);
#else #else
if (pipe(fds) == -1) if (pipe(fds) == -1)
@ -818,7 +831,7 @@ file_pipe_closexec(int *fds)
} }
#endif #endif
protected int file_protected int
file_clear_closexec(int fd) { file_clear_closexec(int fd) {
#ifdef F_SETFD #ifdef F_SETFD
return fcntl(fd, F_SETFD, 0); return fcntl(fd, F_SETFD, 0);
@ -827,7 +840,7 @@ file_clear_closexec(int fd) {
#endif #endif
} }
protected char * file_protected char *
file_strtrim(char *str) file_strtrim(char *str)
{ {
char *last; char *last;

View file

@ -32,7 +32,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: is_csv.c,v 1.7 2022/05/28 00:44:22 christos Exp $") FILE_RCSID("@(#)$File: is_csv.c,v 1.13 2023/07/17 16:08:17 christos Exp $")
#endif #endif
#include <string.h> #include <string.h>
@ -125,12 +125,13 @@ csv_parse(const unsigned char *uc, const unsigned char *ue)
break; break;
} }
} }
return tf && nl > 2; return tf && nl >= 2;
} }
#ifndef TEST #ifndef TEST
int int
file_is_csv(struct magic_set *ms, const struct buffer *b, int looks_text) file_is_csv(struct magic_set *ms, const struct buffer *b, int looks_text,
const char *code)
{ {
const unsigned char *uc = CAST(const unsigned char *, b->fbuf); const unsigned char *uc = CAST(const unsigned char *, b->fbuf);
const unsigned char *ue = uc + b->flen; const unsigned char *ue = uc + b->flen;
@ -154,7 +155,8 @@ file_is_csv(struct magic_set *ms, const struct buffer *b, int looks_text)
return 1; return 1;
} }
if (file_printf(ms, "CSV text") == -1) if (file_printf(ms, "CSV %s%stext", code ? code : "",
code ? " " : "") == -1)
return -1; return -1;
return 1; return 1;
@ -174,7 +176,7 @@ file_is_csv(struct magic_set *ms, const struct buffer *b, int looks_text)
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int fd, rv; int fd;
struct stat st; struct stat st;
unsigned char *p; unsigned char *p;

View file

@ -32,7 +32,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: is_json.c,v 1.26 2022/09/13 18:46:07 christos Exp $") FILE_RCSID("@(#)$File: is_json.c,v 1.30 2022/09/27 19:12:40 christos Exp $")
#endif #endif
#include "magic.h" #include "magic.h"
@ -440,7 +440,7 @@ file_is_json(struct magic_set *ms, const struct buffer *b)
return 1; return 1;
if (mime) { if (mime) {
if (file_printf(ms, "application/%s", if (file_printf(ms, "application/%s",
jt == 1 ? "json" : "x-ndjason") == -1) jt == 1 ? "json" : "x-ndjson") == -1)
return -1; return -1;
return 1; return 1;
} }
@ -475,7 +475,7 @@ file_is_json(struct magic_set *ms, const struct buffer *b)
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int fd, rv; int fd;
struct stat st; struct stat st;
unsigned char *p; unsigned char *p;
size_t stats[JSON_MAX]; size_t stats[JSON_MAX];

View file

@ -0,0 +1,209 @@
/*-
* Copyright (c) 2023 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 SIM-H tape files
* http://simh.trailing-edge.com/docs/simh_magtape.pdf
*/
#ifndef TEST
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: is_simh.c,v 1.10 2023/07/27 19:39:55 christos Exp $")
#endif
#include <string.h>
#include <stddef.h>
#include "magic.h"
#else
#include <stdint.h>
#include <sys/types.h>
#include <string.h>
#include <stddef.h>
#define CAST(a, b) (a)(b)
#endif
#ifdef DEBUG
#include <stdio.h>
#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
#else
#define DPRINTF(fmt, ...)
#endif
/*
* if SIMH_TAPEMARKS == 0:
* check all the records and tapemarks
* otherwise:
* check only up-to the number of tapemarks specified
*/
#ifndef SIMH_TAPEMARKS
#define SIMH_TAPEMARKS 10
#endif
typedef union {
char s[4];
uint32_t u;
} myword;
static myword simh_bo;
#define NEED_SWAP (simh_bo.u == CAST(uint32_t, 0x01020304))
/*
* swap an int
*/
static uint32_t
swap4(uint32_t sv)
{
myword d, s;
s.u = sv;
d.s[0] = s.s[3];
d.s[1] = s.s[2];
d.s[2] = s.s[1];
d.s[3] = s.s[0];
return d.u;
}
static uint32_t
getlen(const unsigned char **uc)
{
uint32_t n;
memcpy(&n, *uc, sizeof(n));
*uc += sizeof(n);
if (NEED_SWAP)
n = swap4(n);
if (n == 0xffffffff) /* check for End of Medium */
return n;
n &= 0x00ffffff; /* keep only the record len */
if (n & 1)
n++;
return n;
}
static int
simh_parse(const unsigned char *uc, const unsigned char *ue)
{
uint32_t nbytes, cbytes;
const unsigned char *orig_uc = uc;
size_t nt = 0, nr = 0;
(void)memcpy(simh_bo.s, "\01\02\03\04", 4);
while (ue - uc >= CAST(ptrdiff_t, sizeof(nbytes))) {
nbytes = getlen(&uc);
if ((nt > 0 || nr > 0) && nbytes == 0xFFFFFFFF)
/* EOM after at least one record or tapemark */
break;
if (nbytes == 0) {
nt++; /* count tapemarks */
#if SIMH_TAPEMARKS
if (nt == SIMH_TAPEMARKS)
break;
#endif
continue;
}
/* handle a data record */
uc += nbytes;
if (ue - uc < CAST(ptrdiff_t, sizeof(nbytes)))
break;
cbytes = getlen(&uc);
if (nbytes != cbytes)
return 0;
nr++;
}
if (nt * sizeof(uint32_t) == CAST(size_t, uc - orig_uc))
return 0; /* All examined data was tapemarks (0) */
if (nr == 0) /* No records */
return 0;
return 1;
}
#ifndef TEST
int
file_is_simh(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;
int mime = ms->flags & MAGIC_MIME;
if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) != 0)
return 0;
if (!simh_parse(uc, ue))
return 0;
if (mime == MAGIC_MIME_ENCODING)
return 1;
if (mime) {
if (file_printf(ms, "application/SIMH-tape-data") == -1)
return -1;
return 1;
}
if (file_printf(ms, "SIMH tape data") == -1)
return -1;
return 1;
}
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <err.h>
int
main(int argc, char *argv[])
{
int fd;
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 = CAST(char *, 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 simh %d\n", simh_parse(p, p + st.st_size));
return 0;
}
#endif

View file

@ -28,7 +28,7 @@
/* /*
* is_tar() -- figure out whether file is a tar archive. * is_tar() -- figure out whether file is a tar archive.
* *
* Stolen (by the author!) from the public domain tar program: * Stolen (by the author!) from the file_public domain tar program:
* Public Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu). * Public Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu).
* *
* @(#)list.c 1.18 9/23/86 Public Domain - gnu * @(#)list.c 1.18 9/23/86 Public Domain - gnu
@ -40,7 +40,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: is_tar.c,v 1.47 2022/09/13 18:46:07 christos Exp $") FILE_RCSID("@(#)$File: is_tar.c,v 1.50 2022/12/26 17:31:14 christos Exp $")
#endif #endif
#include "magic.h" #include "magic.h"
@ -50,8 +50,8 @@ FILE_RCSID("@(#)$File: is_tar.c,v 1.47 2022/09/13 18:46:07 christos Exp $")
#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') ) #define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
private int is_tar(const unsigned char *, size_t); file_private int is_tar(const unsigned char *, size_t);
private int from_oct(const char *, size_t); /* Decode octal number */ file_private int from_oct(const char *, size_t); /* Decode octal number */
static const char tartype[][32] = { /* should be equal to messages */ static const char tartype[][32] = { /* should be equal to messages */
"tar archive", /* found in ../magic/Magdir/archive */ "tar archive", /* found in ../magic/Magdir/archive */
@ -59,7 +59,7 @@ static const char tartype[][32] = { /* should be equal to messages */
"POSIX tar archive (GNU)", /* */ "POSIX tar archive (GNU)", /* */
}; };
protected int file_protected int
file_is_tar(struct magic_set *ms, const struct buffer *b) file_is_tar(struct magic_set *ms, const struct buffer *b)
{ {
const unsigned char *buf = CAST(const unsigned char *, b->fbuf); const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
@ -95,7 +95,7 @@ file_is_tar(struct magic_set *ms, const struct buffer *b)
* 2 for Unix Std (POSIX) tar file, * 2 for Unix Std (POSIX) tar file,
* 3 for GNU tar file. * 3 for GNU tar file.
*/ */
private int file_private int
is_tar(const unsigned char *buf, size_t nbytes) is_tar(const unsigned char *buf, size_t nbytes)
{ {
static const char gpkg_match[] = "/gpkg-1"; static const char gpkg_match[] = "/gpkg-1";
@ -153,7 +153,7 @@ is_tar(const unsigned char *buf, size_t nbytes)
* *
* Result is -1 if the field is invalid (all blank, or non-octal). * Result is -1 if the field is invalid (all blank, or non-octal).
*/ */
private int file_private int
from_oct(const char *where, size_t digs) from_oct(const char *where, size_t digs)
{ {
int value; int value;

View file

@ -28,7 +28,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: magic.c,v 1.117 2021/12/06 15:33:00 christos Exp $") FILE_RCSID("@(#)$File: magic.c,v 1.121 2023/02/09 17:45:19 christos Exp $")
#endif /* lint */ #endif /* lint */
#include "magic.h" #include "magic.h"
@ -71,20 +71,20 @@ FILE_RCSID("@(#)$File: magic.c,v 1.117 2021/12/06 15:33:00 christos Exp $")
# undef S_IFIFO # undef S_IFIFO
#endif #endif
private int unreadable_info(struct magic_set *, mode_t, const char *); file_private int unreadable_info(struct magic_set *, mode_t, const char *);
private const char *file_or_stream(struct magic_set *, const char *, php_stream *); file_private const char *file_or_stream(struct magic_set *, const char *, php_stream *);
#ifndef STDIN_FILENO #ifndef STDIN_FILENO
#define STDIN_FILENO 0 #define STDIN_FILENO 0
#endif #endif
public struct magic_set * file_public struct magic_set *
magic_open(int flags) magic_open(int flags)
{ {
return file_ms_alloc(flags); return file_ms_alloc(flags);
} }
private int file_private int
unreadable_info(struct magic_set *ms, mode_t md, const char *file) unreadable_info(struct magic_set *ms, mode_t md, const char *file)
{ {
if (file) { if (file) {
@ -117,7 +117,7 @@ unreadable_info(struct magic_set *ms, mode_t md, const char *file)
return 0; return 0;
} }
public void file_public void
magic_close(struct magic_set *ms) magic_close(struct magic_set *ms)
{ {
if (ms == NULL) if (ms == NULL)
@ -128,7 +128,7 @@ magic_close(struct magic_set *ms)
/* /*
* load a magic file * load a magic file
*/ */
public int file_public int
magic_load(struct magic_set *ms, const char *magicfile) magic_load(struct magic_set *ms, const char *magicfile)
{ {
if (ms == NULL) if (ms == NULL)
@ -136,7 +136,7 @@ magic_load(struct magic_set *ms, const char *magicfile)
return file_apprentice(ms, magicfile, FILE_LOAD); return file_apprentice(ms, magicfile, FILE_LOAD);
} }
public int file_public int
magic_compile(struct magic_set *ms, const char *magicfile) magic_compile(struct magic_set *ms, const char *magicfile)
{ {
if (ms == NULL) if (ms == NULL)
@ -144,7 +144,7 @@ magic_compile(struct magic_set *ms, const char *magicfile)
return file_apprentice(ms, magicfile, FILE_COMPILE); return file_apprentice(ms, magicfile, FILE_COMPILE);
} }
public int file_public int
magic_check(struct magic_set *ms, const char *magicfile) magic_check(struct magic_set *ms, const char *magicfile)
{ {
if (ms == NULL) if (ms == NULL)
@ -152,7 +152,7 @@ magic_check(struct magic_set *ms, const char *magicfile)
return file_apprentice(ms, magicfile, FILE_CHECK); return file_apprentice(ms, magicfile, FILE_CHECK);
} }
public int file_public int
magic_list(struct magic_set *ms, const char *magicfile) magic_list(struct magic_set *ms, const char *magicfile)
{ {
if (ms == NULL) if (ms == NULL)
@ -165,7 +165,7 @@ magic_list(struct magic_set *ms, const char *magicfile)
/* /*
* find type of descriptor * find type of descriptor
*/ */
public const char * file_public const char *
magic_descriptor(struct magic_set *ms, int fd) magic_descriptor(struct magic_set *ms, int fd)
{ {
if (ms == NULL) if (ms == NULL)
@ -176,7 +176,7 @@ magic_descriptor(struct magic_set *ms, int fd)
/* /*
* find type of named file * find type of named file
*/ */
public const char * file_public const char *
magic_file(struct magic_set *ms, const char *inname) magic_file(struct magic_set *ms, const char *inname)
{ {
if (ms == NULL) if (ms == NULL)
@ -184,7 +184,7 @@ magic_file(struct magic_set *ms, const char *inname)
return file_or_stream(ms, inname, NULL); return file_or_stream(ms, inname, NULL);
} }
public const char * file_public const char *
magic_stream(struct magic_set *ms, php_stream *stream) magic_stream(struct magic_set *ms, php_stream *stream)
{ {
if (ms == NULL) if (ms == NULL)
@ -192,7 +192,7 @@ magic_stream(struct magic_set *ms, php_stream *stream)
return file_or_stream(ms, NULL, stream); return file_or_stream(ms, NULL, stream);
} }
private const char * file_private const char *
file_or_stream(struct magic_set *ms, const char *inname, php_stream *stream) file_or_stream(struct magic_set *ms, const char *inname, php_stream *stream)
{ {
int rv = -1; int rv = -1;
@ -268,7 +268,7 @@ out:
} }
public const char * file_public const char *
magic_buffer(struct magic_set *ms, const void *buf, size_t nb) magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
{ {
if (ms == NULL) if (ms == NULL)
@ -286,7 +286,7 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
} }
#endif #endif
public const char * file_public const char *
magic_error(struct magic_set *ms) magic_error(struct magic_set *ms)
{ {
if (ms == NULL) if (ms == NULL)
@ -294,7 +294,7 @@ magic_error(struct magic_set *ms)
return (ms->event_flags & EVENT_HAD_ERR) ? ms->o.buf : NULL; return (ms->event_flags & EVENT_HAD_ERR) ? ms->o.buf : NULL;
} }
public int file_public int
magic_errno(struct magic_set *ms) magic_errno(struct magic_set *ms)
{ {
if (ms == NULL) if (ms == NULL)
@ -302,7 +302,7 @@ magic_errno(struct magic_set *ms)
return (ms->event_flags & EVENT_HAD_ERR) ? ms->error : 0; return (ms->event_flags & EVENT_HAD_ERR) ? ms->error : 0;
} }
public int file_public int
magic_getflags(struct magic_set *ms) magic_getflags(struct magic_set *ms)
{ {
if (ms == NULL) if (ms == NULL)
@ -311,7 +311,7 @@ magic_getflags(struct magic_set *ms)
return ms->flags; return ms->flags;
} }
public int file_public int
magic_setflags(struct magic_set *ms, int flags) magic_setflags(struct magic_set *ms, int flags)
{ {
if (ms == NULL) if (ms == NULL)
@ -324,13 +324,13 @@ magic_setflags(struct magic_set *ms, int flags)
return 0; return 0;
} }
public int file_public int
magic_version(void) magic_version(void)
{ {
return MAGIC_VERSION; return MAGIC_VERSION;
} }
public int file_public int
magic_setparam(struct magic_set *ms, int param, const void *val) magic_setparam(struct magic_set *ms, int param, const void *val)
{ {
if (ms == NULL) if (ms == NULL)
@ -348,6 +348,9 @@ magic_setparam(struct magic_set *ms, int param, const void *val)
case MAGIC_PARAM_ELF_SHNUM_MAX: case MAGIC_PARAM_ELF_SHNUM_MAX:
ms->elf_shnum_max = CAST(uint16_t, *CAST(const size_t *, val)); ms->elf_shnum_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0; return 0;
case MAGIC_PARAM_ELF_SHSIZE_MAX:
ms->elf_shsize_max = *CAST(const size_t *, val);
return 0;
case MAGIC_PARAM_ELF_NOTES_MAX: case MAGIC_PARAM_ELF_NOTES_MAX:
ms->elf_notes_max = CAST(uint16_t, *CAST(const size_t *, val)); ms->elf_notes_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0; return 0;
@ -366,7 +369,7 @@ magic_setparam(struct magic_set *ms, int param, const void *val)
} }
} }
public int file_public int
magic_getparam(struct magic_set *ms, int param, void *val) magic_getparam(struct magic_set *ms, int param, void *val)
{ {
if (ms == NULL) if (ms == NULL)
@ -384,6 +387,9 @@ magic_getparam(struct magic_set *ms, int param, void *val)
case MAGIC_PARAM_ELF_SHNUM_MAX: case MAGIC_PARAM_ELF_SHNUM_MAX:
*CAST(size_t *, val) = ms->elf_shnum_max; *CAST(size_t *, val) = ms->elf_shnum_max;
return 0; return 0;
case MAGIC_PARAM_ELF_SHSIZE_MAX:
*CAST(size_t *, val) = ms->elf_shsize_max;
return 0;
case MAGIC_PARAM_ELF_NOTES_MAX: case MAGIC_PARAM_ELF_NOTES_MAX:
*CAST(size_t *, val) = ms->elf_notes_max; *CAST(size_t *, val) = ms->elf_notes_max;
return 0; return 0;

View file

@ -60,6 +60,7 @@
#define MAGIC_NO_CHECK_TOKENS 0x0100000 /* Don't check tokens */ #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_ENCODING 0x0200000 /* Don't check text encodings */
#define MAGIC_NO_CHECK_JSON 0x0400000 /* Don't check for JSON files */ #define MAGIC_NO_CHECK_JSON 0x0400000 /* Don't check for JSON files */
#define MAGIC_NO_CHECK_SIMH 0x0800000 /* Don't check for SIMH tape files */
/* No built-in tests; only consult the magic file */ /* No built-in tests; only consult the magic file */
#define MAGIC_NO_CHECK_BUILTIN ( \ #define MAGIC_NO_CHECK_BUILTIN ( \
@ -74,6 +75,7 @@
MAGIC_NO_CHECK_TOKENS | \ MAGIC_NO_CHECK_TOKENS | \
MAGIC_NO_CHECK_ENCODING | \ MAGIC_NO_CHECK_ENCODING | \
MAGIC_NO_CHECK_JSON | \ MAGIC_NO_CHECK_JSON | \
MAGIC_NO_CHECK_SIMH | \
0 \ 0 \
) )
@ -113,7 +115,7 @@ b\31transp_compression\0\
#define MAGIC_NO_CHECK_FORTRAN 0x000000 /* Don't check ascii/fortran */ #define MAGIC_NO_CHECK_FORTRAN 0x000000 /* Don't check ascii/fortran */
#define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */ #define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */
#define MAGIC_VERSION 543 /* This implementation */ #define MAGIC_VERSION 545 /* This implementation */
#ifdef __cplusplus #ifdef __cplusplus
@ -151,6 +153,8 @@ int magic_errno(magic_t);
#define MAGIC_PARAM_REGEX_MAX 5 #define MAGIC_PARAM_REGEX_MAX 5
#define MAGIC_PARAM_BYTES_MAX 6 #define MAGIC_PARAM_BYTES_MAX 6
#define MAGIC_PARAM_ENCODING_MAX 7 #define MAGIC_PARAM_ENCODING_MAX 7
#define MAGIC_PARAM_ELF_SHSIZE_MAX 8
#define MAGIC_PARAM_MAGWARN_MAX 9
int magic_setparam(magic_t, int, const void *); int magic_setparam(magic_t, int, const void *);
int magic_getparam(magic_t, int, void *); int magic_getparam(magic_t, int, void *);

View file

@ -32,7 +32,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: print.c,v 1.92 2022/09/10 13:21:42 christos Exp $") FILE_RCSID("@(#)$File: print.c,v 1.99 2023/07/17 16:40:57 christos Exp $")
#endif /* lint */ #endif /* lint */
#include <string.h> #include <string.h>
@ -46,13 +46,13 @@ FILE_RCSID("@(#)$File: print.c,v 1.92 2022/09/10 13:21:42 christos Exp $")
#include "cdf.h" #include "cdf.h"
#ifndef COMPILE_ONLY #ifndef COMPILE_ONLY
protected void file_protected void
file_mdump(struct magic *m) file_mdump(struct magic *m)
{ {
static const char optyp[] = { FILE_OPS }; static const char optyp[] = { FILE_OPS };
char tbuf[256]; char tbuf[256];
(void) fprintf(stderr, "%u: %.*s %u", m->lineno, (void) fprintf(stderr, "%u: %.*s %d", m->lineno,
(m->cont_level & 7) + 1, ">>>>>>>>", m->offset); (m->cont_level & 7) + 1, ">>>>>>>>", m->offset);
if (m->flag & INDIR) { if (m->flag & INDIR) {
@ -62,7 +62,7 @@ file_mdump(struct magic *m)
"*bad in_type*"); "*bad in_type*");
if (m->in_op & FILE_OPINVERSE) if (m->in_op & FILE_OPINVERSE)
(void) fputc('~', stderr); (void) fputc('~', stderr);
(void) fprintf(stderr, "%c%u),", (void) fprintf(stderr, "%c%d),",
(CAST(size_t, m->in_op & FILE_OPS_MASK) < (CAST(size_t, m->in_op & FILE_OPS_MASK) <
__arraycount(optyp)) ? __arraycount(optyp)) ?
optyp[m->in_op & FILE_OPS_MASK] : '?', m->in_offset); optyp[m->in_op & FILE_OPS_MASK] : '?', m->in_offset);
@ -134,7 +134,7 @@ file_mdump(struct magic *m)
case FILE_BESHORT: case FILE_BESHORT:
case FILE_BELONG: case FILE_BELONG:
case FILE_INDIRECT: case FILE_INDIRECT:
(void) fprintf(stderr, "%d", m->value.l); (void) fprintf(stderr, "%d", CAST(int32_t, m->value.l));
break; break;
case FILE_BEQUAD: case FILE_BEQUAD:
case FILE_LEQUAD: case FILE_LEQUAD:
@ -242,7 +242,7 @@ file_mdump(struct magic *m)
#endif #endif
/*VARARGS*/ /*VARARGS*/
protected void file_protected void
file_magwarn(struct magic_set *ms, const char *f, ...) file_magwarn(struct magic_set *ms, const char *f, ...)
{ {
va_list va; va_list va;
@ -260,14 +260,15 @@ file_magwarn(struct magic_set *ms, const char *f, ...)
} }
} }
protected const char * file_protected const char *
file_fmtvarint(char *buf, size_t blen, const unsigned char *us, int t) file_fmtvarint(char *buf, size_t blen, const unsigned char *us, int t)
{ {
snprintf(buf, blen, "%jd", file_varint2uintmax_t(us, t, NULL)); snprintf(buf, blen, "%jd", CAST(intmax_t,
file_varint2uintmax_t(us, t, NULL)));
return buf; return buf;
} }
protected const char * file_protected const char *
file_fmtdatetime(char *buf, size_t bsize, uint64_t v, int flags) file_fmtdatetime(char *buf, size_t bsize, uint64_t v, int flags)
{ {
char *pp; char *pp;
@ -284,6 +285,9 @@ file_fmtdatetime(char *buf, size_t bsize, uint64_t v, int flags)
t = CAST(time_t, v); t = CAST(time_t, v);
} }
if (t > MAX_CTIME)
goto out;
if (flags & FILE_T_LOCAL) { if (flags & FILE_T_LOCAL) {
tm = php_localtime_r(&t, &tmz); tm = php_localtime_r(&t, &tmz);
} else { } else {
@ -306,7 +310,7 @@ out:
* https://docs.microsoft.com/en-us/windows/win32/api/winbase/\ * https://docs.microsoft.com/en-us/windows/win32/api/winbase/\
* nf-winbase-dosdatetimetofiletime?redirectedfrom=MSDN * nf-winbase-dosdatetimetofiletime?redirectedfrom=MSDN
*/ */
protected const char * file_protected const char *
file_fmtdate(char *buf, size_t bsize, uint16_t v) file_fmtdate(char *buf, size_t bsize, uint16_t v)
{ {
struct tm tm; struct tm tm;
@ -325,7 +329,7 @@ out:
return buf; return buf;
} }
protected const char * file_protected const char *
file_fmttime(char *buf, size_t bsize, uint16_t v) file_fmttime(char *buf, size_t bsize, uint16_t v)
{ {
struct tm tm; struct tm tm;
@ -345,7 +349,7 @@ out:
} }
protected const char * file_protected const char *
file_fmtnum(char *buf, size_t blen, const char *us, int base) file_fmtnum(char *buf, size_t blen, const char *us, int base)
{ {
char *endptr; char *endptr;

View file

@ -26,7 +26,7 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: readcdf.c,v 1.76 2022/01/17 16:59:01 christos Exp $") FILE_RCSID("@(#)$File: readcdf.c,v 1.80 2023/01/24 20:13:40 christos Exp $")
#endif #endif
#include <assert.h> #include <assert.h>
@ -94,7 +94,7 @@ static const struct cv {
}, },
}; };
private const char * file_private const char *
cdf_clsid_to_mime(const uint64_t clsid[2], const struct cv *cv) cdf_clsid_to_mime(const uint64_t clsid[2], const struct cv *cv)
{ {
size_t i; size_t i;
@ -105,7 +105,7 @@ cdf_clsid_to_mime(const uint64_t clsid[2], const struct cv *cv)
return NULL; return NULL;
} }
private const char * file_private const char *
cdf_app_to_mime(const char *vbuf, const struct nv *nv) cdf_app_to_mime(const char *vbuf, const struct nv *nv)
{ {
size_t i; size_t i;
@ -131,7 +131,7 @@ cdf_app_to_mime(const char *vbuf, const struct nv *nv)
return rv; return rv;
} }
private int file_private int
cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, 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 count, const cdf_directory_t *root_storage)
{ {
@ -251,7 +251,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
return 1; return 1;
} }
private int file_private int
cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h, cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h,
const cdf_stream_t *sst) const cdf_stream_t *sst)
{ {
@ -282,7 +282,7 @@ cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h,
return 1; return 1;
} }
private int file_private int
cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
const cdf_stream_t *sst, const cdf_directory_t *root_storage) const cdf_stream_t *sst, const cdf_directory_t *root_storage)
{ {
@ -341,7 +341,7 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
} }
#ifdef notdef #ifdef notdef
private char * file_private char *
format_clsid(char *buf, size_t len, const uint64_t uuid[2]) { 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, PRIx64 "-%.12" PRIx64,
@ -354,7 +354,7 @@ format_clsid(char *buf, size_t len, const uint64_t uuid[2]) {
} }
#endif #endif
private int file_private int
cdf_file_catalog_info(struct magic_set *ms, const cdf_info_t *info, cdf_file_catalog_info(struct magic_set *ms, const cdf_info_t *info,
const cdf_header_t *h, const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_header_t *h, const cdf_sat_t *sat, const cdf_sat_t *ssat,
const cdf_stream_t *sst, const cdf_dir_t *dir, cdf_stream_t *scn) const cdf_stream_t *sst, const cdf_dir_t *dir, cdf_stream_t *scn)
@ -372,7 +372,7 @@ cdf_file_catalog_info(struct magic_set *ms, const cdf_info_t *info,
return i; return i;
} }
private int file_private int
cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info, cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info,
const cdf_header_t *h, const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_header_t *h, const cdf_sat_t *sat, const cdf_sat_t *ssat,
const cdf_stream_t *sst, const cdf_dir_t *dir, cdf_stream_t *scn, const cdf_stream_t *sst, const cdf_dir_t *dir, cdf_stream_t *scn,
@ -420,7 +420,7 @@ cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info,
return i; return i;
} }
private struct sinfo { file_private struct sinfo {
const char *name; const char *name;
const char *mime; const char *mime;
const char *sections[5]; const char *sections[5];
@ -497,7 +497,7 @@ private struct sinfo {
}, },
}; };
private int file_private int
cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir) cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir)
{ {
size_t sd, j; size_t sd, j;
@ -526,7 +526,7 @@ cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir)
return -1; return -1;
} }
protected int file_protected int
file_trycdf(struct magic_set *ms, const struct buffer *b) file_trycdf(struct magic_set *ms, const struct buffer *b)
{ {
int fd = b->fd; int fd = b->fd;
@ -602,7 +602,7 @@ file_trycdf(struct magic_set *ms, const struct buffer *b)
sizeof(HWP5_SIGNATURE) - 1) == 0) { sizeof(HWP5_SIGNATURE) - 1) == 0) {
if (NOTMIME(ms)) { if (NOTMIME(ms)) {
if (file_printf(ms, if (file_printf(ms,
"Hangul (Korean) Word Processor File 5.x") == -1) "Hancom HWP (Hangul Word Processor) file, version 5.0") == -1)
return -1; return -1;
} else if (ms->flags & MAGIC_MIME_TYPE) { } else if (ms->flags & MAGIC_MIME_TYPE) {
if (file_printf(ms, "application/x-hwp") == -1) if (file_printf(ms, "application/x-hwp") == -1)

View file

@ -32,40 +32,42 @@
#include "file.h" #include "file.h"
#ifndef lint #ifndef lint
FILE_RCSID("@(#)$File: softmagic.c,v 1.328 2022/09/13 18:46:07 christos Exp $") FILE_RCSID("@(#)$File: softmagic.c,v 1.345 2023/07/02 12:48:39 christos Exp $")
#endif /* lint */ #endif /* lint */
#include "magic.h" #include "magic.h"
#include <assert.h> #include <assert.h>
#include <math.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h>
#include <time.h> #include <time.h>
#include "der.h" #include "der.h"
private int match(struct magic_set *, struct magic *, size_t, file_private int match(struct magic_set *, struct magic *, size_t,
const struct buffer *, size_t, int, int, int, uint16_t *, const struct buffer *, size_t, int, int, int, uint16_t *,
uint16_t *, int *, int *, int *, int *); uint16_t *, int *, int *, int *, int *, int *);
private int mget(struct magic_set *, struct magic *, const struct buffer *, file_private int mget(struct magic_set *, struct magic *, const struct buffer *,
const unsigned char *, size_t, const unsigned char *, size_t,
size_t, unsigned int, int, int, int, uint16_t *, size_t, unsigned int, int, int, int, uint16_t *,
uint16_t *, int *, int *, int *, int *); uint16_t *, int *, int *, int *, int *, int *);
private int msetoffset(struct magic_set *, struct magic *, struct buffer *, file_private int msetoffset(struct magic_set *, struct magic *, struct buffer *,
const struct buffer *, size_t, unsigned int); const struct buffer *, size_t, unsigned int);
private int magiccheck(struct magic_set *, struct magic *); file_private int magiccheck(struct magic_set *, struct magic *);
private int mprint(struct magic_set *, struct magic *); file_private int mprint(struct magic_set *, struct magic *);
private int moffset(struct magic_set *, struct magic *, const struct buffer *, file_private int moffset(struct magic_set *, struct magic *, const struct buffer *,
int32_t *); int32_t *);
private void mdebug(uint32_t, const char *, size_t); file_private void mdebug(uint32_t, const char *, size_t);
private int mcopy(struct magic_set *, union VALUETYPE *, int, int, file_private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
const unsigned char *, uint32_t, size_t, struct magic *); const unsigned char *, uint32_t, size_t, struct magic *);
private int mconvert(struct magic_set *, struct magic *, int); file_private int mconvert(struct magic_set *, struct magic *, int);
private int print_sep(struct magic_set *, int); file_private int print_sep(struct magic_set *, int);
private int handle_annotation(struct magic_set *, struct magic *, int); file_private int handle_annotation(struct magic_set *, struct magic *, int);
private int cvt_8(union VALUETYPE *, const struct magic *); file_private int cvt_8(union VALUETYPE *, const struct magic *);
private int cvt_16(union VALUETYPE *, const struct magic *); file_private int cvt_16(union VALUETYPE *, const struct magic *);
private int cvt_32(union VALUETYPE *, const struct magic *); file_private int cvt_32(union VALUETYPE *, const struct magic *);
private int cvt_64(union VALUETYPE *, const struct magic *); file_private int cvt_64(union VALUETYPE *, const struct magic *);
#define OFFSET_OOB(n, o, i) ((n) < CAST(uint32_t, (o)) || (i) > ((n) - (o))) #define OFFSET_OOB(n, o, i) ((n) < CAST(uint32_t, (o)) || (i) > ((n) - (o)))
#define BE64(p) ( \ #define BE64(p) ( \
@ -113,12 +115,12 @@ private int cvt_64(union VALUETYPE *, const struct magic *);
* Passed the name and FILE * of one file to be typed. * Passed the name and FILE * of one file to be typed.
*/ */
/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
protected int file_protected int
file_softmagic(struct magic_set *ms, const struct buffer *b, file_softmagic(struct magic_set *ms, const struct buffer *b,
uint16_t *indir_count, uint16_t *name_count, int mode, int text) uint16_t *indir_count, uint16_t *name_count, int mode, int text)
{ {
struct mlist *ml; struct mlist *ml;
int rv = 0, printed_something = 0, need_separator = 0; int rv = 0, printed_something = 0, need_separator = 0, firstline = 1;
uint16_t nc, ic; uint16_t nc, ic;
if (name_count == NULL) { if (name_count == NULL) {
@ -133,7 +135,8 @@ file_softmagic(struct magic_set *ms, const struct buffer *b,
for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next) { for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next) {
int ret = match(ms, ml->magic, ml->nmagic, b, int ret = match(ms, ml->magic, ml->nmagic, b,
0, mode, text, 0, indir_count, name_count, 0, mode, text, 0, indir_count, name_count,
&printed_something, &need_separator, NULL, NULL); &printed_something, &need_separator, &firstline,
NULL, NULL);
switch (ret) { switch (ret) {
case -1: case -1:
return ret; return ret;
@ -154,7 +157,7 @@ file_softmagic(struct magic_set *ms, const struct buffer *b,
#if defined(FILE_FMTDEBUG) && defined(HAVE_FMTCHECK) #if defined(FILE_FMTDEBUG) && defined(HAVE_FMTCHECK)
#define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__) #define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__)
private const char * __attribute__((__format_arg__(3))) file_private const char * __attribute__((__format_arg__(3)))
file_fmtcheck(struct magic_set *ms, const char *desc, const char *def, file_fmtcheck(struct magic_set *ms, const char *desc, const char *def,
const char *file, size_t line) const char *file, size_t line)
{ {
@ -205,19 +208,17 @@ file_fmtcheck(struct magic_set *ms, const char *desc, const char *def,
* If a continuation matches, we bump the current continuation level * If a continuation matches, we bump the current continuation level
* so that higher-level continuations are processed. * so that higher-level continuations are processed.
*/ */
private int file_private int
match(struct magic_set *ms, struct magic *magic, match(struct magic_set *ms, struct magic *magic,
size_t nmagic, const struct buffer *b, size_t offset, int mode, int text, size_t nmagic, const struct buffer *b, size_t offset, int mode, int text,
int flip, uint16_t *indir_count, uint16_t *name_count, 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 *firstline,
int *found_match) int *returnval, int *found_match)
{ {
uint32_t magindex = 0; uint32_t magindex = 0;
unsigned int cont_level = 0; unsigned int cont_level = 0;
int found_matchv = 0; /* 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 returnvalv = 0, e;
/* a flag to print X\n X\n- X */
int firstline = !(*printed_something || *need_separator);
struct buffer bb; struct buffer bb;
int print = (ms->flags & MAGIC_NODESC) == 0; int print = (ms->flags & MAGIC_NODESC) == 0;
@ -260,7 +261,8 @@ flush:
switch (mget(ms, m, b, CAST(const unsigned char *, bb.fbuf), switch (mget(ms, m, b, CAST(const unsigned char *, bb.fbuf),
bb.flen, offset, cont_level, bb.flen, offset, cont_level,
mode, text, flip, indir_count, name_count, mode, text, flip, indir_count, name_count,
printed_something, need_separator, returnval, found_match)) printed_something, need_separator, firstline, returnval,
found_match))
{ {
case -1: case -1:
return -1; return -1;
@ -293,12 +295,13 @@ flush:
goto flush; goto flush;
} }
if ((e = handle_annotation(ms, m, firstline)) != 0) if ((e = handle_annotation(ms, m, *firstline)) != 0)
{ {
*found_match = 1; *found_match = 1;
*need_separator = 1; *need_separator = 1;
*printed_something = 1; *printed_something = 1;
*returnval = 1; *returnval = 1;
*firstline = 0;
return e; return e;
} }
@ -312,7 +315,7 @@ flush:
*returnval = 1; *returnval = 1;
*need_separator = 1; *need_separator = 1;
*printed_something = 1; *printed_something = 1;
if (print_sep(ms, firstline) == -1) if (print_sep(ms, *firstline) == -1)
return -1; return -1;
if (mprint(ms, m) == -1) if (mprint(ms, m) == -1)
return -1; return -1;
@ -370,7 +373,7 @@ flush:
bb.fbuf), bb.flen, offset, bb.fbuf), bb.flen, offset,
cont_level, mode, text, flip, indir_count, cont_level, mode, text, flip, indir_count,
name_count, printed_something, need_separator, name_count, printed_something, need_separator,
returnval, found_match)) { firstline, returnval, found_match)) {
case -1: case -1:
return -1; return -1;
case 0: case 0:
@ -407,7 +410,7 @@ flush:
} else } else
ms->c.li[cont_level].got_match = 1; ms->c.li[cont_level].got_match = 1;
if ((e = handle_annotation(ms, m, firstline)) if ((e = handle_annotation(ms, m, *firstline))
!= 0) { != 0) {
*found_match = 1; *found_match = 1;
*need_separator = 1; *need_separator = 1;
@ -433,7 +436,7 @@ flush:
*/ */
if (!*printed_something) { if (!*printed_something) {
*printed_something = 1; *printed_something = 1;
if (print_sep(ms, firstline) if (print_sep(ms, *firstline)
== -1) == -1)
return -1; return -1;
} }
@ -469,21 +472,21 @@ flush:
} }
} }
if (*printed_something) { if (*printed_something) {
firstline = 0; *firstline = 0;
} }
if (*found_match) { if (*found_match) {
if ((ms->flags & MAGIC_CONTINUE) == 0) if ((ms->flags & MAGIC_CONTINUE) == 0)
return *returnval; return *returnval;
// So that we print a separator // So that we print a separator
*printed_something = 0; *printed_something = 0;
firstline = 0; *firstline = 0;
} }
cont_level = 0; cont_level = 0;
} }
return *returnval; return *returnval;
} }
private int file_private int
check_fmt(struct magic_set *ms, const char *fmt) check_fmt(struct magic_set *ms, const char *fmt)
{ {
pcre_cache_entry *pce; pcre_cache_entry *pce;
@ -504,7 +507,7 @@ check_fmt(struct magic_set *ms, const char *fmt)
php_pcre_free_match_data(match_data); php_pcre_free_match_data(match_data);
} }
} }
zend_string_release(pattern); zend_string_release_ex(pattern, 0);
return rv; return rv;
} }
@ -585,7 +588,7 @@ varexpand(struct magic_set *ms, char *buf, size_t len, const char *str)
} }
private int file_private int
mprint(struct magic_set *ms, struct magic *m) mprint(struct magic_set *ms, struct magic *m)
{ {
uint64_t v; uint64_t v;
@ -836,7 +839,7 @@ mprint(struct magic_set *ms, struct magic *m)
return 0; return 0;
} }
private int file_private int
moffset(struct magic_set *ms, struct magic *m, const struct buffer *b, moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
int32_t *op) int32_t *op)
{ {
@ -989,7 +992,7 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
return 1; return 1;
} }
private uint32_t file_private uint32_t
cvt_id3(struct magic_set *ms, uint32_t v) cvt_id3(struct magic_set *ms, uint32_t v)
{ {
v = ((((v >> 0) & 0x7f) << 0) | v = ((((v >> 0) & 0x7f) << 0) |
@ -1001,7 +1004,7 @@ cvt_id3(struct magic_set *ms, uint32_t v)
return v; return v;
} }
private int file_private int
cvt_flip(int type, int flip) cvt_flip(int type, int flip)
{ {
if (flip == 0) if (flip == 0)
@ -1086,28 +1089,28 @@ cvt_flip(int type, int flip)
if (m->mask_op & FILE_OPINVERSE) \ if (m->mask_op & FILE_OPINVERSE) \
p->fld = ~p->fld \ p->fld = ~p->fld \
private int file_private int
cvt_8(union VALUETYPE *p, const struct magic *m) cvt_8(union VALUETYPE *p, const struct magic *m)
{ {
DO_CVT(b, uint8_t); DO_CVT(b, uint8_t);
return 0; return 0;
} }
private int file_private int
cvt_16(union VALUETYPE *p, const struct magic *m) cvt_16(union VALUETYPE *p, const struct magic *m)
{ {
DO_CVT(h, uint16_t); DO_CVT(h, uint16_t);
return 0; return 0;
} }
private int file_private int
cvt_32(union VALUETYPE *p, const struct magic *m) cvt_32(union VALUETYPE *p, const struct magic *m)
{ {
DO_CVT(l, uint32_t); DO_CVT(l, uint32_t);
return 0; return 0;
} }
private int file_private int
cvt_64(union VALUETYPE *p, const struct magic *m) cvt_64(union VALUETYPE *p, const struct magic *m)
{ {
DO_CVT(q, uint64_t); DO_CVT(q, uint64_t);
@ -1133,14 +1136,14 @@ cvt_64(union VALUETYPE *p, const struct magic *m)
break; \ break; \
} \ } \
private int file_private int
cvt_float(union VALUETYPE *p, const struct magic *m) cvt_float(union VALUETYPE *p, const struct magic *m)
{ {
DO_CVT2(f, float); DO_CVT2(f, float);
return 0; return 0;
} }
private int file_private int
cvt_double(union VALUETYPE *p, const struct magic *m) cvt_double(union VALUETYPE *p, const struct magic *m)
{ {
DO_CVT2(d, double); DO_CVT2(d, double);
@ -1152,7 +1155,7 @@ cvt_double(union VALUETYPE *p, const struct magic *m)
* While we're here, let's apply the mask operation * While we're here, let's apply the mask operation
* (unless you have a better idea) * (unless you have a better idea)
*/ */
private int file_private int
mconvert(struct magic_set *ms, struct magic *m, int flip) mconvert(struct magic_set *ms, struct magic *m, int flip)
{ {
union VALUETYPE *p = &ms->ms_value; union VALUETYPE *p = &ms->ms_value;
@ -1315,7 +1318,7 @@ out:
} }
private void file_private void
mdebug(uint32_t offset, const char *str, size_t len) mdebug(uint32_t offset, const char *str, size_t len)
{ {
(void) fprintf(stderr, "mget/%" SIZE_T_FORMAT "u @%d: ", len, offset); (void) fprintf(stderr, "mget/%" SIZE_T_FORMAT "u @%d: ", len, offset);
@ -1324,10 +1327,11 @@ mdebug(uint32_t offset, const char *str, size_t len)
(void) fputc('\n', stderr); (void) fputc('\n', stderr);
} }
private int file_private int
mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m) const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)
{ {
size_t size = sizeof(*p);
/* /*
* Note: FILE_SEARCH and FILE_REGEX do not actually copy * Note: FILE_SEARCH and FILE_REGEX do not actually copy
* anything, but setup pointers into the source * anything, but setup pointers into the source
@ -1425,6 +1429,9 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
} }
case FILE_STRING: /* XXX - these two should not need */ case FILE_STRING: /* XXX - these two should not need */
case FILE_PSTRING: /* to copy anything, but do anyway. */ case FILE_PSTRING: /* to copy anything, but do anyway. */
if (m->str_range != 0 && m->str_range < sizeof(*p))
size = m->str_range;
break;
default: default:
break; break;
} }
@ -1440,10 +1447,10 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
(void)memset(p, '\0', sizeof(*p)); (void)memset(p, '\0', sizeof(*p));
return 0; return 0;
} }
if (nbytes - offset < sizeof(*p)) if (nbytes - offset < size)
nbytes = nbytes - offset; nbytes = nbytes - offset;
else else
nbytes = sizeof(*p); nbytes = size;
(void)memcpy(p, s + offset, nbytes); (void)memcpy(p, s + offset, nbytes);
@ -1457,10 +1464,19 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
return 0; return 0;
} }
private uint32_t file_private int
do_ops(struct magic *m, intmax_t lhs, intmax_t off) do_ops(struct magic_set *ms, struct magic *m, uint32_t *rv, intmax_t lhs,
intmax_t off)
{ {
intmax_t offset; intmax_t offset;
// On purpose not INTMAX_MAX
if (lhs >= UINT_MAX || lhs <= INT_MIN ||
off >= UINT_MAX || off <= INT_MIN) {
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "lhs/off overflow %jd %jd\n", lhs, off);
return 1;
}
if (off) { if (off) {
switch (m->in_op & FILE_OPS_MASK) { switch (m->in_op & FILE_OPS_MASK) {
case FILE_OPAND: case FILE_OPAND:
@ -1492,11 +1508,16 @@ do_ops(struct magic *m, intmax_t lhs, intmax_t off)
offset = lhs; offset = lhs;
if (m->in_op & FILE_OPINVERSE) if (m->in_op & FILE_OPINVERSE)
offset = ~offset; offset = ~offset;
if (offset >= UINT_MAX) {
return CAST(uint32_t, offset); if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "offset overflow %jd\n", offset);
return 1;
}
*rv = CAST(uint32_t, offset);
return 0;
} }
private int file_private int
msetoffset(struct magic_set *ms, struct magic *m, struct buffer *bb, msetoffset(struct magic_set *ms, struct magic *m, struct buffer *bb,
const struct buffer *b, size_t o, unsigned int cont_level) const struct buffer *b, size_t o, unsigned int cont_level)
{ {
@ -1546,7 +1567,7 @@ normal:
return 0; return 0;
} }
private int file_private int
save_cont(struct magic_set *ms, struct cont *c) save_cont(struct magic_set *ms, struct cont *c)
{ {
size_t len; size_t len;
@ -1561,18 +1582,18 @@ save_cont(struct magic_set *ms, struct cont *c)
return 0; return 0;
} }
private void file_private void
restore_cont(struct magic_set *ms, struct cont *c) restore_cont(struct magic_set *ms, struct cont *c)
{ {
efree(ms->c.li); efree(ms->c.li);
ms->c = *c; ms->c = *c;
} }
private int file_private int
mget(struct magic_set *ms, struct magic *m, const struct buffer *b, 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, 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 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 *firstline, int *returnval,
int *found_match) int *found_match)
{ {
uint32_t eoffset, offset = ms->offset; uint32_t eoffset, offset = ms->offset;
@ -1693,22 +1714,26 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
case FILE_BYTE: case FILE_BYTE:
if (OFFSET_OOB(nbytes, offset, 1)) if (OFFSET_OOB(nbytes, offset, 1))
return 0; return 0;
offset = do_ops(m, SEXT(sgn,8,p->b), off); if (do_ops(ms, m, &offset, SEXT(sgn,8,p->b), off))
return 0;
break; break;
case FILE_BESHORT: case FILE_BESHORT:
if (OFFSET_OOB(nbytes, offset, 2)) if (OFFSET_OOB(nbytes, offset, 2))
return 0; return 0;
offset = do_ops(m, SEXT(sgn,16,BE16(p)), off); if (do_ops(ms, m, &offset, SEXT(sgn,16,BE16(p)), off))
return 0;
break; break;
case FILE_LESHORT: case FILE_LESHORT:
if (OFFSET_OOB(nbytes, offset, 2)) if (OFFSET_OOB(nbytes, offset, 2))
return 0; return 0;
offset = do_ops(m, SEXT(sgn,16,LE16(p)), off); if (do_ops(ms, m, &offset, SEXT(sgn,16,LE16(p)), off))
return 0;
break; break;
case FILE_SHORT: case FILE_SHORT:
if (OFFSET_OOB(nbytes, offset, 2)) if (OFFSET_OOB(nbytes, offset, 2))
return 0; return 0;
offset = do_ops(m, SEXT(sgn,16,p->h), off); if (do_ops(ms, m, &offset, SEXT(sgn,16,p->h), off))
return 0;
break; break;
case FILE_BELONG: case FILE_BELONG:
case FILE_BEID3: case FILE_BEID3:
@ -1717,7 +1742,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
lhs = BE32(p); lhs = BE32(p);
if (in_type == FILE_BEID3) if (in_type == FILE_BEID3)
lhs = cvt_id3(ms, CAST(uint32_t, lhs)); lhs = cvt_id3(ms, CAST(uint32_t, lhs));
offset = do_ops(m, SEXT(sgn,32,lhs), off); if (do_ops(ms, m, &offset, SEXT(sgn,32,lhs), off))
return 0;
break; break;
case FILE_LELONG: case FILE_LELONG:
case FILE_LEID3: case FILE_LEID3:
@ -1726,33 +1752,39 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
lhs = LE32(p); lhs = LE32(p);
if (in_type == FILE_LEID3) if (in_type == FILE_LEID3)
lhs = cvt_id3(ms, CAST(uint32_t, lhs)); lhs = cvt_id3(ms, CAST(uint32_t, lhs));
offset = do_ops(m, SEXT(sgn,32,lhs), off); if (do_ops(ms, m, &offset, SEXT(sgn,32,lhs), off))
return 0;
break; break;
case FILE_MELONG: case FILE_MELONG:
if (OFFSET_OOB(nbytes, offset, 4)) if (OFFSET_OOB(nbytes, offset, 4))
return 0; return 0;
offset = do_ops(m, SEXT(sgn,32,ME32(p)), off); if (do_ops(ms, m, &offset, SEXT(sgn,32,ME32(p)), off))
return 0;
break; break;
case FILE_LONG: case FILE_LONG:
if (OFFSET_OOB(nbytes, offset, 4)) if (OFFSET_OOB(nbytes, offset, 4))
return 0; return 0;
offset = do_ops(m, SEXT(sgn,32,p->l), off); if (do_ops(ms, m, &offset, SEXT(sgn,32,p->l), off))
return 0;
break; break;
case FILE_LEQUAD: case FILE_LEQUAD:
if (OFFSET_OOB(nbytes, offset, 8)) if (OFFSET_OOB(nbytes, offset, 8))
return 0; return 0;
offset = do_ops(m, SEXT(sgn,64,LE64(p)), off); if (do_ops(ms, m, &offset, SEXT(sgn,64,LE64(p)), off))
return 0;
break; break;
case FILE_BEQUAD: case FILE_BEQUAD:
if (OFFSET_OOB(nbytes, offset, 8)) if (OFFSET_OOB(nbytes, offset, 8))
return 0; return 0;
offset = do_ops(m, SEXT(sgn,64,BE64(p)), off); if (do_ops(ms, m, &offset, SEXT(sgn,64,BE64(p)), off))
return 0;
break; break;
case FILE_OCTAL: case FILE_OCTAL:
if (OFFSET_OOB(nbytes, offset, m->vallen)) if (OFFSET_OOB(nbytes, offset, m->vallen))
return 0; return 0;
offset = do_ops(m, if(do_ops(ms, m, &offset,
SEXT(sgn,64,strtoull(p->s, NULL, 8)), off); SEXT(sgn,64,strtoull(p->s, NULL, 8)), off))
return 0;
break; break;
default: default:
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
@ -1864,6 +1896,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
bb = *b; bb = *b;
bb.fbuf = s + offset; bb.fbuf = s + offset;
bb.flen = nbytes - offset; bb.flen = nbytes - offset;
bb.ebuf = NULL;
bb.elen = 0;
rv = -1; rv = -1;
for (mlp = ms->mlist[0]->next; mlp != ms->mlist[0]; for (mlp = ms->mlist[0]->next; mlp != ms->mlist[0];
mlp = mlp->next) mlp = mlp->next)
@ -1871,9 +1905,10 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
if ((rv = match(ms, mlp->magic, if ((rv = match(ms, mlp->magic,
mlp->nmagic, &bb, 0, BINTEST, text, 0, indir_count, mlp->nmagic, &bb, 0, BINTEST, text, 0, indir_count,
name_count, printed_something, need_separator, name_count, printed_something, need_separator,
NULL, NULL)) != 0) firstline, NULL, NULL)) != 0)
break; break;
} }
buffer_fini(&bb);
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv); fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
@ -1923,7 +1958,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
eoffset = ms->eoffset; eoffset = ms->eoffset;
rv = match(ms, ml.magic, ml.nmagic, b, rv = match(ms, ml.magic, ml.nmagic, b,
offset + o, mode, text, flip, indir_count, name_count, offset + o, mode, text, flip, indir_count, name_count,
printed_something, need_separator, returnval, printed_something, need_separator, firstline, returnval,
&nfound_match); &nfound_match);
ms->ms_value.q = nfound_match; ms->ms_value.q = nfound_match;
(*name_count)--; (*name_count)--;
@ -1935,7 +1970,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
*need_separator = oneed_separator; *need_separator = oneed_separator;
ms->offset = offset; ms->offset = offset;
ms->eoffset = eoffset; ms->eoffset = eoffset;
return rv; return rv || *found_match;
case FILE_NAME: case FILE_NAME:
if (ms->flags & MAGIC_NODESC) if (ms->flags & MAGIC_NODESC)
@ -1954,7 +1989,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
return 1; return 1;
} }
private uint64_t file_private uint64_t
file_strncmp(const char *s1, const char *s2, size_t len, size_t maxlen, file_strncmp(const char *s1, const char *s2, size_t len, size_t maxlen,
uint32_t flags) uint32_t flags)
{ {
@ -2033,7 +2068,7 @@ file_strncmp(const char *s1, const char *s2, size_t len, size_t maxlen,
return v; return v;
} }
private uint64_t file_private uint64_t
file_strncmp16(const char *a, const char *b, size_t len, size_t maxlen, file_strncmp16(const char *a, const char *b, size_t len, size_t maxlen,
uint32_t flags) uint32_t flags)
{ {
@ -2046,7 +2081,7 @@ file_strncmp16(const char *a, const char *b, size_t len, size_t maxlen,
return file_strncmp(a, b, len, maxlen, flags); return file_strncmp(a, b, len, maxlen, flags);
} }
private int file_private int
magiccheck(struct magic_set *ms, struct magic *m) magiccheck(struct magic_set *ms, struct magic *m)
{ {
uint64_t l = m->value.q; uint64_t l = m->value.q;
@ -2115,19 +2150,19 @@ magiccheck(struct magic_set *ms, struct magic *m)
break; break;
case '!': case '!':
matched = fv != fl; matched = isunordered(fl, fv) ? 1 : fv != fl;
break; break;
case '=': case '=':
matched = fv == fl; matched = isunordered(fl, fv) ? 0 : fv == fl;
break; break;
case '>': case '>':
matched = fv > fl; matched = isgreater(fv, fl);
break; break;
case '<': case '<':
matched = fv < fl; matched = isless(fv, fl);
break; break;
default: default:
@ -2148,19 +2183,19 @@ magiccheck(struct magic_set *ms, struct magic *m)
break; break;
case '!': case '!':
matched = dv != dl; matched = isunordered(dv, dl) ? 1 : dv != dl;
break; break;
case '=': case '=':
matched = dv == dl; matched = isunordered(dv, dl) ? 0 : dv == dl;
break; break;
case '>': case '>':
matched = dv > dl; matched = isgreater(dv, dl);
break; break;
case '<': case '<':
matched = dv < dl; matched = isless(dv, dl);
break; break;
default: default:
@ -2340,7 +2375,7 @@ error_out:
case 'x': case 'x':
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT (void) fprintf(stderr, "%" INT64_T_FORMAT
"u == *any* = 1\n", CAST(unsigned long long, v)); "u == *any* = 1", CAST(unsigned long long, v));
matched = 1; matched = 1;
break; break;
@ -2348,7 +2383,7 @@ error_out:
matched = v != l; matched = v != l;
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT "u != %" (void) fprintf(stderr, "%" INT64_T_FORMAT "u != %"
INT64_T_FORMAT "u = %d\n", INT64_T_FORMAT "u = %d",
CAST(unsigned long long, v), CAST(unsigned long long, v),
CAST(unsigned long long, l), matched); CAST(unsigned long long, l), matched);
break; break;
@ -2357,7 +2392,7 @@ error_out:
matched = v == l; matched = v == l;
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT "u == %" (void) fprintf(stderr, "%" INT64_T_FORMAT "u == %"
INT64_T_FORMAT "u = %d\n", INT64_T_FORMAT "u = %d",
CAST(unsigned long long, v), CAST(unsigned long long, v),
CAST(unsigned long long, l), matched); CAST(unsigned long long, l), matched);
break; break;
@ -2367,7 +2402,7 @@ error_out:
matched = v > l; matched = v > l;
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT (void) fprintf(stderr, "%" INT64_T_FORMAT
"u > %" INT64_T_FORMAT "u = %d\n", "u > %" INT64_T_FORMAT "u = %d",
CAST(unsigned long long, v), CAST(unsigned long long, v),
CAST(unsigned long long, l), matched); CAST(unsigned long long, l), matched);
} }
@ -2375,7 +2410,7 @@ error_out:
matched = CAST(int64_t, v) > CAST(int64_t, l); matched = CAST(int64_t, v) > CAST(int64_t, l);
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT (void) fprintf(stderr, "%" INT64_T_FORMAT
"d > %" INT64_T_FORMAT "d = %d\n", "d > %" INT64_T_FORMAT "d = %d",
CAST(long long, v), CAST(long long, v),
CAST(long long, l), matched); CAST(long long, l), matched);
} }
@ -2386,7 +2421,7 @@ error_out:
matched = v < l; matched = v < l;
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT (void) fprintf(stderr, "%" INT64_T_FORMAT
"u < %" INT64_T_FORMAT "u = %d\n", "u < %" INT64_T_FORMAT "u = %d",
CAST(unsigned long long, v), CAST(unsigned long long, v),
CAST(unsigned long long, l), matched); CAST(unsigned long long, l), matched);
} }
@ -2394,7 +2429,7 @@ error_out:
matched = CAST(int64_t, v) < CAST(int64_t, l); matched = CAST(int64_t, v) < CAST(int64_t, l);
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT (void) fprintf(stderr, "%" INT64_T_FORMAT
"d < %" INT64_T_FORMAT "d = %d\n", "d < %" INT64_T_FORMAT "d = %d",
CAST(long long, v), CAST(long long, v),
CAST(long long, l), matched); CAST(long long, l), matched);
} }
@ -2405,7 +2440,7 @@ error_out:
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %" (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
INT64_T_FORMAT "x) == %" INT64_T_FORMAT INT64_T_FORMAT "x) == %" INT64_T_FORMAT
"x) = %d\n", CAST(unsigned long long, v), "x) = %d", CAST(unsigned long long, v),
CAST(unsigned long long, l), CAST(unsigned long long, l),
CAST(unsigned long long, l), CAST(unsigned long long, l),
matched); matched);
@ -2416,7 +2451,7 @@ error_out:
if ((ms->flags & MAGIC_DEBUG) != 0) if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %" (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
INT64_T_FORMAT "x) != %" INT64_T_FORMAT INT64_T_FORMAT "x) != %" INT64_T_FORMAT
"x) = %d\n", CAST(unsigned long long, v), "x) = %d", CAST(unsigned long long, v),
CAST(unsigned long long, l), CAST(unsigned long long, l),
CAST(unsigned long long, l), matched); CAST(unsigned long long, l), matched);
break; break;
@ -2426,11 +2461,15 @@ error_out:
m->reln); m->reln);
return -1; return -1;
} }
if ((ms->flags & MAGIC_DEBUG) != 0) {
(void) fprintf(stderr, " strength=%zu\n",
file_magic_strength(m, 1));
}
return matched; return matched;
} }
private int file_private int
handle_annotation(struct magic_set *ms, struct magic *m, int firstline) handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
{ {
if ((ms->flags & MAGIC_APPLE) && m->apple[0]) { if ((ms->flags & MAGIC_APPLE) && m->apple[0]) {
@ -2463,7 +2502,7 @@ handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
return 0; return 0;
} }
private int file_private int
print_sep(struct magic_set *ms, int firstline) print_sep(struct magic_set *ms, int firstline)
{ {
if (firstline) if (firstline)

View file

@ -26,13 +26,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
/* /*
* Header file for public domain tar (tape archive) program. * Header file for file_public domain tar (tape archive) program.
* *
* @(#)tar.h 1.20 86/10/29 Public Domain. * @(#)tar.h 1.20 86/10/29 Public Domain.
* *
* Created 25 August 1985 by John Gilmore, ihnp4!hoptoad!gnu. * 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.16 2022/12/26 17:31:14 christos Exp $ # checkin only
*/ */
/* /*

View file

@ -1,36 +1,3 @@
diff -ur Magdir.orig/fonts Magdir/fonts
--- Magdir.orig/fonts 2021-02-23 01:49:24.000000000 +0100
+++ Magdir/fonts 2022-09-18 14:07:14.233023271 +0200
@@ -384,11 +384,13 @@
# https://www.w3.org/TR/WOFF/
0 string wOFF Web Open Font Format
+!:mime font/woff
>0 use woff
>20 beshort x \b, version %d
>22 beshort x \b.%d
# https://www.w3.org/TR/WOFF2/
0 string wOF2 Web Open Font Format (Version 2)
+!:mime font/woff2
>0 use woff
#>20 belong x \b, totalCompressedSize %d
>24 beshort x \b, version %d
diff -ur Magdir.orig/mail.news Magdir/mail.news
--- Magdir.orig/mail.news 2021-03-31 01:47:28.000000000 +0200
+++ Magdir/mail.news 2021-04-05 19:41:55.168556972 +0200
@@ -1,5 +1,5 @@
#------------------------------------------------------------------------------
-# $File: mail.news,v 1.26 2021/03/21 14:37:03 christos Exp $
+# $File: mail.news,v 1.27 2021/04/05 16:36:14 christos Exp $
# mail.news: file(1) magic for mail and news
#
# Unfortunately, saved netnews also has From line added in some news software.
@@ -81,4 +81,4 @@
# File format spec: https://wiki.dovecot.org/Design/Dcrypt/#File_format
# From: Stephen Gildea
0 string CRYPTED\003\007 Dovecot encrypted message
->9 byte xu \b, dcrypt version %d
+>9 byte x \b, dcrypt version %d
diff -ur Magdir.orig/rpm Magdir/rpm diff -ur Magdir.orig/rpm Magdir/rpm
--- Magdir.orig/rpm 2021-02-23 01:49:24.000000000 +0100 --- Magdir.orig/rpm 2021-02-23 01:49:24.000000000 +0100
+++ Magdir/rpm 2021-04-05 19:40:55.080911893 +0200 +++ Magdir/rpm 2021-04-05 19:40:55.080911893 +0200

View file

@ -10,13 +10,11 @@ $a='#!env python
from serial import Serial from serial import Serial
from sys import exit from sys import exit
'; ';
// As of libmagic >= 5.41 libmagic delivers text/plain for this buffer,
// to be observed further
$finfo = new finfo(FILEINFO_MIME_TYPE); $finfo = new finfo(FILEINFO_MIME_TYPE);
echo $finfo->buffer($a) . "\n"; echo $finfo->buffer($a) . "\n";
$finfo = new finfo(); $finfo = new finfo();
echo $finfo->buffer($a) . "\n"; echo $finfo->buffer($a) . "\n";
?> ?>
--EXPECT-- --EXPECT--
text/plain text/x-script.python
a env python script, ASCII text executable Python script, ASCII text executable

View file

@ -8,5 +8,5 @@ finfo_open(FILEINFO_NONE, __DIR__ . '/bug77961.magic');
?> ?>
--EXPECTF-- --EXPECTF--
Warning: finfo_open(): Expected numeric type got `indirect' in %s on line %d Warning: finfo_open(): Expected numeric type got `indirect' in %s on line %d
Bad width %d
Fatal error: fatal libmagic error in %s on line %d Warning: finfo_open(): Failed to load magic database at "%sbug77961.magic" in %s on line %d

View file

@ -11,14 +11,14 @@ $minSize = 128 * 1024;
$maxSize = 16 * 1024 * 1024; $maxSize = 16 * 1024 * 1024;
$map = array( $map = array(
131072 => 10055680, 131072 => 10612736,
262144 => 10055680, 262144 => 10612736,
524288 => 11898880, 524288 => 11898880,
1048576 => 12152832, 1048576 => 12709888,
2097152 => 14254080, 2097152 => 14811136,
4194304 => 18452480, 4194304 => 19009536,
8388608 => 24743936, 8388608 => 25300992,
16777216 => 37326848, 16777216 => 37883904,
); );
for($size = $minSize; $size <= $maxSize; $size *= 2) { for($size = $minSize; $size <= $maxSize; $size *= 2) {
$content = str_repeat('0', $size); $content = str_repeat('0', $size);

View file

@ -31,7 +31,5 @@ Done
?> ?>
--EXPECTF-- --EXPECTF--
string(%d) "%s" string(%d) "%s"
string(14) "SIMH tape data"
Warning: finfo_file(): Failed identify data 0:indirect count (%d) exceeded in %s on line %d
bool(false)
Done Done

View file

@ -31,7 +31,5 @@ Done
?> ?>
--EXPECTF-- --EXPECTF--
string(%d) "%s" string(%d) "%s"
string(14) "SIMH tape data"
Warning: finfo_file(): Failed identify data 0:indirect count (%d) exceeded in %s on line %d
bool(false)
Done Done

View file

@ -24,5 +24,5 @@ try {
*** Testing finfo_file() : basic functionality *** *** Testing finfo_file() : basic functionality ***
string(28) "text/x-php; charset=us-ascii" string(28) "text/x-php; charset=us-ascii"
string(22) "PHP script, ASCII text" string(22) "PHP script, ASCII text"
string(28) "text/plain; charset=us-ascii" string(29) "text/x-file; charset=us-ascii"
finfo_file(): Argument #1 ($finfo) must not contain any null bytes finfo_file(): Argument #1 ($finfo) must not contain any null bytes