diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
--- libmagic.orig/apprentice.c 2018-03-11 01:46:42.000000000 +0100
-+++ libmagic/apprentice.c 2019-03-08 09:31:16.392796494 +0100
++++ libmagic/apprentice.c 2019-04-11 15:17:54.486688613 +0200
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
const char *, int);
private struct mlist *mlist_alloc(void);
private void mlist_free(struct mlist *);
-@@ -170,38 +179,7 @@
+@@ -136,10 +145,7 @@
+ private uint32_t swap4(uint32_t);
+ private uint64_t swap8(uint64_t);
+ private char *mkdbname(struct magic_set *, const char *, int);
+-private struct magic_map *apprentice_buf(struct magic_set *, struct magic *,
+- size_t);
+ private struct magic_map *apprentice_map(struct magic_set *, const char *);
+-private int check_buffer(struct magic_set *, struct magic_map *, const char *);
+ private void apprentice_unmap(struct magic_map *);
+ private int apprentice_compile(struct magic_set *, struct magic_map *,
+ const char *);
+@@ -170,38 +176,7 @@
{ NULL, 0, NULL }
};
struct type_tbl_s {
const char name[16];
-@@ -409,7 +387,7 @@
+@@ -409,7 +384,7 @@
struct mlist *ml;
mlp->map = NULL;
return -1;
ml->map = idx == 0 ? map : NULL;
-@@ -430,10 +408,8 @@
+@@ -430,10 +405,8 @@
apprentice_1(struct magic_set *ms, const char *fn, int action)
{
struct magic_map *map;
if (magicsize != FILE_MAGICSIZE) {
file_error(ms, 0, "magic element size %lu != %lu",
-@@ -449,14 +425,15 @@
+@@ -449,14 +422,15 @@
return apprentice_compile(ms, map, fn);
}
if (map == NULL)
return -1;
}
-@@ -478,9 +455,6 @@
+@@ -478,9 +452,6 @@
}
}
return 0;
}
protected void
-@@ -491,10 +465,16 @@
+@@ -491,10 +462,16 @@
return;
for (i = 0; i < MAGIC_SETS; i++)
mlist_free(ms->mlist[i]);
}
protected struct magic_set *
-@@ -503,7 +483,7 @@
+@@ -503,7 +480,7 @@
struct magic_set *ms;
size_t i, len;
sizeof(struct magic_set)))) == NULL)
return NULL;
-@@ -515,7 +495,7 @@
+@@ -515,7 +492,7 @@
ms->o.buf = ms->o.pbuf = NULL;
len = (ms->c.len = 10) * sizeof(*ms->c.li);
goto free;
ms->event_flags = 0;
-@@ -533,48 +513,35 @@
+@@ -533,48 +510,35 @@
ms->bytes_max = FILE_BYTES_MAX;
return ms;
free:
return NULL;
}
mlist->next = mlist->prev = mlist;
-@@ -593,60 +560,12 @@
+@@ -593,60 +557,12 @@
for (ml = mlist->next; (next = ml->next) != NULL; ml = next) {
if (ml->map)
apprentice_unmap(CAST(struct magic_map *, ml->map));
/* const char *fn: list of magic files and directories */
protected int
file_apprentice(struct magic_set *ms, const char *fn, int action)
-@@ -655,14 +574,31 @@
+@@ -655,14 +571,31 @@
int fileerr, errs = -1;
size_t i;
file_oomem(ms, strlen(fn));
return -1;
}
-@@ -675,7 +611,7 @@
+@@ -675,7 +608,7 @@
mlist_free(ms->mlist[i]);
ms->mlist[i] = NULL;
}
return -1;
}
}
-@@ -692,7 +628,7 @@
+@@ -692,7 +625,7 @@
fn = p;
}
if (errs == -1) {
for (i = 0; i < MAGIC_SETS; i++) {
-@@ -974,7 +910,7 @@
+@@ -974,7 +907,7 @@
return val;
}
* Sort callback for sorting entries by "strength" (basically length)
*/
private int
-@@ -992,7 +928,7 @@
+@@ -992,7 +925,7 @@
return 1;
}
* Shows sorted patterns list in the order which is used for the matching
*/
private void
-@@ -1088,7 +1024,7 @@
+@@ -1088,7 +1021,7 @@
mstart->flag |= BINTEST;
if (mstart->str_flags & STRING_TEXTTEST)
mstart->flag |= TEXTTEST;
if (mstart->flag & (TEXTTEST|BINTEST))
break;
-@@ -1120,7 +1056,7 @@
+@@ -1120,7 +1053,7 @@
mset[i].max += ALLOC_INCR;
if ((mp = CAST(struct magic_entry *,
NULL) {
file_oomem(ms, sizeof(*mp) * mset[i].max);
return -1;
-@@ -1141,13 +1077,19 @@
+@@ -1141,13 +1074,19 @@
load_1(struct magic_set *ms, int action, const char *fn, int *errs,
struct magic_entry_set *mset)
{
if (errno != ENOENT)
file_error(ms, errno, "cannot read magic file `%s'",
fn);
-@@ -1157,8 +1099,7 @@
+@@ -1157,8 +1096,7 @@
memset(&me, 0, sizeof(me));
/* read and parse this file */
if (len == 0) /* null line, garbage, etc */
continue;
if (line[len - 1] == '\n') {
-@@ -1216,8 +1157,8 @@
+@@ -1216,8 +1154,8 @@
}
if (me.mp)
(void)addentry(ms, &me, mset);
}
/*
-@@ -1280,7 +1221,7 @@
+@@ -1280,7 +1218,7 @@
file_magwarn(ms,
"level 0 \"default\" did not sort last");
}
}
}
}
-@@ -1296,7 +1237,7 @@
+@@ -1296,7 +1234,7 @@
mentrycount += me[i].cont_count;
slen = sizeof(**ma) * mentrycount;
file_oomem(ms, slen);
return -1;
}
-@@ -1318,8 +1259,8 @@
+@@ -1318,8 +1256,8 @@
if (me == NULL)
return;
for (i = 0; i < nme; i++)
}
private struct magic_map *
-@@ -1328,18 +1269,19 @@
+@@ -1328,18 +1266,19 @@
int errs = 0;
uint32_t i, j;
size_t files = 0, maxfiles = 0;
{
file_oomem(ms, sizeof(*map));
return NULL;
-@@ -1351,24 +1293,26 @@
+@@ -1351,24 +1290,26 @@
(void)fprintf(stderr, "%s\n", usg_hdr);
/* load directory or file */
continue;
}
if (files >= maxfiles) {
-@@ -1376,23 +1320,22 @@
+@@ -1376,23 +1317,22 @@
maxfiles = (maxfiles + 1) * 2;
mlen = maxfiles * sizeof(*filearr);
if ((filearr = CAST(char **,
} else
load_1(ms, action, fn, &errs, mset);
if (errs)
-@@ -1833,7 +1776,7 @@
+@@ -1833,7 +1773,7 @@
*/
while (*l == '>') {
++l; /* step over */
}
#ifdef ENABLE_CONDITIONALS
if (cont_level == 0 || cont_level > last_cont_level)
-@@ -1859,7 +1802,7 @@
+@@ -1859,7 +1799,7 @@
if (me->cont_count == me->max_count) {
struct magic *nm;
size_t cnt = me->max_count + ALLOC_CHUNK;
sizeof(*nm) * cnt))) == NULL) {
file_oomem(ms, sizeof(*nm) * cnt);
return -1;
-@@ -1874,7 +1817,7 @@
+@@ -1874,7 +1814,7 @@
static const size_t len = sizeof(*m) * ALLOC_CHUNK;
if (me->mp != NULL)
return 1;
file_oomem(ms, len);
return -1;
}
-@@ -1916,17 +1859,6 @@
+@@ -1916,17 +1856,6 @@
file_magwarn(ms, "offset `%s' invalid", l);
return -1;
}
l = t;
if (m->flag & INDIR) {
-@@ -2012,7 +1944,7 @@
+@@ -2012,7 +1941,7 @@
}
l = t;
}
((m->in_op & FILE_OPINDIRECT) && *l++ != ')')) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms,
-@@ -2037,7 +1969,7 @@
+@@ -2037,7 +1966,7 @@
/*
* Try it as a keyword type prefixed by "u"; match what
* follows the "u". If that fails, try it as an SUS
*/
m->type = get_type(type_tbl, l + 1, &l);
if (m->type == FILE_INVALID) {
-@@ -2077,7 +2009,7 @@
+@@ -2077,7 +2006,7 @@
/* Not found - try it as a special keyword. */
m->type = get_type(special_tbl, l, &l);
}
if (m->type == FILE_INVALID) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms, "type `%s' invalid", l);
-@@ -2089,7 +2021,7 @@
+@@ -2089,7 +2018,7 @@
m->mask_op = 0;
if (*l == '~') {
m->mask_op |= FILE_OPINVERSE;
else if (ms->flags & MAGIC_CHECK)
file_magwarn(ms, "'~' invalid for string types");
-@@ -2098,7 +2030,7 @@
+@@ -2098,7 +2027,7 @@
m->str_range = 0;
m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0;
if ((op = get_op(*l)) != -1) {
int r;
if (op != FILE_OPDIVIDE) {
-@@ -2124,7 +2056,7 @@
+@@ -2124,7 +2053,7 @@
* anything if mask = 0 (unless you have a better idea)
*/
EATAB;
switch (*l) {
case '>':
case '<':
-@@ -2156,7 +2088,7 @@
+@@ -2156,7 +2085,7 @@
break;
default:
m->reln = '='; /* the default relation */
isspace((unsigned char)l[1])) || !l[1])) {
m->reln = *l;
++l;
-@@ -2171,7 +2103,7 @@
+@@ -2171,7 +2100,7 @@
/*
* TODO finish this macro and start using it!
* magwarn("offset too big"); }
*/
-@@ -2203,11 +2135,6 @@
+@@ -2203,11 +2132,6 @@
if (check_format(ms, m) == -1)
return -1;
}
m->mimetype[0] = '\0'; /* initialise MIME type to none */
return 0;
}
-@@ -2279,7 +2206,7 @@
+@@ -2279,7 +2203,7 @@
private int
parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
{
size_t i;
const char *l = line;
-@@ -2291,7 +2218,7 @@
+@@ -2291,7 +2215,7 @@
file_magwarn(ms, "Current entry already has a %s type "
"`%.*s', new type `%s'", name, (int)len, buf, l);
return -1;
if (*m->desc == '\0') {
file_magwarn(ms, "Current entry does not yet have a "
-@@ -2361,7 +2288,7 @@
+@@ -2361,7 +2285,7 @@
struct magic *m = &me->mp[0];
return parse_extra(ms, me, line,
sizeof(m->mimetype), "MIME", "+-/.$?:{}", 1);
}
-@@ -2428,7 +2355,7 @@
+@@ -2428,7 +2352,7 @@
if (*ptr++ != 'l')
goto invalid;
}
switch (*ptr++) {
#ifdef STRICT_FORMAT /* "long" formats are int formats for us */
/* so don't accept the 'l' modifier */
-@@ -2446,7 +2373,7 @@
+@@ -2446,7 +2370,7 @@
default:
goto invalid;
}
/*
* Don't accept h and hh modifiers. They make writing
* magic entries more complicated, for very little benefit
-@@ -2502,7 +2429,7 @@
+@@ -2502,7 +2426,7 @@
default:
goto invalid;
}
case FILE_FMT_FLOAT:
case FILE_FMT_DOUBLE:
if (*ptr == '-')
-@@ -2521,11 +2448,11 @@
+@@ -2521,11 +2445,11 @@
case 'g':
case 'G':
return 0;
case FILE_FMT_STR:
if (*ptr == '-')
-@@ -2537,14 +2464,14 @@
+@@ -2537,14 +2461,14 @@
while (isdigit((unsigned char )*ptr))
ptr++;
}
default:
/* internal error */
abort();
-@@ -2555,7 +2482,7 @@
+@@ -2555,7 +2479,7 @@
*estr = "too long";
return -1;
}
/*
* Check that the optional printf format in description matches
* the type of the magic.
-@@ -2578,7 +2505,7 @@
+@@ -2578,7 +2502,7 @@
if (m->type >= file_nformats) {
file_magwarn(ms, "Internal error inconsistency between "
return -1;
}
if (file_formats[m->type] == FILE_FMT_NONE) {
-@@ -2598,7 +2525,7 @@
+@@ -2598,7 +2522,7 @@
file_names[m->type], m->desc);
return -1;
}
for (; *ptr; ptr++) {
if (*ptr == '%') {
file_magwarn(ms,
-@@ -2611,9 +2538,9 @@
+@@ -2611,9 +2535,9 @@
return 0;
}
* just after the number read. Return 0 for success, non-zero for failure.
*/
private int
-@@ -2640,14 +2567,19 @@
+@@ -2640,14 +2564,19 @@
return -1;
}
if (m->type == FILE_REGEX) {
}
return 0;
default:
-@@ -2770,7 +2702,7 @@
+@@ -2770,7 +2699,7 @@
default:
if (warn) {
if (isprint((unsigned char)c)) {
* ``relations'' */
if (strchr("<>&^=!", c) == NULL
&& (m->type != FILE_REGEX ||
-@@ -2975,7 +2907,7 @@
+@@ -2975,7 +2904,7 @@
{
const char *l = *p;
l++;
switch (LOWCASE(*l)) {
-@@ -3001,7 +2933,7 @@
+@@ -2993,6 +2922,7 @@
+ *p = l;
+ }
+
++#if 0
+ /*
+ * handle a buffer containing a compiled file.
+ */
+@@ -3001,7 +2931,7 @@
{
struct magic_map *map;
file_oomem(ms, sizeof(*map));
return NULL;
}
-@@ -3022,79 +2954,145 @@
+@@ -3014,6 +2944,7 @@
+ }
+ return map;
+ }
++#endif
+
+ /*
+ * handle a compiled file.
+@@ -3022,81 +2953,148 @@
private struct magic_map *
apprentice_map(struct magic_set *ms, const char *fn)
{
+ size_t i;
+ php_stream *stream = NULL;
+ php_stream_statbuf st;
-+
-+
- fd = -1;
- if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
++
++
+ if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) {
file_oomem(ms, sizeof(*map));
- goto error;
+ return NULL;
}
++#if 0
private int
+ check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname)
+ {
@@ -3120,7 +3118,7 @@
version = ptr[1];
if (version != VERSIONNO) {
VERSIONNO, dbname, version);
return -1;
}
-@@ -3161,7 +3159,6 @@
+@@ -3152,6 +3150,7 @@
+ byteswap(map->magic[i], map->nmagic[i]);
+ return 0;
+ }
++#endif
+
+ /*
+ * handle an mmaped file.
+@@ -3161,7 +3160,6 @@
{
static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS;
static const size_t m = sizeof(**map->magic);
size_t len;
char *dbname;
int rv = -1;
-@@ -3170,14 +3167,17 @@
+@@ -3170,14 +3168,17 @@
struct magic m;
uint32_t h[2 + MAGIC_SETS];
} hdr;
file_error(ms, errno, "cannot open `%s'", dbname);
goto out;
}
-@@ -3186,26 +3186,25 @@
+@@ -3186,26 +3187,25 @@
hdr.h[1] = VERSIONNO;
memcpy(hdr.h + 2, map->nmagic, nm);
return rv;
}
-@@ -3239,16 +3238,18 @@
+@@ -3239,16 +3239,18 @@
q++;
/* Compatibility with old code that looked in .mime */
if (ms->flags & MAGIC_MIME) {
/* Compatibility with old code that looked in .mime */
if (strstr(fn, ".mime") != NULL)
-@@ -3274,8 +3275,8 @@
+@@ -3274,8 +3276,8 @@
swap2(uint16_t sv)
{
uint16_t rv;
d[0] = s[1];
d[1] = s[0];
return rv;
-@@ -3288,8 +3289,8 @@
+@@ -3288,8 +3290,8 @@
swap4(uint32_t sv)
{
uint32_t rv;
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
-@@ -3304,8 +3305,8 @@
+@@ -3304,8 +3306,8 @@
swap8(uint64_t sv)
{
uint64_t rv;
#if 0
d[0] = s[3];
d[1] = s[2];
-@@ -3338,7 +3339,7 @@
+@@ -3338,7 +3340,7 @@
m->offset = swap4((int32_t)m->offset);
m->in_offset = swap4((uint32_t)m->in_offset);
m->lineno = swap4((uint32_t)m->lineno);
m->str_range = swap4(m->str_range);
m->str_flags = swap4(m->str_flags);
}
-@@ -3348,7 +3349,7 @@
+@@ -3348,7 +3350,7 @@
}
}
(void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n",
diff -u libmagic.orig/compress.c libmagic/compress.c
--- libmagic.orig/compress.c 2017-11-02 21:25:39.000000000 +0100
-+++ libmagic/compress.c 2019-03-08 09:31:16.392796494 +0100
++++ libmagic/compress.c 2019-04-11 15:16:47.060067956 +0200
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_WAIT_H
-@@ -62,51 +60,12 @@
+@@ -62,56 +60,18 @@
#if defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#endif
#define gzip_flags "-cd"
#define lrzip_flags "-do"
-@@ -169,7 +128,7 @@
+ #define lzip_flags gzip_flags
+
++#ifdef PHP_FILEINFO_UNCOMPRESS
+ static const char *gzip_args[] = {
+ "gzip", gzip_flags, NULL
+ };
+@@ -163,13 +123,14 @@
+ { RCAST(const void *, zlibcmp), 0, zlib_args }, /* zlib */
+ #endif
+ };
++#endif
+
+ #define OKDATA 0
+ #define NODATA 1
#define ERRDATA 2
private ssize_t swrite(int, const void *, size_t);
private size_t ncompr = sizeof(compr) / sizeof(compr[0]);
private int uncompressbuf(int, size_t, size_t, const unsigned char *,
unsigned char **, size_t *);
-@@ -179,12 +138,12 @@
+@@ -179,12 +140,12 @@
private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
size_t *);
#endif
{
unsigned char *newbuf = NULL;
size_t i, nsz;
-@@ -192,9 +151,6 @@
+@@ -192,9 +153,6 @@
file_pushbuf_t *pb;
int urv, prv, rv = 0;
int mime = ms->flags & MAGIC_MIME;
#ifdef HAVE_SIGNAL_H
sig_t osigpipe;
#endif
-@@ -226,7 +182,7 @@
+@@ -226,7 +184,7 @@
switch (urv) {
case OKDATA:
case ERRDATA:
ms->flags &= ~MAGIC_COMPRESS;
if (urv == ERRDATA)
prv = file_printf(ms, "%s ERROR: %s",
-@@ -253,10 +209,10 @@
+@@ -253,10 +211,10 @@
goto error;
if ((rbuf = file_pop_buffer(ms, pb)) != NULL) {
if (file_printf(ms, "%s", rbuf) == -1) {
}
if (!mime && file_printf(ms, ")") == -1)
goto error;
-@@ -277,7 +233,8 @@
+@@ -277,7 +235,8 @@
#ifdef HAVE_SIGNAL_H
(void)signal(SIGPIPE, osigpipe);
#endif
ms->flags |= MAGIC_COMPRESS;
DPRINTF("Zmagic returns %d\n", rv);
return rv;
-@@ -312,7 +269,7 @@
+@@ -312,7 +271,7 @@
* `safe' read for sockets and pipes.
*/
protected ssize_t
{
ssize_t rv;
#ifdef FIONREAD
-@@ -360,7 +317,7 @@
+@@ -360,7 +319,7 @@
nocheck:
do
case -1:
if (errno == EINTR)
continue;
-@@ -437,13 +394,14 @@
+@@ -437,13 +396,14 @@
return -1;
}
(void)close(tfd);
#ifdef BUILTIN_DECOMPRESS
#define FHCRC (1 << 1)
-@@ -494,7 +452,7 @@
+@@ -494,7 +454,7 @@
int rc;
z_stream z;
return makeerror(newch, n, "No buffer, %s", strerror(errno));
z.next_in = CCAST(Bytef *, old);
-@@ -518,7 +476,7 @@
+@@ -518,7 +478,7 @@
rc = inflateEnd(&z);
if (rc != Z_OK)
goto err;
/* let's keep the nul-terminate tradition */
(*newch)[*n] = '\0';
-@@ -586,7 +544,7 @@
+@@ -586,7 +546,7 @@
int status;
closefd(fdp[STDIN_FILENO], 0);
* fork again, to avoid blocking because both
* pipes filled
*/
-@@ -689,13 +647,13 @@
+@@ -689,13 +649,13 @@
fdp[STDIN_FILENO][0] = fd;
(void) lseek(fd, (off_t)0, SEEK_SET);
}
compr[method].argv[0], strerror(errno));
exit(1);
/*NOTREACHED*/
-@@ -711,7 +669,7 @@
+@@ -711,7 +671,7 @@
if (fd == -1)
writechild(fdp, old, *n);
if (*newch == NULL) {
rv = makeerror(newch, n, "No buffer, %s",
strerror(errno));
-@@ -730,7 +688,7 @@
+@@ -730,7 +690,7 @@
r = filter_error(*newch, r);
break;
}
if (r == 0)
rv = makeerror(newch, n, "Read failed, %s",
strerror(errno));
-@@ -738,27 +696,5 @@
+@@ -738,27 +698,5 @@
rv = makeerror(newch, n, "No data");
goto err;
}
diff -u libmagic.orig/magic.c libmagic/magic.c
--- libmagic.orig/magic.c 2017-08-28 15:39:18.000000000 +0200
-+++ libmagic/magic.c 2019-03-08 09:31:16.396796480 +0100
++++ libmagic/magic.c 2019-04-11 15:19:30.857295866 +0200
@@ -25,11 +25,6 @@
* SUCH DAMAGE.
*/
#if defined(HAVE_UTIMES)
# include <sys/time.h>
-@@ -71,194 +71,23 @@
+@@ -71,194 +71,21 @@
#endif
#endif
+-private void close_and_restore(const struct magic_set *, const char *, int,
+- const struct stat *);
+#ifdef PHP_WIN32
+# undef S_IFLNK
+# undef S_IFIFO
+#endif
+
- private void close_and_restore(const struct magic_set *, const char *, int,
-- const struct stat *);
-+ const zend_stat_t *);
private int unreadable_info(struct magic_set *, mode_t, const char *);
+#if 0
private const char* get_default_magic(void);
public struct magic_set *
magic_open(int flags)
{
-@@ -304,20 +133,6 @@
+@@ -304,20 +131,6 @@
return file_apprentice(ms, magicfile, FILE_LOAD);
}
public int
magic_compile(struct magic_set *ms, const char *magicfile)
{
-@@ -344,7 +159,7 @@
+@@ -342,9 +155,10 @@
+ return file_apprentice(ms, magicfile, FILE_LIST);
+ }
++#if 0
private void
close_and_restore(const struct magic_set *ms, const char *name, int fd,
- const struct stat *sb)
{
if (fd == STDIN_FILENO || name == NULL)
return;
-@@ -375,7 +190,6 @@
+@@ -374,8 +188,8 @@
+ #endif
}
}
++#endif
-#ifndef COMPILE_ONLY