]> granicus.if.org Git - php/commitdiff
update libmagic.patch
authorAnatol Belski <ab@php.net>
Thu, 24 Nov 2016 13:58:54 +0000 (14:58 +0100)
committerAnatol Belski <ab@php.net>
Thu, 24 Nov 2016 13:58:54 +0000 (14:58 +0100)
ext/fileinfo/libmagic.patch

index 5dce310184259636056d4ee9f61c2ce61040cc4a..676172979b6eb13f5dcd408d5ad0f1b0416c4888 100644 (file)
@@ -1,6 +1,6 @@
 diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
---- libmagic.orig/apprentice.c 2016-01-25 11:31:21.473017702 +0800
-+++ libmagic/apprentice.c      2016-01-25 11:41:58.210723599 +0800
+--- libmagic.orig/apprentice.c 2016-11-23 17:08:22.955687700 +0100
++++ libmagic/apprentice.c      2016-11-24 13:42:04.122242100 +0100
 @@ -29,6 +29,8 @@
   * apprentice - make one pass through /etc/magic, learning its secrets.
   */
@@ -49,7 +49,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  
  #ifndef SSIZE_MAX
  #define MAXMAGIC_SIZE        ((ssize_t)0x7fffffff)
-@@ -168,38 +173,7 @@
+@@ -170,38 +175,7 @@
        { NULL, 0, NULL }
  };
  
@@ -89,7 +89,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  
  struct type_tbl_s {
        const char name[16];
-@@ -281,6 +255,10 @@
+@@ -285,6 +259,10 @@
  # undef XX
  # undef XX_NULL
  
@@ -100,16 +100,16 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  private int
  get_type(const struct type_tbl_s *tbl, const char *l, const char **t)
  {
-@@ -405,7 +383,7 @@
+@@ -409,7 +387,7 @@
        struct mlist *ml;
  
-       mlp->map = idx == 0 ? map : NULL;
+       mlp->map = NULL;
 -      if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL)
 +      if ((ml = CAST(struct mlist *, emalloc(sizeof(*ml)))) == NULL)
                return -1;
  
-       ml->map = NULL;
-@@ -426,10 +404,8 @@
+       ml->map = idx == 0 ? map : NULL;
+@@ -430,10 +408,8 @@
  apprentice_1(struct magic_set *ms, const char *fn, int action)
  {
        struct magic_map *map;
@@ -120,12 +120,14 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  
        if (magicsize != FILE_MAGICSIZE) {
                file_error(ms, 0, "magic element size %lu != %lu",
-@@ -445,12 +421,13 @@
+@@ -449,14 +425,15 @@
                return apprentice_compile(ms, map, fn);
        }
  
 -#ifndef COMPILE_ONLY
        map = apprentice_map(ms, fn);
+       if (map == (struct magic_map *)-1)
+               return -1;
        if (map == NULL) {
 -              if (ms->flags & MAGIC_CHECK)
 -                      file_magwarn(ms, "using regular magic file `%s'", fn);
@@ -138,33 +140,17 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                if (map == NULL)
                        return -1;
        }
-@@ -458,7 +435,8 @@
-       for (i = 0; i < MAGIC_SETS; i++) {
-               if (add_mlist(ms->mlist[i], map, i) == -1) {
-                       file_oomem(ms, sizeof(*ml));
--                      goto fail;
-+                      apprentice_unmap(map);
-+                      return -1;
-               }
-       }
-@@ -472,15 +450,6 @@
+@@ -478,9 +455,6 @@
                }
        }
        return 0;
--fail:
--      for (i = 0; i < MAGIC_SETS; i++) {
--              mlist_free(ms->mlist[i]);
--              ms->mlist[i] = NULL;
--      }
--      return -1;
 -#else
 -      return 0;
 -#endif /* COMPILE_ONLY */
  }
  
  protected void
-@@ -491,10 +460,16 @@
+@@ -491,10 +465,16 @@
                return;
        for (i = 0; i < MAGIC_SETS; i++)
                mlist_free(ms->mlist[i]);
@@ -185,7 +171,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  }
  
  protected struct magic_set *
-@@ -503,7 +478,7 @@
+@@ -503,7 +483,7 @@
        struct magic_set *ms;
        size_t i, len;
  
@@ -194,7 +180,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
            sizeof(struct magic_set)))) == NULL)
                return NULL;
  
-@@ -515,7 +490,7 @@
+@@ -515,7 +495,7 @@
        ms->o.buf = ms->o.pbuf = NULL;
        len = (ms->c.len = 10) * sizeof(*ms->c.li);
  
@@ -203,8 +189,8 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                goto free;
  
        ms->event_flags = 0;
-@@ -531,7 +506,7 @@
-       ms->elf_notes_max = FILE_ELF_NOTES_MAX;
+@@ -533,46 +513,35 @@
+       ms->bytes_max = FILE_BYTES_MAX;
        return ms;
  free:
 -      free(ms);
@@ -212,25 +198,22 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
        return NULL;
  }
  
-@@ -540,30 +515,26 @@
+ private void
+ apprentice_unmap(struct magic_map *map)
  {
+-      size_t i;
        if (map == NULL)
                return;
 -
 -      switch (map->type) {
--#ifdef QUICK
--      case MAP_TYPE_MMAP:
--              if (map->p)
--                      (void)munmap(map->p, map->len);
--              break;
--#endif
--      case MAP_TYPE_MALLOC:
--              free(map->p);
--              break;
 -      case MAP_TYPE_USER:
 -              break;
--      default:
--              abort();
+-      case MAP_TYPE_MALLOC:
+-              for (i = 0; i < MAGIC_SETS; i++) {
+-                      if ((char *)map->magic[i] >= (char *)map->p &&
+-                          (char *)map->magic[i] <= (char *)map->p + map->len)
+-                              continue;
+-                      free(map->magic[i]);
 +      if (map->p != php_magic_database) {
 +              if (map->p == NULL) {
 +                      int j;
@@ -241,7 +224,17 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
 +                      }
 +              } else {
 +                      efree(map->p);
-+              }
+               }
+-              free(map->p);
+-              break;
+-#ifdef QUICK
+-      case MAP_TYPE_MMAP:
+-              if (map->p && map->p != MAP_FAILED)
+-                      (void)munmap(map->p, map->len);
+-              break;
+-#endif
+-      default:
+-              abort();
        }
 -      free(map);
 +      efree(map);
@@ -256,10 +249,10 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                return NULL;
        }
        mlist->next = mlist->prev = mlist;
-@@ -582,61 +553,12 @@
+@@ -591,61 +560,12 @@
        for (ml = mlist->next; (next = ml->next) != NULL; ml = next) {
                if (ml->map)
-                       apprentice_unmap(ml->map);
+                       apprentice_unmap(CAST(struct magic_map *, ml->map));
 -              free(ml);
 +              efree(ml);
                if (ml == mlist)
@@ -319,7 +312,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  /* const char *fn: list of magic files and directories */
  protected int
  file_apprentice(struct magic_set *ms, const char *fn, int action)
-@@ -648,12 +570,28 @@
+@@ -657,12 +577,28 @@
        if (ms->mlist[0] != NULL)
                file_reset(ms);
  
@@ -349,7 +342,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                file_oomem(ms, strlen(fn));
                return -1;
        }
-@@ -666,7 +604,7 @@
+@@ -675,7 +611,7 @@
                                mlist_free(ms->mlist[i]);
                                ms->mlist[i] = NULL;
                        }
@@ -358,7 +351,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                        return -1;
                }
        }
-@@ -683,7 +621,7 @@
+@@ -692,7 +628,7 @@
                fn = p;
        }
  
@@ -367,7 +360,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  
        if (errs == -1) {
                for (i = 0; i < MAGIC_SETS; i++) {
-@@ -1062,7 +1000,7 @@
+@@ -1076,7 +1012,7 @@
  
                mset[i].max += ALLOC_INCR;
                if ((mp = CAST(struct magic_entry *,
@@ -376,7 +369,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                    NULL) {
                        file_oomem(ms, sizeof(*mp) * mset[i].max);
                        return -1;
-@@ -1083,13 +1021,19 @@
+@@ -1097,13 +1033,19 @@
  load_1(struct magic_set *ms, int action, const char *fn, int *errs,
     struct magic_entry_set *mset)
  {
@@ -400,7 +393,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                if (errno != ENOENT)
                        file_error(ms, errno, "cannot read magic file `%s'",
                                   fn);
-@@ -1099,8 +1043,7 @@
+@@ -1113,8 +1055,7 @@
  
        memset(&me, 0, sizeof(me));
        /* read and parse this file */
@@ -410,7 +403,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                if (len == 0) /* null line, garbage, etc */
                        continue;
                if (line[len - 1] == '\n') {
-@@ -1158,8 +1101,8 @@
+@@ -1172,8 +1113,8 @@
        }
        if (me.mp)
                (void)addentry(ms, &me, mset);
@@ -421,7 +414,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  }
  
  /*
-@@ -1238,7 +1181,7 @@
+@@ -1252,7 +1193,7 @@
                mentrycount += me[i].cont_count;
  
        slen = sizeof(**ma) * mentrycount;
@@ -430,7 +423,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                file_oomem(ms, slen);
                return -1;
        }
-@@ -1260,8 +1203,8 @@
+@@ -1274,8 +1215,8 @@
        if (me == NULL)
                return;
        for (i = 0; i < nme; i++)
@@ -441,7 +434,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  }
  
  private struct magic_map *
-@@ -1270,18 +1213,19 @@
+@@ -1284,18 +1225,19 @@
        int errs = 0;
        uint32_t i, j;
        size_t files = 0, maxfiles = 0;
@@ -466,7 +459,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
        {
                file_oomem(ms, sizeof(*map));
                return NULL;
-@@ -1292,22 +1236,26 @@
+@@ -1307,22 +1249,26 @@
                (void)fprintf(stderr, "%s\n", usg_hdr);
  
        /* load directory or file */
@@ -501,7 +494,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                                continue;
                        }
                        if (files >= maxfiles) {
-@@ -1315,23 +1263,22 @@
+@@ -1330,23 +1276,22 @@
                                maxfiles = (maxfiles + 1) * 2;
                                mlen = maxfiles * sizeof(*filearr);
                                if ((filearr = CAST(char **,
@@ -531,7 +524,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
        } else
                load_1(ms, action, fn, &errs, mset);
        if (errs)
-@@ -1796,7 +1743,7 @@
+@@ -1813,7 +1758,7 @@
                if (me->cont_count == me->max_count) {
                        struct magic *nm;
                        size_t cnt = me->max_count + ALLOC_CHUNK;
@@ -540,7 +533,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                            sizeof(*nm) * cnt))) == NULL) {
                                file_oomem(ms, sizeof(*nm) * cnt);
                                return -1;
-@@ -1811,7 +1758,7 @@
+@@ -1828,7 +1773,7 @@
                static const size_t len = sizeof(*m) * ALLOC_CHUNK;
                if (me->mp != NULL)
                        return 1;
@@ -549,16 +542,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                        file_oomem(ms, len);
                        return -1;
                }
-@@ -1984,7 +1931,7 @@
-                               m->type = get_standard_integer_type(l, &l);
-                       else if (*l == 's' && !isalpha((unsigned char)l[1])) {
-                               m->type = FILE_STRING;
--                              ++l;
-+              ++l;
-                       }
-               }
-       }
-@@ -2005,7 +1952,7 @@
+@@ -2032,7 +1977,7 @@
  
        m->mask_op = 0;
        if (*l == '~') {
@@ -567,7 +551,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                        m->mask_op |= FILE_OPINVERSE;
                else if (ms->flags & MAGIC_CHECK)
                        file_magwarn(ms, "'~' invalid for string types");
-@@ -2014,7 +1961,7 @@
+@@ -2041,7 +1986,7 @@
        m->str_range = 0;
        m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0;
        if ((op = get_op(*l)) != -1) {
@@ -576,7 +560,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                        int r;
  
                        if (op != FILE_OPDIVIDE) {
-@@ -2119,11 +2066,6 @@
+@@ -2146,11 +2091,6 @@
                if (check_format(ms, m) == -1)
                        return -1;
        }
@@ -588,7 +572,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
        m->mimetype[0] = '\0';          /* initialise MIME type to none */
        return 0;
  }
-@@ -2195,7 +2137,7 @@
+@@ -2222,7 +2162,7 @@
  
  private int
  parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
@@ -597,7 +581,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  {
        size_t i;
        const char *l = line;
-@@ -2264,7 +2206,7 @@
+@@ -2304,7 +2244,7 @@
        struct magic *m = &me->mp[0];
  
        return parse_extra(ms, me, line,
@@ -606,7 +590,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
            sizeof(m->mimetype), "MIME", "+-/.", 1);
  }
  
-@@ -2517,14 +2459,18 @@
+@@ -2578,14 +2518,18 @@
                        return -1;
                }
                if (m->type == FILE_REGEX) {
@@ -632,7 +616,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                }
                return 0;
        case FILE_FLOAT:
-@@ -2854,68 +2800,144 @@
+@@ -2924,79 +2868,145 @@
  private struct magic_map *
  apprentice_map(struct magic_set *ms, const char *fn)
  {
@@ -643,6 +627,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
 +      int needsbyteswap;
        char *dbname = NULL;
        struct magic_map *map;
+-      struct magic_map *rv = NULL;
 +      size_t i;
 +      php_stream *stream = NULL;
 +      php_stream_statbuf st;
@@ -655,12 +640,13 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                file_oomem(ms, sizeof(*map));
 -              goto error;
 +              return NULL;
-       }
++      }
++
 +      if (fn == NULL) {
 +              map->p = (void *)&php_magic_database;
 +              goto internal_loaded;
-+      }
+       }
+-      map->type = MAP_TYPE_USER;      /* unspecified */
 +
 +#ifdef PHP_WIN32
 +      /* Don't bother on windows with php_stream_open_wrapper,
@@ -671,7 +657,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
 +               }
 +       }
 +#endif
-+
        dbname = mkdbname(ms, fn, 0);
        if (dbname == NULL)
                goto error;
@@ -698,13 +684,14 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  
 -      map->len = (size_t)st.st_size;
 -#ifdef QUICK
+-      map->type = MAP_TYPE_MMAP;
 -      if ((map->p = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE,
 -          MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) {
 -              file_error(ms, errno, "cannot map `%s'", dbname);
 -              goto error;
 -      }
--      map->type = MAP_TYPE_MMAP;
 -#else
+-      map->type = MAP_TYPE_MALLOC;
 -      if ((map->p = CAST(void *, malloc(map->len))) == NULL) {
 +      map->len = (size_t)st.sb.st_size;
 +      if ((map->p = CAST(void *, emalloc(map->len))) == NULL) {
@@ -716,14 +703,14 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                file_badread(ms);
                goto error;
        }
--      map->type = MAP_TYPE_MALLOC;
 +      map->len = 0;
  #define RET   1
 -#endif
 -      (void)close(fd);
 -      fd = -1;
  
--      if (check_buffer(ms, map, dbname) != 0)
+-      if (check_buffer(ms, map, dbname) != 0) {
+-              rv = (struct magic_map *)-1;
 +      php_stream_close(stream);
 +      stream = NULL;
 +
@@ -745,8 +732,11 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
 +              file_error(ms, 0, "File %d.%d supports only version %d magic "
 +                  "files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel,
 +                  VERSIONNO, dbname, version);
-+              goto error;
-+      }
+               goto error;
+       }
+-#ifdef QUICK
+-      if (mprotect(map->p, (size_t)st.st_size, PROT_READ) == -1) {
+-              file_error(ms, errno, "cannot mprotect `%s'", dbname);
 +
 +      /* php_magic_database is a const, performing writes will segfault. This is for big-endian
 +      machines only, PPC and Sparc specifically. Consider static variable or MINIT in
@@ -781,7 +771,8 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
 +              file_error(ms, 0, "Inconsistent entries in `%s' %u != %u",
 +                  dbname, entries, nentries + 1);
                goto error;
-+      }
+       }
+-#endif
 +      if (needsbyteswap)
 +              for (i = 0; i < MAGIC_SETS; i++)
 +                      byteswap(map->magic[i], map->nmagic[i]);
@@ -800,13 +791,15 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
 +      }
        apprentice_unmap(map);
 -      free(dbname);
+-      return rv;
 +      if (dbname) {
 +              efree(dbname);
 +      }
-       return NULL;
++      return NULL;
  }
  
-@@ -2942,7 +2964,7 @@
+ private int
+@@ -3022,7 +3032,7 @@
                version = ptr[1];
        if (version != VERSIONNO) {
                file_error(ms, 0, "File %s supports only version %d magic "
@@ -815,7 +808,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                    VERSIONNO, dbname, version);
                return -1;
        }
-@@ -2983,7 +3005,6 @@
+@@ -3063,7 +3073,6 @@
  {
        static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS;
        static const size_t m = sizeof(**map->magic);
@@ -823,18 +816,15 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
        size_t len;
        char *dbname;
        int rv = -1;
-@@ -2992,14 +3013,18 @@
+@@ -3072,14 +3081,17 @@
                struct magic m;
                uint32_t h[2 + MAGIC_SETS];
        } hdr;
 +      php_stream *stream;
  
--      dbname = mkdbname(ms, fn, 1);
+       dbname = mkdbname(ms, fn, 1);
  
--      if (dbname == NULL) 
-+      dbname = mkdbname(ms, fn, 0);
-+
-+      if (dbname == NULL)
+       if (dbname == NULL) 
                goto out;
  
 -      if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1) 
@@ -846,7 +836,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                file_error(ms, errno, "cannot open `%s'", dbname);
                goto out;
        }
-@@ -3008,24 +3033,25 @@
+@@ -3088,25 +3100,25 @@
        hdr.h[1] = VERSIONNO;
        memcpy(hdr.h + 2, map->nmagic, nm);
  
@@ -872,12 +862,13 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
 +      }
        rv = 0;
  out:
+-      apprentice_unmap(map);
 -      free(dbname);
 +      efree(dbname);
        return rv;
  }
  
-@@ -3059,16 +3085,18 @@
+@@ -3140,16 +3152,18 @@
        q++;
        /* Compatibility with old code that looked in .mime */
        if (ms->flags & MAGIC_MIME) {
@@ -901,8 +892,8 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
 +      spprintf(&buf, MAXPATHLEN, "%.*s%s", (int)(q - fn), fn, ext);
  
        /* Compatibility with old code that looked in .mime */
-       if (strstr(p, ".mime") != NULL)
-@@ -3158,7 +3186,7 @@
+       if (strstr(fn, ".mime") != NULL)
+@@ -3239,7 +3253,7 @@
        m->offset = swap4((uint32_t)m->offset);
        m->in_offset = swap4((uint32_t)m->in_offset);
        m->lineno = swap4((uint32_t)m->lineno);
@@ -912,9 +903,9 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
                m->str_flags = swap4(m->str_flags);
        }
 diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
---- libmagic.orig/ascmagic.c   2016-01-25 11:31:21.495017704 +0800
-+++ libmagic/ascmagic.c        2016-01-25 11:31:32.676017695 +0800
-@@ -139,7 +139,7 @@
+--- libmagic.orig/ascmagic.c   2016-11-23 17:08:23.422184100 +0100
++++ libmagic/ascmagic.c        2016-11-24 13:42:04.130245900 +0100
+@@ -133,7 +133,7 @@
                /* malloc size is a conservative overestimate; could be
                   improved, or at least realloced after conversion. */
                mlen = ulen * 6;
@@ -934,17 +925,8 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
        return rv;
  }
 diff -u libmagic.orig/cdf.c libmagic/cdf.c
---- libmagic.orig/cdf.c        2016-01-25 11:31:21.472017703 +0800
-+++ libmagic/cdf.c     2016-01-25 11:31:32.676017695 +0800
-@@ -35,7 +35,7 @@
- #include "file.h"
- #ifndef lint
--FILE_RCSID("@(#)$File: cdf.c,v 1.75 2015/02/27 21:16:55 christos Exp $")
-+FILE_RCSID("@(#)$File: cdf.c,v 1.73 2015/01/11 16:58:25 christos Exp $")
- #endif
- #include <assert.h>
+--- libmagic.orig/cdf.c        2016-11-23 17:08:24.328677300 +0100
++++ libmagic/cdf.c     2016-11-24 13:42:04.138254700 +0100
 @@ -43,7 +43,17 @@
  #include <err.h>
  #endif
@@ -963,7 +945,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
  #include <string.h>
  #include <time.h>
  #include <ctype.h>
-@@ -286,11 +296,11 @@
+@@ -305,12 +315,13 @@
  }
  
  static ssize_t
@@ -972,14 +954,16 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
  {
        size_t siz = (size_t)off + len;
  
--      if ((off_t)(off + len) != (off_t)siz) {
+-      if ((off_t)(off + len) != (off_t)siz)
 +      if ((zend_off_t)(off + len) != (zend_off_t)siz) {
-               errno = EINVAL;
-               return -1;
-       }
-@@ -303,7 +313,10 @@
+               goto out;
++      }
+       if (info->i_buf != NULL && info->i_len >= siz) {
+               (void)memcpy(buf, &info->i_buf[off], len);
+@@ -320,7 +331,10 @@
        if (info->i_fd == -1)
-               return -1;
+               goto out;
  
 -      if (pread(info->i_fd, buf, len, off) != (ssize_t)len)
 +      if (FINFO_LSEEK_FUNC(info->i_fd, off, SEEK_SET) == (zend_off_t)-1)
@@ -989,7 +973,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
                return -1;
  
        return (ssize_t)len;
-@@ -315,7 +328,7 @@
+@@ -335,7 +349,7 @@
        char buf[512];
  
        (void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
@@ -998,7 +982,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
                return -1;
        cdf_unpack_header(h, buf);
        cdf_swap_header(h);
-@@ -349,7 +362,7 @@
+@@ -369,7 +383,7 @@
        size_t ss = CDF_SEC_SIZE(h);
        size_t pos = CDF_SEC_POS(h, id);
        assert(ss == len);
@@ -1007,59 +991,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
  }
  
  ssize_t
-@@ -1026,33 +1039,31 @@
-           CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h);
-       const char *b = CAST(const char *, sst->sst_tab);
-       const char *eb = b + ss * sst->sst_len;
--      size_t nr, i, j, k;
-+      size_t nr, i, k;
-       cdf_catalog_entry_t *ce;
-       uint16_t reclen;
-       const uint16_t *np;
--      for (nr = 0;; nr++) {
-+      for (nr = 0; b < eb; nr++) {
-               memcpy(&reclen, b, sizeof(reclen));
-               reclen = CDF_TOLE2(reclen);
-               if (reclen == 0)
-                       break;
-               b += reclen;
--              if (b > eb)
--                  break;
-       }
--      nr--;
-       *cat = CAST(cdf_catalog_t *,
-           malloc(sizeof(cdf_catalog_t) + nr * sizeof(*ce)));
-+      (*cat)->cat_num = nr;
-       ce = (*cat)->cat_e;
-       memset(ce, 0, nr * sizeof(*ce));
-       b = CAST(const char *, sst->sst_tab);
--      for (j = i = 0; i < nr; b += reclen) {
--              cdf_catalog_entry_t *cep = &ce[j];
-+      for (i = 0; i < nr; i++, b += reclen) {
-+              cdf_catalog_entry_t *cep = &ce[i];
-               uint16_t rlen;
-               extract_catalog_field(uint16_t, ce_namlen, 0);
--              extract_catalog_field(uint16_t, ce_num, 4);
--              extract_catalog_field(uint64_t, ce_timestamp, 8);
-+              extract_catalog_field(uint16_t, ce_num, 2);
-+              extract_catalog_field(uint64_t, ce_timestamp, 6);
-               reclen = cep->ce_namlen;
-               if (reclen < 14) {
-@@ -1074,10 +1085,7 @@
-               for (k = 0; k < cep->ce_namlen; k++)
-                       cep->ce_name[k] = np[k]; /* XXX: CDF_TOLE2? */
-               cep->ce_name[cep->ce_namlen] = 0;
--              j = i;
--              i++;
-       }
--      (*cat)->cat_num = j;
-       return 0;
- }
-@@ -1259,7 +1267,7 @@
+@@ -1302,7 +1316,7 @@
        cdf_directory_t *d;
        char name[__arraycount(d->d_name)];
        cdf_stream_t scn;
@@ -1068,7 +1000,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
  
        static const char *types[] = { "empty", "user storage",
            "user stream", "lockbytes", "property", "root storage" };
-@@ -1314,7 +1322,7 @@
+@@ -1357,7 +1371,7 @@
  cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
  {
        cdf_timestamp_t tp;
@@ -1077,7 +1009,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
        char buf[64];
        size_t i, j;
  
-@@ -1436,10 +1444,7 @@
+@@ -1479,10 +1493,7 @@
        cdf_dir_t dir;
        cdf_info_t info;
        const cdf_directory_t *root;
@@ -1089,20 +1021,9 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
        if (argc < 2) {
                (void)fprintf(stderr, "Usage: %s <filename>\n", getprogname());
                return -1;
-@@ -1491,8 +1496,8 @@
-               else
-                       cdf_dump_summary_info(&h, &scn);
- #endif
--              if (cdf_read_user_stream(&info, &h, &sat, &ssat, &sst,
--                  &dir, "Catalog", &scn) == -1)
-+              if (cdf_read_catalog(&info, &h, &sat, &ssat, &sst, &dir,
-+                  &scn) == -1)
-                       warn("Cannot read catalog");
- #ifdef CDF_DEBUG
-               else
 diff -u libmagic.orig/cdf.h libmagic/cdf.h
---- libmagic.orig/cdf.h        2016-01-25 11:31:21.493017704 +0800
-+++ libmagic/cdf.h     2016-01-25 11:31:32.676017695 +0800
+--- libmagic.orig/cdf.h        2016-11-23 17:08:24.651177800 +0100
++++ libmagic/cdf.h     2016-11-24 13:41:34.182417000 +0100
 @@ -35,10 +35,12 @@
  #ifndef _H_CDF_
  #define _H_CDF_
@@ -1117,8 +1038,8 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h
  #endif
  #ifdef __DJGPP__
  #define timespec timeval
-@@ -280,9 +282,9 @@
-       cdf_catalog_entry_t cat_e[0];
+@@ -281,9 +283,9 @@
+       cdf_catalog_entry_t cat_e[1];
  } cdf_catalog_t;
  
 -struct timespec;
@@ -1131,8 +1052,8 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h
  void cdf_swap_header(cdf_header_t *);
  void cdf_unpack_header(cdf_header_t *, char *);
 diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
---- libmagic.orig/cdf_time.c   2016-01-25 11:31:21.494017704 +0800
-+++ libmagic/cdf_time.c        2016-01-25 11:31:32.676017695 +0800
+--- libmagic.orig/cdf_time.c   2016-11-23 17:08:25.086670200 +0100
++++ libmagic/cdf_time.c        2016-11-24 13:40:19.272464700 +0100
 @@ -96,7 +96,7 @@
  }
  
@@ -1182,22 +1103,17 @@ diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
        static const cdf_timestamp_t tst = 0x01A5E403C2D59C00ULL;
        static const char *ref = "Sat Apr 23 01:30:00 1977";
 diff -u libmagic.orig/compress.c libmagic/compress.c
---- libmagic.orig/compress.c   2016-01-25 11:31:21.483017704 +0800
-+++ libmagic/compress.c        2016-01-25 11:31:32.676017695 +0800
-@@ -32,10 +32,11 @@
-  *    uncompress(method, old, n, newch) - uncompress old into new, 
-  *                                        using method, return sizeof new
-  */
-+#include "config.h"
- #include "file.h"
- #ifndef lint
--FILE_RCSID("@(#)$File: compress.c,v 1.78 2015/01/02 21:29:39 christos Exp $")
-+FILE_RCSID("@(#)$File: compress.c,v 1.77 2014/12/12 16:33:01 christos Exp $")
+--- libmagic.orig/compress.c   2016-11-23 17:08:25.345167600 +0100
++++ libmagic/compress.c        2016-11-24 13:42:04.146247600 +0100
+@@ -45,15 +45,13 @@
  #endif
- #include "magic.h"
-@@ -51,7 +52,7 @@
+ #include <string.h>
+ #include <errno.h>
+-#include <ctype.h>
+-#include <stdarg.h>
+ #ifdef HAVE_SIGNAL_H
+ #include <signal.h>
+ # ifndef HAVE_SIG_T
  typedef void (*sig_t)(int);
  # endif /* HAVE_SIG_T */
  #endif 
@@ -1206,27 +1122,74 @@ diff -u libmagic.orig/compress.c libmagic/compress.c
  #include <sys/ioctl.h>
  #endif
  #ifdef HAVE_SYS_WAIT_H
-@@ -65,6 +66,9 @@
+@@ -66,46 +64,8 @@
+ #define BUILTIN_DECOMPRESS
  #include <zlib.h>
  #endif
+-#ifdef DEBUG
+-int tty = -1;
+-#define DPRINTF(...)  do { \
+-      if (tty == -1) \
+-              tty = open("/dev/tty", O_RDWR); \
+-      if (tty == -1) \
+-              abort(); \
+-      dprintf(tty, __VA_ARGS__); \
+-} while (/*CONSTCOND*/0)
+-#else
+-#define DPRINTF(...)
+-#endif
  
+-#ifdef ZLIBSUPPORT
+-/*
+- * The following python code is not really used because ZLIBSUPPORT is only
+- * defined if we have a built-in zlib, and the built-in zlib handles that.
+- */
+-static const char zlibcode[] =
+-    "import sys, zlib; sys.stdout.write(zlib.decompress(sys.stdin.read()))";
+-
+-static const char *zlib_args[] = { "python", "-c", zlibcode, NULL };
+-
+-static int
+-zlibcmp(const unsigned char *buf)
+-{
+-      unsigned short x = 1;
+-      unsigned char *s = (unsigned char *)&x;
+-
+-      if ((buf[0] & 0xf) != 8 || (buf[0] & 0x80) != 0)
+-              return 0;
+-      if (s[0] != 1)  /* endianness test */
+-              x = buf[0] | (buf[1] << 8);
+-      else
+-              x = buf[1] | (buf[0] << 8);
+-      if (x % 31)
+-              return 0;
+-      return 1;
+-}
+-#endif
 +#undef FIONREAD
-+
-+
- private const struct {
-       const char magic[8];
-       size_t maglen;
-@@ -92,8 +96,7 @@
- #define NODATA ((size_t)~0)
+ #define gzip_flags "-cd"
+ #define lrzip_flags "-do"
+@@ -168,7 +128,7 @@
+ #define ERRDATA       2
  
  private ssize_t swrite(int, const void *, size_t);
 -#if HAVE_FORK
--private size_t ncompr = sizeof(compr) / sizeof(compr[0]);
 +#ifdef PHP_FILEINFO_UNCOMPRESS
- private size_t uncompressbuf(struct magic_set *, int, size_t,
-     const unsigned char *, unsigned char **, size_t);
- #ifdef BUILTIN_DECOMPRESS
-@@ -148,7 +151,8 @@
+ private size_t ncompr = sizeof(compr) / sizeof(compr[0]);
+ private int uncompressbuf(int, size_t, size_t, const unsigned char *,
+     unsigned char **, size_t *);
+@@ -178,8 +138,7 @@
+ private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
+     size_t *);
+ #endif
+-static int makeerror(unsigned char **, size_t *, const char *, ...)
+-    __attribute__((__format__(__printf__, 3, 4)));
++static int makeerror(unsigned char **, size_t *, const char *, ...);
+ private const char *methodname(size_t);
+ protected int
+@@ -274,7 +233,8 @@
  #ifdef HAVE_SIGNAL_H
        (void)signal(SIGPIPE, osigpipe);
  #endif
@@ -1234,9 +1197,9 @@ diff -u libmagic.orig/compress.c libmagic/compress.c
 +      if (newbuf)
 +              efree(newbuf);
        ms->flags |= MAGIC_COMPRESS;
+       DPRINTF("Zmagic returns %d\n", rv);
        return rv;
- }
-@@ -182,7 +186,7 @@
+@@ -309,7 +269,7 @@
   * `safe' read for sockets and pipes.
   */
  protected ssize_t
@@ -1245,7 +1208,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c
  {
        ssize_t rv;
  #ifdef FIONREAD
-@@ -230,7 +234,7 @@
+@@ -357,7 +317,7 @@
  
  nocheck:
        do
@@ -1254,7 +1217,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c
                case -1:
                        if (errno == EINTR)
                                continue;
-@@ -307,13 +311,14 @@
+@@ -434,13 +394,14 @@
                return -1;
        }
        (void)close(tfd);
@@ -1271,119 +1234,68 @@ diff -u libmagic.orig/compress.c libmagic/compress.c
  #ifdef BUILTIN_DECOMPRESS
  
  #define FHCRC         (1 << 1)
-@@ -350,7 +355,7 @@
-       if (data_start >= n)
-               return 0;
--      if ((*newch = CAST(unsigned char *, malloc(HOWMANY + 1))) == NULL) {
-+      if ((*newch = CAST(unsigned char *, emalloc(HOWMANY + 1))) == NULL) {
-               return 0;
-       }
-       
-@@ -411,19 +416,16 @@
-       case 0: /* child */
-               (void) close(0);
-               if (fd != -1) {
--                  if (dup(fd) == -1)
--                      _exit(1);
--                  (void) lseek(0, (off_t)0, SEEK_SET);
-+                  (void) dup(fd);
-+                  (void) FINFO_LSEEK_FUNC(0, (zend_off_t)0, SEEK_SET);
-               } else {
--                  if (dup(fdin[0]) == -1)
--                      _exit(1);
-+                  (void) dup(fdin[0]);
-                   (void) close(fdin[0]);
-                   (void) close(fdin[1]);
-               }
-               (void) close(1);
--              if (dup(fdout[1]) == -1)
--                      _exit(1);
-+              (void) dup(fdout[1]);
-               (void) close(fdout[0]);
-               (void) close(fdout[1]);
- #ifndef DEBUG
-@@ -474,37 +476,21 @@
-                               /*NOTREACHED*/
-                       default:  /* parent */
--                              if (wait(&status) == -1) {
--#ifdef DEBUG
--                                      (void)fprintf(stderr,
--                                          "Wait failed (%s)\n",
--                                          strerror(errno));
--#endif
--                                      exit(1);
--                              }
--                              exit(WIFEXITED(status) ?
--                                  WEXITSTATUS(status) : 1);
--                              /*NOTREACHED*/
-+                              break;
-                       }
-                       (void) close(fdin[1]);
-                       fdin[1] = -1;
-               }
--              if ((*newch = (unsigned char *) malloc(HOWMANY + 1)) == NULL) {
--#ifdef DEBUG
--                      (void)fprintf(stderr, "Malloc failed (%s)\n",
--                          strerror(errno));
--#endif
--                      n = NODATA;
--                      goto err;
--              }
-+              *newch = (unsigned char *) emalloc(HOWMANY + 1);
-+
-               if ((r = sread(fdout[0], *newch, HOWMANY, 0)) <= 0) {
- #ifdef DEBUG
-                       (void)fprintf(stderr, "Read failed (%s)\n",
-                           strerror(errno));
- #endif
--                      free(*newch);
--                      n = NODATA;
-+                      efree(*newch);
-+                      n = NODATA-;
-                       *newch = NULL;
-                       goto err;
-               } else {
-@@ -516,27 +502,16 @@
-               if (fdin[1] != -1)
-                       (void) close(fdin[1]);
-               (void) close(fdout[0]);
--              if (wait(&status) == -1) {
--#ifdef DEBUG
--                      (void)fprintf(stderr, "Wait failed (%s)\n",
--                          strerror(errno));
--#endif
--                      n = NODATA;
--              } else if (!WIFEXITED(status)) {
--#ifdef DEBUG
--                      (void)fprintf(stderr, "Child not exited (0x%x)\n",
--                          status);
--#endif
--              } else if (WEXITSTATUS(status) != 0) {
--#ifdef DEBUG
--                      (void)fprintf(stderr, "Child exited (0x%d)\n",
--                          WEXITSTATUS(status));
-+#ifdef WNOHANG
-+              while (waitpid(pid, NULL, WNOHANG) != -1)
-+                      continue;
-+#else
-+              (void)wait(NULL);
- #endif
--              }
-               (void) close(fdin[0]);
-           
-               return n;
+@@ -735,27 +696,5 @@
+                       rv = makeerror(newch, n, "No data");
+               goto err;
        }
+-
+-      *n = r;
+-      /* NUL terminate, as every buffer is handled here. */
+-      (*newch)[*n] = '\0';
+-err:
+-      closefd(fdp[STDIN_FILENO], 1);
+-      closefd(fdp[STDOUT_FILENO], 0);
+-      closefd(fdp[STDERR_FILENO], 0);
+-      if (wait(&status) == -1) {
+-              free(*newch);
+-              rv = makeerror(newch, n, "Wait failed, %s", strerror(errno));
+-              DPRINTF("Child wait return %#x\n", status);
+-      } else if (!WIFEXITED(status)) {
+-              DPRINTF("Child not exited (0x%x)\n", status);
+-      } else if (WEXITSTATUS(status) != 0) {
+-              DPRINTF("Child exited (0x%d)\n", WEXITSTATUS(status));
+-      }
+-
+-      closefd(fdp[STDIN_FILENO], 0);
+-      DPRINTF("Returning %p n=%zu rv=%d\n", *newch, *n, rv);
+-    
+-      return rv;
  }
 -#endif
 +#endif /* if PHP_FILEINFO_UNCOMPRESS */
+diff -u libmagic.orig/der.c libmagic/der.c
+--- libmagic.orig/der.c        2016-11-23 17:08:25.601237900 +0100
++++ libmagic/der.c     2016-11-24 13:41:34.200418900 +0100
+@@ -51,7 +51,9 @@
+ #include "magic.h"
+ #include "der.h"
+ #else
++#ifndef PHP_WIN32
+ #include <sys/mman.h>
++#endif
+ #include <sys/stat.h>
+ #include <err.h>
+ #endif
+@@ -201,6 +203,7 @@
+ der_data(char *buf, size_t blen, uint32_t tag, const void *q, uint32_t len)
+ {
+       const uint8_t *d = CAST(const uint8_t *, q);
++      uint32_t i;
+       switch (tag) {
+       case DER_TAG_PRINTABLE_STRING:
+       case DER_TAG_UTF8_STRING:
+@@ -211,7 +214,7 @@
+               break;
+       }
+               
+-      for (uint32_t i = 0; i < len; i++) {
++      for (i = 0; i < len; i++) {
+               uint32_t z = i << 1;
+               if (z < blen - 2)
+                       snprintf(buf + z, blen - z, "%.2x", d[i]);
 diff -u libmagic.orig/elfclass.h libmagic/elfclass.h
---- libmagic.orig/elfclass.h   2016-01-25 11:31:21.471017705 +0800
-+++ libmagic/elfclass.h        2016-01-25 11:31:32.677017695 +0800
+--- libmagic.orig/elfclass.h   2016-11-23 17:08:25.910282200 +0100
++++ libmagic/elfclass.h        2015-07-18 21:35:36.472082600 +0200
 @@ -41,7 +41,7 @@
                        return toomany(ms, "program headers", phnum);
                flags |= FLAGS_IS_CORE;
@@ -1412,8 +1324,8 @@ diff -u libmagic.orig/elfclass.h libmagic/elfclass.h
                    fsize, elf_getu16(swap, elfhdr.e_machine),
                    (int)elf_getu16(swap, elfhdr.e_shstrndx),
 diff -u libmagic.orig/file.h libmagic/file.h
---- libmagic.orig/file.h       2016-01-25 11:31:21.472017703 +0800
-+++ libmagic/file.h    2016-01-25 11:31:32.677017695 +0800
+--- libmagic.orig/file.h       2016-11-23 17:08:26.334387400 +0100
++++ libmagic/file.h    2016-11-24 13:41:34.210416500 +0100
 @@ -33,11 +33,9 @@
  #ifndef __file_h__
  #define __file_h__
@@ -1428,7 +1340,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
    #ifdef _WIN64
      #define SIZE_T_FORMAT "I64"
    #else
-@@ -61,10 +59,18 @@
+@@ -63,10 +61,18 @@
  #ifdef HAVE_INTTYPES_H
  #include <inttypes.h>
  #endif
@@ -1450,7 +1362,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
  #include <sys/param.h>
  #endif
  /* Do this here and now, because struct stat gets re-defined on solaris */
-@@ -77,7 +83,7 @@
+@@ -79,7 +85,7 @@
  #define MAGIC "/etc/magic"
  #endif
  
@@ -1459,7 +1371,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
  #define PATHSEP       ';'
  #else
  #define PATHSEP       ':'
-@@ -111,12 +117,6 @@
+@@ -113,12 +119,6 @@
  #endif
  #endif
  
@@ -1472,16 +1384,16 @@ diff -u libmagic.orig/file.h libmagic/file.h
  #ifndef MIN
  #define       MIN(a,b)        (((a) < (b)) ? (a) : (b))
  #endif
-@@ -227,7 +227,7 @@
- #define                               FILE_CLEAR      47
- #define                               FILE_NAMES_SIZE 48 /* size of array to contain all names */
+@@ -230,7 +230,7 @@
+ #define                               FILE_DER        48
+ #define                               FILE_NAMES_SIZE 49 /* size of array to contain all names */
  
 -#define IS_STRING(t) \
 +#define IS_LIBMAGIC_STRING(t) \
        ((t) == FILE_STRING || \
         (t) == FILE_PSTRING || \
         (t) == FILE_BESTRING16 || \
-@@ -421,28 +421,22 @@
+@@ -431,28 +431,22 @@
  /* Type for Unicode characters */
  typedef unsigned long unichar;
  
@@ -1514,7 +1426,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
  protected int file_zmagic(struct magic_set *, int, const char *,
      const unsigned char *, size_t);
  #endif
-@@ -462,16 +456,13 @@
+@@ -472,16 +466,13 @@
  protected int file_magicfind(struct magic_set *, const char *, struct mlist *);
  protected uint64_t file_signextend(struct magic_set *, struct magic *,
      uint64_t);
@@ -1535,7 +1447,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
  protected void file_showstr(FILE *, const char *, size_t);
  protected size_t file_mbswidth(const char *);
  protected const char *file_getbuffer(struct magic_set *);
-@@ -487,30 +478,6 @@
+@@ -497,32 +488,6 @@
      size_t);
  #endif /* __EMX__ */
  
@@ -1552,6 +1464,8 @@ diff -u libmagic.orig/file.h libmagic/file.h
 -#define USE_C_LOCALE
 -      locale_t old_lc_ctype;
 -      locale_t c_lc_ctype;
+-#else
+-      char *old_lc_ctype;
 -#endif
 -      int rc;
 -      regex_t rx;
@@ -1566,7 +1480,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
  typedef struct {
        char *buf;
        uint32_t offset;
-@@ -519,10 +486,8 @@
+@@ -531,10 +496,8 @@
  protected file_pushbuf_t *file_push_buffer(struct magic_set *);
  protected char  *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
  
@@ -1577,7 +1491,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
  
  #ifndef HAVE_STRERROR
  extern int sys_nerr;
-@@ -535,20 +500,10 @@
+@@ -547,23 +510,10 @@
  #define strtoul(a, b, c)      strtol(a, b, c)
  #endif
  
@@ -1590,6 +1504,9 @@ diff -u libmagic.orig/file.h libmagic/file.h
 -#ifndef HAVE_ASPRINTF
 -int asprintf(char **, const char *, ...);
 -#endif
+-#ifndef HAVE_DPRINTF
+-int dprintf(int, const char *, ...);
+-#endif
 -
 -#ifndef HAVE_STRLCPY
 +#ifndef strlcpy
@@ -1600,7 +1517,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
  size_t strlcat(char *, const char *, size_t);
  #endif
  #ifndef HAVE_STRCASESTR
-@@ -564,16 +519,6 @@
+@@ -579,16 +529,6 @@
  #ifndef HAVE_ASCTIME_R
  char   *asctime_r(const struct tm *, char *);
  #endif
@@ -1617,7 +1534,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
  
  #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
  #define QUICK
-@@ -596,6 +541,14 @@
+@@ -611,6 +551,14 @@
  #else
  #define FILE_RCSID(id)
  #endif
@@ -1633,8 +1550,8 @@ diff -u libmagic.orig/file.h libmagic/file.h
  #define __RCSID(a)
  #endif
 diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
---- libmagic.orig/fsmagic.c    2016-01-25 11:31:21.471017705 +0800
-+++ libmagic/fsmagic.c 2016-01-25 11:31:32.677017695 +0800
+--- libmagic.orig/fsmagic.c    2016-11-23 17:08:26.758003500 +0100
++++ libmagic/fsmagic.c 2016-11-24 13:41:34.212917300 +0100
 @@ -63,27 +63,21 @@
  # define minor(dev)  ((dev) & 0xff)
  #endif
@@ -1677,7 +1594,7 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
  private int
  handle_mime(struct magic_set *ms, int mime, const char *str)
  {
-@@ -100,72 +94,39 @@
+@@ -100,71 +94,38 @@
  }
  
  protected int
@@ -1692,7 +1609,7 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
 -      struct stat tstatbuf;
 -#endif
  
-       if (ms->flags & MAGIC_APPLE)
+       if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))
                return 0;
 -      if (fn == NULL)
 +
@@ -1725,14 +1642,7 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
 -                      if (ret) {
 -                              sb->st_mode = S_IFBLK;
 -                              ret = 0;
-+
-+      if (stream) {
-+              php_stream_statbuf ssb;
-+              if (php_stream_stat(stream, &ssb) < 0) {
-+                      if (ms->flags & MAGIC_ERROR) {
-+                              file_error(ms, errno, "cannot stat `%s'", fn);
-+                              return -1;
-                       }
+-                      }
 -                      switch (GetFileType(hFile)) {
 -                      case FILE_TYPE_CHAR:
 -                              sb->st_mode |= S_IFCHR;
@@ -1742,11 +1652,10 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
 -                              sb->st_mode |= S_IFIFO;
 -                              sb->st_mode &= ~S_IFREG;
 -                              break;
-+                      return 0;
-+              }
-+              memcpy(sb, &ssb.sb, sizeof(struct stat));
-+      } else {
-+              if (php_sys_stat(fn, sb) != 0) {
++
++      if (stream) {
++              php_stream_statbuf ssb;
++              if (php_stream_stat(stream, &ssb) < 0) {
 +                      if (ms->flags & MAGIC_ERROR) {
 +                              file_error(ms, errno, "cannot stat `%s'", fn);
 +                              return -1;
@@ -1754,22 +1663,29 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
 -                      CloseHandle(hFile);
 +                      return 0;
                }
-       }
+-      }
 -#endif
 -
 -      if (ret) {
 -              if (ms->flags & MAGIC_ERROR) {
 -                      file_error(ms, errno, "cannot stat `%s'", fn);
 -                      return -1;
--              }
++              memcpy(sb, &ssb.sb, sizeof(struct stat));
++      } else {
++              if (php_sys_stat(fn, sb) != 0) {
++                      if (ms->flags & MAGIC_ERROR) {
++                              file_error(ms, errno, "cannot stat `%s'", fn);
++                              return -1;
++                      }
++                      return 0;
+               }
 -              if (file_printf(ms, "cannot open `%s' (%s)",
 -                  fn, strerror(errno)) == -1)
 -                      return -1;
 -              return 0;
--      }
+       }
  
        ret = 1;
-       if (!mime) {
 @@ -187,30 +148,24 @@
        }
        
@@ -1858,10 +1774,10 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
 -#else
 -                      if (file_printf(ms, "%sblock special", COMMA) == -1)
 -                              return -1;
- #endif
+-#endif
 -              }
 -              break;
--#endif
+ #endif
 -      /* TODO add code to handle V7 MUX and Blit MUX files */
 +
  #ifdef        S_IFIFO
@@ -1951,42 +1867,9 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
  #ifdef        S_IFSOCK
  #ifndef __COHERENT__
        case S_IFSOCK:
-@@ -381,15 +238,15 @@
-                * size for raw disk partitions. (If the block special device
-                * really has zero length, the fact that it is empty will be
-                * detected and reported correctly when we read the file.)
--               */
--              if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) {
--                      if (mime) {
--                              if (handle_mime(ms, mime, "x-empty") == -1)
--                                      return -1;
--                      } else if (file_printf(ms, "%sempty", COMMA) == -1)
-+       */
-+      if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) {
-+              if (mime) {
-+                      if (handle_mime(ms, mime, "x-empty") == -1)
-                               return -1;
-+                      } else if (file_printf(ms, "%sempty", COMMA) == -1)
-+                      return -1;
-                       break;
--              }
-+      }
-               ret = 0;
-               break;
-@@ -399,9 +256,5 @@
-               /*NOTREACHED*/
-       }
--      if (!mime && did && ret == 0) {
--          if (file_printf(ms, " ") == -1)
--                  return -1;
--      }
-       return ret;
- }
 diff -u libmagic.orig/funcs.c libmagic/funcs.c
---- libmagic.orig/funcs.c      2016-01-25 11:31:21.483017704 +0800
-+++ libmagic/funcs.c   2016-01-25 11:41:34.164723619 +0800
+--- libmagic.orig/funcs.c      2016-11-23 17:08:26.917536700 +0100
++++ libmagic/funcs.c   2016-11-24 13:42:04.163244800 +0100
 @@ -31,7 +31,6 @@
  #endif        /* lint */
  
@@ -1995,7 +1878,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
  #include <stdarg.h>
  #include <stdlib.h>
  #include <string.h>
-@@ -42,76 +41,79 @@
+@@ -42,78 +41,80 @@
  #if defined(HAVE_WCTYPE_H)
  #include <wctype.h>
  #endif
@@ -2048,7 +1931,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
  protected int
  file_printf(struct magic_set *ms, const char *fmt, ...)
  {
--      int rv;
+       int rv;
        va_list ap;
 +      int len;
 +      char *buf = NULL, *newstr;
@@ -2090,8 +1973,10 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
 -              free(ms->o.buf);
 +              efree(ms->o.buf);
                ms->o.buf = NULL;
-               file_printf(ms, "line %" SIZE_T_FORMAT "u: ", lineno);
+               file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno);
        }
+-      if (ms->o.buf && *ms->o.buf)
+-              file_printf(ms, " ");
 -      file_vprintf(ms, f, va);
 -      if (error > 0)
 -              file_printf(ms, " (%s)", strerror(error));
@@ -2112,12 +1997,17 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
        ms->event_flags |= EVENT_HAD_ERR;
        ms->error = error;
  }
-@@ -158,11 +160,9 @@
+@@ -160,7 +161,6 @@
        file_error(ms, errno, "error reading");
  }
  
 -#ifndef COMPILE_ONLY
--/*ARGSUSED*/
+ static int
+ checkdone(struct magic_set *ms, int *rv)
+@@ -174,8 +174,8 @@
+ /*ARGSUSED*/
  protected int
 -file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__unused__)),
 -    const void *buf, size_t nb)
@@ -2125,8 +2015,8 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
 +    size_t nb)
  {
        int m = 0, rv = 0, looks_text = 0;
-       int mime = ms->flags & MAGIC_MIME;
-@@ -201,10 +201,10 @@
+       const unsigned char *ubuf = CAST(const unsigned char *, buf);
+@@ -216,10 +216,10 @@
                }
        }
  #endif
@@ -2134,35 +2024,29 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
 -      /* try compression stuff */
 +
 +#if PHP_FILEINFO_UNCOMPRESS
-       if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0)
--              if ((m = file_zmagic(ms, fd, inname, ubuf, nb)) != 0) {
-+              if ((m = file_zmagic(ms, stream, inname, ubuf, nb)) != 0) {
-                       if ((ms->flags & MAGIC_DEBUG) != 0)
-                               (void)fprintf(stderr, "zmagic %d\n", m);
-                       goto done_encoding;
-@@ -219,12 +219,16 @@
-               }
+       if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0) {
+-              m = file_zmagic(ms, fd, inname, ubuf, nb);
++              m = file_zmagic(ms, stream, inname, ubuf, nb);
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void)fprintf(stderr, "[try zmagic %d]\n", m);
+               if (m) {
+@@ -240,12 +240,15 @@
  
        /* Check if we have a CDF file */
--      if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0)
--              if ((m = file_trycdf(ms, fd, ubuf, nb)) != 0) {
--                      if ((ms->flags & MAGIC_DEBUG) != 0)
--                              (void)fprintf(stderr, "cdf %d\n", m);
--                      goto done;
-+      if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) {
+       if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) {
 +              php_socket_t fd;
-+                      if (stream && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&fd, 0)) {
-+                      if ((m = file_trycdf(ms, fd, ubuf, nb)) != 0) {
-+                              if ((ms->flags & MAGIC_DEBUG) != 0)
-+                                      (void)fprintf(stderr, "cdf %d\n", m);
-+                              goto done;
++              if (stream && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&fd, 0)) {
+               m = file_trycdf(ms, fd, ubuf, nb);
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void)fprintf(stderr, "[try cdf %d]\n", m);
+               if (m) {
+                       if (checkdone(ms, &rv))
+                               goto done;
 +                      }
                }
-+      }
+       }
  
-       /* try soft magic tests */
-       if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0)
-@@ -278,7 +282,7 @@
+@@ -316,7 +319,7 @@
                if (file_printf(ms, "%s", code_mime) == -1)
                        rv = -1;
        }
@@ -2171,7 +2055,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
   done_encoding:
  #endif
        free(u8buf);
-@@ -287,7 +291,6 @@
+@@ -325,7 +328,6 @@
  
        return m;
  }
@@ -2179,7 +2063,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
  
  protected int
  file_reset(struct magic_set *ms)
-@@ -297,11 +300,11 @@
+@@ -335,11 +337,11 @@
                return -1;
        }
        if (ms->o.buf) {
@@ -2193,31 +2077,18 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
                ms->o.pbuf = NULL;
        }
        ms->event_flags &= ~EVENT_HAD_ERR;
-@@ -320,7 +323,7 @@
- protected const char *
- file_getbuffer(struct magic_set *ms)
- {
--      char *pbuf, *op, *np;
-+      char *op, *np;
-       size_t psize, len;
-       if (ms->event_flags & EVENT_HAD_ERR)
-@@ -339,11 +342,10 @@
+@@ -377,7 +379,7 @@
                return NULL;
        }
        psize = len * 4 + 1;
 -      if ((pbuf = CAST(char *, realloc(ms->o.pbuf, psize))) == NULL) {
-+      if ((ms->o.pbuf = CAST(char *, erealloc(ms->o.pbuf, psize))) == NULL) {
++      if ((pbuf = CAST(char *, erealloc(ms->o.pbuf, psize))) == NULL) {
                file_oomem(ms, psize);
                return NULL;
        }
--      ms->o.pbuf = pbuf;
- #if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
-       {
-@@ -403,8 +405,8 @@
+@@ -441,8 +443,8 @@
        if (level >= ms->c.len) {
-               len = (ms->c.len += 20) * sizeof(*ms->c.li);
+               len = (ms->c.len = 20 + level) * sizeof(*ms->c.li);
                ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ?
 -                  malloc(len) :
 -                  realloc(ms->c.li, len));
@@ -2226,7 +2097,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
                if (ms->c.li == NULL) {
                        file_oomem(ms, len);
                        return -1;
-@@ -427,70 +429,41 @@
+@@ -465,74 +467,41 @@
  protected int
  file_replace(struct magic_set *ms, const char *pat, const char *rep)
  {
@@ -2277,6 +2148,8 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
 -      assert(rx->c_lc_ctype != NULL);
 -      rx->old_lc_ctype = uselocale(rx->c_lc_ctype);
 -      assert(rx->old_lc_ctype != NULL);
+-#else
+-      rx->old_lc_ctype = setlocale(LC_CTYPE, "C");
 -#endif
 -      rx->pat = pat;
 +      ZVAL_STRING(&repl, rep);
@@ -2284,7 +2157,12 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
  
 -      return rx->rc = regcomp(&rx->rx, pat, flags);
 -}
--
++      zval_ptr_dtor(&repl);
++      if (NULL == res) {
++              rep_cnt = -1;
++              goto out;
++      }
 -protected int
 -file_regexec(file_regex_t *rx, const char *str, size_t nmatch,
 -    regmatch_t* pmatch, int eflags)
@@ -2292,11 +2170,8 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
 -      assert(rx->rc == 0);
 -      return regexec(&rx->rx, str, nmatch, pmatch, eflags);
 -}
-+      zval_ptr_dtor(&repl);
-+      if (NULL == res) {
-+              rep_cnt = -1;
-+              goto out;
-+      }
++      strncpy(ms->o.buf, ZSTR_VAL(res), ZSTR_LEN(res));
++      ms->o.buf[ZSTR_LEN(res)] = '\0';
  
 -protected void
 -file_regfree(file_regex_t *rx)
@@ -2306,11 +2181,11 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
 -#ifdef USE_C_LOCALE
 -      (void)uselocale(rx->old_lc_ctype);
 -      freelocale(rx->c_lc_ctype);
+-#else
+-      (void)setlocale(LC_CTYPE, rx->old_lc_ctype);
 -#endif
 -}
-+      strncpy(ms->o.buf, ZSTR_VAL(res), ZSTR_LEN(res));
-+      ms->o.buf[ZSTR_LEN(res)] = '\0';
+-
 -protected void
 -file_regerror(file_regex_t *rx, int rc, struct magic_set *ms)
 -{
@@ -2326,7 +2201,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
  }
  
  protected file_pushbuf_t *
-@@ -501,7 +474,7 @@
+@@ -543,7 +512,7 @@
        if (ms->event_flags & EVENT_HAD_ERR)
                return NULL;
  
@@ -2335,7 +2210,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
                return NULL;
  
        pb->buf = ms->o.buf;
-@@ -519,8 +492,8 @@
+@@ -561,8 +530,8 @@
        char *rbuf;
  
        if (ms->event_flags & EVENT_HAD_ERR) {
@@ -2346,7 +2221,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
                return NULL;
        }
  
-@@ -529,7 +502,7 @@
+@@ -571,7 +540,7 @@
        ms->o.buf = pb->buf;
        ms->offset = pb->offset;
  
@@ -2355,24 +2230,9 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
        return rbuf;
  }
  
-@@ -550,10 +523,11 @@
-               if (ptr >= eptr - 3)
-                       break;
-               *ptr++ = '\\';
--              *ptr++ = ((CAST(unsigned int, *s) >> 6) & 7) + '0';
--              *ptr++ = ((CAST(unsigned int, *s) >> 3) & 7) + '0';
--              *ptr++ = ((CAST(unsigned int, *s) >> 0) & 7) + '0';
-+              *ptr++ = ((*s >> 6) & 7) + '0';
-+              *ptr++ = ((*s >> 3) & 7) + '0';
-+              *ptr++ = ((*s >> 0) & 7) + '0';
-       }
-       *ptr = '\0';
-       return buf;
- }
-+
 diff -u libmagic.orig/magic.c libmagic/magic.c
---- libmagic.orig/magic.c      2016-01-25 11:31:21.495017704 +0800
-+++ libmagic/magic.c   2016-01-25 11:31:32.677017695 +0800
+--- libmagic.orig/magic.c      2016-11-23 17:08:27.605158000 +0100
++++ libmagic/magic.c   2016-11-24 13:42:10.074024300 +0100
 @@ -25,11 +25,6 @@
   * SUCH DAMAGE.
   */
@@ -2414,7 +2274,7 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
  #if defined(HAVE_UTIMES)
  # include <sys/time.h>
  #elif defined(HAVE_UTIME)
-@@ -71,18 +75,25 @@
+@@ -71,194 +75,23 @@
  #endif
  #endif
  
@@ -2438,36 +2298,119 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
  #define       STDIN_FILENO    0
  #endif
  
-+/* XXX this functionality is excluded in php, enable it in apprentice.c:340 */
-+#if 0
- private const char *
- get_default_magic(void)
- {
-@@ -90,7 +101,7 @@
-       static char *default_magic;
-       char *home, *hmagicpath;
+-#ifdef WIN32
+-/* HINSTANCE of this shared library. Needed for get_default_magic() */
+-static HINSTANCE _w32_dll_instance = NULL;
+-
+-static void
+-_w32_append_path(char **hmagicpath, const char *fmt, ...)
+-{
+-      char *tmppath;
+-        char *newpath;
+-      va_list ap;
+-
+-      va_start(ap, fmt);
+-      if (vasprintf(&tmppath, fmt, ap) < 0) {
+-              va_end(ap);
+-              return;
+-      }
+-      va_end(ap);
+-
+-      if (access(tmppath, R_OK) == -1)
+-              goto out;
+-
+-      if (*hmagicpath == NULL) {
+-              *hmagicpath = tmppath;
+-              return;
+-      }
+-
+-      if (asprintf(&newpath, "%s%c%s", *hmagicpath, PATHSEP, tmppath) < 0)
+-              goto out;
+-
+-      free(*hmagicpath);
+-      free(tmppath);
+-      *hmagicpath = newpath;
+-      return;
+-out:
+-      free(tmppath);
+-}
+-
+-static void
+-_w32_get_magic_relative_to(char **hmagicpath, HINSTANCE module)
+-{
+-      static const char *trypaths[] = {
+-              "%s/share/misc/magic.mgc",
+-              "%s/magic.mgc",
+-      };
+-      LPSTR dllpath;
+-      size_t sp;
+-
+-      dllpath = calloc(MAX_PATH + 1, sizeof(*dllpath));
+-
+-      if (!GetModuleFileNameA(module, dllpath, MAX_PATH))
+-              goto out;
+-
+-      PathRemoveFileSpecA(dllpath);
+-
+-      if (module) {
+-              char exepath[MAX_PATH];
+-              GetModuleFileNameA(NULL, exepath, MAX_PATH);
+-              PathRemoveFileSpecA(exepath);
+-              if (stricmp(exepath, dllpath) == 0)
+-                      goto out;
+-      }
+-
+-      sp = strlen(dllpath);
+-      if (sp > 3 && stricmp(&dllpath[sp - 3], "bin") == 0) {
+-              _w32_append_path(hmagicpath,
+-                  "%s/../share/misc/magic.mgc", dllpath);
+-              goto out;
+-      }
+-
+-      for (sp = 0; sp < __arraycount(trypaths); sp++)
+-              _w32_append_path(hmagicpath, trypaths[sp], dllpath);
+-out:
+-      free(dllpath);
+-}
+-
+-/* Placate GCC by offering a sacrificial previous prototype */
+-BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID);
+-
+-BOOL WINAPI
+-DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
+-    LPVOID lpvReserved __attribute__((__unused__)))
+-{
+-      if (fdwReason == DLL_PROCESS_ATTACH)
+-              _w32_dll_instance = hinstDLL;
+-      return TRUE;
+-}
+-#endif
+-
+-private const char *
+-get_default_magic(void)
+-{
+-      static const char hmagic[] = "/.magic/magic.mgc";
+-      static char *default_magic;
+-      char *home, *hmagicpath;
+-
 -#ifndef WIN32
-+#ifndef PHP_WIN32
-       struct stat st;
-       if (default_magic) {
-@@ -104,17 +115,17 @@
-               return MAGIC;
-       if (stat(hmagicpath, &st) == -1) {
-               free(hmagicpath);
+-      struct stat st;
+-
+-      if (default_magic) {
+-              free(default_magic);
+-              default_magic = NULL;
+-      }
+-      if ((home = getenv("HOME")) == NULL)
+-              return MAGIC;
+-
+-      if (asprintf(&hmagicpath, "%s/.magic.mgc", home) < 0)
+-              return MAGIC;
+-      if (stat(hmagicpath, &st) == -1) {
+-              free(hmagicpath);
 -              if (asprintf(&hmagicpath, "%s/.magic", home) < 0)
-+      if (asprintf(&hmagicpath, "%s/.magic", home) < 0)
-+              return MAGIC;
-+      if (stat(hmagicpath, &st) == -1)
-+              goto out;
-+      if (S_ISDIR(st.st_mode)) {
-+              free(hmagicpath);
-+              if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0)
-                       return MAGIC;
+-                      return MAGIC;
 -              if (stat(hmagicpath, &st) == -1)
-+              if (access(hmagicpath, R_OK) == -1)
-                       goto out;
+-                      goto out;
 -              if (S_ISDIR(st.st_mode)) {
 -                      free(hmagicpath);
 -                      if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0)
@@ -2475,31 +2418,66 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
 -                      if (access(hmagicpath, R_OK) == -1)
 -                              goto out;
 -              }
-+      }
-       }
-       if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0)
-@@ -126,10 +137,9 @@
-       free(hmagicpath);
-       return MAGIC;
- #else
--      char *hmagicp;
-+      char *hmagicp = hmagicpath;
-       char *tmppath = NULL;
-       LPTSTR dllpath;
+-      }
+-
+-      if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0)
+-              goto out;
+-      free(hmagicpath);
+-      return default_magic;
+-out:
+-      default_magic = NULL;
+-      free(hmagicpath);
+-      return MAGIC;
+-#else
 -      hmagicpath = NULL;
- #define APPENDPATH() \
-       do { \
-@@ -212,6 +222,7 @@
-       return action == FILE_LOAD ? get_default_magic() : MAGIC;
- }
-+#endif
+-
+-      if (default_magic) {
+-              free(default_magic);
+-              default_magic = NULL;
+-      }
+-
+-      /* First, try to get a magic file from user-application data */
+-      if ((home = getenv("LOCALAPPDATA")) != NULL)
+-              _w32_append_path(&hmagicpath, "%s%s", home, hmagic);
+-
+-      /* Second, try to get a magic file from the user profile data */
+-      if ((home = getenv("USERPROFILE")) != NULL)
+-              _w32_append_path(&hmagicpath,
+-                  "%s/Local Settings/Application Data%s", home, hmagic);
+-
+-      /* Third, try to get a magic file from Common Files */
+-      if ((home = getenv("COMMONPROGRAMFILES")) != NULL)
+-              _w32_append_path(&hmagicpath, "%s%s", home, hmagic);
+-
+-      /* Fourth, try to get magic file relative to exe location */
+-        _w32_get_magic_relative_to(&hmagicpath, NULL);
+-
+-      /* Fifth, try to get magic file relative to dll location */
+-        _w32_get_magic_relative_to(&hmagicpath, _w32_dll_instance);
+-
+-      /* Avoid MAGIC constant - it likely points to a file within MSys tree */
+-      default_magic = hmagicpath;
+-      return default_magic;
+-#endif
+-}
+-
+-public const char *
+-magic_getpath(const char *magicfile, int action)
+-{
+-      if (magicfile != NULL)
+-              return magicfile;
+-
+-      magicfile = getenv("MAGIC");
+-      if (magicfile != NULL)
+-              return magicfile;
+-
+-      return action == FILE_LOAD ? get_default_magic() : MAGIC;
+-}
+-
  public struct magic_set *
  magic_open(int flags)
-@@ -258,20 +269,6 @@
+ {
+@@ -304,20 +137,6 @@
        return file_apprentice(ms, magicfile, FILE_LOAD);
  }
  
@@ -2520,7 +2498,7 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
  public int
  magic_compile(struct magic_set *ms, const char *magicfile)
  {
-@@ -280,13 +277,6 @@
+@@ -326,13 +145,6 @@
        return file_apprentice(ms, magicfile, FILE_COMPILE);
  }
  
@@ -2534,7 +2512,7 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
  
  public int
  magic_list(struct magic_set *ms, const char *magicfile)
-@@ -298,11 +288,8 @@
+@@ -344,11 +156,8 @@
  
  private void
  close_and_restore(const struct magic_set *ms, const char *name, int fd,
@@ -2547,7 +2525,7 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
  
        if ((ms->flags & MAGIC_PRESERVE_ATIME) != 0) {
                /*
-@@ -329,7 +316,6 @@
+@@ -375,7 +184,6 @@
        }
  }
  
@@ -2555,7 +2533,7 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
  
  /*
   * find type of descriptor
-@@ -339,7 +325,7 @@
+@@ -385,7 +193,7 @@
  {
        if (ms == NULL)
                return NULL;
@@ -2564,7 +2542,7 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
  }
  
  /*
-@@ -350,31 +336,41 @@
+@@ -396,31 +204,42 @@
  {
        if (ms == NULL)
                return NULL;
@@ -2593,30 +2571,28 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
 -      off_t   pos = (off_t)-1;
 +      int no_in_stream = 0;
  
--      if (file_reset(ms) == -1)
--              goto out;
+       if (file_reset(ms) == -1)
+               goto out;
 +      if (!inname && !stream) {
 +              return NULL;
 +      }
++
        /*
         * one extra for terminating '\0', and
         * some overlapping space for matches near EOF
         */
  #define SLOP (1 + sizeof(union VALUETYPE))
--      if ((buf = CAST(unsigned char *, malloc(HOWMANY + SLOP))) == NULL)
--              return NULL;
-+      buf = emalloc(HOWMANY + SLOP);
+-      if ((buf = CAST(unsigned char *, malloc(ms->bytes_max + SLOP))) == NULL)
++      if ((buf = CAST(unsigned char *, emalloc(ms->bytes_max + SLOP))) == NULL)
+               return NULL;
  
 -      switch (file_fsmagic(ms, inname, &sb)) {
-+      if (file_reset(ms) == -1)
-+              goto done;
-+
 +      switch (file_fsmagic(ms, inname, &sb, stream)) {
        case -1:                /* error */
                goto done;
        case 0:                 /* nothing found */
-@@ -384,103 +380,44 @@
+@@ -430,103 +249,41 @@
                goto done;
        }
  
@@ -2625,8 +2601,7 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
 -      if (fd == STDIN_FILENO)
 -              _setmode(STDIN_FILENO, O_BINARY);
 -#endif
-+      errno = 0;
+-
 -      if (inname == NULL) {
 -              if (fstat(fd, &sb) == 0 && S_ISFIFO(sb.st_mode))
 -                      ispipe = 1;
@@ -2635,7 +2610,8 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
 -      } else {
 -              int flags = O_RDONLY|O_BINARY;
 -              int okstat = stat(inname, &sb) == 0;
--
++      errno = 0;
 -              if (okstat && S_ISFIFO(sb.st_mode)) {
 -#ifdef O_NONBLOCK
 -                      flags |= O_NONBLOCK;
@@ -2683,18 +2659,18 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
 -      }
  
        /*
-        * try looking at the first HOWMANY bytes
+        * try looking at the first ms->bytes_max bytes
         */
 -      if (ispipe) {
 -              ssize_t r = 0;
 -
 -              while ((r = sread(fd, (void *)&buf[nbytes],
--                  (size_t)(HOWMANY - nbytes), 1)) > 0) {
+-                  (size_t)(ms->bytes_max - nbytes), 1)) > 0) {
 -                      nbytes += r;
 -                      if (r < PIPE_BUF) break;
 -              }
 -
--              if (nbytes == 0) {
+-              if (nbytes == 0 && inname) {
 -                      /* We can not read it, but we were able to stat it. */
 -                      if (unreadable_info(ms, sb.st_mode, inname) == -1)
 -                              goto done;
@@ -2705,10 +2681,10 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
 -      } else {
 -              /* Windows refuses to read from a big console buffer. */
 -              size_t howmany =
--#if defined(WIN32) && HOWMANY > 8 * 1024
+-#if defined(WIN32)
 -                              _isatty(fd) ? 8 * 1024 :
 -#endif
--                              HOWMANY;
+-                              ms->bytes_max;
 -              if ((nbytes = read(fd, (char *)buf, howmany)) == -1) {
 -                      if (inname == NULL && fd != STDIN_FILENO)
 -                              file_error(ms, errno, "cannot read fd %d", fd);
@@ -2717,7 +2693,7 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
 -                                  inname == NULL ? "/dev/stdin" : inname);
 -                      goto done;
 -              }
-+      if ((nbytes = php_stream_read(stream, (char *)buf, HOWMANY)) < 0) {
++      if ((nbytes = php_stream_read(stream, (char *)buf, ms->bytes_max - nbytes)) < 0) {
 +              file_error(ms, errno, "cannot read `%s'", inname);
 +              goto done;
        }
@@ -2729,21 +2705,18 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
        rv = 0;
  done:
 -      free(buf);
--      if (pos != (off_t)-1)
--              (void)lseek(fd, pos, SEEK_SET);
--      close_and_restore(ms, inname, fd, &sb);
--out:
+-      if (fd != -1) {
+-              if (pos != (off_t)-1)
+-                      (void)lseek(fd, pos, SEEK_SET);
+-              close_and_restore(ms, inname, fd, &sb);
 +      efree(buf);
 +
 +      if (no_in_stream && stream) {
 +              php_stream_close(stream);
-+      }
-+
-+      close_and_restore(ms, inname, 0, &sb);
+       }
+ out:
        return rv == 0 ? file_getbuffer(ms) : NULL;
- }
-@@ -494,14 +431,13 @@
+@@ -542,14 +299,13 @@
                return NULL;
        /*
         * The main work is done here!
@@ -2761,9 +2734,9 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
  public const char *
  magic_error(struct magic_set *ms)
 diff -u libmagic.orig/magic.h libmagic/magic.h
---- libmagic.orig/magic.h      2016-01-25 11:31:21.471017705 +0800
-+++ libmagic/magic.h   2016-01-25 11:31:32.677017695 +0800
-@@ -88,6 +88,7 @@
+--- libmagic.orig/magic.h      2016-11-23 17:08:27.691621600 +0100
++++ libmagic/magic.h   2016-11-24 13:41:34.229416200 +0100
+@@ -93,6 +93,7 @@
  
  const char *magic_getpath(const char *, int);
  const char *magic_file(magic_t, const char *);
@@ -2771,7 +2744,7 @@ diff -u libmagic.orig/magic.h libmagic/magic.h
  const char *magic_descriptor(magic_t, int);
  const char *magic_buffer(magic_t, const void *, size_t);
  
-@@ -99,7 +100,6 @@
+@@ -104,7 +105,6 @@
  int magic_load_buffers(magic_t, void **, size_t *, size_t);
  
  int magic_compile(magic_t, const char *);
@@ -2780,75 +2753,29 @@ diff -u libmagic.orig/magic.h libmagic/magic.h
  int magic_errno(magic_t);
  
 diff -u libmagic.orig/patchlevel.h libmagic/patchlevel.h
---- libmagic.orig/patchlevel.h 2016-01-25 11:31:21.473017702 +0800
-+++ libmagic/patchlevel.h      2016-01-25 11:31:32.678017695 +0800
-@@ -1,34 +1,43 @@
+--- libmagic.orig/patchlevel.h 2016-11-24 14:55:09.402121100 +0100
++++ libmagic/patchlevel.h      2016-11-24 14:56:16.720869700 +0100
+@@ -1,11 +1,15 @@
  #define       FILE_VERSION_MAJOR      5
--#define       patchlevel              6
-+#define       patchlevel              22
+-#define       patchlevel              28
++#define       patchlevel              29
  
  /*
   * Patchlevel file for Ian Darwin's MAGIC command.
-- * $File: patchlevel.h,v 1.76 2011/01/17 16:40:41 christos Exp $
-+ * $File: patchlevel.h,v 1.68 2008/03/22 21:39:43 christos Exp $
+  * $File: patchlevel.h,v 1.68 2008/03/22 21:39:43 christos Exp $
   *
-- * $Log: patchlevel.h,v $
-- * Revision 1.77  2011/04/15 22:07:27  christos
-- * fix the patchlevel.
-+ * $Log$
-+ * Revision 1.9  2015/03/06 22:27:12 ab
-+ * Update libmagic to 5.2X
-  *
-- * Revision 1.76  2011/01/17 16:40:41  christos
-- * welcome to 5_05
-+ * $Log$
-+ * Revision 1.8  2014/02/18 22:27:12 ab
-+ * Update libmagic to 5.17
-  *
-- * Revision 1.75  2010/01/22 21:08:13  christos
-- * welcome to 5.04
-+ * $Log$
-+ * Revision 1.7  2013/03/26 22:27:12 ab
-+ * Update libmagic to 5.14
-  *
-- * Revision 1.74  2009/05/06 20:32:48  christos
-- * welcome to 5.03
-+ * $Log$
-+ * Revision 1.6  2012/03/26 21:01:37 ab
-+ * Update libmagic to 5.11
-  *
-- * Revision 1.73  2009/05/04 15:15:13  christos
-- * 5.02...
-+ * Revision 1.5  2012/03/25 13:54:37  ab
-+ * Update libmagic to 5.04
-  *
-- * Revision 1.72  2009/04/30 21:20:15  christos
-- * 5.01 we are almost here.
-+ * Revision 1.4  2009/05/04 20:52:43  scottmac
-+ * Update libmagic to 5.02
-  *
-- * Revision 1.71  2009/01/21 19:09:42  christos
-- * file 5.0
-+ * Revision 1.3  2009/03/15 23:02:35  scottmac
-+ * Update fileinfo to libmagic 5.00 and remove dependency on dirent.h on Windows
-  *
-- * Revision 1.70  2008/08/30 10:01:01  christos
-- * file 4.26
-+ * Revision 1.2  2008/11/02 16:09:27  scottmac
-+ * Update libmagic to 4.26 and add support for v6 of the magic file format.
+  * $Log$
++ * Revision 1.9  2016/11/24 22:27:12 ab
++ * Update libmagic to 5.28
 + *
-+ * Revision 1.1  2008/07/11 14:13:50  derick
-+ * - Move lib to libmagic
-+ *
-+ * Revision 1.1  2008/07/11 14:10:50  derick
-+ * - Step one for bundling the libmagic library. Some config.m4 issues left.
-  *
-  * Revision 1.69  2008/07/02 15:27:05  christos
-  * welcome to 4.25
++ * $Log$
+  * Revision 1.9  2016/10/11 22:27:12 ab
+  * Update libmagic to 5.28
+  * 
 diff -u libmagic.orig/print.c libmagic/print.c
---- libmagic.orig/print.c      2016-01-25 11:31:21.495017704 +0800
-+++ libmagic/print.c   2016-01-25 11:31:32.678017695 +0800
-@@ -28,13 +28,17 @@
+--- libmagic.orig/print.c      2016-11-23 17:08:28.349281600 +0100
++++ libmagic/print.c   2016-11-24 13:42:04.178244800 +0100
+@@ -28,6 +28,8 @@
  /*
   * print.c - debugging printout routines
   */
@@ -2856,24 +2783,20 @@ diff -u libmagic.orig/print.c libmagic/print.c
 +#include "php.h"
  
  #include "file.h"
-+#include "cdf.h"
  
- #ifndef lint
- FILE_RCSID("@(#)$File: print.c,v 1.78 2015/01/06 02:04:10 christos Exp $")
- #endif  /* lint */
-+#include <stdio.h>
- #include <string.h>
- #include <stdarg.h>
- #include <stdlib.h>
-@@ -43,201 +47,42 @@
+@@ -43,202 +45,44 @@
  #endif
  #include <time.h>
  
--#define SZOF(a)       (sizeof(a) / sizeof(a[0]))
--
--#include "cdf.h"
--
++#ifdef PHP_WIN32
++# define asctime_r php_asctime_r
++# define ctime_r php_ctime_r
++#endif
++
+ #define SZOF(a)       (sizeof(a) / sizeof(a[0]))
+ #include "cdf.h"
 -#ifndef COMPILE_ONLY
 -protected void
 -file_mdump(struct magic *m)
@@ -2983,26 +2906,26 @@ diff -u libmagic.orig/print.c libmagic/print.c
 -              case FILE_BEDATE:
 -              case FILE_MEDATE:
 -                      (void)fprintf(stderr, "%s,",
--                          file_fmttime(m->value.l, FILE_T_LOCAL, tbuf));
+-                          file_fmttime(m->value.l, 0, tbuf));
 -                      break;
 -              case FILE_LDATE:
 -              case FILE_LELDATE:
 -              case FILE_BELDATE:
 -              case FILE_MELDATE:
 -                      (void)fprintf(stderr, "%s,",
--                          file_fmttime(m->value.l, 0, tbuf));
+-                          file_fmttime(m->value.l, FILE_T_LOCAL, tbuf));
 -                      break;
 -              case FILE_QDATE:
 -              case FILE_LEQDATE:
 -              case FILE_BEQDATE:
 -                      (void)fprintf(stderr, "%s,",
--                          file_fmttime(m->value.q, FILE_T_LOCAL, tbuf));
+-                          file_fmttime(m->value.q, 0, tbuf));
 -                      break;
 -              case FILE_QLDATE:
 -              case FILE_LEQLDATE:
 -              case FILE_BEQLDATE:
 -                      (void)fprintf(stderr, "%s,",
--                          file_fmttime(m->value.q, 0, tbuf));
+-                          file_fmttime(m->value.q, FILE_T_LOCAL, tbuf));
 -                      break;
 -              case FILE_QWDATE:
 -              case FILE_LEQWDATE:
@@ -3025,6 +2948,7 @@ diff -u libmagic.orig/print.c libmagic/print.c
 -                      break;
 -              case FILE_USE:
 -              case FILE_NAME:
+-              case FILE_DER:
 -                      (void) fprintf(stderr, "'%s'", m->value.s);
 -                      break;
 -              default:
@@ -3034,13 +2958,8 @@ diff -u libmagic.orig/print.c libmagic/print.c
 -      }
 -      (void) fprintf(stderr, ",\"%s\"]\n", m->desc);
 -}
-+#ifdef PHP_WIN32
-+# define asctime_r php_asctime_r
-+# define ctime_r php_ctime_r
- #endif
-+#define SZOF(a)       (sizeof(a) / sizeof(a[0]))
-+
+-#endif
+-
  /*VARARGS*/
  protected void
  file_magwarn(struct magic_set *ms, const char *f, ...)
@@ -3086,7 +3005,7 @@ diff -u libmagic.orig/print.c libmagic/print.c
                t = ts.tv_sec;
        } else {
                // XXX: perhaps detect and print something if overflow
-@@ -246,9 +91,29 @@
+@@ -247,9 +91,29 @@
        }
  
        if (flags & FILE_T_LOCAL) {
@@ -3119,17 +3038,18 @@ diff -u libmagic.orig/print.c libmagic/print.c
        if (tm == NULL)
                goto out;
 diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
---- libmagic.orig/readcdf.c    2016-01-25 11:31:21.493017704 +0800
-+++ libmagic/readcdf.c 2016-01-25 11:31:32.678017695 +0800
-@@ -26,15 +26,21 @@
- #include "file.h"
- #ifndef lint
--FILE_RCSID("@(#)$File: readcdf.c,v 1.51 2015/01/11 16:58:25 christos Exp $")
-+FILE_RCSID("@(#)$File: readcdf.c,v 1.50 2015/01/02 21:29:39 christos Exp $")
- #endif
+--- libmagic.orig/readcdf.c    2016-11-23 17:08:28.502932500 +0100
++++ libmagic/readcdf.c 2016-11-24 13:42:04.185245900 +0100
+@@ -1,5 +1,5 @@
+ /*-
+- * Copyright (c) 2008, 2016 Christos Zoulas
++ * Copyright (c) 2008 Christos Zoulas
+  * All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+@@ -31,7 +31,11 @@
  
--#include <assert.h>
+ #include <assert.h>
  #include <stdlib.h>
 +#ifdef PHP_WIN32
 +#include "win32/unistd.h"
@@ -3139,13 +3059,7 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
  #include <string.h>
  #include <time.h>
  #include <ctype.h>
-+#if defined(HAVE_LOCALE_H)
-+#include <locale.h>
-+#endif
- #include "cdf.h"
- #include "magic.h"
-@@ -71,6 +77,10 @@
+@@ -75,6 +79,10 @@
        { NULL,                         NULL,                   },
  };
  
@@ -3156,16 +3070,7 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
  static const struct cv {
        uint64_t clsid[2];
        const char *mime;
-@@ -81,7 +91,7 @@
-       },
-       {       { 0,                     0                      },
-               NULL,
--      },
-+      }
- }, clsid2desc[] = {
-       {
-               { 0x00000000000c1084ULL, 0x46000000000000c0ULL  },
-@@ -100,10 +110,6 @@
+@@ -104,10 +112,6 @@
                if (clsid[0] == cv[i].clsid[0] && clsid[1] == cv[i].clsid[1])
                        return cv[i].mime;
        }
@@ -3176,7 +3081,7 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
        return NULL;
  }
  
-@@ -112,26 +118,14 @@
+@@ -116,30 +120,14 @@
  {
        size_t i;
        const char *rv = NULL;
@@ -3187,6 +3092,8 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
 -      assert(c_lc_ctype != NULL);
 -      old_lc_ctype = uselocale(c_lc_ctype);
 -      assert(old_lc_ctype != NULL);
+-#else
+-      char *old_lc_ctype = setlocale(LC_CTYPE, "C");
 -#endif
 +      (void)setlocale(LC_CTYPE, "C");
        for (i = 0; nv[i].pattern != NULL; i++)
@@ -3200,12 +3107,14 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
 -#ifdef USE_C_LOCALE
 -      (void)uselocale(old_lc_ctype);
 -      freelocale(c_lc_ctype);
+-#else
+-      setlocale(LC_CTYPE, old_lc_ctype);
 -#endif
 +      (void)setlocale(LC_CTYPE, "");
        return rv;
  }
  
-@@ -141,12 +135,14 @@
+@@ -149,12 +137,14 @@
  {
          size_t i;
          cdf_timestamp_t tp;
@@ -3221,7 +3130,7 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
          if (!NOTMIME(ms) && root_storage)
                str = cdf_clsid_to_mime(root_storage->d_storage_uuid,
                    clsid2mime);
-@@ -224,8 +220,11 @@
+@@ -232,8 +222,11 @@
                                                  return -1;
                                  } else {
                                          char *c, *ec;
@@ -3235,40 +3144,21 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
                                          if (c != NULL &&
                                            (ec = strchr(c, '\n')) != NULL)
                                                *ec = '\0';
-@@ -362,7 +361,7 @@
-       int i;
-       if ((i = cdf_read_user_stream(info, h, sat, ssat, sst,
--          dir, "Catalog", scn)) == -1)
-+          dir, "Catalog", scn)) <= 0)
-               return i;
- #ifdef CDF_DEBUG
-       cdf_dump_catalog(&h, &scn);
 diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
---- libmagic.orig/softmagic.c  2016-01-25 11:31:21.471017705 +0800
-+++ libmagic/softmagic.c       2016-01-25 11:44:35.541684679 +0800
-@@ -36,11 +36,19 @@
- #endif        /* lint */
- #include "magic.h"
--#include <assert.h>
- #include <string.h>
- #include <ctype.h>
- #include <stdlib.h>
+--- libmagic.orig/softmagic.c  2016-11-23 17:08:28.915798800 +0100
++++ libmagic/softmagic.c       2016-11-24 13:42:10.086018300 +0100
+@@ -43,6 +43,10 @@
  #include <time.h>
-+#if defined(HAVE_LOCALE_H)
-+#include <locale.h>
-+#endif
-+
+ #include "der.h"
 +#ifndef PREG_OFFSET_CAPTURE
 +# define PREG_OFFSET_CAPTURE                 (1<<8)
 +#endif
 +
-+
  private int match(struct magic_set *, struct magic *, uint32_t,
-     const unsigned char *, size_t, size_t, int, int, int, uint16_t,
-@@ -91,8 +99,8 @@
+     const unsigned char *, size_t, size_t, int, int, int, uint16_t *,
+     uint16_t *, int *, int *, int *);
+@@ -113,8 +117,8 @@
        return 0;
  }
  
@@ -3279,7 +3169,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
  #define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__)
  
  private const char * __attribute__((__format_arg__(3)))
-@@ -106,8 +114,10 @@
+@@ -128,8 +132,10 @@
                    " with `%s'", file, line, m->desc, def);
        return ptr;
  }
@@ -3291,7 +3181,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
  #endif
  
  /*
-@@ -160,7 +170,7 @@
+@@ -182,7 +188,7 @@
                struct magic *m = &magic[magindex];
  
                if (m->type != FILE_NAME)
@@ -3300,7 +3190,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
  #define FLT (STRING_BINTEST | STRING_TEXTTEST)
                     ((text && (m->str_flags & FLT) == STRING_BINTEST) ||
                      (!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
-@@ -369,42 +379,26 @@
+@@ -404,42 +410,26 @@
  private int
  check_fmt(struct magic_set *ms, struct magic *m)
  {
@@ -3354,7 +3244,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
  private int32_t
  mprint(struct magic_set *ms, struct magic *m)
  {
-@@ -630,19 +624,18 @@
+@@ -665,19 +655,18 @@
                t = ms->offset + sizeof(double);
                break;
  
@@ -3376,7 +3266,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
  
                if (rval == -1)
                        return -1;
-@@ -654,6 +647,15 @@
+@@ -689,6 +678,15 @@
                break;
        }
  
@@ -3392,28 +3282,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
        case FILE_DEFAULT:
        case FILE_CLEAR:
                if (file_printf(ms, "%s", m->desc) == -1)
-@@ -879,16 +881,16 @@
-       if (m->num_mask) \
-               switch (m->mask_op & FILE_OPS_MASK) { \
-               case FILE_OPADD: \
--                      p->fld += cast m->num_mask; \
-+                      p->fld += cast (int64_t)m->num_mask; \
-                       break; \
-               case FILE_OPMINUS: \
--                      p->fld -= cast m->num_mask; \
-+                      p->fld -= cast (int64_t)m->num_mask; \
-                       break; \
-               case FILE_OPMULTIPLY: \
--                      p->fld *= cast m->num_mask; \
-+                      p->fld *= cast (int64_t)m->num_mask; \
-                       break; \
-               case FILE_OPDIVIDE: \
--                      p->fld /= cast m->num_mask; \
-+                      p->fld /= cast (int64_t)m->num_mask; \
-                       break; \
-               } \
-@@ -1095,17 +1097,26 @@
+@@ -1204,21 +1202,28 @@
                                return 0;
                        }
  
@@ -3431,6 +3300,8 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
  
 -                      if (bytecnt == 0 || bytecnt > nbytes - offset)
 -                              bytecnt = nbytes - offset;
+-                      if (bytecnt > ms->regex_max)
+-                              bytecnt = ms->regex_max;
 +                      if (bytecnt == 0) {
 +                              bytecnt = 1 << 14;
 +                      }
@@ -3447,11 +3318,14 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
 +                              return 0;
 +                      }
                        buf = RCAST(const char *, s) + offset;
-                       end = last = RCAST(const char *, s) + bytecnt;
+-                      end = last = RCAST(const char *, s) + bytecnt + offset;
++                      end = last = RCAST(const char *, s) + bytecnt;
                        /* mget() guarantees buf <= last */
-@@ -1221,9 +1232,6 @@
+                       for (lines = linecnt, b = buf; lines && b < end &&
+                            ((b = CAST(const char *,
+@@ -1371,9 +1376,6 @@
                    m->type, m->flag, offset, o, nbytes,
-                   indir_level, *name_count);
+                   *indir_count, *name_count);
                mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
 -#ifndef COMPILE_ONLY
 -              file_mdump(m);
@@ -3459,7 +3333,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
        }
  
        if (m->flag & INDIR) {
-@@ -1593,9 +1601,6 @@
+@@ -1486,9 +1488,6 @@
                if ((ms->flags & MAGIC_DEBUG) != 0) {
                        mdebug(offset, (char *)(void *)p,
                            sizeof(union VALUETYPE));
@@ -3469,9 +3343,9 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
                }
        }
  
-@@ -1676,15 +1681,15 @@
+@@ -1570,15 +1569,15 @@
                if (rv == 1) {
-                       if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
+                       if ((ms->flags & MAGIC_NODESC) == 0 &&
                            file_printf(ms, F(ms, m, "%u"), offset) == -1) {
 -                              free(rbuf);
 +                              if (rbuf) efree(rbuf);
@@ -3488,7 +3362,36 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
                return rv;
  
        case FILE_USE:
-@@ -1799,6 +1804,41 @@
+@@ -1660,9 +1659,14 @@
+                           isspace(*a)) {
+                               a++;
+                               if (isspace(*b++)) {
+-                                      if (!isspace(*a))
+-                                              while (isspace(*b))
++                                      if (!isspace(*a)) {
++                                              /* Limit to the remaining len only, otherwise
++                                                      we risk to cause CVE-2014-3538. This
++                                                      might be done better though, not sure. */
++                                              size_t remaining_len = len;
++                                              while (isspace(*b) && remaining_len-- > 0)
+                                                       b++;
++                                      }
+                               }
+                               else {
+                                       v = 1;
+@@ -1671,8 +1675,10 @@
+                       }
+                       else if ((flags & STRING_COMPACT_OPTIONAL_WHITESPACE) &&
+                           isspace(*a)) {
++                              /* Same as the comment in the previous elif clause. */
++                              size_t remaining_len = len;
+                               a++;
+-                              while (isspace(*b))
++                              while (isspace(*b)&& remaining_len-- > 0)
+                                       b++;
+                       }
+                       else {
+@@ -1696,6 +1702,41 @@
        return file_strncmp(a, b, len, flags);
  }
  
@@ -3530,7 +3433,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
  private int
  magiccheck(struct magic_set *ms, struct magic *m)
  {
-@@ -1959,73 +1999,77 @@
+@@ -1856,65 +1897,77 @@
                break;
        }
        case FILE_REGEX: {
@@ -3563,14 +3466,13 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
 +                      zval_ptr_dtor(&pattern);
 +                      return -1;
                } else {
--                      regmatch_t pmatch[1];
+-                      regmatch_t pmatch;
 -                      size_t slen = ms->search.s_len;
--#ifndef REG_STARTEND
--#define       REG_STARTEND    0
 -                      char *copy;
 -                      if (slen != 0) {
--                          copy = malloc(slen);
+-                          copy = CAST(char *, malloc(slen));
 -                          if (copy == NULL)  {
+-                              file_regfree(&rx);
 -                              file_error(ms, errno,
 -                                  "can't allocate %" SIZE_T_FORMAT "u bytes",
 -                                  slen);
@@ -3631,22 +3533,15 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
 -                          search = ms->search.s;
 -                          copy = NULL;
 -                      }
--#else
--                      search = ms->search.s;
--                      pmatch[0].rm_so = 0;
--                      pmatch[0].rm_eo = slen;
--#endif
 -                      rc = file_regexec(&rx, (const char *)search,
--                          1, pmatch, REG_STARTEND);
--#if REG_STARTEND == 0
+-                          1, &pmatch, 0);
 -                      free(copy);
--#endif
 -                      switch (rc) {
 -                      case 0:
--                              ms->search.s += (int)pmatch[0].rm_so;
--                              ms->search.offset += (size_t)pmatch[0].rm_so;
+-                              ms->search.s += (int)pmatch.rm_so;
+-                              ms->search.offset += (size_t)pmatch.rm_so;
 -                              ms->search.rm_len =
--                                  (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so);
+-                                  (size_t)(pmatch.rm_eo - pmatch.rm_so);
 -                              v = 0;
 -                              break;
 -
@@ -3669,8 +3564,8 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
        }
        case FILE_INDIRECT:
 diff -u libmagic.orig/strcasestr.c libmagic/strcasestr.c
---- libmagic.orig/strcasestr.c 2016-01-25 11:31:21.494017704 +0800
-+++ libmagic/strcasestr.c      2016-01-25 11:31:32.678017695 +0800
+--- libmagic.orig/strcasestr.c 2016-11-23 17:08:29.069351700 +0100
++++ libmagic/strcasestr.c      2015-07-18 21:35:36.510103100 +0200
 @@ -39,6 +39,8 @@
  
  #include "file.h"