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)
. Implemented "Improve callbacks in ext/dom and ext/xsl" RFC. (nielsdos)
- Fileinfo:
. Update to libmagic 5.45. (nielsdos)
- FPM:
. Implement GH-12385 (flush headers without body when calling flush()).
(nielsdos)

View File

@ -10,7 +10,7 @@ if test "$PHP_FILEINFO" != "no"; then
libmagic/apprentice.c libmagic/apptype.c libmagic/ascmagic.c \
libmagic/cdf.c libmagic/cdf_time.c libmagic/compress.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/buffer.c libmagic/is_csv.c"

View File

@ -6,7 +6,7 @@ if (PHP_FILEINFO != 'no') {
LIBMAGIC_SOURCES=" apprentice.c apptype.c ascmagic.c \
cdf.c cdf_time.c compress.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 \
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
mkdir libmagic.orig
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"
#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 */
#include "magic.h"
@ -114,25 +114,24 @@ const size_t file_nformats = FILE_NAMES_SIZE;
const char *file_names[FILE_NAMES_SIZE];
const size_t file_nnames = FILE_NAMES_SIZE;
private int getvalue(struct magic_set *ms, struct magic *, const char **, int);
private int hextoint(int);
private const char *getstr(struct magic_set *, struct magic *, const char *,
file_private int getvalue(struct magic_set *ms, struct magic *, const char **, int);
file_private int hextoint(int);
file_private const char *getstr(struct magic_set *, struct magic *, const char *,
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);
private void eatsize(const char **);
private int apprentice_1(struct magic_set *, const char *, int);
private ssize_t apprentice_magic_strength_1(const struct magic *);
private size_t apprentice_magic_strength(const struct magic *, size_t);
private int apprentice_sort(const void *, const void *);
private void apprentice_list(struct mlist *, int );
private struct magic_map *apprentice_load(struct magic_set *,
file_private void eatsize(const char **);
file_private int apprentice_1(struct magic_set *, const char *, int);
file_private ssize_t apprentice_magic_strength_1(const struct magic *);
file_private int apprentice_sort(const void *, const void *);
file_private void apprentice_list(struct mlist *, int );
file_private struct magic_map *apprentice_load(struct magic_set *,
const char *, int);
private struct mlist *mlist_alloc(void);
private void mlist_free_all(struct magic_set *);
private void mlist_free(struct mlist *);
private void byteswap(struct magic *, uint32_t);
private void bs1(struct magic *);
file_private struct mlist *mlist_alloc(void);
file_private void mlist_free_all(struct magic_set *);
file_private void mlist_free(struct mlist *);
file_private void byteswap(struct magic *, uint32_t);
file_private void bs1(struct magic *);
#if defined(HAVE_BYTESWAP_H)
#define swap2(x) bswap_16(x)
@ -143,34 +142,34 @@ private void bs1(struct magic *);
#define swap4(x) bswap32(x)
#define swap8(x) bswap64(x)
#else
private uint16_t swap2(uint16_t);
private uint32_t swap4(uint32_t);
private uint64_t swap8(uint64_t);
file_private uint16_t swap2(uint16_t);
file_private uint32_t swap4(uint32_t);
file_private uint64_t swap8(uint64_t);
#endif
private char *mkdbname(struct magic_set *, const char *, int);
private struct magic_map *apprentice_map(struct magic_set *, const char *);
private void apprentice_unmap(struct magic_map *);
private int apprentice_compile(struct magic_set *, struct magic_map *,
file_private char *mkdbname(struct magic_set *, const char *, int);
file_private struct magic_map *apprentice_map(struct magic_set *, const char *);
file_private void apprentice_unmap(struct magic_map *);
file_private int apprentice_compile(struct magic_set *, struct magic_map *,
const char *);
private int check_format_type(const char *, int, const char **);
private int check_format(struct magic_set *, struct magic *);
private int get_op(char);
private int parse_mime(struct magic_set *, struct magic_entry *, const char *,
file_private int check_format_type(const char *, int, const char **);
file_private int check_format(struct magic_set *, struct magic *);
file_private int get_op(char);
file_private int parse_mime(struct magic_set *, struct magic_entry *, const char *,
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);
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);
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);
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;
size_t len;
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_NULL
private int
file_private int
get_type(const struct type_tbl_s *tbl, const char *l, const char **t)
{
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;
}
private off_t
file_private off_t
maxoff_t(void) {
if (/*CONSTCOND*/sizeof(off_t) == sizeof(int))
return CAST(off_t, INT_MAX);
@ -338,7 +337,7 @@ maxoff_t(void) {
return 0x7fffffff;
}
private int
file_private int
get_standard_integer_type(const char *l, const char **t)
{
int type;
@ -423,7 +422,7 @@ get_standard_integer_type(const char *l, const char **t)
return type;
}
private void
file_private void
init_file_tables(void)
{
static int done = 0;
@ -441,7 +440,7 @@ init_file_tables(void)
assert(p - type_tbl == FILE_NAMES_SIZE);
}
private int
file_private int
add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx)
{
struct mlist *ml;
@ -464,12 +463,11 @@ add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx)
/*
* Handle one file or directory.
*/
private int
file_private int
apprentice_1(struct magic_set *ms, const char *fn, int action)
{
struct magic_map *map;
#ifndef COMPILE_ONLY
struct mlist *ml;
size_t i;
#endif
@ -491,7 +489,7 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
map = apprentice_map(ms, fn);
if (map == NULL) {
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);
if (map == NULL)
return -1;
@ -504,7 +502,7 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
apprentice_unmap(map);
else
mlist_free_all(ms);
file_oomem(ms, sizeof(*ml));
file_oomem(ms, sizeof(*ms->mlist[0]));
return -1;
}
}
@ -524,7 +522,7 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
#endif /* COMPILE_ONLY */
}
protected void
file_protected void
file_ms_free(struct magic_set *ms)
{
size_t i;
@ -547,14 +545,14 @@ file_ms_free(struct magic_set *ms)
efree(ms);
}
protected struct magic_set *
file_protected struct magic_set *
file_ms_alloc(int flags)
{
struct magic_set *ms;
size_t i, len;
if ((ms = CAST(struct magic_set *, ecalloc(CAST(size_t, 1u),
sizeof(struct magic_set)))) == NULL)
sizeof(*ms)))) == NULL)
return NULL;
if (magic_setflags(ms, flags) == -1) {
@ -578,6 +576,7 @@ file_ms_alloc(int flags)
ms->indir_max = FILE_INDIR_MAX;
ms->name_max = FILE_NAME_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_notes_max = FILE_ELF_NOTES_MAX;
ms->regex_max = FILE_REGEX_MAX;
@ -589,11 +588,11 @@ file_ms_alloc(int flags)
#endif
return ms;
free:
free(ms);
efree(ms);
return NULL;
}
private void
file_private void
apprentice_unmap(struct magic_map *map)
{
if (map == NULL)
@ -613,7 +612,7 @@ apprentice_unmap(struct magic_map *map)
efree(map);
}
private struct mlist *
file_private struct mlist *
mlist_alloc(void)
{
struct mlist *mlist;
@ -624,7 +623,7 @@ mlist_alloc(void)
return mlist;
}
private void
file_private void
mlist_free_all(struct magic_set *ms)
{
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)
{
if (ml->map)
@ -643,7 +642,7 @@ mlist_free_one(struct mlist *ml)
efree(ml);
}
private void
file_private void
mlist_free(struct mlist *mlist)
{
struct mlist *ml, *next;
@ -660,7 +659,7 @@ mlist_free(struct mlist *mlist)
}
/* 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)
{
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++) {
mlist_free(ms->mlist[i]);
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++) {
mlist_free(ms->mlist[j]);
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
* - 0 length expressions count as one
*/
private size_t
file_private size_t
nonmagic(const char *str)
{
const char *p;
@ -806,7 +805,7 @@ nonmagic(const char *str)
}
private size_t
file_private size_t
typesize(int type)
{
switch (type) {
@ -876,7 +875,7 @@ typesize(int type)
/*
* Get weight of this magic entry, for sorting purposes.
*/
private ssize_t
file_private ssize_t
apprentice_magic_strength_1(const struct magic *m)
{
#define MULT 10U
@ -886,8 +885,8 @@ apprentice_magic_strength_1(const struct magic *m)
switch (m->type) {
case FILE_DEFAULT: /* make sure this sorts last */
if (m->factor_op != FILE_FACTOR_OP_NONE) {
fprintf(stderr, "Bad factor_op %d", m->factor_op);
abort();
file_magwarn(NULL, "Usupported factor_op in default %d",
m->factor_op);
}
return 0;
@ -1013,8 +1012,8 @@ apprentice_magic_strength_1(const struct magic *m)
/*ARGSUSED*/
private size_t
apprentice_magic_strength(const struct magic *m,
file_protected size_t
file_magic_strength(const struct magic *m,
size_t nmagic __attribute__((__unused__)))
{
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)
*/
private int
file_private int
apprentice_sort(const void *a, const void *b)
{
const struct magic_entry *ma = CAST(const struct magic_entry *, a);
const struct magic_entry *mb = CAST(const struct magic_entry *, b);
size_t sa = apprentice_magic_strength(ma->mp, ma->cont_count);
size_t sb = apprentice_magic_strength(mb->mp, mb->cont_count);
size_t sa = file_magic_strength(ma->mp, ma->cont_count);
size_t sb = file_magic_strength(mb->mp, mb->cont_count);
if (sa == sb)
return 0;
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
*/
private void
file_private void
apprentice_list(struct mlist *mlist, int mode)
{
uint32_t magindex, descindex, mimeindex, lineindex;
@ -1113,18 +1112,20 @@ apprentice_list(struct mlist *mlist, int mode)
* description/mimetype.
*/
lineindex = descindex = mimeindex = magindex;
for (magindex++; magindex < ml->nmagic &&
ml->magic[magindex].cont_level != 0; magindex++) {
for (; magindex + 1 < ml->nmagic &&
ml->magic[magindex + 1].cont_level != 0;
magindex++) {
uint32_t mi = magindex + 1;
if (*ml->magic[descindex].desc == '\0'
&& *ml->magic[magindex].desc)
descindex = magindex;
&& *ml->magic[mi].desc)
descindex = mi;
if (*ml->magic[mimeindex].mimetype == '\0'
&& *ml->magic[magindex].mimetype)
mimeindex = magindex;
&& *ml->magic[mi].mimetype)
mimeindex = mi;
}
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[descindex].desc,
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)
{
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,
struct magic_entry_set *mset)
{
@ -1252,7 +1253,7 @@ addentry(struct magic_set *ms, struct magic_entry *me,
/*
* Load and parse one file.
*/
private void
file_private void
load_1(struct magic_set *ms, int action, const char *fn, int *errs,
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
* const char *fn: name of magic file or directory
*/
private int
file_private int
cmpstrp(const void *p1, const void *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,
uint32_t starttest)
{
@ -1385,7 +1386,7 @@ set_text_binary(struct magic_set *ms, struct magic_entry *me, uint32_t nme,
return i;
}
private void
file_private void
set_last_default(struct magic_set *ms, struct magic_entry *me, uint32_t nme)
{
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,
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;
}
private void
file_private void
magic_entry_free(struct magic_entry *me, uint32_t nme)
{
uint32_t i;
@ -1449,7 +1450,7 @@ magic_entry_free(struct magic_entry *me, uint32_t nme)
efree(me);
}
private struct magic_map *
file_private struct magic_map *
apprentice_load(struct magic_set *ms, const char *fn, int action)
{
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);
}
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);
/*
@ -1573,7 +1574,7 @@ out:
/*
* 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)
{
if (!(m->flag & UNSIGNED)) {
@ -1659,7 +1660,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
return v;
}
private int
file_private int
string_modifier_check(struct magic_set *ms, struct magic *m)
{
if ((ms->flags & MAGIC_CHECK) == 0)
@ -1718,7 +1719,7 @@ string_modifier_check(struct magic_set *ms, struct magic *m)
return 0;
}
private int
file_private int
get_op(char c)
{
switch (c) {
@ -1744,7 +1745,7 @@ get_op(char c)
}
#ifdef ENABLE_CONDITIONALS
private int
file_private int
get_cond(const char *l, const char **t)
{
static const struct cond_tbl_s {
@ -1770,7 +1771,7 @@ get_cond(const char *l, const char **t)
return p->cond;
}
private int
file_private int
check_cond(struct magic_set *ms, int cond, uint32_t cont_level)
{
int last_cond;
@ -1814,7 +1815,7 @@ check_cond(struct magic_set *ms, int cond, uint32_t cont_level)
}
#endif /* ENABLE_CONDITIONALS */
private int
file_private int
parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp)
{
const char *l = *lp;
@ -1835,7 +1836,7 @@ parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp)
return 0;
}
private void
file_private void
parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp,
int op)
{
@ -1852,7 +1853,7 @@ parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp,
*lp = l;
}
private int
file_private int
parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp)
{
const char *l = *lp;
@ -1959,7 +1960,7 @@ out:
/*
* 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,
size_t lineno, int action)
{
@ -2376,13 +2377,14 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
* if valid
*/
/*ARGSUSED*/
private int
file_private int
parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line,
size_t len __attribute__((__unused__)))
{
const char *l = line;
char *el;
unsigned long factor;
char sbuf[512];
struct magic *m = &me->mp[0];
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) {
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;
}
EATAB;
switch (*l) {
case FILE_FACTOR_OP_NONE:
break;
case FILE_FACTOR_OP_PLUS:
case FILE_FACTOR_OP_MINUS:
case FILE_FACTOR_OP_TIMES:
@ -2432,15 +2437,16 @@ out:
return -1;
}
private int
file_private int
goodchar(unsigned char x, const char *extra)
{
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,
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;
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
* magic[index - 1]
*/
private int
file_private int
parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line,
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
*/
private int
file_private int
parse_ext(struct magic_set *ms, struct magic_entry *me, const char *line,
size_t len)
{
return parse_extra(ms, me, line, len,
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]
* if valid
*/
private int
file_private int
parse_mime(struct magic_set *ms, struct magic_entry *me, const char *line,
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);
}
private int
file_private int
check_format_type(const char *ptr, int type, const char **estr)
{
int quad = 0, h;
@ -2708,6 +2716,7 @@ check_format_type(const char *ptr, int type, const char **estr)
}
invalid:
*estr = "not valid";
return -1;
toolong:
*estr = "too long";
return -1;
@ -2717,7 +2726,7 @@ toolong:
* Check that the optional printf format in description matches
* the type of the magic.
*/
private int
file_private int
check_format(struct magic_set *ms, struct magic *m)
{
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
* 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)
{
char *ep;
uint64_t ull;
int y;
switch (m->type) {
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);
if (*p == ep) {
file_magwarn(ms, "Unparsable number `%s'", *p);
return -1;
} else {
size_t ts = typesize(m->type);
uint64_t x;
@ -2860,32 +2871,38 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
file_magwarn(ms,
"Expected numeric type got `%s'",
type_tbl[m->type].name);
return -1;
}
for (q = *p; isspace(CAST(unsigned char, *q)); q++)
continue;
if (*q == '-')
if (*q == '-' && ull != UINT64_MAX)
ull = -CAST(int64_t, ull);
switch (ts) {
case 1:
x = CAST(uint64_t, ull & ~0xffULL);
y = (x & ~0xffULL) != ~0xffULL;
break;
case 2:
x = CAST(uint64_t, ull & ~0xffffULL);
y = (x & ~0xffffULL) != ~0xffffULL;
break;
case 4:
x = CAST(uint64_t, ull & ~0xffffffffULL);
y = (x & ~0xffffffffULL) != ~0xffffffffULL;
break;
case 8:
x = 0;
y = 0;
break;
default:
fprintf(stderr, "Bad width %zu", ts);
abort();
}
if (x) {
if (x && y) {
file_magwarn(ms, "Overflow for numeric"
" type `%s' value %#" PRIx64,
type_tbl[m->type].name, ull);
return -1;
}
}
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.
* 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)
{
const char *origs = s;
@ -3080,7 +3097,7 @@ out:
/* Single hex char to int; -1 if not a hex char. */
private int
file_private int
hextoint(int c)
{
if (!isascii(CAST(unsigned char, c)))
@ -3098,7 +3115,7 @@ hextoint(int c)
/*
* Print a string containing C character escapes.
*/
protected void
file_protected void
file_showstr(FILE *fp, const char *s, size_t len)
{
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]
*/
private void
file_private void
eatsize(const char **p)
{
const char *l = *p;
@ -3185,7 +3202,7 @@ eatsize(const char **p)
* handle a compiled file.
*/
private struct magic_map *
file_private struct magic_map *
apprentice_map(struct magic_set *ms, const char *fn)
{
uint32_t *ptr;
@ -3331,7 +3348,7 @@ error:
/*
* handle an mmaped file.
*/
private int
file_private int
apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn)
{
static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS;
@ -3385,11 +3402,11 @@ out:
return rv;
}
private const char ext[] = ".mgc";
file_private const char ext[] = ".mgc";
/*
* make a dbname
*/
private char *
file_private char *
mkdbname(struct magic_set *ms, const char *fn, int strip)
{
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
*/
private void
file_private void
byteswap(struct magic *magic, uint32_t nmagic)
{
uint32_t i;
@ -3449,7 +3466,7 @@ byteswap(struct magic *magic, uint32_t nmagic)
/*
* swap a short
*/
private uint16_t
file_private uint16_t
swap2(uint16_t sv)
{
uint16_t rv;
@ -3463,7 +3480,7 @@ swap2(uint16_t sv)
/*
* swap an int
*/
private uint32_t
file_private uint32_t
swap4(uint32_t sv)
{
uint32_t rv;
@ -3479,7 +3496,7 @@ swap4(uint32_t sv)
/*
* swap a quad
*/
private uint64_t
file_private uint64_t
swap8(uint64_t sv)
{
uint64_t rv;
@ -3508,7 +3525,7 @@ swap8(uint64_t sv)
}
#endif
protected uintmax_t
file_protected uintmax_t
file_varint2uintmax_t(const unsigned char *us, int t, size_t *l)
{
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
*/
private void
file_private void
bs1(struct magic *m)
{
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)
{
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;
}
}
protected size_t
file_protected size_t
file_pstring_get_length(struct magic_set *ms, const struct magic *m,
const char *ss)
{
@ -3630,7 +3647,7 @@ file_pstring_get_length(struct magic_set *ms, const struct magic *m,
return len;
}
protected int
file_protected int
file_magicfind(struct magic_set *ms, const char *name, struct mlist *v)
{
uint32_t i, j;

View File

@ -1,6 +1,6 @@
/*
* 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
* searches.
@ -27,7 +27,7 @@
#include "file.h"
#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 */
#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>
typedef ULONG APPTYPE;
protected int
file_protected int
file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf,
size_t nb)
{
@ -116,7 +116,7 @@ file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf,
return -1;
} else if (type & FAPPTYP_DLL) {
if (type & FAPPTYP_PROTDLL)
if (file_printf(ms, "protected ") == -1)
if (file_printf(ms, "file_protected ") == -1)
return -1;
if (file_printf(ms, "DLL") == -1)
return -1;

View File

@ -35,7 +35,7 @@
#include "file.h"
#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 */
#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' \
|| (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);
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()
* 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)
{
while (nbytes > 1 && buf[nbytes - 1] == '\0')
@ -67,7 +67,7 @@ trim_nuls(const unsigned char *buf, size_t nbytes)
return nbytes;
}
protected int
file_protected int
file_ascmagic(struct magic_set *ms, const struct buffer *b, int text)
{
file_unichar_t *ubuf = NULL;
@ -101,7 +101,7 @@ file_ascmagic(struct magic_set *ms, const struct buffer *b, int text)
return rv;
}
protected int
file_protected int
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,
int text)
@ -121,10 +121,10 @@ file_ascmagic_with_encoding(struct magic_set *ms, const struct buffer *b,
int has_backspace = 0;
int seen_cr = 0;
int n_crlf = 0;
int n_lf = 0;
int n_cr = 0;
int n_nel = 0;
size_t n_crlf = 0;
size_t n_lf = 0;
size_t n_cr = 0;
size_t n_nel = 0;
int executable = 0;
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;
}
if ((utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen))
== NULL)
== NULL) {
rv = 0;
goto done;
}
buffer_init(&bb, b->fd, &b->st, 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;
}
/* 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) {
rv = 0;
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)
goto done;
} else {
if (file_printf(ms, "text/plain") == -1)
goto done;
}
if (file_printf(ms, "text/plain") == -1)
goto done;
}
} else {
if (len) {
@ -340,7 +334,7 @@ done:
* Encode Unicode string as UTF-8, returning pointer to character
* 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)
{
size_t i;

View File

@ -27,7 +27,7 @@
#include "file.h"
#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 */
#include "magic.h"
@ -58,6 +58,8 @@ void
buffer_fini(struct buffer *b)
{
efree(b->ebuf);
b->ebuf = NULL;
b->elen = 0;
}
int
@ -71,8 +73,13 @@ buffer_fill(const struct buffer *bb)
if (!S_ISREG(b->st.st_mode))
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;
if (b->elen == 0) {
efree(b->ebuf);
b->ebuf = NULL;
return 0;
}
if ((b->ebuf = emalloc(b->elen)) == NULL)
goto out;

View File

@ -35,7 +35,7 @@
#include "file.h"
#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
#include <assert.h>

View File

@ -27,7 +27,7 @@
#include "file.h"
#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
#include <time.h>
@ -157,7 +157,7 @@ cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timespec *ts)
return -1;
}
*t = (ts->ts_nsec / 100) * CDF_TIME_PREC;
*t = tm.tm_sec;
*t += tm.tm_sec;
*t += tm.tm_min * 60;
*t += tm.tm_hour * 60 * 60;
*t += tm.tm_mday * 60 * 60 * 24;
@ -168,7 +168,7 @@ cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timespec *ts)
char *
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)
return buf;
#ifdef WIN32

View File

@ -35,7 +35,7 @@
#include "file.h"
#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
#include "magic.h"
@ -80,6 +80,17 @@ typedef void (*sig_t)(int);
#include <lzma.h>
#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
int tty = -1;
#define DPRINTF(...) do { \
@ -135,7 +146,6 @@ lzmacmp(const unsigned char *buf)
}
#define gzip_flags "-cd"
#define lrzip_flags "-do"
#define lzip_flags gzip_flags
static const char *gzip_args[] = {
@ -154,7 +164,7 @@ static const char *xz_args[] = {
"xz", "-cd", NULL
};
static const char *lrzip_args[] = {
"lrzip", lrzip_flags, NULL
"lrzip", "-qdf", "-", NULL
};
static const char *lz4_args[] = {
"lz4", "-cd", NULL
@ -166,7 +176,7 @@ static const char *zstd_args[] = {
#define do_zlib NULL
#define do_bzlib NULL
private const struct {
file_private const struct {
union {
const char *magic;
int (*func)(const unsigned char *);
@ -178,6 +188,8 @@ private const struct {
#define METH_FROZEN 2
#define METH_BZIP 7
#define METH_XZ 9
#define METH_LZIP 8
#define METH_ZSTD 12
#define METH_LZMA 13
#define METH_ZLIB 14
{ { .magic = "\037\235" }, 2, gzip_args, NULL }, /* 0, compressed */
@ -207,31 +219,39 @@ private const struct {
#define NODATA 1
#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
private size_t ncompr = __arraycount(compr);
private int uncompressbuf(int, size_t, size_t, const unsigned char *,
file_private size_t ncompr = __arraycount(compr);
file_private int uncompressbuf(int, size_t, size_t, int, const unsigned char *,
unsigned char **, size_t *);
#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);
private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
size_t *);
#endif
#ifdef BUILTIN_BZLIB
private int uncompressbzlib(const unsigned char *, unsigned char **, size_t,
size_t *);
file_private int uncompressbzlib(const unsigned char *, unsigned char **, size_t,
size_t *, int);
#endif
#ifdef BUILTIN_XZLIB
private int uncompressxzlib(const unsigned char *, unsigned char **, size_t,
size_t *);
file_private int uncompressxzlib(const unsigned char *, unsigned char **, 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
static int makeerror(unsigned char **, size_t *, const char *, ...)
__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)
{
unsigned char *p;
@ -248,7 +268,7 @@ format_decompression_error(struct magic_set *ms, size_t i, unsigned char *buf)
methodname(i), buf);
}
protected int
file_protected int
file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
{
unsigned char *newbuf = NULL;
@ -290,7 +310,9 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
}
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,
(char *)newbuf, nsz);
switch (urv) {
@ -300,7 +322,8 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
if (urv == ERRDATA)
prv = format_decompression_error(ms, i, newbuf);
else
prv = file_buffer(ms, NULL, NULL, name, newbuf, nsz);
prv = file_buffer(ms, NULL, NULL, name, newbuf,
nsz);
if (prv == -1)
goto error;
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
* 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)
abort();
goto error;
@ -358,7 +382,7 @@ out:
/*
* `safe' write for sockets and pipes.
*/
private ssize_t
file_private ssize_t
swrite(int fd, const void *buf, size_t n)
{
ssize_t rv;
@ -383,11 +407,11 @@ swrite(int fd, const void *buf, size_t n)
/*
* `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__)))
{
ssize_t rv;
#ifdef FIONREAD
#if defined(FIONREAD) && !defined(__MINGW32__)
int t = 0;
#endif
size_t rn = n;
@ -395,7 +419,7 @@ sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
if (fd == STDIN_FILENO)
goto nocheck;
#ifdef FIONREAD
#if defined(FIONREAD) && !defined(__MINGW32__)
if (canbepipe && (ioctl(fd, FIONREAD, &t) == -1 || t == 0)) {
#ifdef FD_ZERO
ssize_t cnt;
@ -448,7 +472,7 @@ nocheck:
return rn;
}
protected int
file_protected int
file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
size_t nbytes)
{
@ -540,13 +564,19 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
#define FCOMMENT (1 << 4)
private int
file_private int
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;
if (*n < 4) {
goto err;
}
flg = old[3];
if (flg & FEXTRA) {
if (data_start + 1 >= *n)
goto err;
@ -575,16 +605,14 @@ err:
return makeerror(newch, n, "File too short");
}
private int
file_private int
uncompresszlib(const unsigned char *old, unsigned char **newch,
size_t bytes_max, size_t *n, int zlib)
{
int rc;
z_stream z;
if ((*newch = CAST(unsigned char *, emalloc(bytes_max + 1))) == NULL)
return makeerror(newch, n, "No buffer, %s", strerror(errno));
DPRINTF("builtin zlib decompression\n");
z.next_in = CCAST(Bytef *, old);
z.avail_in = CAST(uint32_t, *n);
z.next_out = *newch;
@ -599,8 +627,10 @@ uncompresszlib(const unsigned char *old, unsigned char **newch,
goto err;
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;
}
*n = CAST(size_t, z.total_out);
rc = inflateEnd(&z);
@ -612,36 +642,34 @@ uncompresszlib(const unsigned char *old, unsigned char **newch,
return OKDATA;
err:
strlcpy(RCAST(char *, *newch), z.msg ? z.msg : zError(rc), bytes_max);
*n = strlen(RCAST(char *, *newch));
return ERRDATA;
return makeerror(newch, n, "%s", z.msg ? z.msg : zError(rc));
}
#endif
#ifdef BUILTIN_BZLIB
private int
file_private int
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;
bz_stream bz;
DPRINTF("builtin bzlib decompression\n");
memset(&bz, 0, sizeof(bz));
rc = BZ2_bzDecompressInit(&bz, 0, 0);
if (rc != BZ_OK)
goto err;
if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
return makeerror(newch, n, "No buffer, %s", strerror(errno));
bz.next_in = CCAST(char *, RCAST(const char *, old));
bz.avail_in = CAST(uint32_t, *n);
bz.next_out = RCAST(char *, *newch);
bz.avail_out = CAST(unsigned int, bytes_max);
rc = BZ2_bzDecompress(&bz);
if (rc != BZ_OK && rc != BZ_STREAM_END)
if (rc != BZ_OK && rc != BZ_STREAM_END) {
BZ2_bzDecompressEnd(&bz);
goto err;
}
/* Assume byte_max is within 32bit */
/* assert(bz.total_out_hi32 == 0); */
@ -655,36 +683,34 @@ uncompressbzlib(const unsigned char *old, unsigned char **newch,
return OKDATA;
err:
snprintf(RCAST(char *, *newch), bytes_max, "bunzip error %d", rc);
*n = strlen(RCAST(char *, *newch));
return ERRDATA;
return makeerror(newch, n, "bunzip error %d", rc);
}
#endif
#ifdef BUILTIN_XZLIB
private int
file_private int
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;
lzma_stream xz;
DPRINTF("builtin xzlib decompression\n");
memset(&xz, 0, sizeof(xz));
rc = lzma_auto_decoder(&xz, UINT64_MAX, 0);
if (rc != LZMA_OK)
goto err;
if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
return makeerror(newch, n, "No buffer, %s", strerror(errno));
xz.next_in = CCAST(const uint8_t *, old);
xz.avail_in = CAST(uint32_t, *n);
xz.next_out = RCAST(uint8_t *, *newch);
xz.avail_out = CAST(unsigned int, bytes_max);
rc = lzma_code(&xz, LZMA_RUN);
if (rc != LZMA_OK && rc != LZMA_STREAM_END)
if (rc != LZMA_OK && rc != LZMA_STREAM_END) {
lzma_end(&xz);
goto err;
}
*n = CAST(size_t, xz.total_out);
@ -695,9 +721,115 @@ uncompressxzlib(const unsigned char *old, unsigned char **newch,
return OKDATA;
err:
snprintf(RCAST(char *, *newch), bytes_max, "unxz error %d", rc);
*n = strlen(RCAST(char *, *newch));
return ERRDATA;
return makeerror(newch, n, "unxz error %d", rc);
}
#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
@ -709,10 +841,13 @@ makeerror(unsigned char **buf, size_t *len, const char *fmt, ...)
va_list ap;
int rv;
DPRINTF("Makeerror %s\n", fmt);
free(*buf);
va_start(ap, fmt);
rv = vasprintf(&msg, fmt, ap);
va_end(ap);
if (rv < 0) {
DPRINTF("Makeerror failed");
*buf = NULL;
*len = 0;
return NODATA;
@ -751,7 +886,7 @@ movedesc(void *v, int i, int fd)
#else
if (dup2(fd, i) == -1) {
DPRINTF("dup(%d, %d) failed (%s)\n", fd, i, strerror(errno));
exit(1);
exit(EXIT_FAILURE);
}
close(v ? fd : fd);
#endif
@ -808,15 +943,15 @@ writechild(int fd, const void *old, size_t n)
pid = fork();
if (pid == -1) {
DPRINTF("Fork failed (%s)\n", strerror(errno));
exit(1);
return -1;
}
if (pid == 0) {
/* child */
if (swrite(fd, old, n) != CAST(ssize_t, n)) {
DPRINTF("Write failed (%s)\n", strerror(errno));
exit(1);
exit(EXIT_FAILURE);
}
exit(0);
exit(EXIT_SUCCESS);
}
/* parent */
return pid;
@ -850,7 +985,7 @@ filter_error(unsigned char *ubuf, ssize_t n)
return n;
}
private const char *
file_private const char *
methodname(size_t method)
{
switch (method) {
@ -867,45 +1002,80 @@ methodname(size_t method)
case METH_XZ:
case METH_LZMA:
return "xzlib";
#endif
#ifdef BUILTIN_ZSTDLIB
case METH_ZSTD:
return "zstd";
#endif
#ifdef BUILTIN_LZLIB
case METH_LZIP:
return "lzlib";
#endif
default:
return compr[method].argv[0];
}
}
private int
uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
unsigned char **newch, size_t* n)
file_private int (*
getdecompressor(size_t method))(const unsigned char *, unsigned char **, size_t,
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 status, rv, w;
pid_t pid;
pid_t writepid = -1;
size_t i;
ssize_t r;
ssize_t r, re;
char *const *args;
#ifdef HAVE_POSIX_SPAWNP
posix_spawn_file_actions_t fa;
#endif
int (*decompress)(const unsigned char *, unsigned char **,
size_t, size_t *, int) = getdecompressor(method);
switch (method) {
#ifdef BUILTIN_DECOMPRESS
case METH_FROZEN:
return uncompressgzipped(old, newch, bytes_max, n);
case METH_ZLIB:
return uncompresszlib(old, newch, bytes_max, n, 1);
#endif
#ifdef BUILTIN_BZLIB
case METH_BZIP:
return uncompressbzlib(old, newch, bytes_max, n);
#endif
#ifdef BUILTIN_XZLIB
case METH_XZ:
case METH_LZMA:
return uncompressxzlib(old, newch, bytes_max, n);
#endif
default:
break;
*newch = CAST(unsigned char *, emalloc(bytes_max + 1));
if (*newch == NULL)
return makeerror(newch, n, "No buffer, %s", strerror(errno));
if (decompress) {
if (nofork) {
return makeerror(newch, n,
"Fork is required to uncompress, but disabled");
}
return (*decompress)(old, newch, bytes_max, n, 1);
}
(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
* an uncompressing child here, which writes out uncompressed data.
* 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
* inherit pipe fds, thus keeping pipe open and making writes in
* 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);
DPRINTF("Executing %s\n", compr[method].argv[0]);
status = posix_spawnp(&pid, compr[method].argv[0], &fa, 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].
*/
handledesc(NULL, fd, fdp);
DPRINTF("Executing %s\n", compr[method].argv[0]);
(void)execvp(compr[method].argv[0], args);
dprintf(STDERR_FILENO, "exec `%s' failed, %s",
compr[method].argv[0], strerror(errno));
_exit(1); /* _exit(), not exit(), because of vfork */
_exit(EXIT_FAILURE); /* _exit(), not exit(), because of vfork */
}
#endif
/* parent */
@ -983,39 +1155,45 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
if (fd == -1) {
closefd(fdp[STDIN_FILENO], 0);
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);
}
*newch = CAST(unsigned char *, malloc(bytes_max + 1));
if (*newch == NULL) {
rv = makeerror(newch, n, "No buffer, %s",
strerror(errno));
goto err;
}
rv = OKDATA;
errno = 0;
r = sread(fdp[STDOUT_FILENO][0], *newch, bytes_max, 0);
if (r == 0 && errno == 0)
goto ok;
if (r <= 0) {
DPRINTF("Read stdout failed %d (%s)\n", fdp[STDOUT_FILENO][0],
r != -1 ? strerror(errno) : "no data");
DPRINTF("read got %zd\n", r);
if (r < 0) {
rv = ERRDATA;
if (r == 0 &&
(r = sread(fdp[STDERR_FILENO][0], *newch, bytes_max, 0)) > 0)
{
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");
DPRINTF("Read stdout failed %d (%s)\n", fdp[STDOUT_FILENO][0],
strerror(errno));
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:
*n = r;
/* NUL terminate, as every buffer is handled here. */
@ -1028,7 +1206,6 @@ err:
w = waitpid(pid, &status, 0);
wait_err:
if (w == -1) {
free(*newch);
rv = makeerror(newch, n, "Wait failed, %s", strerror(errno));
DPRINTF("Child wait return %#x\n", status);
} else if (!WIFEXITED(status)) {

View File

@ -35,7 +35,7 @@
#include "file.h"
#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
#else
#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__));
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));
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__));
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 += ms->offset + m->offset;
@ -288,14 +288,14 @@ der_offs(struct magic_set *ms, struct magic *m, size_t nbytes)
#ifdef DEBUG_DER
size_t 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);
#endif
if (m->cont_level != 0) {
if (offs + tlen > nbytes)
return -1;
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));
}
return CAST(int32_t, offs);
@ -318,7 +318,7 @@ der_cmp(struct magic_set *ms, struct magic *m)
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));
tlen = getlength(b, &offs, len);

View File

@ -35,7 +35,7 @@
#include "file.h"
#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 */
#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>
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 *);
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 *);
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 *);
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 *);
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 *);
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 *);
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 *);
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
#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
* 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_unichar_t **ubuf, size_t *ulen, const char **code,
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 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 */
F, F, F, F, F, F, F, T, T, T, T, T, T, T, F, F, /* 0x0X */
/* ESC */
@ -260,7 +260,7 @@ private char text_chars[256] = {
};
#define LOOKS(NAME, COND) \
private int \
file_private int \
looks_ ## NAME(const unsigned char *buf, size_t nbytes, file_unichar_t *ubuf, \
size_t *ulen) \
{ \
@ -346,7 +346,7 @@ struct accept_range {
{ LOCB, 0x8F },
};
protected int
file_protected int
file_looks_utf8(const unsigned char *buf, size_t nbytes, file_unichar_t *ubuf,
size_t *ulen)
{
@ -427,7 +427,7 @@ done:
* BOM, return -1; otherwise return the result of looks_utf8 on the
* rest of the text.
*/
private int
file_private int
looks_utf8_with_BOM(const unsigned char *buf, size_t nbytes,
file_unichar_t *ubuf, size_t *ulen)
{
@ -437,7 +437,7 @@ looks_utf8_with_BOM(const unsigned char *buf, size_t nbytes,
return -1;
}
private int
file_private int
looks_utf7(const unsigned char *buf, size_t nbytes, file_unichar_t *ubuf,
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_LOSURR(c) ((c) >= 0xdc00 && (c) <= 0xdfff)
private int
file_private int
looks_ucs16(const unsigned char *bf, size_t nbytes, file_unichar_t *ubf,
size_t *ulen)
{
@ -521,7 +521,7 @@ looks_ucs16(const unsigned char *bf, size_t nbytes, file_unichar_t *ubf,
return 1 + bigend;
}
private int
file_private int
looks_ucs32(const unsigned char *bf, size_t nbytes, file_unichar_t *ubf,
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.
*/
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,
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,
@ -624,7 +624,7 @@ private unsigned char ebcdic_to_ascii[] = {
* 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,
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,
@ -647,7 +647,7 @@ private unsigned char ebcdic_1047_to_8859[] = {
/*
* 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)
{
size_t i;

View File

@ -27,7 +27,7 @@
*/
/*
* 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__
@ -98,17 +98,17 @@
#define PATHSEP ':'
#endif
#define private static
#define file_private static
#if HAVE_VISIBILITY && !defined(WIN32)
#define public __attribute__ ((__visibility__("default")))
#ifndef protected
#define protected __attribute__ ((__visibility__("hidden")))
#define file_public __attribute__ ((__visibility__("default")))
#ifndef file_protected
#define file_protected __attribute__ ((__visibility__("hidden")))
#endif
#else
#define public
#ifndef protected
#define protected
#define file_public
#ifndef file_protected
#define file_protected
#endif
#endif
@ -148,6 +148,14 @@
# define FD_CLOEXEC 1
#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 MAXDESC 64 /* max len of text description/MIME type */
#define MAXMIME 80 /* max len of text MIME type */
@ -472,12 +480,14 @@ struct magic_set {
uint16_t regex_max;
size_t bytes_max; /* number of bytes to read from file */
size_t encoding_max; /* bytes to look for encoding */
size_t elf_shsize_max;
#ifndef FILE_BYTES_MAX
# define FILE_BYTES_MAX (1024 * 1024) /* how much of the file to look at */
#endif
# define FILE_BYTES_MAX (7 * 1024 * 1024)/* how much of the file to look at */
#endif /* above 0x6ab0f4 map offset for HelveticaNeue.dfont */
#define FILE_ELF_NOTES_MAX 256
#define FILE_ELF_PHNUM_MAX 2048
#define FILE_ELF_SHNUM_MAX 32768
#define FILE_ELF_SHSIZE_MAX (128 * 1024 * 1024)
#define FILE_INDIR_MAX 50
#define FILE_NAME_MAX 50
#define FILE_REGEX_MAX 8192
@ -497,90 +507,98 @@ typedef unsigned long file_unichar_t;
struct stat;
#define FILE_T_LOCAL 1
#define FILE_T_WINDOWS 2
protected const char *file_fmtdatetime(char *, size_t, uint64_t, int);
protected const char *file_fmtdate(char *, size_t, uint16_t);
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_fmtdatetime(char *, size_t, uint64_t, int);
file_protected const char *file_fmtdate(char *, size_t, uint16_t);
file_protected const char *file_fmttime(char *, size_t, uint16_t);
file_protected const char *file_fmtvarint(char *, size_t, const unsigned char *,
int);
protected const char *file_fmtnum(char *, size_t, const char *, int);
protected struct magic_set *file_ms_alloc(int);
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 const char *file_fmtnum(char *, size_t, const char *, int);
file_protected struct magic_set *file_ms_alloc(int);
file_protected void file_ms_free(struct magic_set *);
file_protected int file_buffer(struct magic_set *, php_stream *, zend_stat_t *, const char *, const void *,
size_t);
protected int file_fsmagic(struct magic_set *, const char *, zend_stat_t *);
protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
protected int file_vprintf(struct magic_set *, const char *, va_list)
file_protected int file_fsmagic(struct magic_set *, const char *, zend_stat_t *);
file_protected int file_pipe2file(struct magic_set *, int, const void *,
size_t);
file_protected int file_vprintf(struct magic_set *, const char *, va_list)
__attribute__((__format__(__printf__, 2, 0)));
protected int file_separator(struct magic_set *);
protected char *file_copystr(char *, size_t, size_t, const char *);
protected int file_checkfmt(char *, size_t, const char *);
protected size_t file_printedlen(const struct magic_set *);
protected int file_print_guid(char *, size_t, const uint64_t *);
protected int file_parse_guid(const char *, uint64_t *);
protected int file_replace(struct magic_set *, const char *, const char *);
protected int file_printf(struct magic_set *, const char *, ...)
file_protected int file_separator(struct magic_set *);
file_protected char *file_copystr(char *, size_t, size_t, const char *);
file_protected int file_checkfmt(char *, size_t, const char *);
file_protected size_t file_printedlen(const struct magic_set *);
file_protected int file_print_guid(char *, size_t, const uint64_t *);
file_protected int file_parse_guid(const char *, uint64_t *);
file_protected int file_replace(struct magic_set *, const char *, const char *);
file_protected int file_printf(struct magic_set *, const char *, ...)
__attribute__((__format__(__printf__, 2, 3)));
protected int file_reset(struct magic_set *, int);
protected int file_tryelf(struct magic_set *, const struct buffer *);
protected int file_trycdf(struct magic_set *, const struct buffer *);
file_protected int file_reset(struct magic_set *, int);
file_protected int file_tryelf(struct magic_set *, const struct buffer *);
file_protected int file_trycdf(struct magic_set *, const struct buffer *);
#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 *);
#endif
protected int file_ascmagic(struct magic_set *, const struct buffer *,
file_protected int file_ascmagic(struct magic_set *, const struct buffer *,
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);
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 **);
protected int file_is_json(struct magic_set *, const struct buffer *);
protected int file_is_csv(struct magic_set *, const struct buffer *, int);
protected int file_is_tar(struct magic_set *, const struct buffer *);
protected int file_softmagic(struct magic_set *, const struct buffer *,
file_protected int file_is_json(struct magic_set *, const struct buffer *);
file_protected int file_is_csv(struct magic_set *, const struct buffer *, int,
const char *);
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);
protected int file_apprentice(struct magic_set *, const char *, int);
protected int buffer_apprentice(struct magic_set *, struct magic **,
file_protected int file_apprentice(struct magic_set *, const char *, int);
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);
protected int file_magicfind(struct magic_set *, const char *, struct mlist *);
protected uint64_t file_signextend(struct magic_set *, struct magic *,
file_protected int file_magicfind(struct magic_set *, const char *,
struct mlist *);
file_protected uint64_t file_signextend(struct magic_set *, struct magic *,
uint64_t);
protected uintmax_t file_varint2uintmax_t(const unsigned char *, int, size_t *);
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 *,
file_protected uintmax_t file_varint2uintmax_t(const unsigned char *, int,
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 *);
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 *);
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);
#ifdef __EMX__
protected int file_os2_apptype(struct magic_set *, const char *, const void *,
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 *,
file_protected int file_os2_apptype(struct magic_set *, const char *,
const void *, size_t);
protected void buffer_fini(struct buffer *);
protected int buffer_fill(const struct buffer *);
#endif /* __EMX__ */
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 {
char *buf;
@ -588,8 +606,8 @@ typedef struct {
uint32_t offset;
} file_pushbuf_t;
protected file_pushbuf_t *file_push_buffer(struct magic_set *);
protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
file_protected file_pushbuf_t *file_push_buffer(struct magic_set *);
file_protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
#ifndef COMPILE_ONLY
extern const char *file_names[];

View File

@ -32,7 +32,7 @@
#include "file.h"
#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 */
#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
#endif
private int
file_private int
handle_mime(struct magic_set *ms, int mime, const char *str)
{
if ((mime & MAGIC_MIME_TYPE)) {
@ -86,7 +86,7 @@ handle_mime(struct magic_set *ms, int mime, const char *str)
return 0;
}
protected int
file_protected int
file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb)
{
int ret, did = 0;

View File

@ -27,7 +27,7 @@
#include "file.h"
#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 */
#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)
#endif
protected char *
file_protected char *
file_copystr(char *buf, size_t blen, size_t width, const char *str)
{
if (blen == 0)
@ -63,7 +63,7 @@ file_copystr(char *buf, size_t blen, size_t width, const char *str)
return buf;
}
private void
file_private void
file_clearbuf(struct magic_set *ms)
{
efree(ms->o.buf);
@ -71,7 +71,7 @@ file_clearbuf(struct magic_set *ms)
ms->o.blen = 0;
}
private int
file_private int
file_checkfield(char *msg, size_t mlen, const char *what, const char **pp)
{
const char *p = *pp;
@ -90,7 +90,7 @@ file_checkfield(char *msg, size_t mlen, const char *what, const char **pp)
return 0;
}
protected int
file_protected int
file_checkfmt(char *msg, size_t mlen, const char *fmt)
{
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.
*/
protected int
file_protected int
file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
{
size_t len;
@ -166,7 +166,7 @@ file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
return 0;
}
protected int
file_protected int
file_printf(struct magic_set *ms, const char *fmt, ...)
{
int rv;
@ -183,7 +183,7 @@ file_printf(struct magic_set *ms, const char *fmt, ...)
*/
/*VARARGS*/
__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,
size_t lineno)
{
@ -204,7 +204,7 @@ file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
}
/*VARARGS*/
protected void
file_protected void
file_error(struct magic_set *ms, int error, const char *f, ...)
{
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.
*/
/*VARARGS*/
protected void
file_protected void
file_magerror(struct magic_set *ms, const char *f, ...)
{
va_list va;
@ -226,20 +226,20 @@ file_magerror(struct magic_set *ms, const char *f, ...)
va_end(va);
}
protected void
file_protected void
file_oomem(struct magic_set *ms, size_t len)
{
file_error(ms, errno, "cannot allocate %" SIZE_T_FORMAT "u bytes",
len);
}
protected void
file_protected void
file_badseek(struct magic_set *ms)
{
file_error(ms, errno, "error seeking");
}
protected void
file_protected void
file_badread(struct magic_set *ms)
{
file_error(ms, errno, "error reading");
@ -248,7 +248,7 @@ file_badread(struct magic_set *ms)
#ifndef COMPILE_ONLY
#define FILE_SEPARATOR "\n- "
protected int
file_protected int
file_separator(struct magic_set *ms)
{
return file_printf(ms, FILE_SEPARATOR);
@ -283,7 +283,7 @@ checkdone(struct magic_set *ms, int *rv)
return 0;
}
protected int
file_protected int
file_default(struct magic_set *ms, size_t nb)
{
if (ms->flags & MAGIC_MIME) {
@ -313,9 +313,9 @@ file_default(struct magic_set *ms, size_t nb)
* -1: error
*/
/*ARGSUSED*/
protected int
file_protected int
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)
{
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 */
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)
(void)fprintf(stderr, "[try csv %d]\n", 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 */
if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) {
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);
rbuf = file_pop_buffer(ms, pb);
if (rv == -1) {
free(rbuf);
efree(rbuf);
rbuf = NULL;
}
if ((ms->flags & MAGIC_DEBUG) != 0)
@ -508,7 +519,7 @@ simple:
}
#endif
protected int
file_protected int
file_reset(struct magic_set *ms, int checkloaded)
{
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', \
(o)++)
protected const char *
file_protected const char *
file_getbuffer(struct magic_set *ms)
{
char *pbuf, *op, *np;
@ -611,7 +622,7 @@ file_getbuffer(struct magic_set *ms)
return ms->o.pbuf;
}
protected int
file_protected int
file_check_mem(struct magic_set *ms, unsigned int level)
{
size_t len;
@ -634,13 +645,13 @@ file_check_mem(struct magic_set *ms, unsigned int level)
return 0;
}
protected size_t
file_protected size_t
file_printedlen(const struct magic_set *ms)
{
return ms->o.blen;
}
protected int
file_protected int
file_replace(struct magic_set *ms, const char *pat, const char *rep)
{
zend_string *pattern;
@ -668,7 +679,7 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep)
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';
zend_string_release_ex(res, 0);
@ -677,7 +688,7 @@ out:
return rep_cnt;
}
protected file_pushbuf_t *
file_protected file_pushbuf_t *
file_push_buffer(struct magic_set *ms)
{
file_pushbuf_t *pb;
@ -699,7 +710,7 @@ file_push_buffer(struct magic_set *ms)
return pb;
}
protected char *
file_protected char *
file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
{
char *rbuf;
@ -723,7 +734,7 @@ file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
/*
* convert string to ascii printable format.
*/
protected char *
file_protected char *
file_printable(struct magic_set *ms, char *buf, size_t bufsiz,
const char *str, size_t slen)
{
@ -754,7 +765,7 @@ struct guid {
uint8_t data4[8];
};
protected int
file_protected int
file_parse_guid(const char *s, uint64_t *guid)
{
struct guid *g = CAST(struct guid *, CAST(void *, guid));
@ -779,7 +790,7 @@ file_parse_guid(const char *s, uint64_t *guid)
#endif
}
protected int
file_protected int
file_print_guid(char *str, size_t len, const uint64_t *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
protected int
file_protected int
file_pipe_closexec(int *fds)
{
#ifdef HAVE_PIPE2
#ifdef __MINGW32__
return 0;
#elif defined(HAVE_PIPE2)
return pipe2(fds, O_CLOEXEC);
#else
if (pipe(fds) == -1)
@ -818,7 +831,7 @@ file_pipe_closexec(int *fds)
}
#endif
protected int
file_protected int
file_clear_closexec(int fd) {
#ifdef F_SETFD
return fcntl(fd, F_SETFD, 0);
@ -827,7 +840,7 @@ file_clear_closexec(int fd) {
#endif
}
protected char *
file_protected char *
file_strtrim(char *str)
{
char *last;

View File

@ -32,7 +32,7 @@
#include "file.h"
#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
#include <string.h>
@ -125,12 +125,13 @@ csv_parse(const unsigned char *uc, const unsigned char *ue)
break;
}
}
return tf && nl > 2;
return tf && nl >= 2;
}
#ifndef TEST
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 *ue = uc + b->flen;
@ -154,7 +155,8 @@ file_is_csv(struct magic_set *ms, const struct buffer *b, int looks_text)
return 1;
}
if (file_printf(ms, "CSV text") == -1)
if (file_printf(ms, "CSV %s%stext", code ? code : "",
code ? " " : "") == -1)
return -1;
return 1;
@ -174,7 +176,7 @@ file_is_csv(struct magic_set *ms, const struct buffer *b, int looks_text)
int
main(int argc, char *argv[])
{
int fd, rv;
int fd;
struct stat st;
unsigned char *p;

View File

@ -32,7 +32,7 @@
#include "file.h"
#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
#include "magic.h"
@ -440,7 +440,7 @@ file_is_json(struct magic_set *ms, const struct buffer *b)
return 1;
if (mime) {
if (file_printf(ms, "application/%s",
jt == 1 ? "json" : "x-ndjason") == -1)
jt == 1 ? "json" : "x-ndjson") == -1)
return -1;
return 1;
}
@ -475,7 +475,7 @@ file_is_json(struct magic_set *ms, const struct buffer *b)
int
main(int argc, char *argv[])
{
int fd, rv;
int fd;
struct stat st;
unsigned char *p;
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.
*
* 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).
*
* @(#)list.c 1.18 9/23/86 Public Domain - gnu
@ -40,7 +40,7 @@
#include "file.h"
#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
#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') )
private int is_tar(const unsigned char *, size_t);
private int from_oct(const char *, size_t); /* Decode octal number */
file_private int is_tar(const unsigned char *, size_t);
file_private int from_oct(const char *, size_t); /* Decode octal number */
static const char tartype[][32] = { /* should be equal to messages */
"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)", /* */
};
protected int
file_protected int
file_is_tar(struct magic_set *ms, const struct buffer *b)
{
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,
* 3 for GNU tar file.
*/
private int
file_private int
is_tar(const unsigned char *buf, size_t nbytes)
{
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).
*/
private int
file_private int
from_oct(const char *where, size_t digs)
{
int value;

View File

@ -28,7 +28,7 @@
#include "file.h"
#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 */
#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
#endif
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 int unreadable_info(struct magic_set *, mode_t, const char *);
file_private const char *file_or_stream(struct magic_set *, const char *, php_stream *);
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif
public struct magic_set *
file_public struct magic_set *
magic_open(int flags)
{
return file_ms_alloc(flags);
}
private int
file_private int
unreadable_info(struct magic_set *ms, mode_t md, const char *file)
{
if (file) {
@ -117,7 +117,7 @@ unreadable_info(struct magic_set *ms, mode_t md, const char *file)
return 0;
}
public void
file_public void
magic_close(struct magic_set *ms)
{
if (ms == NULL)
@ -128,7 +128,7 @@ magic_close(struct magic_set *ms)
/*
* load a magic file
*/
public int
file_public int
magic_load(struct magic_set *ms, const char *magicfile)
{
if (ms == NULL)
@ -136,7 +136,7 @@ magic_load(struct magic_set *ms, const char *magicfile)
return file_apprentice(ms, magicfile, FILE_LOAD);
}
public int
file_public int
magic_compile(struct magic_set *ms, const char *magicfile)
{
if (ms == NULL)
@ -144,7 +144,7 @@ magic_compile(struct magic_set *ms, const char *magicfile)
return file_apprentice(ms, magicfile, FILE_COMPILE);
}
public int
file_public int
magic_check(struct magic_set *ms, const char *magicfile)
{
if (ms == NULL)
@ -152,7 +152,7 @@ magic_check(struct magic_set *ms, const char *magicfile)
return file_apprentice(ms, magicfile, FILE_CHECK);
}
public int
file_public int
magic_list(struct magic_set *ms, const char *magicfile)
{
if (ms == NULL)
@ -165,7 +165,7 @@ magic_list(struct magic_set *ms, const char *magicfile)
/*
* find type of descriptor
*/
public const char *
file_public const char *
magic_descriptor(struct magic_set *ms, int fd)
{
if (ms == NULL)
@ -176,7 +176,7 @@ magic_descriptor(struct magic_set *ms, int fd)
/*
* find type of named file
*/
public const char *
file_public const char *
magic_file(struct magic_set *ms, const char *inname)
{
if (ms == NULL)
@ -184,7 +184,7 @@ magic_file(struct magic_set *ms, const char *inname)
return file_or_stream(ms, inname, NULL);
}
public const char *
file_public const char *
magic_stream(struct magic_set *ms, php_stream *stream)
{
if (ms == NULL)
@ -192,7 +192,7 @@ magic_stream(struct magic_set *ms, php_stream *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)
{
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)
{
if (ms == NULL)
@ -286,7 +286,7 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
}
#endif
public const char *
file_public const char *
magic_error(struct magic_set *ms)
{
if (ms == NULL)
@ -294,7 +294,7 @@ magic_error(struct magic_set *ms)
return (ms->event_flags & EVENT_HAD_ERR) ? ms->o.buf : NULL;
}
public int
file_public int
magic_errno(struct magic_set *ms)
{
if (ms == NULL)
@ -302,7 +302,7 @@ magic_errno(struct magic_set *ms)
return (ms->event_flags & EVENT_HAD_ERR) ? ms->error : 0;
}
public int
file_public int
magic_getflags(struct magic_set *ms)
{
if (ms == NULL)
@ -311,7 +311,7 @@ magic_getflags(struct magic_set *ms)
return ms->flags;
}
public int
file_public int
magic_setflags(struct magic_set *ms, int flags)
{
if (ms == NULL)
@ -324,13 +324,13 @@ magic_setflags(struct magic_set *ms, int flags)
return 0;
}
public int
file_public int
magic_version(void)
{
return MAGIC_VERSION;
}
public int
file_public int
magic_setparam(struct magic_set *ms, int param, const void *val)
{
if (ms == NULL)
@ -348,6 +348,9 @@ magic_setparam(struct magic_set *ms, int param, const void *val)
case MAGIC_PARAM_ELF_SHNUM_MAX:
ms->elf_shnum_max = CAST(uint16_t, *CAST(const size_t *, val));
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:
ms->elf_notes_max = CAST(uint16_t, *CAST(const size_t *, val));
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)
{
if (ms == NULL)
@ -384,6 +387,9 @@ magic_getparam(struct magic_set *ms, int param, void *val)
case MAGIC_PARAM_ELF_SHNUM_MAX:
*CAST(size_t *, val) = ms->elf_shnum_max;
return 0;
case MAGIC_PARAM_ELF_SHSIZE_MAX:
*CAST(size_t *, val) = ms->elf_shsize_max;
return 0;
case MAGIC_PARAM_ELF_NOTES_MAX:
*CAST(size_t *, val) = ms->elf_notes_max;
return 0;

View File

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

View File

@ -32,7 +32,7 @@
#include "file.h"
#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 */
#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"
#ifndef COMPILE_ONLY
protected void
file_protected void
file_mdump(struct magic *m)
{
static const char optyp[] = { FILE_OPS };
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);
if (m->flag & INDIR) {
@ -62,7 +62,7 @@ file_mdump(struct magic *m)
"*bad in_type*");
if (m->in_op & FILE_OPINVERSE)
(void) fputc('~', stderr);
(void) fprintf(stderr, "%c%u),",
(void) fprintf(stderr, "%c%d),",
(CAST(size_t, m->in_op & FILE_OPS_MASK) <
__arraycount(optyp)) ?
optyp[m->in_op & FILE_OPS_MASK] : '?', m->in_offset);
@ -134,7 +134,7 @@ file_mdump(struct magic *m)
case FILE_BESHORT:
case FILE_BELONG:
case FILE_INDIRECT:
(void) fprintf(stderr, "%d", m->value.l);
(void) fprintf(stderr, "%d", CAST(int32_t, m->value.l));
break;
case FILE_BEQUAD:
case FILE_LEQUAD:
@ -242,7 +242,7 @@ file_mdump(struct magic *m)
#endif
/*VARARGS*/
protected void
file_protected void
file_magwarn(struct magic_set *ms, const char *f, ...)
{
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)
{
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;
}
protected const char *
file_protected const char *
file_fmtdatetime(char *buf, size_t bsize, uint64_t v, int flags)
{
char *pp;
@ -284,6 +285,9 @@ file_fmtdatetime(char *buf, size_t bsize, uint64_t v, int flags)
t = CAST(time_t, v);
}
if (t > MAX_CTIME)
goto out;
if (flags & FILE_T_LOCAL) {
tm = php_localtime_r(&t, &tmz);
} else {
@ -306,7 +310,7 @@ out:
* https://docs.microsoft.com/en-us/windows/win32/api/winbase/\
* nf-winbase-dosdatetimetofiletime?redirectedfrom=MSDN
*/
protected const char *
file_protected const char *
file_fmtdate(char *buf, size_t bsize, uint16_t v)
{
struct tm tm;
@ -325,7 +329,7 @@ out:
return buf;
}
protected const char *
file_protected const char *
file_fmttime(char *buf, size_t bsize, uint16_t v)
{
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)
{
char *endptr;

View File

@ -26,7 +26,7 @@
#include "file.h"
#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
#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)
{
size_t i;
@ -105,7 +105,7 @@ cdf_clsid_to_mime(const uint64_t clsid[2], const struct cv *cv)
return NULL;
}
private const char *
file_private const char *
cdf_app_to_mime(const char *vbuf, const struct nv *nv)
{
size_t i;
@ -131,7 +131,7 @@ cdf_app_to_mime(const char *vbuf, const struct nv *nv)
return rv;
}
private int
file_private int
cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
size_t count, const cdf_directory_t *root_storage)
{
@ -251,7 +251,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
return 1;
}
private int
file_private int
cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h,
const cdf_stream_t *sst)
{
@ -282,7 +282,7 @@ cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h,
return 1;
}
private int
file_private int
cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
const cdf_stream_t *sst, const cdf_directory_t *root_storage)
{
@ -341,7 +341,7 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
}
#ifdef notdef
private char *
file_private char *
format_clsid(char *buf, size_t len, const uint64_t uuid[2]) {
snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4"
PRIx64 "-%.12" PRIx64,
@ -354,7 +354,7 @@ format_clsid(char *buf, size_t len, const uint64_t uuid[2]) {
}
#endif
private int
file_private int
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_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;
}
private int
file_private int
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_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;
}
private struct sinfo {
file_private struct sinfo {
const char *name;
const char *mime;
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)
{
size_t sd, j;
@ -526,7 +526,7 @@ cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir)
return -1;
}
protected int
file_protected int
file_trycdf(struct magic_set *ms, const struct buffer *b)
{
int fd = b->fd;
@ -602,7 +602,7 @@ file_trycdf(struct magic_set *ms, const struct buffer *b)
sizeof(HWP5_SIGNATURE) - 1) == 0) {
if (NOTMIME(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;
} else if (ms->flags & MAGIC_MIME_TYPE) {
if (file_printf(ms, "application/x-hwp") == -1)

View File

@ -32,40 +32,42 @@
#include "file.h"
#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 */
#include "magic.h"
#include <assert.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <limits.h>
#include <time.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 *,
uint16_t *, int *, int *, int *, int *);
private int mget(struct magic_set *, struct magic *, const struct buffer *,
uint16_t *, int *, int *, int *, int *, int *);
file_private int mget(struct magic_set *, struct magic *, const struct buffer *,
const unsigned char *, size_t,
size_t, unsigned int, int, int, int, uint16_t *,
uint16_t *, int *, int *, int *, int *);
private int msetoffset(struct magic_set *, struct magic *, struct buffer *,
uint16_t *, int *, int *, int *, int *, int *);
file_private int msetoffset(struct magic_set *, struct magic *, struct buffer *,
const struct buffer *, size_t, unsigned int);
private int magiccheck(struct magic_set *, struct magic *);
private int mprint(struct magic_set *, struct magic *);
private int moffset(struct magic_set *, struct magic *, const struct buffer *,
file_private int magiccheck(struct magic_set *, struct magic *);
file_private int mprint(struct magic_set *, struct magic *);
file_private int moffset(struct magic_set *, struct magic *, const struct buffer *,
int32_t *);
private void mdebug(uint32_t, const char *, size_t);
private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
file_private void mdebug(uint32_t, const char *, size_t);
file_private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
const unsigned char *, uint32_t, size_t, struct magic *);
private int mconvert(struct magic_set *, struct magic *, int);
private int print_sep(struct magic_set *, int);
private int handle_annotation(struct magic_set *, struct magic *, int);
private int cvt_8(union VALUETYPE *, const struct magic *);
private int cvt_16(union VALUETYPE *, const struct magic *);
private int cvt_32(union VALUETYPE *, const struct magic *);
private int cvt_64(union VALUETYPE *, const struct magic *);
file_private int mconvert(struct magic_set *, struct magic *, int);
file_private int print_sep(struct magic_set *, int);
file_private int handle_annotation(struct magic_set *, struct magic *, int);
file_private int cvt_8(union VALUETYPE *, const struct magic *);
file_private int cvt_16(union VALUETYPE *, const struct magic *);
file_private int cvt_32(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 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.
*/
/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
protected int
file_protected int
file_softmagic(struct magic_set *ms, const struct buffer *b,
uint16_t *indir_count, uint16_t *name_count, int mode, int text)
{
struct mlist *ml;
int rv = 0, printed_something = 0, need_separator = 0;
int rv = 0, printed_something = 0, need_separator = 0, firstline = 1;
uint16_t nc, ic;
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) {
int ret = match(ms, ml->magic, ml->nmagic, b,
0, mode, text, 0, indir_count, name_count,
&printed_something, &need_separator, NULL, NULL);
&printed_something, &need_separator, &firstline,
NULL, NULL);
switch (ret) {
case -1:
return ret;
@ -154,7 +157,7 @@ file_softmagic(struct magic_set *ms, const struct buffer *b,
#if defined(FILE_FMTDEBUG) && defined(HAVE_FMTCHECK)
#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,
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
* so that higher-level continuations are processed.
*/
private int
file_private int
match(struct magic_set *ms, struct magic *magic,
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 *printed_something, int *need_separator, int *returnval,
int *found_match)
int *printed_something, int *need_separator, int *firstline,
int *returnval, int *found_match)
{
uint32_t magindex = 0;
unsigned int cont_level = 0;
int found_matchv = 0; /* if a match is found it is set to 1*/
int returnvalv = 0, e;
/* a flag to print X\n X\n- X */
int firstline = !(*printed_something || *need_separator);
struct buffer bb;
int print = (ms->flags & MAGIC_NODESC) == 0;
@ -260,7 +261,8 @@ flush:
switch (mget(ms, m, b, CAST(const unsigned char *, bb.fbuf),
bb.flen, offset, cont_level,
mode, text, flip, indir_count, name_count,
printed_something, need_separator, returnval, found_match))
printed_something, need_separator, firstline, returnval,
found_match))
{
case -1:
return -1;
@ -293,12 +295,13 @@ flush:
goto flush;
}
if ((e = handle_annotation(ms, m, firstline)) != 0)
if ((e = handle_annotation(ms, m, *firstline)) != 0)
{
*found_match = 1;
*need_separator = 1;
*printed_something = 1;
*returnval = 1;
*firstline = 0;
return e;
}
@ -312,7 +315,7 @@ flush:
*returnval = 1;
*need_separator = 1;
*printed_something = 1;
if (print_sep(ms, firstline) == -1)
if (print_sep(ms, *firstline) == -1)
return -1;
if (mprint(ms, m) == -1)
return -1;
@ -370,7 +373,7 @@ flush:
bb.fbuf), bb.flen, offset,
cont_level, mode, text, flip, indir_count,
name_count, printed_something, need_separator,
returnval, found_match)) {
firstline, returnval, found_match)) {
case -1:
return -1;
case 0:
@ -407,7 +410,7 @@ flush:
} else
ms->c.li[cont_level].got_match = 1;
if ((e = handle_annotation(ms, m, firstline))
if ((e = handle_annotation(ms, m, *firstline))
!= 0) {
*found_match = 1;
*need_separator = 1;
@ -433,7 +436,7 @@ flush:
*/
if (!*printed_something) {
*printed_something = 1;
if (print_sep(ms, firstline)
if (print_sep(ms, *firstline)
== -1)
return -1;
}
@ -469,21 +472,21 @@ flush:
}
}
if (*printed_something) {
firstline = 0;
*firstline = 0;
}
if (*found_match) {
if ((ms->flags & MAGIC_CONTINUE) == 0)
return *returnval;
// So that we print a separator
*printed_something = 0;
firstline = 0;
*firstline = 0;
}
cont_level = 0;
}
return *returnval;
}
private int
file_private int
check_fmt(struct magic_set *ms, const char *fmt)
{
pcre_cache_entry *pce;
@ -504,7 +507,7 @@ check_fmt(struct magic_set *ms, const char *fmt)
php_pcre_free_match_data(match_data);
}
}
zend_string_release(pattern);
zend_string_release_ex(pattern, 0);
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)
{
uint64_t v;
@ -836,7 +839,7 @@ mprint(struct magic_set *ms, struct magic *m)
return 0;
}
private int
file_private int
moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
int32_t *op)
{
@ -989,7 +992,7 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
return 1;
}
private uint32_t
file_private uint32_t
cvt_id3(struct magic_set *ms, uint32_t v)
{
v = ((((v >> 0) & 0x7f) << 0) |
@ -1001,7 +1004,7 @@ cvt_id3(struct magic_set *ms, uint32_t v)
return v;
}
private int
file_private int
cvt_flip(int type, int flip)
{
if (flip == 0)
@ -1086,28 +1089,28 @@ cvt_flip(int type, int flip)
if (m->mask_op & FILE_OPINVERSE) \
p->fld = ~p->fld \
private int
file_private int
cvt_8(union VALUETYPE *p, const struct magic *m)
{
DO_CVT(b, uint8_t);
return 0;
}
private int
file_private int
cvt_16(union VALUETYPE *p, const struct magic *m)
{
DO_CVT(h, uint16_t);
return 0;
}
private int
file_private int
cvt_32(union VALUETYPE *p, const struct magic *m)
{
DO_CVT(l, uint32_t);
return 0;
}
private int
file_private int
cvt_64(union VALUETYPE *p, const struct magic *m)
{
DO_CVT(q, uint64_t);
@ -1133,14 +1136,14 @@ cvt_64(union VALUETYPE *p, const struct magic *m)
break; \
} \
private int
file_private int
cvt_float(union VALUETYPE *p, const struct magic *m)
{
DO_CVT2(f, float);
return 0;
}
private int
file_private int
cvt_double(union VALUETYPE *p, const struct magic *m)
{
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
* (unless you have a better idea)
*/
private int
file_private int
mconvert(struct magic_set *ms, struct magic *m, int flip)
{
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)
{
(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);
}
private int
file_private int
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)
{
size_t size = sizeof(*p);
/*
* Note: FILE_SEARCH and FILE_REGEX do not actually copy
* 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_PSTRING: /* to copy anything, but do anyway. */
if (m->str_range != 0 && m->str_range < sizeof(*p))
size = m->str_range;
break;
default:
break;
}
@ -1440,10 +1447,10 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
(void)memset(p, '\0', sizeof(*p));
return 0;
}
if (nbytes - offset < sizeof(*p))
if (nbytes - offset < size)
nbytes = nbytes - offset;
else
nbytes = sizeof(*p);
nbytes = size;
(void)memcpy(p, s + offset, nbytes);
@ -1457,10 +1464,19 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
return 0;
}
private uint32_t
do_ops(struct magic *m, intmax_t lhs, intmax_t off)
file_private int
do_ops(struct magic_set *ms, struct magic *m, uint32_t *rv, intmax_t lhs,
intmax_t off)
{
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) {
switch (m->in_op & FILE_OPS_MASK) {
case FILE_OPAND:
@ -1492,11 +1508,16 @@ do_ops(struct magic *m, intmax_t lhs, intmax_t off)
offset = lhs;
if (m->in_op & FILE_OPINVERSE)
offset = ~offset;
return CAST(uint32_t, offset);
if (offset >= UINT_MAX) {
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,
const struct buffer *b, size_t o, unsigned int cont_level)
{
@ -1546,7 +1567,7 @@ normal:
return 0;
}
private int
file_private int
save_cont(struct magic_set *ms, struct cont *c)
{
size_t len;
@ -1561,18 +1582,18 @@ save_cont(struct magic_set *ms, struct cont *c)
return 0;
}
private void
file_private void
restore_cont(struct magic_set *ms, struct cont *c)
{
efree(ms->c.li);
ms->c = *c;
}
private int
file_private int
mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
const unsigned char *s, size_t nbytes, size_t o, unsigned int cont_level,
int mode, int text, int flip, uint16_t *indir_count, uint16_t *name_count,
int *printed_something, int *need_separator, int *returnval,
int *printed_something, int *need_separator, int *firstline, int *returnval,
int *found_match)
{
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:
if (OFFSET_OOB(nbytes, offset, 1))
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;
case FILE_BESHORT:
if (OFFSET_OOB(nbytes, offset, 2))
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;
case FILE_LESHORT:
if (OFFSET_OOB(nbytes, offset, 2))
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;
case FILE_SHORT:
if (OFFSET_OOB(nbytes, offset, 2))
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;
case FILE_BELONG:
case FILE_BEID3:
@ -1717,7 +1742,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
lhs = BE32(p);
if (in_type == FILE_BEID3)
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;
case FILE_LELONG:
case FILE_LEID3:
@ -1726,33 +1752,39 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
lhs = LE32(p);
if (in_type == FILE_LEID3)
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;
case FILE_MELONG:
if (OFFSET_OOB(nbytes, offset, 4))
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;
case FILE_LONG:
if (OFFSET_OOB(nbytes, offset, 4))
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;
case FILE_LEQUAD:
if (OFFSET_OOB(nbytes, offset, 8))
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;
case FILE_BEQUAD:
if (OFFSET_OOB(nbytes, offset, 8))
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;
case FILE_OCTAL:
if (OFFSET_OOB(nbytes, offset, m->vallen))
return 0;
offset = do_ops(m,
SEXT(sgn,64,strtoull(p->s, NULL, 8)), off);
if(do_ops(ms, m, &offset,
SEXT(sgn,64,strtoull(p->s, NULL, 8)), off))
return 0;
break;
default:
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.fbuf = s + offset;
bb.flen = nbytes - offset;
bb.ebuf = NULL;
bb.elen = 0;
rv = -1;
for (mlp = ms->mlist[0]->next; mlp != ms->mlist[0];
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,
mlp->nmagic, &bb, 0, BINTEST, text, 0, indir_count,
name_count, printed_something, need_separator,
NULL, NULL)) != 0)
firstline, NULL, NULL)) != 0)
break;
}
buffer_fini(&bb);
if ((ms->flags & MAGIC_DEBUG) != 0)
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;
rv = match(ms, ml.magic, ml.nmagic, b,
offset + o, mode, text, flip, indir_count, name_count,
printed_something, need_separator, returnval,
printed_something, need_separator, firstline, returnval,
&nfound_match);
ms->ms_value.q = nfound_match;
(*name_count)--;
@ -1935,7 +1970,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
*need_separator = oneed_separator;
ms->offset = offset;
ms->eoffset = eoffset;
return rv;
return rv || *found_match;
case FILE_NAME:
if (ms->flags & MAGIC_NODESC)
@ -1954,7 +1989,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
return 1;
}
private uint64_t
file_private uint64_t
file_strncmp(const char *s1, const char *s2, size_t len, size_t maxlen,
uint32_t flags)
{
@ -2033,7 +2068,7 @@ file_strncmp(const char *s1, const char *s2, size_t len, size_t maxlen,
return v;
}
private uint64_t
file_private uint64_t
file_strncmp16(const char *a, const char *b, size_t len, size_t maxlen,
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);
}
private int
file_private int
magiccheck(struct magic_set *ms, struct magic *m)
{
uint64_t l = m->value.q;
@ -2115,19 +2150,19 @@ magiccheck(struct magic_set *ms, struct magic *m)
break;
case '!':
matched = fv != fl;
matched = isunordered(fl, fv) ? 1 : fv != fl;
break;
case '=':
matched = fv == fl;
matched = isunordered(fl, fv) ? 0 : fv == fl;
break;
case '>':
matched = fv > fl;
matched = isgreater(fv, fl);
break;
case '<':
matched = fv < fl;
matched = isless(fv, fl);
break;
default:
@ -2148,19 +2183,19 @@ magiccheck(struct magic_set *ms, struct magic *m)
break;
case '!':
matched = dv != dl;
matched = isunordered(dv, dl) ? 1 : dv != dl;
break;
case '=':
matched = dv == dl;
matched = isunordered(dv, dl) ? 0 : dv == dl;
break;
case '>':
matched = dv > dl;
matched = isgreater(dv, dl);
break;
case '<':
matched = dv < dl;
matched = isless(dv, dl);
break;
default:
@ -2340,7 +2375,7 @@ error_out:
case 'x':
if ((ms->flags & MAGIC_DEBUG) != 0)
(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;
break;
@ -2348,7 +2383,7 @@ error_out:
matched = v != l;
if ((ms->flags & MAGIC_DEBUG) != 0)
(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, l), matched);
break;
@ -2357,7 +2392,7 @@ error_out:
matched = v == l;
if ((ms->flags & MAGIC_DEBUG) != 0)
(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, l), matched);
break;
@ -2367,7 +2402,7 @@ error_out:
matched = v > l;
if ((ms->flags & MAGIC_DEBUG) != 0)
(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, l), matched);
}
@ -2375,7 +2410,7 @@ error_out:
matched = CAST(int64_t, v) > CAST(int64_t, l);
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT
"d > %" INT64_T_FORMAT "d = %d\n",
"d > %" INT64_T_FORMAT "d = %d",
CAST(long long, v),
CAST(long long, l), matched);
}
@ -2386,7 +2421,7 @@ error_out:
matched = v < l;
if ((ms->flags & MAGIC_DEBUG) != 0)
(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, l), matched);
}
@ -2394,7 +2429,7 @@ error_out:
matched = CAST(int64_t, v) < CAST(int64_t, l);
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT
"d < %" INT64_T_FORMAT "d = %d\n",
"d < %" INT64_T_FORMAT "d = %d",
CAST(long long, v),
CAST(long long, l), matched);
}
@ -2405,7 +2440,7 @@ error_out:
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
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),
matched);
@ -2416,7 +2451,7 @@ error_out:
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
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), matched);
break;
@ -2426,11 +2461,15 @@ error_out:
m->reln);
return -1;
}
if ((ms->flags & MAGIC_DEBUG) != 0) {
(void) fprintf(stderr, " strength=%zu\n",
file_magic_strength(m, 1));
}
return matched;
}
private int
file_private int
handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
{
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;
}
private int
file_private int
print_sep(struct magic_set *ms, int firstline)
{
if (firstline)

View File

@ -26,13 +26,13 @@
* 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.
*
* 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
--- Magdir.orig/rpm 2021-02-23 01:49:24.000000000 +0100
+++ Magdir/rpm 2021-04-05 19:40:55.080911893 +0200

View File

@ -10,13 +10,11 @@ $a='#!env python
from serial import Serial
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);
echo $finfo->buffer($a) . "\n";
$finfo = new finfo();
echo $finfo->buffer($a) . "\n";
?>
--EXPECT--
text/plain
a env python script, ASCII text executable
text/x-script.python
Python script, ASCII text executable

View File

@ -8,5 +8,5 @@ finfo_open(FILEINFO_NONE, __DIR__ . '/bug77961.magic');
?>
--EXPECTF--
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;
$map = array(
131072 => 10055680,
262144 => 10055680,
131072 => 10612736,
262144 => 10612736,
524288 => 11898880,
1048576 => 12152832,
2097152 => 14254080,
4194304 => 18452480,
8388608 => 24743936,
16777216 => 37326848,
1048576 => 12709888,
2097152 => 14811136,
4194304 => 19009536,
8388608 => 25300992,
16777216 => 37883904,
);
for($size = $minSize; $size <= $maxSize; $size *= 2) {
$content = str_repeat('0', $size);

View File

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

View File

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

View File

@ -24,5 +24,5 @@ try {
*** Testing finfo_file() : basic functionality ***
string(28) "text/x-php; charset=us-ascii"
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