Annotation of embedaddon/php/ext/fileinfo/libmagic.patch, revision 1.1.1.3

1.1       misho       1: diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
1.1.1.3 ! misho       2: --- libmagic.orig/apprentice.c 2013-03-21 18:45:14.000000000 +0100
        !             3: +++ libmagic/apprentice.c      2013-04-27 13:53:32.175250261 +0200
1.1       misho       4: @@ -29,6 +29,8 @@
                      5:   * apprentice - make one pass through /etc/magic, learning its secrets.
                      6:   */
                      7:  
                      8: +#include "php.h"
                      9: +
                     10:  #include "file.h"
                     11:  
                     12:  #ifndef       lint
1.1.1.3 ! misho      13: @@ -36,18 +38,30 @@
1.1.1.2   misho      14:  #endif        /* lint */
                     15:  
1.1       misho      16:  #include "magic.h"
1.1.1.2   misho      17: +#include "patchlevel.h"
1.1       misho      18:  #include <stdlib.h>
                     19: -#ifdef HAVE_UNISTD_H
                     20: +
                     21: +#if defined(__hpux) && !defined(HAVE_STRTOULL)
                     22: +#if SIZEOF_LONG == 8
                     23: +# define strtoull strtoul
                     24: +#else
                     25: +# define strtoull __strtoull
                     26: +#endif
                     27: +#endif
                     28: +
                     29: +#ifdef PHP_WIN32
                     30: +#include "win32/unistd.h"
                     31: +#if _MSC_VER <= 1300
                     32: +# include "win32/php_strtoi64.h"
                     33: +#endif
                     34: +#define strtoull _strtoui64
                     35: +#else
                     36:  #include <unistd.h>
                     37:  #endif
                     38:  #include <string.h>
                     39:  #include <assert.h>
                     40:  #include <ctype.h>
                     41:  #include <fcntl.h>
                     42: -#ifdef QUICK
                     43: -#include <sys/mman.h>
                     44: -#endif
1.1.1.3 ! misho      45: -#include <dirent.h>
1.1       misho      46:  
                     47:  #define       EATAB {while (isascii((unsigned char) *l) && \
                     48:                      isspace((unsigned char) *l))  ++l;}
1.1.1.3 ! misho      49: @@ -143,38 +157,7 @@
1.1       misho      50:        { NULL, 0, NULL }
                     51:  };
                     52:  
                     53: -#ifdef COMPILE_ONLY
                     54: -
                     55: -int main(int, char *[]);
                     56: -
                     57: -int
                     58: -main(int argc, char *argv[])
                     59: -{
                     60: -      int ret;
                     61: -      struct magic_set *ms;
                     62: -      char *progname;
                     63: -
                     64: -      if ((progname = strrchr(argv[0], '/')) != NULL)
                     65: -              progname++;
                     66: -      else
                     67: -              progname = argv[0];
                     68: -
                     69: -      if (argc != 2) {
                     70: -              (void)fprintf(stderr, "Usage: %s file\n", progname);
                     71: -              return 1;
                     72: -      }
                     73: -
                     74: -      if ((ms = magic_open(MAGIC_CHECK)) == NULL) {
                     75: -              (void)fprintf(stderr, "%s: %s\n", progname, strerror(errno));
                     76: -              return 1;
                     77: -      }
                     78: -      ret = magic_compile(ms, argv[1]) == -1 ? 1 : 0;
                     79: -      if (ret == 1)
                     80: -              (void)fprintf(stderr, "%s: %s\n", progname, magic_error(ms));
                     81: -      magic_close(ms);
                     82: -      return ret;
                     83: -}
                     84: -#endif /* COMPILE_ONLY */
                     85: +#include "../data_file.c"
                     86:  
1.1.1.3 ! misho      87:  struct type_tbl_s {
1.1       misho      88:        const char name[16];
1.1.1.3 ! misho      89: @@ -255,6 +238,10 @@
        !            90:  # undef XX
1.1       misho      91:  # undef XX_NULL
                     92:  
                     93: +#ifndef S_ISDIR
                     94: +#define S_ISDIR(mode) ((mode) & _S_IFDIR)
                     95: +#endif
                     96: +
                     97:  private int
1.1.1.3 ! misho      98:  get_type(const struct type_tbl_s *tbl, const char *l, const char **t)
1.1       misho      99:  {
1.1.1.3 ! misho     100: @@ -378,7 +365,7 @@
        !           101:  {
        !           102:        struct mlist *ml;
        !           103:  
        !           104: -      if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL)
        !           105: +      if ((ml = CAST(struct mlist *, emalloc(sizeof(*ml)))) == NULL)
        !           106:                return -1;
        !           107:  
        !           108:        ml->map = idx == 0 ? map : NULL;
        !           109: @@ -416,12 +403,13 @@
        !           110:                return apprentice_compile(ms, map, fn);
1.1       misho     111:        }
                    112:  
                    113: -#ifndef COMPILE_ONLY
1.1.1.3 ! misho     114:        map = apprentice_map(ms, fn);
        !           115:        if (map == NULL) {
1.1       misho     116: -              if (ms->flags & MAGIC_CHECK)
                    117: -                      file_magwarn(ms, "using regular magic file `%s'", fn);
1.1.1.3 ! misho     118: -              map = apprentice_load(ms, fn, action);
1.1       misho     119: +              if (fn) {
                    120: +                      if (ms->flags & MAGIC_CHECK)
                    121: +                              file_magwarn(ms, "using regular magic file `%s'", fn);
1.1.1.3 ! misho     122: +                      map = apprentice_load(ms, fn, action);
1.1       misho     123: +              }
1.1.1.3 ! misho     124:                if (map == NULL)
1.1       misho     125:                        return -1;
                    126:        }
1.1.1.3 ! misho     127: @@ -444,7 +432,6 @@
1.1.1.2   misho     128:        }
                    129:        
1.1       misho     130:        return 0;
                    131: -#endif /* COMPILE_ONLY */
                    132:  }
                    133:  
                    134:  protected void
1.1.1.3 ! misho     135: @@ -455,10 +442,16 @@
        !           136:                return;
        !           137:        for (i = 0; i < MAGIC_SETS; i++)
        !           138:                mlist_free(ms->mlist[i]);
        !           139: -      free(ms->o.pbuf);
        !           140: -      free(ms->o.buf);
        !           141: -      free(ms->c.li);
        !           142: -      free(ms);
        !           143: +      if (ms->o.pbuf) {
        !           144: +              efree(ms->o.pbuf);
        !           145: +      }
        !           146: +      if (ms->o.buf) {
        !           147: +              efree(ms->o.buf);
        !           148: +      }
        !           149: +      if (ms->c.li) {
        !           150: +              efree(ms->c.li);
        !           151: +      }
        !           152: +      efree(ms);
        !           153:  }
        !           154:  
        !           155:  protected struct magic_set *
        !           156: @@ -467,7 +460,7 @@
        !           157:        struct magic_set *ms;
        !           158:        size_t i, len;
        !           159:  
        !           160: -      if ((ms = CAST(struct magic_set *, calloc((size_t)1,
        !           161: +      if ((ms = CAST(struct magic_set *, ecalloc((size_t)1,
        !           162:            sizeof(struct magic_set)))) == NULL)
        !           163:                return NULL;
        !           164:  
        !           165: @@ -479,7 +472,7 @@
        !           166:        ms->o.buf = ms->o.pbuf = NULL;
        !           167:        len = (ms->c.len = 10) * sizeof(*ms->c.li);
        !           168:  
        !           169: -      if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL)
        !           170: +      if ((ms->c.li = CAST(struct level_info *, emalloc(len))) == NULL)
        !           171:                goto free;
        !           172:  
        !           173:        ms->event_flags = 0;
        !           174: @@ -490,7 +483,7 @@
        !           175:        ms->line = 0;
        !           176:        return ms;
        !           177:  free:
        !           178: -      free(ms);
        !           179: +      efree(ms);
        !           180:        return NULL;
        !           181:  }
        !           182:  
        !           183: @@ -499,22 +492,24 @@
        !           184:  {
        !           185:        if (map == NULL)
1.1       misho     186:                return;
1.1.1.3 ! misho     187: -      if (map->p == NULL)
        !           188: -              return;
1.1       misho     189: -#ifdef QUICK
1.1.1.3 ! misho     190: -      if (map->len)
        !           191: -              (void)munmap(map->p, map->len);
        !           192: -      else
1.1       misho     193: -#endif
1.1.1.3 ! misho     194: -              free(map->p);
        !           195: -      free(map);
        !           196: +      if (map->p != php_magic_database) {
        !           197: +              int j;
        !           198: +              for (j = 0; j < MAGIC_SETS; j++) {
        !           199: +                      if (map->magic[j])
        !           200: +                              efree(map->magic[j]);
        !           201: +              }
        !           202: +              if (map->p != NULL) {
        !           203: +                      efree(map->p);
        !           204: +              }
        !           205: +      }
        !           206: +      efree(map);
        !           207:  }
        !           208:  
        !           209:  private struct mlist *
        !           210:  mlist_alloc(void)
        !           211:  {
        !           212:        struct mlist *mlist;
        !           213: -      if ((mlist = CAST(struct mlist *, calloc(1, sizeof(*mlist)))) == NULL) {
        !           214: +      if ((mlist = CAST(struct mlist *, ecalloc(1, sizeof(*mlist)))) == NULL) {
        !           215:                return NULL;
        !           216:        }
        !           217:        mlist->next = mlist->prev = mlist;
        !           218: @@ -533,10 +528,10 @@
        !           219:                struct mlist *next = ml->next;
        !           220:                if (ml->map)
        !           221:                        apprentice_unmap(ml->map);
        !           222: -              free(ml);
        !           223: +              efree(ml);
        !           224:                ml = next;
1.1       misho     225:        }
1.1.1.3 ! misho     226: -      free(ml);
        !           227: +      efree(ml);
        !           228:  }
        !           229:  
        !           230:  /* const char *fn: list of magic files and directories */
        !           231: @@ -546,13 +541,28 @@
1.1.1.2   misho     232:        char *p, *mfn;
                    233:        int file_err, errs = -1;
1.1.1.3 ! misho     234:        size_t i;
1.1.1.2   misho     235: -
                    236: +/* XXX disabling default magic loading so the compiled in data is used */
                    237: +#if 0
                    238:        if ((fn = magic_getpath(fn, action)) == NULL)
1.1.1.3 ! misho     239:                return -1;
1.1.1.2   misho     240: +#endif
                    241:  
                    242:        init_file_tables();
1.1       misho     243:  
                    244: -      if ((mfn = strdup(fn)) == NULL) {
1.1.1.2   misho     245: +      if (fn == NULL)
                    246: +              fn = getenv("MAGIC");
1.1       misho     247: +      if (fn == NULL) {
1.1.1.3 ! misho     248: +              for (i = 0; i < MAGIC_SETS; i++) {
        !           249: +                      mlist_free(ms->mlist[i]);
        !           250: +                      if ((ms->mlist[i] = mlist_alloc()) == NULL) {
        !           251: +                              file_oomem(ms, sizeof(*ms->mlist[i]));
        !           252: +                              return -1;
        !           253: +                      }
        !           254: +              }
        !           255: +              return apprentice_1(ms, fn, action);
        !           256: +      }
1.1       misho     257: +
1.1.1.3 ! misho     258: +      if ((mfn = estrdup(fn)) == NULL) {
        !           259:                file_oomem(ms, strlen(fn));
        !           260:                return -1;
1.1       misho     261:        }
1.1.1.3 ! misho     262: @@ -567,7 +577,7 @@
        !           263:                                        mlist_free(ms->mlist[i]);
        !           264:                                while (i != 0);
        !           265:                        }
        !           266: -                      free(mfn);
        !           267: +                      efree(mfn);
        !           268:                        return -1;
        !           269:                }
1.1       misho     270:        }
1.1.1.3 ! misho     271: @@ -584,7 +594,7 @@
        !           272:                fn = p;
        !           273:        }
        !           274:  
1.1       misho     275: -      free(mfn);
                    276: +      efree(mfn);
                    277:  
1.1.1.3 ! misho     278:        if (errs == -1) {
        !           279:                for (i = 0; i < MAGIC_SETS; i++) {
        !           280: @@ -904,7 +914,7 @@
1.1       misho     281:  
1.1.1.3 ! misho     282:                maxmagic[i] += ALLOC_INCR;
        !           283:                if ((mp = CAST(struct magic_entry *,
        !           284: -                  realloc(mentry[i], sizeof(*mp) * maxmagic[i]))) ==
        !           285: +                  erealloc(mentry[i], sizeof(*mp) * maxmagic[i]))) ==
        !           286:                    NULL) {
        !           287:                        file_oomem(ms, sizeof(*mp) * maxmagic[i]);
        !           288:                        return -1;
        !           289: @@ -925,13 +935,24 @@
1.1       misho     290:  load_1(struct magic_set *ms, int action, const char *fn, int *errs,
1.1.1.3 ! misho     291:     struct magic_entry **mentry, uint32_t *mentrycount)
1.1       misho     292:  {
1.1.1.2   misho     293: -      size_t lineno = 0, llen = 0;
1.1       misho     294: +      char buffer[BUFSIZ + 1];
1.1.1.2   misho     295:        char *line = NULL;
                    296: -      ssize_t len;
                    297: +      size_t len;
                    298: +      size_t lineno = 0;
1.1.1.3 ! misho     299:        struct magic_entry me;
        !           300:  
        !           301: -      FILE *f = fopen(ms->file = fn, "r");
        !           302: -      if (f == NULL) {
1.1       misho     303: +      php_stream *stream;
                    304: +
                    305: +      TSRMLS_FETCH();
                    306: +
1.1.1.3 ! misho     307: +      ms->file = fn;
1.1       misho     308: +#if PHP_API_VERSION < 20100412
                    309: +      stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
                    310: +#else
                    311: +      stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);
                    312: +#endif
1.1.1.3 ! misho     313: +
1.1       misho     314: +      if (stream == NULL) {
                    315:                if (errno != ENOENT)
                    316:                        file_error(ms, errno, "cannot read magic file `%s'",
                    317:                                   fn);
1.1.1.3 ! misho     318: @@ -941,8 +962,7 @@
1.1.1.2   misho     319:  
1.1.1.3 ! misho     320:        memset(&me, 0, sizeof(me));
        !           321:        /* read and parse this file */
1.1.1.2   misho     322: -      for (ms->line = 1; (len = getline(&line, &llen, f)) != -1;
                    323: -          ms->line++) {
                    324: +      for (ms->line = 1; (line = php_stream_get_line(stream, buffer , BUFSIZ, &len)) != NULL; ms->line++) {
                    325:                if (len == 0) /* null line, garbage, etc */
                    326:                        continue;
                    327:                if (line[len - 1] == '\n') {
1.1.1.3 ! misho     328: @@ -994,14 +1014,13 @@
        !           329:                                goto again;
        !           330:                        default:
        !           331:                                (*errs)++;
        !           332: -                              break;
        !           333: -                      }
        !           334: +                      break;
1.1       misho     335:                }
                    336:        }
1.1.1.3 ! misho     337: +      }
        !           338:        if (me.mp)
        !           339:                (void)addentry(ms, &me, mentry, mentrycount);
1.1.1.2   misho     340: -      free(line);
                    341: -      (void)fclose(f);
                    342: +      php_stream_close(stream);
1.1       misho     343:  }
                    344:  
1.1.1.2   misho     345:  /*
1.1.1.3 ! misho     346: @@ -1080,7 +1099,7 @@
        !           347:                mentrycount += me[i].cont_count;
        !           348:  
        !           349:        slen = sizeof(**ma) * mentrycount;
        !           350: -      if ((*ma = CAST(struct magic *, malloc(slen))) == NULL) {
        !           351: +      if ((*ma = CAST(struct magic *, emalloc(slen))) == NULL) {
        !           352:                file_oomem(ms, slen);
        !           353:                return -1;
        !           354:        }
        !           355: @@ -1102,27 +1121,29 @@
        !           356:        if (me == NULL)
        !           357:                return;
        !           358:        for (i = 0; i < nme; i++)
        !           359: -              free(me[i].mp);
        !           360: -      free(me);
        !           361: +              efree(me[i].mp);
        !           362: +      efree(me);
        !           363:  }
        !           364:  
        !           365:  private struct magic_map *
        !           366:  apprentice_load(struct magic_set *ms, const char *fn, int action)
        !           367:  {
        !           368: -      int errs = 0;
        !           369: +      int errs = 0; 
        !           370:        struct magic_entry *mentry[MAGIC_SETS] = { NULL };
        !           371:        uint32_t mentrycount[MAGIC_SETS] = { 0 };
        !           372:        uint32_t i, j;
        !           373:        size_t files = 0, maxfiles = 0;
1.1.1.2   misho     374: -      char **filearr = NULL, *mfn;
1.1.1.3 ! misho     375: +      char **filearr = NULL;
1.1       misho     376:        struct stat st;
1.1.1.3 ! misho     377:        struct magic_map *map;
        !           378: -      DIR *dir;
        !           379: -      struct dirent *d;
        !           380: +      php_stream *dir;
        !           381: +      php_stream_dirent d;
        !           382: +
        !           383: +      TSRMLS_FETCH();
1.1       misho     384:  
                    385:        ms->flags |= MAGIC_CHECK;       /* Enable checks for parsed files */
                    386:  
1.1.1.3 ! misho     387: -      if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
        !           388: +      if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) {
        !           389:                file_oomem(ms, sizeof(*map));
        !           390:                return NULL;
        !           391:        }
        !           392: @@ -1131,23 +1152,37 @@
        !           393:        if (action == FILE_CHECK)
1.1.1.2   misho     394:                (void)fprintf(stderr, "%s\n", usg_hdr);
                    395:  
1.1.1.3 ! misho     396: +      {
        !           397: +              /* XXX the maxmagic has to be reset each time we load some new magic file.
        !           398: +              Where file commando is used it's not essential as the CLI process
        !           399: +              ends, multiple loading within the same process wouldn't work. */
        !           400: +              int k;
        !           401: +              for (k = 0; k < MAGIC_SETS; k++) {
        !           402: +                      maxmagic[k] = 0;
        !           403: +              }
        !           404: +      }
        !           405: +
1.1       misho     406:        /* load directory or file */
                    407: -      if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
1.1.1.3 ! misho     408: -              dir = opendir(fn);
        !           409: +      /* FIXME: Read file names and sort them to prevent
        !           410: +         non-determinism. See Debian bug #488562. */
1.1       misho     411: +      if (php_sys_stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
1.1.1.3 ! misho     412: +              int mflen;
        !           413: +              char mfn[MAXPATHLEN];
        !           414: +
        !           415: +              dir = php_stream_opendir((char *)fn, REPORT_ERRORS, NULL);
1.1.1.2   misho     416:                if (!dir) {
                    417:                        errs++;
                    418:                        goto out;
                    419:                }
1.1.1.3 ! misho     420: -              while ((d = readdir(dir)) != NULL) {
1.1.1.2   misho     421: -                      if (asprintf(&mfn, "%s/%s", fn, d->d_name) < 0) {
1.1.1.3 ! misho     422: +              while (php_stream_readdir(dir, &d)) {
        !           423: +                      if ((mflen = snprintf(mfn, sizeof(mfn), "%s/%s", fn, d.d_name)) < 0) {
1.1.1.2   misho     424:                                file_oomem(ms,
1.1.1.3 ! misho     425: -                                  strlen(fn) + strlen(d->d_name) + 2);
        !           426: +                              strlen(fn) + strlen(d.d_name) + 2);
1.1.1.2   misho     427:                                errs++;
1.1.1.3 ! misho     428: -                              closedir(dir);
        !           429: +                              php_stream_closedir(dir);
1.1.1.2   misho     430:                                goto out;
                    431:                        }
                    432:                        if (stat(mfn, &st) == -1 || !S_ISREG(st.st_mode)) {
                    433: -                              free(mfn);
                    434:                                continue;
                    435:                        }
                    436:                        if (files >= maxfiles) {
1.1.1.3 ! misho     437: @@ -1155,24 +1190,23 @@
        !           438:                                maxfiles = (maxfiles + 1) * 2;
        !           439:                                mlen = maxfiles * sizeof(*filearr);
1.1.1.2   misho     440:                                if ((filearr = CAST(char **,
1.1.1.3 ! misho     441: -                                  realloc(filearr, mlen))) == NULL) {
        !           442: +                                  erealloc(filearr, mlen))) == NULL) {
1.1.1.2   misho     443:                                        file_oomem(ms, mlen);
                    444: -                                      free(mfn);
1.1.1.3 ! misho     445: -                                      closedir(dir);
        !           446: +                                      php_stream_closedir(dir);
1.1.1.2   misho     447:                                        errs++;
                    448:                                        goto out;
1.1.1.3 ! misho     449:                                }
        !           450:                        }
        !           451: -                      filearr[files++] = mfn;
        !           452: +                      filearr[files++] = estrndup(mfn, (mflen > sizeof(mfn) - 1)? sizeof(mfn) - 1: mflen);
        !           453:                }
        !           454: -              closedir(dir);
        !           455: +              php_stream_closedir(dir);
        !           456:                qsort(filearr, files, sizeof(*filearr), cmpstrp);
        !           457:                for (i = 0; i < files; i++) {
        !           458:                        load_1(ms, action, filearr[i], &errs, mentry,
        !           459:                            mentrycount);
        !           460: -                      free(filearr[i]);
        !           461: +                      efree(filearr[i]);
        !           462:                }
        !           463: -              free(filearr);
        !           464: +              efree(filearr);
        !           465:        } else
        !           466:                load_1(ms, action, fn, &errs, mentry, mentrycount);
        !           467:        if (errs)
        !           468: @@ -1211,9 +1245,9 @@
1.1       misho     469:        if (errs) {
1.1.1.3 ! misho     470:                for (j = 0; j < MAGIC_SETS; j++) {
        !           471:                        if (map->magic[j])
        !           472: -                              free(map->magic[j]);
        !           473: +                              efree(map->magic[j]);
        !           474:                }
        !           475: -              free(map);
        !           476: +              efree(map);
        !           477:                return NULL;
        !           478:        }
        !           479:        return map;
        !           480: @@ -1500,7 +1534,7 @@
1.1       misho     481:                if (me->cont_count == me->max_count) {
                    482:                        struct magic *nm;
                    483:                        size_t cnt = me->max_count + ALLOC_CHUNK;
                    484: -                      if ((nm = CAST(struct magic *, realloc(me->mp,
1.1.1.3 ! misho     485: +                      if ((nm = CAST(struct magic *, erealloc(me->mp,
        !           486:                            sizeof(*nm) * cnt))) == NULL) {
        !           487:                                file_oomem(ms, sizeof(*nm) * cnt);
        !           488:                                return -1;
        !           489: @@ -1515,7 +1549,7 @@
        !           490:                static const size_t len = sizeof(*m) * ALLOC_CHUNK;
        !           491:                if (me->mp != NULL)
        !           492:                        return 1;
        !           493: -              if ((m = CAST(struct magic *, malloc(len))) == NULL) {
        !           494: +              if ((m = CAST(struct magic *, emalloc(len))) == NULL) {
        !           495:                        file_oomem(ms, len);
        !           496:                        return -1;
        !           497:                }
        !           498: @@ -1688,7 +1722,7 @@
        !           499:                                m->type = get_standard_integer_type(l, &l);
        !           500:                        else if (*l == 's' && !isalpha((unsigned char)l[1])) {
        !           501:                                m->type = FILE_STRING;
        !           502: -                              ++l;
        !           503: +              ++l;
        !           504:                        }
        !           505:                }
        !           506:        }
        !           507: @@ -1701,6 +1735,10 @@
        !           508:        if (m->type == FILE_INVALID) {
        !           509:                if (ms->flags & MAGIC_CHECK)
        !           510:                        file_magwarn(ms, "type `%s' invalid", l);
        !           511: +              if (me->mp) {
        !           512: +                      efree(me->mp);
        !           513: +                      me->mp = NULL;
        !           514: +              }
        !           515:                return -1;
        !           516:        }
        !           517:  
        !           518: @@ -1709,7 +1747,7 @@
1.1       misho     519:  
                    520:        m->mask_op = 0;
                    521:        if (*l == '~') {
                    522: -              if (!IS_STRING(m->type))
                    523: +              if (!IS_LIBMAGIC_STRING(m->type))
                    524:                        m->mask_op |= FILE_OPINVERSE;
                    525:                else if (ms->flags & MAGIC_CHECK)
                    526:                        file_magwarn(ms, "'~' invalid for string types");
1.1.1.3 ! misho     527: @@ -1718,7 +1756,7 @@
1.1.1.2   misho     528:        m->str_range = 0;
                    529:        m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0;
1.1       misho     530:        if ((op = get_op(*l)) != -1) {
                    531: -              if (!IS_STRING(m->type)) {
                    532: +              if (!IS_LIBMAGIC_STRING(m->type)) {
                    533:                        uint64_t val;
                    534:                        ++l;
                    535:                        m->mask_op |= op;
1.1.1.3 ! misho     536: @@ -1909,11 +1947,6 @@
1.1       misho     537:                if (check_format(ms, m) == -1)
                    538:                        return -1;
                    539:        }
                    540: -#ifndef COMPILE_ONLY
                    541: -      if (action == FILE_CHECK) {
                    542: -              file_mdump(m);
                    543: -      }
                    544: -#endif
                    545:        m->mimetype[0] = '\0';          /* initialise MIME type to none */
1.1.1.3 ! misho     546:        return 0;
        !           547:  }
        !           548: @@ -2554,59 +2587,80 @@
        !           549:  private struct magic_map *
        !           550:  apprentice_map(struct magic_set *ms, const char *fn)
1.1       misho     551:  {
                    552: -      int fd;
                    553: -      struct stat st;
                    554:        uint32_t *ptr;
1.1.1.3 ! misho     555:        uint32_t version, entries, nentries;
1.1       misho     556:        int needsbyteswap;
                    557:        char *dbname = NULL;
1.1.1.3 ! misho     558:        struct magic_map *map;
        !           559:        size_t i;
1.1       misho     560: +      php_stream *stream = NULL;
                    561: +      php_stream_statbuf st;
                    562: +
1.1.1.3 ! misho     563:  
        !           564: -      fd = -1;
        !           565: -      if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
1.1       misho     566: +      TSRMLS_FETCH();
                    567: +
1.1.1.3 ! misho     568: +      if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) {
        !           569:                file_oomem(ms, sizeof(*map));
        !           570: +              efree(map);
        !           571:                goto error;
        !           572:        }
        !           573:  
1.1       misho     574: +      if (fn == NULL) {
1.1.1.3 ! misho     575: +              map->p = (void *)&php_magic_database;
1.1       misho     576: +              goto internal_loaded;
                    577: +      }
1.1.1.3 ! misho     578: +
        !           579: +#ifdef PHP_WIN32
        !           580: +      /* Don't bother on windows with php_stream_open_wrapper,
        !           581: +      return to give apprentice_load() a chance. */
        !           582: +      if (php_stream_stat_path_ex((char *)fn, 0, &st, NULL) == SUCCESS) {
        !           583: +               if (st.sb.st_mode & S_IFDIR) {
        !           584: +                       goto error;
        !           585: +               }
        !           586: +       }
        !           587: +#endif
        !           588: +
1.1       misho     589:        dbname = mkdbname(ms, fn, 0);
                    590:        if (dbname == NULL)
1.1.1.3 ! misho     591:                goto error;
1.1       misho     592:  
                    593: -      if ((fd = open(dbname, O_RDONLY|O_BINARY)) == -1)
                    594: +#if PHP_API_VERSION < 20100412
                    595: +              stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
                    596: +#else
                    597: +              stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);
                    598: +#endif
                    599: +
                    600: +      if (!stream) {
1.1.1.3 ! misho     601:                goto error;
1.1       misho     602: +      }
                    603:  
                    604: -      if (fstat(fd, &st) == -1) {
                    605: +      if (php_stream_stat(stream, &st) < 0) {
                    606:                file_error(ms, errno, "cannot stat `%s'", dbname);
1.1.1.3 ! misho     607:                goto error;
1.1       misho     608:        }
                    609: -      if (st.st_size < 8) {
                    610: +
                    611: +      if (st.sb.st_size < 8) {
                    612:                file_error(ms, 0, "file `%s' is too small", dbname);
1.1.1.3 ! misho     613:                goto error;
1.1       misho     614:        }
                    615:  
1.1.1.3 ! misho     616: -      map->len = (size_t)st.st_size;
1.1       misho     617: -#ifdef QUICK
1.1.1.3 ! misho     618: -      if ((map->p = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE,
1.1       misho     619: -          MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) {
                    620: -              file_error(ms, errno, "cannot map `%s'", dbname);
1.1.1.3 ! misho     621: -              goto error;
1.1       misho     622: -      }
                    623: -#else
1.1.1.3 ! misho     624: -      if ((map->p = CAST(void *, malloc(map->len))) == NULL) {
        !           625: +      map->len = (size_t)st.sb.st_size;
        !           626: +      if ((map->p = CAST(void *, emalloc(map->len))) == NULL) {
        !           627:                file_oomem(ms, map->len);
        !           628:                goto error;
        !           629:        }
        !           630: -      if (read(fd, map->p, map->len) != (ssize_t)map->len) {
        !           631: +      if (php_stream_read(stream, map->p, (size_t)st.sb.st_size) != (size_t)st.sb.st_size) {
1.1       misho     632:                file_badread(ms);
1.1.1.3 ! misho     633:                goto error;
1.1       misho     634:        }
1.1.1.3 ! misho     635:        map->len = 0;
        !           636:  #define RET   1
1.1       misho     637: -#endif
                    638: -      (void)close(fd);
                    639: -      fd = -1;
1.1.1.3 ! misho     640: -      ptr = CAST(uint32_t *, map->p);
1.1       misho     641: +
                    642: +      php_stream_close(stream);
                    643: +      stream = NULL;
                    644: +
                    645: +internal_loaded:
1.1.1.3 ! misho     646: +      ptr = (uint32_t *)(void *)map->p;
1.1       misho     647:        if (*ptr != MAGICNO) {
                    648:                if (swap4(*ptr) != MAGICNO) {
1.1.1.3 ! misho     649:                        file_error(ms, 0, "bad magic in `%s'", dbname);
        !           650: @@ -2620,17 +2674,29 @@
1.1       misho     651:        else
                    652:                version = ptr[1];
                    653:        if (version != VERSIONNO) {
1.1.1.2   misho     654: -              file_error(ms, 0, "File %s supports only version %d magic "
                    655: -                  "files. `%s' is version %d", VERSION,
                    656: +              file_error(ms, 0, "File %d.%d supports only version %d magic "
                    657: +                  "files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel,
1.1       misho     658:                    VERSIONNO, dbname, version);
1.1.1.3 ! misho     659:                goto error;
1.1       misho     660:        }
1.1.1.3 ! misho     661: -      entries = (uint32_t)(st.st_size / sizeof(struct magic));
        !           662: -      if ((off_t)(entries * sizeof(struct magic)) != st.st_size) {
        !           663: -              file_error(ms, 0, "Size of `%s' %llu is not a multiple of %zu",
        !           664: -                  dbname, (unsigned long long)st.st_size,
        !           665: -                  sizeof(struct magic));
        !           666: -              goto error;
1.1       misho     667: +
                    668: +      /* php_magic_database is a const, performing writes will segfault. This is for big-endian
                    669: +      machines only, PPC and Sparc specifically. Consider static variable or MINIT in
                    670: +      future. */
                    671: +      if (needsbyteswap && fn == NULL) {
1.1.1.3 ! misho     672: +              map->p = emalloc(sizeof(php_magic_database));
        !           673: +              map->p = memcpy(map->p, php_magic_database, sizeof(php_magic_database));
1.1       misho     674: +      }
                    675: +
1.1.1.3 ! misho     676: +      if (NULL != fn) {
        !           677: +              nentries = (uint32_t)(st.sb.st_size / sizeof(struct magic));
        !           678: +              entries = (uint32_t)(st.sb.st_size / sizeof(struct magic));
        !           679: +              if ((off_t)(entries * sizeof(struct magic)) != st.sb.st_size) {
        !           680: +                      file_error(ms, 0, "Size of `%s' %llu is not a multiple of %zu",
        !           681: +                              dbname, (unsigned long long)st.sb.st_size,
        !           682: +                              sizeof(struct magic));
        !           683: +                      goto error;
        !           684: +              }
        !           685:        }
        !           686:        map->magic[0] = CAST(struct magic *, map->p) + 1;
        !           687:        nentries = 0;
        !           688: @@ -2643,22 +2709,29 @@
        !           689:                        map->magic[i + 1] = map->magic[i] + map->nmagic[i];
        !           690:                nentries += map->nmagic[i];
        !           691:        }
        !           692: -      if (entries != nentries + 1) {
        !           693: +      if (NULL != fn && entries != nentries + 1) {
        !           694:                file_error(ms, 0, "Inconsistent entries in `%s' %u != %u",
        !           695:                    dbname, entries, nentries + 1);
        !           696:                goto error;
        !           697:        }
        !           698: +
        !           699:        if (needsbyteswap)
        !           700:                for (i = 0; i < MAGIC_SETS; i++)
        !           701:                        byteswap(map->magic[i], map->nmagic[i]);
1.1       misho     702: -      free(dbname);
                    703: +
                    704: +      if (dbname) {
                    705: +              efree(dbname);
                    706: +      }
1.1.1.3 ! misho     707:        return map;
1.1       misho     708:  
1.1.1.3 ! misho     709:  error:
1.1       misho     710: -      if (fd != -1)
                    711: -              (void)close(fd);
                    712: +      if (stream) {
                    713: +              php_stream_close(stream);
                    714: +      }
1.1.1.3 ! misho     715:        apprentice_unmap(map);
1.1       misho     716: -      free(dbname);
                    717: +      if (dbname) {
                    718: +              efree(dbname);
                    719: +      }
1.1.1.3 ! misho     720:        return NULL;
1.1       misho     721:  }
                    722:  
1.1.1.3 ! misho     723: @@ -2679,14 +2752,23 @@
1.1       misho     724:        char *dbname;
                    725:        int rv = -1;
1.1.1.3 ! misho     726:        uint32_t i;
1.1       misho     727: +      php_stream *stream;
1.1.1.3 ! misho     728: +
        !           729: +      TSRMLS_FETCH();
1.1       misho     730:  
                    731: -      dbname = mkdbname(ms, fn, 1);
1.1.1.2   misho     732: +      dbname = mkdbname(ms, fn, 0);
                    733:  
                    734:        if (dbname == NULL) 
1.1       misho     735:                goto out;
                    736:  
1.1.1.3 ! misho     737: -      if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1) 
        !           738: -      {
1.1       misho     739: +/* wb+ == O_WRONLY|O_CREAT|O_TRUNC|O_BINARY */
                    740: +#if PHP_API_VERSION < 20100412
                    741: +      stream = php_stream_open_wrapper((char *)fn, "wb+", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
                    742: +#else
                    743: +      stream = php_stream_open_wrapper((char *)fn, "wb+", REPORT_ERRORS, NULL);
                    744: +#endif
                    745: +
                    746: +      if (!stream) {
                    747:                file_error(ms, errno, "cannot open `%s'", dbname);
                    748:                goto out;
                    749:        }
1.1.1.3 ! misho     750: @@ -2696,31 +2778,33 @@
        !           751:                goto out;
        !           752:        }
1.1       misho     753:  
1.1.1.3 ! misho     754: -      if (write(fd, map->nmagic, nm) != (ssize_t)nm) {
        !           755: +      if (php_stream_write(stream, (const char *)map->nmagic, nm) != (ssize_t)nm) {
1.1       misho     756:                file_error(ms, errno, "error writing `%s'", dbname);
                    757:                goto out;
                    758:        }
                    759:  
1.1.1.3 ! misho     760:        assert(nm + sizeof(ar) < m);
        !           761:  
        !           762: -      if (lseek(fd, (off_t)m, SEEK_SET) != (off_t)m) {
1.1       misho     763: +      if (php_stream_seek(stream,(off_t)sizeof(struct magic), SEEK_SET) != sizeof(struct magic)) {
                    764:                file_error(ms, errno, "error seeking `%s'", dbname);
                    765:                goto out;
                    766:        }
                    767:  
1.1.1.3 ! misho     768:        for (i = 0; i < MAGIC_SETS; i++) {
        !           769:                len = m * map->nmagic[i];
        !           770: -              if (write(fd, map->magic[i], len) != (ssize_t)len) {
        !           771: +              if (php_stream_write(stream, (const char *)map->magic[i], len) != (ssize_t)len) {
        !           772:                        file_error(ms, errno, "error writing `%s'", dbname);
        !           773:                        goto out;
        !           774:                }
1.1       misho     775:        }
                    776:  
1.1.1.2   misho     777: -      if (fd != -1)
                    778: -              (void)close(fd);
1.1.1.3 ! misho     779: +      if (stream) {
        !           780: +              php_stream_close(stream);
        !           781: +      }
1.1       misho     782: +
                    783:        rv = 0;
                    784:  out:
                    785: -      free(dbname);
                    786: +      efree(dbname);
                    787:        return rv;
                    788:  }
                    789:  
1.1.1.3 ! misho     790: @@ -2733,6 +2817,7 @@
1.1       misho     791:  {
                    792:        const char *p, *q;
                    793:        char *buf;
                    794: +      TSRMLS_FETCH();
                    795:  
                    796:        if (strip) {
                    797:                if ((p = strrchr(fn, '/')) != NULL)
1.1.1.3 ! misho     798: @@ -2754,16 +2839,18 @@
1.1       misho     799:        q++;
                    800:        /* Compatibility with old code that looked in .mime */
                    801:        if (ms->flags & MAGIC_MIME) {
1.1.1.3 ! misho     802: -              if (asprintf(&buf, "%.*s.mime%s", (int)(q - fn), fn, ext) < 0)
        !           803: -                      return NULL;
1.1       misho     804: -              if (access(buf, R_OK) != -1) {
                    805: +              spprintf(&buf, MAXPATHLEN, "%.*s.mime%s", (int)(q - fn), fn, ext);
1.1.1.3 ! misho     806: +#ifdef PHP_WIN32
        !           807: +              if (VCWD_ACCESS(buf, R_OK) == 0) {
        !           808: +#else
1.1       misho     809: +              if (VCWD_ACCESS(buf, R_OK) != -1) {
1.1.1.3 ! misho     810: +#endif
1.1       misho     811:                        ms->flags &= MAGIC_MIME_TYPE;
                    812:                        return buf;
                    813:                }
                    814: -              free(buf);
                    815: +              efree(buf);
                    816:        }
1.1.1.3 ! misho     817: -      if (asprintf(&buf, "%.*s%s", (int)(q - fn), fn, ext) < 0)
        !           818: -              return NULL;
1.1       misho     819: +      spprintf(&buf, MAXPATHLEN, "%.*s%s", (int)(q - fn), fn, ext);
                    820:  
                    821:        /* Compatibility with old code that looked in .mime */
                    822:        if (strstr(p, ".mime") != NULL)
1.1.1.3 ! misho     823: @@ -2853,7 +2940,7 @@
1.1       misho     824:        m->offset = swap4((uint32_t)m->offset);
                    825:        m->in_offset = swap4((uint32_t)m->in_offset);
                    826:        m->lineno = swap4((uint32_t)m->lineno);
                    827: -      if (IS_STRING(m->type)) {
                    828: +      if (IS_LIBMAGIC_STRING(m->type)) {
                    829:                m->str_range = swap4(m->str_range);
                    830:                m->str_flags = swap4(m->str_flags);
                    831:        }
                    832: diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
1.1.1.3 ! misho     833: --- libmagic.orig/ascmagic.c   2012-10-31 18:03:01.000000000 +0100
        !           834: +++ libmagic/ascmagic.c        2013-04-08 15:42:57.328298809 +0200
        !           835: @@ -139,7 +139,7 @@
1.1.1.2   misho     836:                /* malloc size is a conservative overestimate; could be
                    837:                   improved, or at least realloced after conversion. */
                    838:                mlen = ulen * 6;
                    839: -              if ((utf8_buf = CAST(unsigned char *, malloc(mlen))) == NULL) {
1.1.1.3 ! misho     840: +              if ((utf8_buf = CAST(unsigned char *, emalloc(mlen))) == NULL) {
        !           841:                        file_oomem(ms, mlen);
1.1.1.2   misho     842:                        goto done;
1.1.1.3 ! misho     843:                }
        !           844: @@ -211,6 +211,7 @@
        !           845:                                case 0:
        !           846:                                        if (file_printf(ms, ", ") == -1)
        !           847:                                                goto done;
        !           848: +                                      break;
        !           849:                                case -1:
        !           850:                                        goto done;
        !           851:                                default:
        !           852: @@ -296,7 +297,8 @@
1.1.1.2   misho     853:        }
1.1       misho     854:        rv = 1;
                    855:  done:
1.1.1.2   misho     856: -      free(utf8_buf);
                    857: +      if (utf8_buf)
1.1       misho     858: +              efree(utf8_buf);
                    859:  
                    860:        return rv;
                    861:  }
                    862: diff -u libmagic.orig/cdf.c libmagic/cdf.c
1.1.1.3 ! misho     863: --- libmagic.orig/cdf.c        2013-03-21 18:45:14.000000000 +0100
        !           864: +++ libmagic/cdf.c     2013-04-08 15:42:57.328298809 +0200
1.1.1.2   misho     865: @@ -43,7 +43,17 @@
1.1       misho     866:  #include <err.h>
                    867:  #endif
                    868:  #include <stdlib.h>
                    869: +
                    870: +#ifdef PHP_WIN32
                    871: +#include "win32/unistd.h"
                    872: +#else
                    873:  #include <unistd.h>
                    874: +#endif
                    875: +
                    876: +#ifndef UINT32_MAX
                    877: +# define UINT32_MAX (0xffffffff)
                    878: +#endif
                    879: +
                    880:  #include <string.h>
                    881:  #include <time.h>
                    882:  #include <ctype.h>
1.1.1.3 ! misho     883: @@ -296,7 +306,10 @@
        !           884:        if (info->i_fd == -1)
        !           885:                return -1;
        !           886:  
        !           887: -      if (pread(info->i_fd, buf, len, off) != (ssize_t)len)
        !           888: +      if (FINFO_LSEEK_FUNC(info->i_fd, off, SEEK_SET) == (off_t)-1)
        !           889: +              return -1;
        !           890: +
        !           891: +      if (FINFO_READ_FUNC(info->i_fd, buf, len) != (ssize_t)len)
        !           892:                return -1;
        !           893:  
        !           894:        return (ssize_t)len;
        !           895: @@ -1132,7 +1145,7 @@
1.1       misho     896:        cdf_directory_t *d;
                    897:        char name[__arraycount(d->d_name)];
                    898:        cdf_stream_t scn;
                    899: -      struct timespec ts;
                    900: +      struct timeval ts;
                    901:  
                    902:        static const char *types[] = { "empty", "user storage",
                    903:            "user stream", "lockbytes", "property", "root storage" };
1.1.1.3 ! misho     904: @@ -1185,7 +1198,7 @@
1.1       misho     905:  cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
                    906:  {
                    907:        cdf_timestamp_t tp;
                    908: -      struct timespec ts;
                    909: +      struct timeval ts;
                    910:        char buf[64];
1.1.1.2   misho     911:        size_t i, j;
1.1       misho     912:  
1.1.1.3 ! misho     913: @@ -1229,7 +1242,11 @@
1.1       misho     914:                        break;
                    915:                case CDF_FILETIME:
                    916:                        tp = info[i].pi_tp;
                    917: +#if defined(PHP_WIN32) && _MSC_VER <= 1500
                    918: +              if (tp < 1000000000000000i64) {
                    919: +#else
                    920:                        if (tp < 1000000000000000LL) {
                    921: +#endif
                    922:                                cdf_print_elapsed_time(buf, sizeof(buf), tp);
                    923:                                (void)fprintf(stderr, "timestamp %s\n", buf);
                    924:                        } else {
                    925: diff -u libmagic.orig/cdf.h libmagic/cdf.h
1.1.1.3 ! misho     926: --- libmagic.orig/cdf.h        2012-10-31 18:03:01.000000000 +0100
        !           927: +++ libmagic/cdf.h     2013-04-08 15:42:57.328298809 +0200
        !           928: @@ -35,10 +35,12 @@
1.1.1.2   misho     929:  #ifndef _H_CDF_
                    930:  #define _H_CDF_
                    931:  
                    932: -#ifdef WIN32
                    933: +#ifdef PHP_WIN32
                    934:  #include <winsock2.h>
                    935:  #define timespec timeval
                    936:  #define tv_nsec tv_usec
1.1.1.3 ! misho     937: +#define asctime_r php_asctime_r
        !           938: +#define ctime_r php_ctime_r
        !           939:  #endif
        !           940:  #ifdef __DJGPP__
        !           941:  #define timespec timeval
        !           942: @@ -57,7 +59,11 @@
1.1       misho     943:  
                    944:  typedef struct {
                    945:        uint64_t        h_magic;
                    946: -#define CDF_MAGIC     0xE11AB1A1E011CFD0LL
                    947: +#if defined(PHP_WIN32) && _MSC_VER <= 1500
                    948: +# define CDF_MAGIC    0xE11AB1A1E011CFD0i64
                    949: +#else
                    950: +# define CDF_MAGIC    0xE11AB1A1E011CFD0LL
                    951: +#endif
                    952:        uint64_t        h_uuid[2];
                    953:        uint16_t        h_revision;
                    954:        uint16_t        h_version;
1.1.1.3 ! misho     955: @@ -267,9 +273,9 @@
1.1       misho     956:        size_t i_len;
                    957:  } cdf_info_t;
                    958:  
                    959: -struct timespec;
                    960: -int cdf_timestamp_to_timespec(struct timespec *, cdf_timestamp_t);
                    961: -int cdf_timespec_to_timestamp(cdf_timestamp_t *, const struct timespec *);
                    962: +struct timeval;
                    963: +int cdf_timestamp_to_timespec(struct timeval *, cdf_timestamp_t);
                    964: +int cdf_timespec_to_timestamp(cdf_timestamp_t *, const struct timeval *);
                    965:  int cdf_read_header(const cdf_info_t *, cdf_header_t *);
                    966:  void cdf_swap_header(cdf_header_t *);
                    967:  void cdf_unpack_header(cdf_header_t *, char *);
                    968: diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
1.1.1.3 ! misho     969: --- libmagic.orig/cdf_time.c   2012-10-31 18:03:01.000000000 +0100
        !           970: +++ libmagic/cdf_time.c        2013-04-08 15:42:57.328298809 +0200
1.1       misho     971: @@ -96,7 +96,7 @@
                    972:  }
                    973:  
                    974:  int
                    975: -cdf_timestamp_to_timespec(struct timespec *ts, cdf_timestamp_t t)
                    976: +cdf_timestamp_to_timespec(struct timeval *ts, cdf_timestamp_t t)
                    977:  {
                    978:        struct tm tm;
                    979:  #ifdef HAVE_STRUCT_TM_TM_ZONE
1.1.1.3 ! misho     980: @@ -104,8 +104,9 @@
1.1       misho     981:  #endif
                    982:        int rdays;
                    983:  
                    984: -      /* Unit is 100's of nanoseconds */
                    985: -      ts->tv_nsec = (t % CDF_TIME_PREC) * 100;
1.1.1.3 ! misho     986: +      /* XXX 5.14 at least introdced 100 ns intervals, this is to do */
1.1       misho     987: +      /* Time interval, in microseconds */
                    988: +      ts->tv_usec = (t % CDF_TIME_PREC) * CDF_TIME_PREC;
                    989:  
                    990:        t /= CDF_TIME_PREC;
1.1.1.2   misho     991:        tm.tm_sec = (int)(t % 60);
1.1.1.3 ! misho     992: @@ -117,7 +118,7 @@
1.1.1.2   misho     993:        tm.tm_hour = (int)(t % 24);
1.1       misho     994:        t /= 24;
                    995:  
                    996: -      // XXX: Approx
                    997: +      /* XXX: Approx */
1.1.1.2   misho     998:        tm.tm_year = (int)(CDF_BASE_YEAR + (t / 365));
1.1       misho     999:  
                   1000:        rdays = cdf_getdays(tm.tm_year);
1.1.1.3 ! misho    1001: @@ -144,7 +145,7 @@
1.1       misho    1002:  
                   1003:  int
1.1.1.2   misho    1004:  /*ARGSUSED*/
1.1       misho    1005: -cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timespec *ts)
                   1006: +cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timeval *ts)
                   1007:  {
1.1.1.2   misho    1008:  #ifndef __lint__
1.1       misho    1009:        (void)&t;
1.1.1.3 ! misho    1010: @@ -156,7 +157,7 @@
1.1       misho    1011:                errno = EINVAL;
                   1012:                return -1;
                   1013:        }
                   1014: -      *t = (ts->ts_nsec / 100) * CDF_TIME_PREC;
                   1015: +      *t = (ts->ts_usec / CDF_TIME_PREC) * CDF_TIME_PREC;
                   1016:        *t = tm.tm_sec;
                   1017:        *t += tm.tm_min * 60;
                   1018:        *t += tm.tm_hour * 60 * 60;
1.1.1.3 ! misho    1019: @@ -180,7 +181,7 @@
1.1       misho    1020:  int
                   1021:  main(int argc, char *argv[])
                   1022:  {
                   1023: -      struct timespec ts;
                   1024: +      struct timeval ts;
1.1.1.3 ! misho    1025:        char buf[25];
1.1       misho    1026:        static const cdf_timestamp_t tst = 0x01A5E403C2D59C00ULL;
                   1027:        static const char *ref = "Sat Apr 23 01:30:00 1977";
                   1028: diff -u libmagic.orig/compress.c libmagic/compress.c
1.1.1.3 ! misho    1029: --- libmagic.orig/compress.c   2013-01-06 21:35:43.000000000 +0100
        !          1030: +++ libmagic/compress.c        2013-04-08 15:42:57.328298809 +0200
1.1       misho    1031: @@ -32,6 +32,7 @@
                   1032:   *    uncompress(method, old, n, newch) - uncompress old into new, 
                   1033:   *                                        using method, return sizeof new
                   1034:   */
                   1035: +#include "config.h"
                   1036:  #include "file.h"
                   1037:  
                   1038:  #ifndef lint
1.1.1.2   misho    1039: @@ -45,7 +46,8 @@
1.1       misho    1040:  #endif
                   1041:  #include <string.h>
                   1042:  #include <errno.h>
1.1.1.2   misho    1043: -#ifndef __MINGW32__
1.1       misho    1044: +#include <sys/types.h>
                   1045: +#ifndef PHP_WIN32
                   1046:  #include <sys/ioctl.h>
                   1047:  #endif
1.1.1.2   misho    1048:  #ifdef HAVE_SYS_WAIT_H
                   1049: @@ -59,6 +61,9 @@
1.1       misho    1050:  #include <zlib.h>
                   1051:  #endif
                   1052:  
                   1053: +#undef FIONREAD
                   1054: +
                   1055: +
                   1056:  private const struct {
                   1057:        const char magic[8];
                   1058:        size_t maglen;
1.1.1.2   misho    1059: @@ -85,8 +90,7 @@
1.1       misho    1060:  #define NODATA ((size_t)~0)
                   1061:  
                   1062:  private ssize_t swrite(int, const void *, size_t);
1.1.1.2   misho    1063: -#if HAVE_FORK
                   1064: -private size_t ncompr = sizeof(compr) / sizeof(compr[0]);
1.1       misho    1065: +#ifdef PHP_FILEINFO_UNCOMPRESS
                   1066:  private size_t uncompressbuf(struct magic_set *, int, size_t,
                   1067:      const unsigned char *, unsigned char **, size_t);
                   1068:  #ifdef BUILTIN_DECOMPRESS
1.1.1.2   misho    1069: @@ -102,10 +106,13 @@
1.1       misho    1070:        size_t i, nsz;
                   1071:        int rv = 0;
                   1072:        int mime = ms->flags & MAGIC_MIME;
                   1073: +      size_t ncompr;
                   1074:  
                   1075:        if ((ms->flags & MAGIC_COMPRESS) == 0)
                   1076:                return 0;
                   1077:  
                   1078: +      ncompr = sizeof(compr) / sizeof(compr[0]);
                   1079: +
                   1080:        for (i = 0; i < ncompr; i++) {
                   1081:                if (nbytes < compr[i].maglen)
                   1082:                        continue;
1.1.1.2   misho    1083: @@ -134,7 +141,8 @@
                   1084:                }
1.1       misho    1085:        }
                   1086:  error:
1.1.1.2   misho    1087: -      free(newbuf);
                   1088: +      if (newbuf)
1.1       misho    1089: +              efree(newbuf);
                   1090:        ms->flags |= MAGIC_COMPRESS;
                   1091:        return rv;
                   1092:  }
1.1.1.3 ! misho    1093: @@ -168,7 +176,7 @@
1.1.1.2   misho    1094:   * `safe' read for sockets and pipes.
                   1095:   */
1.1       misho    1096:  protected ssize_t
1.1.1.3 ! misho    1097: -sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
1.1.1.2   misho    1098: +sread(int fd, void *buf, size_t n, int canbepipe)
1.1       misho    1099:  {
1.1.1.2   misho    1100:        ssize_t rv;
1.1       misho    1101:  #ifdef FIONREAD
1.1.1.3 ! misho    1102: @@ -216,7 +224,7 @@
        !          1103:  
        !          1104:  nocheck:
        !          1105:        do
        !          1106: -              switch ((rv = read(fd, buf, n))) {
        !          1107: +              switch ((rv = FINFO_READ_FUNC(fd, buf, n))) {
        !          1108:                case -1:
        !          1109:                        if (errno == EINTR)
        !          1110:                                continue;
        !          1111: @@ -293,13 +301,14 @@
        !          1112:                return -1;
        !          1113:        }
        !          1114:        (void)close(tfd);
        !          1115: -      if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) {
        !          1116: +      if (FINFO_LSEEK_FUNC(fd, (off_t)0, SEEK_SET) == (off_t)-1) {
        !          1117:                file_badseek(ms);
        !          1118:                return -1;
1.1.1.2   misho    1119:        }
1.1       misho    1120:        return fd;
                   1121:  }
1.1.1.2   misho    1122: -#if HAVE_FORK
                   1123: +
1.1       misho    1124: +#ifdef PHP_FILEINFO_UNCOMPRESS
                   1125:  #ifdef BUILTIN_DECOMPRESS
                   1126:  
                   1127:  #define FHCRC         (1 << 1)
1.1.1.3 ! misho    1128: @@ -336,7 +345,7 @@
1.1       misho    1129:  
                   1130:        if (data_start >= n)
                   1131:                return 0;
                   1132: -      if ((*newch = CAST(unsigned char *, malloc(HOWMANY + 1))) == NULL) {
1.1.1.3 ! misho    1133: +      if ((*newch = CAST(unsigned char *, emalloc(HOWMANY + 1))) == NULL) {
        !          1134:                return 0;
        !          1135:        }
1.1       misho    1136:        
1.1.1.3 ! misho    1137: @@ -397,19 +406,16 @@
        !          1138:        case 0: /* child */
        !          1139:                (void) close(0);
        !          1140:                if (fd != -1) {
        !          1141: -                  if (dup(fd) == -1)
        !          1142: -                      _exit(1);
        !          1143: -                  (void) lseek(0, (off_t)0, SEEK_SET);
        !          1144: +                  (void) dup(fd);
        !          1145: +                  (void) FINFO_LSEEK_FUNC(0, (off_t)0, SEEK_SET);
        !          1146:                } else {
        !          1147: -                  if (dup(fdin[0]) == -1)
        !          1148: -                      _exit(1);
        !          1149: +                  (void) dup(fdin[0]);
        !          1150:                    (void) close(fdin[0]);
        !          1151:                    (void) close(fdin[1]);
        !          1152:                }
        !          1153:  
        !          1154:                (void) close(1);
        !          1155: -              if (dup(fdout[1]) == -1)
        !          1156: -                      _exit(1);
        !          1157: +              (void) dup(fdout[1]);
        !          1158:                (void) close(fdout[0]);
        !          1159:                (void) close(fdout[1]);
        !          1160:  #ifndef DEBUG
        !          1161: @@ -466,20 +472,14 @@
1.1       misho    1162:                        fdin[1] = -1;
                   1163:                }
                   1164:  
                   1165: -              if ((*newch = (unsigned char *) malloc(HOWMANY + 1)) == NULL) {
                   1166: -#ifdef DEBUG
                   1167: -                      (void)fprintf(stderr, "Malloc failed (%s)\n",
                   1168: -                          strerror(errno));
                   1169: -#endif
                   1170: -                      n = 0;
                   1171: -                      goto err;
                   1172: -              }
                   1173: +              *newch = (unsigned char *) emalloc(HOWMANY + 1);
                   1174: +
                   1175:                if ((r = sread(fdout[0], *newch, HOWMANY, 0)) <= 0) {
                   1176:  #ifdef DEBUG
                   1177:                        (void)fprintf(stderr, "Read failed (%s)\n",
                   1178:                            strerror(errno));
                   1179:  #endif
                   1180: -                      free(*newch);
                   1181: +                      efree(*newch);
                   1182:                        n = 0;
                   1183:                        newch[0] = '\0';
                   1184:                        goto err;
1.1.1.3 ! misho    1185: @@ -503,4 +503,4 @@
1.1       misho    1186:                return n;
                   1187:        }
                   1188:  }
1.1.1.2   misho    1189: -#endif
1.1       misho    1190: +#endif /* if PHP_FILEINFO_UNCOMPRESS */
                   1191: diff -u libmagic.orig/file.h libmagic/file.h
1.1.1.3 ! misho    1192: --- libmagic.orig/file.h       2013-02-18 16:40:59.000000000 +0100
        !          1193: +++ libmagic/file.h    2013-04-08 15:42:57.328298809 +0200
1.1.1.2   misho    1194: @@ -33,11 +33,9 @@
1.1       misho    1195:  #ifndef __file_h__
                   1196:  #define __file_h__
                   1197:  
                   1198: -#ifdef HAVE_CONFIG_H
                   1199: -#include <config.h>
                   1200: -#endif
                   1201: +#include "config.h"
                   1202:  
1.1.1.2   misho    1203: -#ifdef WIN32
                   1204: +#ifdef PHP_WIN32
                   1205:    #ifdef _WIN64
                   1206:      #define SIZE_T_FORMAT "I64"
                   1207:    #else
1.1.1.3 ! misho    1208: @@ -61,10 +59,20 @@
1.1       misho    1209:  #ifdef HAVE_INTTYPES_H
                   1210:  #include <inttypes.h>
                   1211:  #endif
                   1212: -#include <regex.h>
1.1.1.3 ! misho    1213: -#include <time.h>
1.1       misho    1214: +#ifdef PHP_WIN32
                   1215: +#include "win32/php_stdint.h"
                   1216: +#endif
                   1217: +
                   1218: +#include "php.h"
                   1219: +#include "ext/standard/php_string.h"
                   1220: +#include "ext/pcre/php_pcre.h"
                   1221: +
                   1222:  #include <sys/types.h>
                   1223: +#ifdef PHP_WIN32
                   1224: +#include "win32/param.h"
                   1225: +#else
                   1226:  #include <sys/param.h>
                   1227: +#endif
                   1228:  /* Do this here and now, because struct stat gets re-defined on solaris */
                   1229:  #include <sys/stat.h>
                   1230:  #include <stdarg.h>
1.1.1.3 ! misho    1231: @@ -75,7 +83,7 @@
1.1       misho    1232:  #define MAGIC "/etc/magic"
                   1233:  #endif
                   1234:  
1.1.1.2   misho    1235: -#if defined(__EMX__) || defined (WIN32)
1.1       misho    1236: +#if defined(__EMX__) || defined(PHP_WIN32)
                   1237:  #define PATHSEP       ';'
                   1238:  #else
                   1239:  #define PATHSEP       ':'
1.1.1.3 ! misho    1240: @@ -109,12 +117,6 @@
1.1       misho    1241:  #endif
                   1242:  #endif
                   1243:  
                   1244: -#ifndef __GNUC__
                   1245: -#ifndef __attribute__
                   1246: -#define __attribute__(a)
                   1247: -#endif
                   1248: -#endif
                   1249: -
                   1250:  #ifndef MIN
                   1251:  #define       MIN(a,b)        (((a) < (b)) ? (a) : (b))
                   1252:  #endif
1.1.1.3 ! misho    1253: @@ -224,7 +226,7 @@
        !          1254:  #define                               FILE_USE        46
        !          1255:  #define                               FILE_NAMES_SIZE 47 /* size of array to contain all names */
1.1       misho    1256:  
                   1257: -#define IS_STRING(t) \
                   1258: +#define IS_LIBMAGIC_STRING(t) \
                   1259:        ((t) == FILE_STRING || \
                   1260:         (t) == FILE_PSTRING || \
                   1261:         (t) == FILE_BESTRING16 || \
1.1.1.3 ! misho    1262: @@ -248,7 +250,7 @@
1.1       misho    1263:  #ifdef ENABLE_CONDITIONALS
                   1264:        uint8_t cond;           /* conditional type */
                   1265:  #else
                   1266: -      uint8_t dummy;
                   1267: +      uint8_t dummy;  
                   1268:  #endif
                   1269:        uint8_t factor_op;
                   1270:  #define               FILE_FACTOR_OP_PLUS     '+'
1.1.1.3 ! misho    1271: @@ -347,7 +349,7 @@
        !          1272:  /* list of magic entries */
        !          1273:  struct mlist {
        !          1274:        struct magic *magic;            /* array of magic entries */
        !          1275: -      uint32_t nmagic;                /* number of entries in array */
        !          1276: +      uint32_t nmagic;                        /* number of entries in array */
        !          1277:        void *map;                      /* internal resources used by entry */
        !          1278:        struct mlist *next, *prev;
        !          1279:  };
        !          1280: @@ -411,21 +413,18 @@
        !          1281:  protected const char *file_fmttime(uint64_t, int, char *);
        !          1282:  protected struct magic_set *file_ms_alloc(int);
        !          1283:  protected void file_ms_free(struct magic_set *);
1.1       misho    1284: -protected int file_buffer(struct magic_set *, int, const char *, const void *,
                   1285: +protected int file_buffer(struct magic_set *, php_stream *, const char *, const void *,
                   1286:      size_t);
                   1287: -protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
1.1.1.3 ! misho    1288: +protected int file_fsmagic(struct magic_set *, const char *, struct stat *, php_stream *);
1.1       misho    1289:  protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
                   1290: -protected int file_vprintf(struct magic_set *, const char *, va_list);
1.1.1.2   misho    1291: -protected size_t file_printedlen(const struct magic_set *);
                   1292:  protected int file_replace(struct magic_set *, const char *, const char *);
1.1       misho    1293: -protected int file_printf(struct magic_set *, const char *, ...)
                   1294: -    __attribute__((__format__(__printf__, 2, 3)));
                   1295: +protected int file_printf(struct magic_set *, const char *, ...);
                   1296:  protected int file_reset(struct magic_set *);
                   1297:  protected int file_tryelf(struct magic_set *, int, const unsigned char *,
                   1298:      size_t);
                   1299:  protected int file_trycdf(struct magic_set *, int, const unsigned char *,
                   1300:      size_t);
1.1.1.2   misho    1301: -#if HAVE_FORK
1.1       misho    1302: +#ifdef PHP_FILEINFO_UNCOMPRESS 
                   1303:  protected int file_zmagic(struct magic_set *, int, const char *,
                   1304:      const unsigned char *, size_t);
1.1.1.2   misho    1305:  #endif
1.1.1.3 ! misho    1306: @@ -443,16 +442,13 @@
        !          1307:  protected int file_magicfind(struct magic_set *, const char *, struct mlist *);
        !          1308:  protected uint64_t file_signextend(struct magic_set *, struct magic *,
        !          1309:      uint64_t);
        !          1310: +protected void file_delmagic(struct magic *, int type, size_t entries);
1.1       misho    1311:  protected void file_badread(struct magic_set *);
                   1312:  protected void file_badseek(struct magic_set *);
                   1313:  protected void file_oomem(struct magic_set *, size_t);
                   1314: -protected void file_error(struct magic_set *, int, const char *, ...)
                   1315: -    __attribute__((__format__(__printf__, 3, 4)));
                   1316: -protected void file_magerror(struct magic_set *, const char *, ...)
                   1317: -    __attribute__((__format__(__printf__, 2, 3)));
                   1318: -protected void file_magwarn(struct magic_set *, const char *, ...)
                   1319: -    __attribute__((__format__(__printf__, 2, 3)));
                   1320: -protected void file_mdump(struct magic *);
                   1321: +protected void file_error(struct magic_set *, int, const char *, ...);
                   1322: +protected void file_magerror(struct magic_set *, const char *, ...);
                   1323: +protected void file_magwarn(struct magic_set *, const char *, ...);
                   1324:  protected void file_showstr(FILE *, const char *, size_t);
                   1325:  protected size_t file_mbswidth(const char *);
                   1326:  protected const char *file_getbuffer(struct magic_set *);
1.1.1.3 ! misho    1327: @@ -462,16 +458,14 @@
        !          1328:      size_t *);
        !          1329:  protected size_t file_pstring_length_size(const struct magic *);
        !          1330:  protected size_t file_pstring_get_length(const struct magic *, const char *);
        !          1331: +protected size_t file_printedlen(const struct magic_set *ms);
        !          1332:  #ifdef __EMX__
        !          1333:  protected int file_os2_apptype(struct magic_set *, const char *, const void *,
1.1       misho    1334:      size_t);
                   1335:  #endif /* __EMX__ */
                   1336:  
                   1337: -
                   1338: -#ifndef COMPILE_ONLY
                   1339:  extern const char *file_names[];
                   1340:  extern const size_t file_nnames;
                   1341: -#endif
                   1342:  
                   1343:  #ifndef HAVE_STRERROR
                   1344:  extern int sys_nerr;
1.1.1.3 ! misho    1345: @@ -484,32 +478,16 @@
1.1       misho    1346:  #define strtoul(a, b, c)      strtol(a, b, c)
                   1347:  #endif
                   1348:  
1.1.1.3 ! misho    1349: -#ifndef HAVE_PREAD
        !          1350: -ssize_t pread(int, void *, size_t, off_t);
        !          1351: -#endif
1.1       misho    1352: -#ifndef HAVE_VASPRINTF
                   1353: -int vasprintf(char **, const char *, va_list);
                   1354: -#endif
                   1355: -#ifndef HAVE_ASPRINTF
                   1356: -int asprintf(char **ptr, const char *format_string, ...);
                   1357: -#endif
                   1358: -
                   1359: -#ifndef HAVE_STRLCPY
                   1360: +#ifndef strlcpy
                   1361:  size_t strlcpy(char *dst, const char *src, size_t siz);
                   1362:  #endif
                   1363: -#ifndef HAVE_STRLCAT
                   1364: +#ifndef strlcat
                   1365:  size_t strlcat(char *dst, const char *src, size_t siz);
                   1366:  #endif
1.1.1.2   misho    1367:  #ifndef HAVE_GETLINE
1.1.1.3 ! misho    1368:  ssize_t getline(char **dst, size_t *len, FILE *fp);
        !          1369:  ssize_t getdelim(char **dst, size_t *len, int delimiter, FILE *fp);
        !          1370:  #endif
        !          1371: -#ifndef HAVE_CTIME_R
        !          1372: -char   *ctime_r(const time_t *, char *);
        !          1373: -#endif
        !          1374: -#ifndef HAVE_ASCTIME_R
        !          1375: -char   *asctime_r(const struct tm *, char *);
        !          1376: -#endif
        !          1377:  
        !          1378:  #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
        !          1379:  #define QUICK
        !          1380: @@ -533,4 +511,12 @@
        !          1381:  #define FILE_RCSID(id)
        !          1382:  #endif
        !          1383:  
        !          1384: +#ifdef PHP_WIN32
        !          1385: +#define FINFO_LSEEK_FUNC _lseek
        !          1386: +#define FINFO_READ_FUNC _read
        !          1387: +#else
        !          1388: +#define FINFO_LSEEK_FUNC lseek
        !          1389: +#define FINFO_READ_FUNC read
        !          1390: +#endif
        !          1391: +
        !          1392:  #endif /* __file_h__ */
1.1       misho    1393: diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
1.1.1.3 ! misho    1394: --- libmagic.orig/fsmagic.c    2013-03-21 18:45:14.000000000 +0100
        !          1395: +++ libmagic/fsmagic.c 2013-04-08 15:42:57.328298809 +0200
1.1.1.2   misho    1396: @@ -59,27 +59,21 @@
                   1397:  # define minor(dev)  ((dev) & 0xff)
1.1       misho    1398:  #endif
                   1399:  #undef HAVE_MAJOR
1.1.1.2   misho    1400: -#ifdef        S_IFLNK
1.1       misho    1401: -private int
                   1402: -bad_link(struct magic_set *ms, int err, char *buf)
                   1403: -{
                   1404: -      int mime = ms->flags & MAGIC_MIME;
                   1405: -      if ((mime & MAGIC_MIME_TYPE) &&
1.1.1.2   misho    1406: -          file_printf(ms, "inode/symlink")
1.1       misho    1407: -          == -1)
                   1408: -              return -1;
                   1409: -      else if (!mime) {
                   1410: -              if (ms->flags & MAGIC_ERROR) {
1.1.1.2   misho    1411: -                      file_error(ms, err,
                   1412: -                                 "broken symbolic link to `%s'", buf);
1.1       misho    1413: -                      return -1;
                   1414: -              } 
1.1.1.2   misho    1415: -              if (file_printf(ms, "broken symbolic link to `%s'", buf) == -1)
1.1       misho    1416: -                      return -1;
                   1417: -      }
                   1418: -      return 1;
                   1419: -}
1.1.1.2   misho    1420: +
1.1       misho    1421: +#ifdef PHP_WIN32
                   1422: +
                   1423: +# undef S_IFIFO
1.1.1.3 ! misho    1424: +#endif
1.1       misho    1425: +
                   1426: +
                   1427: +#ifndef S_ISDIR
                   1428: +#define S_ISDIR(mode) ((mode) & _S_IFDIR)
                   1429: +#endif
                   1430: +
                   1431: +#ifndef S_ISREG
                   1432: +#define S_ISREG(mode) ((mode) & _S_IFREG)
1.1.1.3 ! misho    1433:  #endif
1.1.1.2   misho    1434: +
1.1       misho    1435:  private int
                   1436:  handle_mime(struct magic_set *ms, int mime, const char *str)
1.1.1.2   misho    1437:  {
1.1.1.3 ! misho    1438: @@ -96,49 +90,45 @@
1.1       misho    1439:  }
                   1440:  
                   1441:  protected int
                   1442: -file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
                   1443: +file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *stream)
                   1444:  {
1.1.1.3 ! misho    1445:        int ret, did = 0;
1.1       misho    1446:        int mime = ms->flags & MAGIC_MIME;
                   1447: -#ifdef        S_IFLNK
                   1448: -      char buf[BUFSIZ+4];
1.1.1.2   misho    1449: -      ssize_t nch;
1.1       misho    1450: -      struct stat tstatbuf;
                   1451: -#endif
                   1452: +      TSRMLS_FETCH();
                   1453:  
                   1454:        if (ms->flags & MAGIC_APPLE)
                   1455:                return 0;
                   1456: -      if (fn == NULL)
                   1457: +
1.1.1.3 ! misho    1458: +      if (fn == NULL && !stream) {
1.1       misho    1459:                return 0;
                   1460: +      }
                   1461:  
1.1.1.3 ! misho    1462:  #define COMMA (did++ ? ", " : "")
1.1       misho    1463: -      /*
                   1464: -       * Fstat is cheaper but fails for files you don't have read perms on.
                   1465: -       * On 4.2BSD and similar systems, use lstat() to identify symlinks.
                   1466: -       */
                   1467: -#ifdef        S_IFLNK
                   1468: -      if ((ms->flags & MAGIC_SYMLINK) == 0)
                   1469: -              ret = lstat(fn, sb);
                   1470: -      else
                   1471: -#endif
                   1472: -      ret = stat(fn, sb);     /* don't merge into if; see "ret =" above */
                   1473: -
                   1474: -      if (ret) {
                   1475: -              if (ms->flags & MAGIC_ERROR) {
                   1476: -                      file_error(ms, errno, "cannot stat `%s'", fn);
                   1477: -                      return -1;
1.1.1.3 ! misho    1478: +
1.1       misho    1479: +      if (stream) {
                   1480: +              php_stream_statbuf ssb;
                   1481: +              if (php_stream_stat(stream, &ssb) < 0) {
                   1482: +                      if (ms->flags & MAGIC_ERROR) {
                   1483: +                              file_error(ms, errno, "cannot stat `%s'", fn);
                   1484: +                              return -1;
                   1485: +                      }
                   1486: +                      return 1;
                   1487: +              }
                   1488: +              memcpy(sb, &ssb.sb, sizeof(struct stat));
                   1489: +      } else {
                   1490: +              if (php_sys_stat(fn, sb) != 0) {
                   1491: +                      if (ms->flags & MAGIC_ERROR) {
                   1492: +                              file_error(ms, errno, "cannot stat `%s'", fn);
                   1493: +                              return -1;
                   1494: +                      }
                   1495: +                      return 1;
                   1496:                }
                   1497: -              if (file_printf(ms, "cannot open `%s' (%s)",
                   1498: -                  fn, strerror(errno)) == -1)
                   1499: -                      return -1;
1.1.1.2   misho    1500: -              ms->event_flags |= EVENT_HAD_ERR;
                   1501: -              return -1;
1.1       misho    1502:        }
                   1503:  
1.1.1.3 ! misho    1504:        ret = 1;
1.1       misho    1505:        if (!mime) {
1.1.1.3 ! misho    1506:  #ifdef S_ISUID
        !          1507: -              if (sb->st_mode & S_ISUID)
        !          1508: +              if (sb->st_mode & S_ISUID) 
        !          1509:                        if (file_printf(ms, "%ssetuid", COMMA) == -1)
        !          1510:                                return -1;
        !          1511:  #endif
        !          1512: @@ -155,82 +145,43 @@
1.1       misho    1513:        }
1.1.1.2   misho    1514:        
1.1       misho    1515:        switch (sb->st_mode & S_IFMT) {
                   1516: -      case S_IFDIR:
                   1517: -              if (mime) {
1.1.1.2   misho    1518: -                      if (handle_mime(ms, mime, "directory") == -1)
1.1       misho    1519: -                              return -1;
1.1.1.3 ! misho    1520: -              } else if (file_printf(ms, "%sdirectory", COMMA) == -1)
1.1       misho    1521: -                      return -1;
1.1.1.3 ! misho    1522: -              break;
1.1       misho    1523: -#ifdef S_IFCHR
                   1524: -      case S_IFCHR:
                   1525: -              /* 
                   1526: -               * If -s has been specified, treat character special files
                   1527: -               * like ordinary files.  Otherwise, just report that they
                   1528: -               * are block special files and go on to the next file.
                   1529: -               */
1.1.1.3 ! misho    1530: -              if ((ms->flags & MAGIC_DEVICES) != 0) {
        !          1531: -                      ret = 0;
1.1       misho    1532: -                      break;
1.1.1.3 ! misho    1533: -              }
1.1       misho    1534: -              if (mime) {
1.1.1.2   misho    1535: -                      if (handle_mime(ms, mime, "chardevice") == -1)
1.1       misho    1536: -                              return -1;
                   1537: -              } else {
                   1538: -#ifdef HAVE_STAT_ST_RDEV
                   1539: -# ifdef dv_unit
1.1.1.3 ! misho    1540: +#ifndef PHP_WIN32
        !          1541: +# ifdef S_IFCHR
        !          1542: +              case S_IFCHR:
        !          1543: +                      /* 
        !          1544: +                       * If -s has been specified, treat character special files
        !          1545: +                       * like ordinary files.  Otherwise, just report that they
        !          1546: +                       * are block special files and go on to the next file.
        !          1547: +                       */
        !          1548: +                      if ((ms->flags & MAGIC_DEVICES) != 0) {
        !          1549: +                              ret = 0;
        !          1550: +                              break;
        !          1551: +                      }
        !          1552: +                      if (mime) {
        !          1553: +                              if (handle_mime(ms, mime, "x-character-device") == -1)
        !          1554: +                                      return -1;
        !          1555: +                      } else {
        !          1556: +#  ifdef HAVE_STAT_ST_RDEV
        !          1557: +#   ifdef dv_unit
        !          1558:                        if (file_printf(ms, "%scharacter special (%d/%d/%d)",
        !          1559:                            COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
1.1       misho    1560: -                                      dv_subunit(sb->st_rdev)) == -1)
                   1561: -                              return -1;
                   1562: -# else
1.1.1.3 ! misho    1563: +                                              dv_subunit(sb->st_rdev)) == -1)
        !          1564: +                                      return -1;
        !          1565: +#   else
        !          1566:                        if (file_printf(ms, "%scharacter special (%ld/%ld)",
        !          1567:                            COMMA, (long)major(sb->st_rdev),
        !          1568:                            (long)minor(sb->st_rdev)) == -1)
1.1       misho    1569: -                              return -1;
                   1570: -# endif
                   1571: -#else
1.1.1.3 ! misho    1572: +                                      return -1;
        !          1573: +#   endif
        !          1574: +#  else
        !          1575:                        if (file_printf(ms, "%scharacter special", COMMA) == -1)
1.1       misho    1576: -                              return -1;
                   1577: -#endif
                   1578: -              }
1.1.1.3 ! misho    1579: -              break;
1.1       misho    1580: -#endif
                   1581: -#ifdef S_IFBLK
                   1582: -      case S_IFBLK:
                   1583: -              /* 
                   1584: -               * If -s has been specified, treat block special files
                   1585: -               * like ordinary files.  Otherwise, just report that they
                   1586: -               * are block special files and go on to the next file.
                   1587: -               */
1.1.1.3 ! misho    1588: -              if ((ms->flags & MAGIC_DEVICES) != 0) {
        !          1589: -                      ret = 0;
1.1       misho    1590: -                      break;
1.1.1.3 ! misho    1591: -              }
1.1       misho    1592: -              if (mime) {
1.1.1.2   misho    1593: -                      if (handle_mime(ms, mime, "blockdevice") == -1)
1.1       misho    1594: -                              return -1;
                   1595: -              } else {
                   1596: -#ifdef HAVE_STAT_ST_RDEV
                   1597: -# ifdef dv_unit
1.1.1.3 ! misho    1598: -                      if (file_printf(ms, "%sblock special (%d/%d/%d)",
        !          1599: -                          COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
        !          1600: -                          dv_subunit(sb->st_rdev)) == -1)
1.1       misho    1601: -                              return -1;
                   1602: -# else
1.1.1.3 ! misho    1603: -                      if (file_printf(ms, "%sblock special (%ld/%ld)",
        !          1604: -                          COMMA, (long)major(sb->st_rdev),
        !          1605: -                          (long)minor(sb->st_rdev)) == -1)
1.1       misho    1606: -                              return -1;
                   1607: +                                      return -1;
                   1608: +#  endif
                   1609: +                      }
1.1.1.2   misho    1610: +                      return 1;
                   1611:  # endif
                   1612: -#else
1.1.1.3 ! misho    1613: -                      if (file_printf(ms, "%sblock special", COMMA) == -1)
1.1.1.2   misho    1614: -                              return -1;
                   1615:  #endif
1.1.1.3 ! misho    1616: -              }
        !          1617: -              break;
        !          1618: -#endif
1.1.1.2   misho    1619: -      /* TODO add code to handle V7 MUX and Blit MUX files */
                   1620: +
                   1621:  #ifdef        S_IFIFO
                   1622:        case S_IFIFO:
                   1623:                if((ms->flags & MAGIC_DEVICES) != 0)
1.1.1.3 ! misho    1624: @@ -253,79 +204,14 @@
1.1.1.2   misho    1625:  #endif
                   1626:  #ifdef        S_IFLNK
                   1627:        case S_IFLNK:
                   1628: -              if ((nch = readlink(fn, buf, BUFSIZ-1)) <= 0) {
                   1629: +              /* stat is used, if it made here then the link is broken */
                   1630:                        if (ms->flags & MAGIC_ERROR) {
                   1631: -                          file_error(ms, errno, "unreadable symlink `%s'",
                   1632: -                              fn);
                   1633: +                          file_error(ms, errno, "unreadable symlink `%s'", fn);
                   1634:                            return -1;
                   1635:                        }
                   1636: -                      if (mime) {
                   1637: -                              if (handle_mime(ms, mime, "symlink") == -1)
                   1638: -                                      return -1;
                   1639: -                      } else if (file_printf(ms,
1.1.1.3 ! misho    1640: -                          "%sunreadable symlink `%s' (%s)", COMMA, fn,
1.1.1.2   misho    1641: -                          strerror(errno)) == -1)
                   1642: -                              return -1;
1.1.1.3 ! misho    1643: -                      break;
1.1       misho    1644: -              }
                   1645: -              buf[nch] = '\0';        /* readlink(2) does not do this */
                   1646: -
                   1647: -              /* If broken symlink, say so and quit early. */
                   1648: -              if (*buf == '/') {
                   1649: -                      if (stat(buf, &tstatbuf) < 0)
                   1650: -                              return bad_link(ms, errno, buf);
                   1651: -              } else {
                   1652: -                      char *tmp;
                   1653: -                      char buf2[BUFSIZ+BUFSIZ+4];
1.1.1.2   misho    1654: -
1.1       misho    1655: -                      if ((tmp = strrchr(fn,  '/')) == NULL) {
                   1656: -                              tmp = buf; /* in current directory anyway */
                   1657: -                      } else {
                   1658: -                              if (tmp - fn + 1 > BUFSIZ) {
                   1659: -                                      if (ms->flags & MAGIC_ERROR) {
                   1660: -                                              file_error(ms, 0, 
                   1661: -                                                  "path too long: `%s'", buf);
1.1.1.2   misho    1662: -                                              return -1;
1.1       misho    1663: -                                      }
1.1.1.2   misho    1664: -                                      if (mime) {
1.1       misho    1665: -                                              if (handle_mime(ms, mime,
                   1666: -                                                  "x-path-too-long") == -1)
1.1.1.2   misho    1667: -                                                      return -1;
1.1       misho    1668: -                                      } else if (file_printf(ms,
1.1.1.3 ! misho    1669: -                                          "%spath too long: `%s'", COMMA,
        !          1670: -                                          fn) == -1)
1.1.1.2   misho    1671: -                                              return -1;
1.1.1.3 ! misho    1672: -                                      break;
1.1       misho    1673: -                              }
                   1674: -                              /* take dir part */
                   1675: -                              (void)strlcpy(buf2, fn, sizeof buf2);
                   1676: -                              buf2[tmp - fn + 1] = '\0';
                   1677: -                              /* plus (rel) link */
                   1678: -                              (void)strlcat(buf2, buf, sizeof buf2);
                   1679: -                              tmp = buf2;
                   1680: -                      }
                   1681: -                      if (stat(tmp, &tstatbuf) < 0)
                   1682: -                              return bad_link(ms, errno, buf);
                   1683: -              }
1.1.1.2   misho    1684: -
1.1       misho    1685: -              /* Otherwise, handle it. */
                   1686: -              if ((ms->flags & MAGIC_SYMLINK) != 0) {
                   1687: -                      const char *p;
                   1688: -                      ms->flags &= MAGIC_SYMLINK;
                   1689: -                      p = magic_file(ms, buf);
                   1690: -                      ms->flags |= MAGIC_SYMLINK;
1.1.1.3 ! misho    1691: -                      if (p == NULL)
        !          1692: -                              return -1;
1.1       misho    1693: -              } else { /* just print what it points to */
                   1694: -                      if (mime) {
1.1.1.2   misho    1695: -                              if (handle_mime(ms, mime, "symlink") == -1)
1.1       misho    1696: -                                      return -1;
1.1.1.3 ! misho    1697: -                      } else if (file_printf(ms, "%ssymbolic link to `%s'",
        !          1698: -                          COMMA, buf) == -1)
1.1       misho    1699: -                              return -1;
                   1700: -              }
1.1.1.3 ! misho    1701: -              break;
1.1       misho    1702: +      return 1;
                   1703:  #endif
                   1704: +
                   1705:  #ifdef        S_IFSOCK
                   1706:  #ifndef __COHERENT__
                   1707:        case S_IFSOCK:
1.1.1.3 ! misho    1708: @@ -337,27 +223,27 @@
        !          1709:                break;
1.1       misho    1710:  #endif
                   1711:  #endif
                   1712: -      case S_IFREG:
1.1.1.3 ! misho    1713: -              /*
        !          1714: -               * regular file, check next possibility
        !          1715: -               *
        !          1716: -               * If stat() tells us the file has zero length, report here that
        !          1717: -               * the file is empty, so we can skip all the work of opening and
        !          1718: -               * reading the file.
1.1       misho    1719: +              case S_IFREG:
1.1.1.3 ! misho    1720: +      /*
        !          1721: +       * regular file, check next possibility
        !          1722: +       *
        !          1723: +       * If stat() tells us the file has zero length, report here that
        !          1724: +       * the file is empty, so we can skip all the work of opening and 
        !          1725: +       * reading the file.
        !          1726:                 * But if the -s option has been given, we skip this
        !          1727:                 * optimization, since on some systems, stat() reports zero
        !          1728:                 * size for raw disk partitions. (If the block special device
        !          1729:                 * really has zero length, the fact that it is empty will be
        !          1730:                 * detected and reported correctly when we read the file.)
        !          1731: -               */
        !          1732: -              if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) {
        !          1733: -                      if (mime) {
        !          1734: -                              if (handle_mime(ms, mime, "x-empty") == -1)
        !          1735: -                                      return -1;
        !          1736: -                      } else if (file_printf(ms, "%sempty", COMMA) == -1)
        !          1737: +       */
        !          1738: +      if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) {
        !          1739: +              if (mime) {
        !          1740: +                      if (handle_mime(ms, mime, "x-empty") == -1)
        !          1741:                                return -1;
        !          1742: +                      } else if (file_printf(ms, "%sempty", COMMA) == -1)
1.1       misho    1743: +                      return -1;
1.1.1.3 ! misho    1744:                        break;
        !          1745: -              }
        !          1746: +      }
        !          1747:                ret = 0;
        !          1748:                break;
        !          1749:  
        !          1750: @@ -367,9 +253,5 @@
        !          1751:                /*NOTREACHED*/
1.1       misho    1752:        }
                   1753:  
1.1.1.3 ! misho    1754: -      if (!mime && did) {
        !          1755: -          if (file_printf(ms, " ") == -1)
        !          1756: -                  return -1;
        !          1757: -      }
        !          1758:        return ret;
        !          1759:  }
1.1       misho    1760: diff -u libmagic.orig/funcs.c libmagic/funcs.c
1.1.1.3 ! misho    1761: --- libmagic.orig/funcs.c      2012-10-31 18:03:01.000000000 +0100
        !          1762: +++ libmagic/funcs.c   2013-04-08 15:42:57.328298809 +0200
1.1.1.2   misho    1763: @@ -41,52 +41,42 @@
1.1       misho    1764:  #if defined(HAVE_WCTYPE_H)
                   1765:  #include <wctype.h>
                   1766:  #endif
                   1767: -#if defined(HAVE_LIMITS_H)
                   1768: -#include <limits.h>
1.1.1.2   misho    1769: +
                   1770: +#ifndef SIZE_MAX 
                   1771: +# define SIZE_MAX ((size_t) -1) 
                   1772:  #endif
1.1       misho    1773:  
                   1774: -#ifndef SIZE_MAX
                   1775: -#define SIZE_MAX      ((size_t)~0)
1.1.1.2   misho    1776: +#ifndef PREG_OFFSET_CAPTURE
                   1777: +# define PREG_OFFSET_CAPTURE                 (1<<8)
1.1       misho    1778:  #endif
                   1779:  
1.1.1.2   misho    1780: +extern public void convert_libmagic_pattern(zval *pattern, int options);
                   1781: +
1.1       misho    1782:  /*
                   1783:   * Like printf, only we append to a buffer.
                   1784:   */
                   1785:  protected int
                   1786: -file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
                   1787: +file_printf(struct magic_set *ms, const char *fmt, ...)
                   1788:  {
                   1789: +      va_list ap;
                   1790:        int len;
                   1791: -      char *buf, *newstr;
                   1792: +      char *buf = NULL, *newstr;
                   1793:  
                   1794: -      len = vasprintf(&buf, fmt, ap);
                   1795: -      if (len < 0)
                   1796: -              goto out;
                   1797: +      va_start(ap, fmt);
                   1798: +      len = vspprintf(&buf, 0, fmt, ap);
                   1799: +      va_end(ap);
                   1800:  
                   1801:        if (ms->o.buf != NULL) {
                   1802: -              len = asprintf(&newstr, "%s%s", ms->o.buf, buf);
                   1803: -              free(buf);
                   1804: -              if (len < 0)
                   1805: -                      goto out;
                   1806: -              free(ms->o.buf);
                   1807: -              buf = newstr;
                   1808: +              len = spprintf(&newstr, 0, "%s%s", ms->o.buf, (buf ? buf : ""));
                   1809: +              if (buf) {
                   1810: +                      efree(buf);
                   1811: +              }
                   1812: +              efree(ms->o.buf);
                   1813: +              ms->o.buf = newstr;
                   1814: +      } else {
                   1815: +              ms->o.buf = buf;
                   1816:        }
                   1817: -      ms->o.buf = buf;
                   1818:        return 0;
                   1819: -out:
                   1820: -      file_error(ms, errno, "vasprintf failed");
                   1821: -      return -1;
                   1822: -}
                   1823: -
                   1824: -protected int
                   1825: -file_printf(struct magic_set *ms, const char *fmt, ...)
                   1826: -{
                   1827: -      int rv;
                   1828: -      va_list ap;
                   1829: -
                   1830: -      va_start(ap, fmt);
                   1831: -      rv = file_vprintf(ms, fmt, ap);
                   1832: -      va_end(ap);
                   1833: -      return rv;
                   1834:  }
                   1835:  
                   1836:  /*
1.1.1.2   misho    1837: @@ -97,17 +87,30 @@
1.1       misho    1838:  file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
1.1.1.2   misho    1839:      size_t lineno)
1.1       misho    1840:  {
                   1841: +      char *buf = NULL;
                   1842: +      
                   1843:        /* Only the first error is ok */
1.1.1.2   misho    1844:        if (ms->event_flags & EVENT_HAD_ERR)
1.1       misho    1845:                return;
                   1846:        if (lineno != 0) {
                   1847: -              free(ms->o.buf);
                   1848: +              efree(ms->o.buf);
                   1849:                ms->o.buf = NULL;
1.1.1.2   misho    1850:                file_printf(ms, "line %" SIZE_T_FORMAT "u: ", lineno);
1.1       misho    1851:        }
                   1852: -      file_vprintf(ms, f, va);
                   1853: -      if (error > 0)
                   1854: -              file_printf(ms, " (%s)", strerror(error));
                   1855: +
                   1856: +      vspprintf(&buf, 0, f, va);
                   1857: +      va_end(va);
                   1858: +      
                   1859: +      if (error > 0) {
                   1860: +              file_printf(ms, "%s (%s)", (*buf ? buf : ""), strerror(error));
                   1861: +      } else if (*buf) {
                   1862: +              file_printf(ms, "%s", buf);
                   1863: +      }
                   1864: +      
                   1865: +      if (buf) {
                   1866: +              efree(buf);
                   1867: +      }
                   1868: +
                   1869:        ms->event_flags |= EVENT_HAD_ERR;
                   1870:        ms->error = error;
                   1871:  }
1.1.1.2   misho    1872: @@ -154,10 +157,9 @@
1.1       misho    1873:        file_error(ms, errno, "error reading");
                   1874:  }
                   1875:  
                   1876: -#ifndef COMPILE_ONLY
                   1877:  protected int
1.1.1.2   misho    1878: -file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unused)),
                   1879: -    const void *buf, size_t nb)
1.1       misho    1880: +file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const void *buf,
1.1.1.2   misho    1881: +    size_t nb)
1.1       misho    1882:  {
                   1883:        int m = 0, rv = 0, looks_text = 0;
                   1884:        int mime = ms->flags & MAGIC_MIME;
1.1.1.2   misho    1885: @@ -201,10 +203,10 @@
                   1886:                }
1.1       misho    1887:        }
                   1888:  #endif
1.1.1.2   misho    1889: -#if HAVE_FORK
1.1       misho    1890: -      /* try compression stuff */
1.1.1.2   misho    1891: +
1.1       misho    1892: +#if PHP_FILEINFO_UNCOMPRESS
                   1893:        if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0)
                   1894: -              if ((m = file_zmagic(ms, fd, inname, ubuf, nb)) != 0) {
                   1895: +              if ((m = file_zmagic(ms, stream, inname, ubuf, nb)) != 0) {
                   1896:                        if ((ms->flags & MAGIC_DEBUG) != 0)
                   1897:                                (void)fprintf(stderr, "zmagic %d\n", m);
                   1898:                        goto done;
1.1.1.2   misho    1899: @@ -219,12 +221,17 @@
1.1       misho    1900:                }
                   1901:  
                   1902:        /* Check if we have a CDF file */
                   1903: -      if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0)
                   1904: -              if ((m = file_trycdf(ms, fd, ubuf, nb)) != 0) {
                   1905: -                      if ((ms->flags & MAGIC_DEBUG) != 0)
                   1906: -                              (void)fprintf(stderr, "cdf %d\n", m);
                   1907: -                      goto done;
                   1908: +      if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) {
                   1909: +              int fd;
                   1910: +              TSRMLS_FETCH();
                   1911: +              if (stream && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&fd, 0)) {
                   1912: +                      if ((m = file_trycdf(ms, fd, ubuf, nb)) != 0) {
                   1913: +                              if ((ms->flags & MAGIC_DEBUG) != 0)
                   1914: +                                      (void)fprintf(stderr, "cdf %d\n", m);
                   1915: +                              goto done;
                   1916: +                      }
                   1917:                }
                   1918: +      }
                   1919:  
                   1920:        /* try soft magic tests */
                   1921:        if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0)
1.1.1.2   misho    1922: @@ -296,7 +303,6 @@
1.1       misho    1923:  
                   1924:        return m;
                   1925:  }
                   1926: -#endif
                   1927:  
                   1928:  protected int
                   1929:  file_reset(struct magic_set *ms)
1.1.1.2   misho    1930: @@ -306,11 +312,11 @@
1.1       misho    1931:                return -1;
                   1932:        }
                   1933:        if (ms->o.buf) {
                   1934: -              free(ms->o.buf);
                   1935: +              efree(ms->o.buf);
                   1936:                ms->o.buf = NULL;
                   1937:        }
                   1938:        if (ms->o.pbuf) {
                   1939: -              free(ms->o.pbuf);
                   1940: +              efree(ms->o.pbuf);
                   1941:                ms->o.pbuf = NULL;
                   1942:        }
                   1943:        ms->event_flags &= ~EVENT_HAD_ERR;
1.1.1.3 ! misho    1944: @@ -329,7 +335,7 @@
        !          1945:  protected const char *
        !          1946:  file_getbuffer(struct magic_set *ms)
        !          1947:  {
        !          1948: -      char *pbuf, *op, *np;
        !          1949: +      char *op, *np;
        !          1950:        size_t psize, len;
        !          1951:  
        !          1952:        if (ms->event_flags & EVENT_HAD_ERR)
        !          1953: @@ -344,15 +350,13 @@
1.1       misho    1954:        /* * 4 is for octal representation, + 1 is for NUL */
                   1955:        len = strlen(ms->o.buf);
                   1956:        if (len > (SIZE_MAX - 1) / 4) {
                   1957: -              file_oomem(ms, len);
                   1958:                return NULL;
                   1959:        }
                   1960:        psize = len * 4 + 1;
                   1961: -      if ((pbuf = CAST(char *, realloc(ms->o.pbuf, psize))) == NULL) {
1.1.1.3 ! misho    1962: +      if ((ms->o.pbuf = CAST(char *, erealloc(ms->o.pbuf, psize))) == NULL) {
        !          1963:                file_oomem(ms, psize);
        !          1964:                return NULL;
        !          1965:        }
        !          1966: -      ms->o.pbuf = pbuf;
1.1       misho    1967:  
                   1968:  #if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
1.1.1.3 ! misho    1969:        {
        !          1970: @@ -412,8 +416,8 @@
1.1       misho    1971:        if (level >= ms->c.len) {
                   1972:                len = (ms->c.len += 20) * sizeof(*ms->c.li);
1.1.1.3 ! misho    1973:                ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ?
1.1       misho    1974: -                  malloc(len) :
                   1975: -                  realloc(ms->c.li, len));
1.1.1.3 ! misho    1976: +                  emalloc(len) :
        !          1977: +                  erealloc(ms->c.li, len));
        !          1978:                if (ms->c.li == NULL) {
        !          1979:                        file_oomem(ms, len);
        !          1980:                        return -1;
        !          1981: @@ -433,29 +437,47 @@
1.1.1.2   misho    1982:        return ms->o.buf == NULL ? 0 : strlen(ms->o.buf);
                   1983:  }
                   1984:  
                   1985: -protected int
                   1986: +
                   1987: +protected int 
                   1988:  file_replace(struct magic_set *ms, const char *pat, const char *rep)
                   1989:  {
                   1990: -      regex_t rx;
                   1991: -      int rc;
                   1992: +      zval *patt;
                   1993: +      int opts = 0;
                   1994: +      pcre_cache_entry *pce;
                   1995: +      char *res;
                   1996: +      zval *repl;
1.1.1.3 ! misho    1997: +      int res_len, rep_cnt = 0;
1.1.1.2   misho    1998: +      TSRMLS_FETCH();
                   1999: +
                   2000: +      MAKE_STD_ZVAL(patt);
                   2001: +      ZVAL_STRINGL(patt, pat, strlen(pat), 0);
                   2002: +      opts |= PCRE_MULTILINE;
                   2003: +      convert_libmagic_pattern(patt, opts);
1.1.1.3 ! misho    2004: +      if ((pce = pcre_get_compiled_regex_cache(Z_STRVAL_P(patt), Z_STRLEN_P(patt) TSRMLS_CC)) == NULL) {
1.1.1.2   misho    2005: +              zval_dtor(patt);
                   2006: +              FREE_ZVAL(patt);
                   2007: +              return -1;
                   2008: +      }
                   2009: +
                   2010: +      MAKE_STD_ZVAL(repl);
                   2011: +      ZVAL_STRINGL(repl, rep, strlen(rep), 0);
1.1.1.3 ! misho    2012: +
        !          2013: +      res = php_pcre_replace_impl(pce, ms->o.buf, strlen(ms->o.buf), repl,
        !          2014: +                      0, &res_len, -1, &rep_cnt TSRMLS_CC);
1.1.1.2   misho    2015:  
                   2016: -      rc = regcomp(&rx, pat, REG_EXTENDED);
                   2017: -      if (rc) {
                   2018: -              char errmsg[512];
                   2019: -              (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
                   2020: -              file_magerror(ms, "regex error %d, (%s)", rc, errmsg);
                   2021: +      FREE_ZVAL(repl);
                   2022: +      zval_dtor(patt);
                   2023: +      FREE_ZVAL(patt);
                   2024: +
                   2025: +      if (NULL == res) {
                   2026:                return -1;
                   2027: -      } else {
                   2028: -              regmatch_t rm;
                   2029: -              int nm = 0;
                   2030: -              while (regexec(&rx, ms->o.buf, 1, &rm, 0) == 0) {
                   2031: -                      ms->o.buf[rm.rm_so] = '\0';
                   2032: -                      if (file_printf(ms, "%s%s", rep,
                   2033: -                          rm.rm_eo != 0 ? ms->o.buf + rm.rm_eo : "") == -1)
                   2034: -                              return -1;
                   2035: -                      nm++;
                   2036: -              }
                   2037: -              regfree(&rx);
                   2038: -              return nm;
                   2039:        }
                   2040: +
                   2041: +      strncpy(ms->o.buf, res, res_len);
                   2042: +      ms->o.buf[res_len] = '\0';
                   2043: +
                   2044: +      efree(res);
                   2045: +
                   2046: +      return rep_cnt;
                   2047:  }
                   2048: +
1.1       misho    2049: diff -u libmagic.orig/magic.c libmagic/magic.c
1.1.1.3 ! misho    2050: --- libmagic.orig/magic.c      2013-01-11 17:43:09.000000000 +0100
        !          2051: +++ libmagic/magic.c   2013-04-27 13:53:32.175250261 +0200
1.1.1.2   misho    2052: @@ -25,11 +25,6 @@
                   2053:   * SUCH DAMAGE.
                   2054:   */
                   2055:  
                   2056: -#ifdef WIN32
                   2057: -#include <windows.h>
                   2058: -#include <shlwapi.h>
                   2059: -#endif
                   2060: -
                   2061:  #include "file.h"
                   2062:  
                   2063:  #ifndef       lint
                   2064: @@ -39,15 +34,24 @@
1.1       misho    2065:  #include "magic.h"
                   2066:  
                   2067:  #include <stdlib.h>
                   2068: +#ifdef PHP_WIN32
                   2069: +#include "win32/unistd.h"
                   2070: +#else
                   2071:  #include <unistd.h>
                   2072: +#endif
                   2073:  #include <string.h>
                   2074: -#ifdef QUICK
                   2075: -#include <sys/mman.h>
                   2076: +#ifdef PHP_WIN32
                   2077: +# include "config.w32.h"
                   2078: +#else
                   2079: +# include "php_config.h"
                   2080:  #endif
                   2081: -#ifdef HAVE_LIMITS_H
1.1.1.2   misho    2082: -#include <limits.h>   /* for PIPE_BUF */
1.1       misho    2083: +
1.1.1.2   misho    2084: +#ifdef PHP_WIN32
                   2085: +#include <shlwapi.h>
                   2086:  #endif
1.1       misho    2087:  
1.1.1.2   misho    2088: +#include <limits.h>   /* for PIPE_BUF */
                   2089: +
1.1       misho    2090:  #if defined(HAVE_UTIMES)
                   2091:  # include <sys/time.h>
1.1.1.2   misho    2092:  #elif defined(HAVE_UTIME)
1.1.1.3 ! misho    2093: @@ -71,18 +75,25 @@
1.1       misho    2094:  #endif
                   2095:  #endif
                   2096:  
                   2097: +#ifdef PHP_WIN32
                   2098: +# undef S_IFLNK
                   2099: +# undef S_IFIFO
                   2100: +#endif
                   2101: +
                   2102:  private void close_and_restore(const struct magic_set *, const char *, int,
                   2103:      const struct stat *);
                   2104:  private int unreadable_info(struct magic_set *, mode_t, const char *);
1.1.1.3 ! misho    2105: +#if 0
1.1.1.2   misho    2106:  private const char* get_default_magic(void);
1.1       misho    2107: -#ifndef COMPILE_ONLY
                   2108: -private const char *file_or_fd(struct magic_set *, const char *, int);
1.1.1.3 ! misho    2109:  #endif
1.1       misho    2110: +private const char *file_or_stream(struct magic_set *, const char *, php_stream *);
                   2111:  
                   2112:  #ifndef       STDIN_FILENO
                   2113:  #define       STDIN_FILENO    0
1.1.1.2   misho    2114:  #endif
                   2115:  
                   2116: +/* XXX this functionality is excluded in php, enable it in apprentice.c:340 */
                   2117: +#if 0
                   2118:  private const char *
                   2119:  get_default_magic(void)
                   2120:  {
1.1.1.3 ! misho    2121: @@ -90,7 +101,7 @@
1.1.1.2   misho    2122:        static char *default_magic;
                   2123:        char *home, *hmagicpath;
                   2124:  
                   2125: -#ifndef WIN32
                   2126: +#ifndef PHP_WIN32
                   2127:        struct stat st;
                   2128:  
                   2129:        if (default_magic) {
1.1.1.3 ! misho    2130: @@ -104,17 +115,17 @@
        !          2131:                return MAGIC;
        !          2132:        if (stat(hmagicpath, &st) == -1) {
        !          2133:                free(hmagicpath);
        !          2134: -              if (asprintf(&hmagicpath, "%s/.magic", home) < 0)
        !          2135: +      if (asprintf(&hmagicpath, "%s/.magic", home) < 0)
        !          2136: +              return MAGIC;
        !          2137: +      if (stat(hmagicpath, &st) == -1)
        !          2138: +              goto out;
        !          2139: +      if (S_ISDIR(st.st_mode)) {
        !          2140: +              free(hmagicpath);
        !          2141: +              if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0)
        !          2142:                        return MAGIC;
        !          2143: -              if (stat(hmagicpath, &st) == -1)
        !          2144: +              if (access(hmagicpath, R_OK) == -1)
        !          2145:                        goto out;
        !          2146: -              if (S_ISDIR(st.st_mode)) {
        !          2147: -                      free(hmagicpath);
        !          2148: -                      if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0)
        !          2149: -                              return MAGIC;
        !          2150: -                      if (access(hmagicpath, R_OK) == -1)
        !          2151: -                              goto out;
        !          2152: -              }
        !          2153: +      }
        !          2154:        }
        !          2155:  
        !          2156:        if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0)
        !          2157: @@ -128,6 +139,7 @@
1.1.1.2   misho    2158:  #else
                   2159:        char *hmagicp = hmagicpath;
                   2160:        char *tmppath = NULL;
                   2161: +      LPTSTR dllpath;
                   2162:  
                   2163:  #define APPENDPATH() \
                   2164:        do { \
1.1.1.3 ! misho    2165: @@ -172,7 +184,7 @@
1.1.1.2   misho    2166:        }
                   2167:  
                   2168:        /* Third, try to get magic file relative to dll location */
                   2169: -      LPTSTR dllpath = malloc(sizeof(*dllpath) * (MAX_PATH + 1));
                   2170: +      dllpath = malloc(sizeof(*dllpath) * (MAX_PATH + 1));
                   2171:        dllpath[MAX_PATH] = 0;  /* just in case long path gets truncated and not null terminated */
                   2172:        if (GetModuleFileNameA(NULL, dllpath, MAX_PATH)){
                   2173:                PathRemoveFileSpecA(dllpath);
1.1.1.3 ! misho    2174: @@ -210,6 +222,7 @@
1.1.1.2   misho    2175:  
                   2176:        return action == FILE_LOAD ? get_default_magic() : MAGIC;
                   2177:  }
                   2178: +#endif
                   2179:  
                   2180:  public struct magic_set *
1.1       misho    2181:  magic_open(int flags)
1.1.1.3 ! misho    2182: @@ -250,7 +263,7 @@
        !          2183:  magic_load(struct magic_set *ms, const char *magicfile)
1.1       misho    2184:  {
1.1.1.3 ! misho    2185:        if (ms == NULL)
        !          2186: -              return -1;
        !          2187: +      return -1;
        !          2188:        return file_apprentice(ms, magicfile, FILE_LOAD);
1.1       misho    2189:  }
                   2190:  
1.1.1.3 ! misho    2191: @@ -262,13 +275,6 @@
        !          2192:        return file_apprentice(ms, magicfile, FILE_COMPILE);
1.1       misho    2193:  }
                   2194:  
                   2195: -public int
                   2196: -magic_check(struct magic_set *ms, const char *magicfile)
                   2197: -{
1.1.1.3 ! misho    2198: -      if (ms == NULL)
        !          2199: -              return -1;
        !          2200: -      return file_apprentice(ms, magicfile, FILE_CHECK);
1.1       misho    2201: -}
1.1.1.2   misho    2202:  
                   2203:  public int
                   2204:  magic_list(struct magic_set *ms, const char *magicfile)
1.1.1.3 ! misho    2205: @@ -282,9 +288,6 @@
1.1       misho    2206:  close_and_restore(const struct magic_set *ms, const char *name, int fd,
                   2207:      const struct stat *sb)
                   2208:  {
                   2209: -      if (fd == STDIN_FILENO)
                   2210: -              return;
                   2211: -      (void) close(fd);
                   2212:  
                   2213:        if ((ms->flags & MAGIC_PRESERVE_ATIME) != 0) {
                   2214:                /*
1.1.1.3 ! misho    2215: @@ -311,7 +314,6 @@
1.1       misho    2216:        }
                   2217:  }
                   2218:  
                   2219: -#ifndef COMPILE_ONLY
                   2220:  
                   2221:  /*
                   2222:   * find type of descriptor
1.1.1.3 ! misho    2223: @@ -321,7 +323,7 @@
1.1       misho    2224:  {
1.1.1.3 ! misho    2225:        if (ms == NULL)
        !          2226:                return NULL;
1.1       misho    2227: -      return file_or_fd(ms, NULL, fd);
                   2228: +      return file_or_stream(ms, NULL, NULL);
                   2229:  }
                   2230:  
                   2231:  /*
1.1.1.3 ! misho    2232: @@ -332,30 +334,42 @@
1.1       misho    2233:  {
1.1.1.3 ! misho    2234:        if (ms == NULL)
        !          2235:                return NULL;
1.1       misho    2236: -      return file_or_fd(ms, inname, STDIN_FILENO);
                   2237: +      return file_or_stream(ms, inname, NULL);
                   2238: +}
                   2239: +
                   2240: +public const char *
                   2241: +magic_stream(struct magic_set *ms, php_stream *stream)
                   2242: +{
1.1.1.3 ! misho    2243: +      if (ms == NULL)
        !          2244: +              return NULL;
1.1       misho    2245: +      return file_or_stream(ms, NULL, stream);
                   2246:  }
                   2247:  
                   2248:  private const char *
                   2249: -file_or_fd(struct magic_set *ms, const char *inname, int fd)
                   2250: +file_or_stream(struct magic_set *ms, const char *inname, php_stream *stream)
                   2251:  {
                   2252:        int     rv = -1;
                   2253:        unsigned char *buf;
                   2254:        struct stat     sb;
                   2255:        ssize_t nbytes = 0;     /* number of bytes read from a datafile */
                   2256: -      int     ispipe = 0;
                   2257: +      int no_in_stream = 0;
                   2258: +      TSRMLS_FETCH();
                   2259: +
                   2260: +      if (!inname && !stream) {
                   2261: +              return NULL;
                   2262: +      }
                   2263:  
                   2264:        /*
                   2265:         * one extra for terminating '\0', and
                   2266:         * some overlapping space for matches near EOF
                   2267:         */
                   2268:  #define SLOP (1 + sizeof(union VALUETYPE))
                   2269: -      if ((buf = CAST(unsigned char *, malloc(HOWMANY + SLOP))) == NULL)
                   2270: -              return NULL;
                   2271: +      buf = emalloc(HOWMANY + SLOP);
                   2272:  
1.1.1.2   misho    2273:        if (file_reset(ms) == -1)
1.1       misho    2274:                goto done;
                   2275:  
                   2276: -      switch (file_fsmagic(ms, inname, &sb)) {
                   2277: +      switch (file_fsmagic(ms, inname, &sb, stream)) {
1.1.1.2   misho    2278:        case -1:                /* error */
                   2279:                goto done;
                   2280:        case 0:                 /* nothing found */
1.1.1.3 ! misho    2281: @@ -365,68 +379,48 @@
1.1       misho    2282:                goto done;
                   2283:        }
                   2284:  
                   2285: -      if (inname == NULL) {
                   2286: -              if (fstat(fd, &sb) == 0 && S_ISFIFO(sb.st_mode))
                   2287: -                      ispipe = 1;
                   2288: -      } else {
                   2289: -              int flags = O_RDONLY|O_BINARY;
1.1.1.2   misho    2290: +      errno = 0;
                   2291:  
1.1       misho    2292: -              if (stat(inname, &sb) == 0 && S_ISFIFO(sb.st_mode)) {
1.1.1.2   misho    2293: -#ifdef O_NONBLOCK
1.1       misho    2294: -                      flags |= O_NONBLOCK;
1.1.1.2   misho    2295: +      if (!stream && inname) {
                   2296: +              no_in_stream = 1;
                   2297: +#if PHP_API_VERSION < 20100412
                   2298: +              stream = php_stream_open_wrapper((char *)inname, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
                   2299: +#else
                   2300: +              stream = php_stream_open_wrapper((char *)inname, "rb", REPORT_ERRORS, NULL);
                   2301:  #endif
1.1       misho    2302: -                      ispipe = 1;
                   2303: -              }
1.1.1.2   misho    2304: +      }
                   2305:  
1.1       misho    2306: -              errno = 0;
                   2307: -              if ((fd = open(inname, flags)) < 0) {
                   2308: -                      if (unreadable_info(ms, sb.st_mode, inname) == -1)
                   2309: -                              goto done;
                   2310: -                      rv = 0;
1.1.1.2   misho    2311: +      if (!stream) {
                   2312: +              if (unreadable_info(ms, sb.st_mode, inname) == -1)
                   2313:                        goto done;
1.1       misho    2314: -              }
1.1.1.2   misho    2315: +              rv = 0;
                   2316: +              goto done;
                   2317: +      }
                   2318: +
1.1       misho    2319:  #ifdef O_NONBLOCK
                   2320: -              if ((flags = fcntl(fd, F_GETFL)) != -1) {
                   2321: -                      flags &= ~O_NONBLOCK;
                   2322: -                      (void)fcntl(fd, F_SETFL, flags);
                   2323: -              }
                   2324: +/* we should be already be in non blocking mode for network socket */
                   2325:  #endif
                   2326: -      }
                   2327:  
                   2328:        /*
                   2329:         * try looking at the first HOWMANY bytes
                   2330:         */
                   2331: -      if (ispipe) {
                   2332: -              ssize_t r = 0;
                   2333: -
                   2334: -              while ((r = sread(fd, (void *)&buf[nbytes],
                   2335: -                  (size_t)(HOWMANY - nbytes), 1)) > 0) {
                   2336: -                      nbytes += r;
                   2337: -                      if (r < PIPE_BUF) break;
                   2338: -              }
                   2339: -
                   2340: -              if (nbytes == 0) {
                   2341: -                      /* We can not read it, but we were able to stat it. */
                   2342: -                      if (unreadable_info(ms, sb.st_mode, inname) == -1)
                   2343: -                              goto done;
                   2344: -                      rv = 0;
                   2345: -                      goto done;
                   2346: -              }
                   2347: -
                   2348: -      } else {
                   2349: -              if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1) {
                   2350: -                      file_error(ms, errno, "cannot read `%s'", inname);
                   2351: -                      goto done;
                   2352: -              }
                   2353: +      if ((nbytes = php_stream_read(stream, (char *)buf, HOWMANY)) < 0) {
                   2354: +              file_error(ms, errno, "cannot read `%s'", inname);
                   2355: +              goto done;
                   2356:        }
                   2357:  
                   2358:        (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
                   2359: -      if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1)
                   2360: +      if (file_buffer(ms, stream, inname, buf, (size_t)nbytes) == -1)
                   2361:                goto done;
                   2362:        rv = 0;
                   2363:  done:
                   2364: -      free(buf);
                   2365: -      close_and_restore(ms, inname, fd, &sb);
                   2366: +      efree(buf);
                   2367: +
                   2368: +      if (no_in_stream && stream) {
                   2369: +              php_stream_close(stream);
                   2370: +      }
                   2371: +
                   2372: +      close_and_restore(ms, inname, 0, &sb);
                   2373:        return rv == 0 ? file_getbuffer(ms) : NULL;
                   2374:  }
                   2375:  
1.1.1.3 ! misho    2376: @@ -440,14 +434,13 @@
1.1       misho    2377:                return NULL;
                   2378:        /*
                   2379:         * The main work is done here!
                   2380: -       * We have the file name and/or the data buffer to be identified.
                   2381: +       * We have the file name and/or the data buffer to be identified. 
                   2382:         */
                   2383: -      if (file_buffer(ms, -1, NULL, buf, nb) == -1) {
                   2384: +      if (file_buffer(ms, NULL, NULL, buf, nb) == -1) {
                   2385:                return NULL;
                   2386:        }
                   2387:        return file_getbuffer(ms);
                   2388:  }
                   2389: -#endif
                   2390:  
                   2391:  public const char *
                   2392:  magic_error(struct magic_set *ms)
                   2393: diff -u libmagic.orig/magic.h libmagic/magic.h
1.1.1.3 ! misho    2394: --- libmagic.orig/magic.h      2013-03-21 18:52:42.000000000 +0100
        !          2395: +++ libmagic/magic.h   2013-04-08 15:42:57.328298809 +0200
        !          2396: @@ -87,6 +87,7 @@
1.1       misho    2397:  
1.1.1.2   misho    2398:  const char *magic_getpath(const char *, int);
1.1       misho    2399:  const char *magic_file(magic_t, const char *);
                   2400: +const char *magic_stream(magic_t, php_stream *);
                   2401:  const char *magic_descriptor(magic_t, int);
                   2402:  const char *magic_buffer(magic_t, const void *, size_t);
                   2403:  
1.1.1.3 ! misho    2404: @@ -96,7 +97,6 @@
        !          2405:  int magic_version(void);
1.1       misho    2406:  int magic_load(magic_t, const char *);
                   2407:  int magic_compile(magic_t, const char *);
                   2408: -int magic_check(magic_t, const char *);
1.1.1.2   misho    2409:  int magic_list(magic_t, const char *);
1.1       misho    2410:  int magic_errno(magic_t);
                   2411:  
                   2412: diff -u libmagic.orig/print.c libmagic/print.c
1.1.1.3 ! misho    2413: --- libmagic.orig/print.c      2013-03-21 18:45:14.000000000 +0100
        !          2414: +++ libmagic/print.c   2013-04-27 13:53:32.175250261 +0200
        !          2415: @@ -28,13 +28,17 @@
        !          2416:  /*
1.1       misho    2417:   * print.c - debugging printout routines
                   2418:   */
1.1.1.3 ! misho    2419: +#define _GNU_SOURCE
1.1.1.2   misho    2420: +#include "php.h"
1.1.1.3 ! misho    2421:  
1.1       misho    2422:  #include "file.h"
1.1.1.3 ! misho    2423: +#include "cdf.h"
1.1       misho    2424:  
1.1.1.2   misho    2425:  #ifndef lint
1.1.1.3 ! misho    2426:  FILE_RCSID("@(#)$File: print.c,v 1.76 2013/02/26 18:25:00 christos Exp $")
        !          2427:  #endif  /* lint */
1.1       misho    2428:  
1.1.1.3 ! misho    2429: +#include <stdio.h>
        !          2430:  #include <string.h>
        !          2431:  #include <stdarg.h>
        !          2432:  #include <stdlib.h>
        !          2433: @@ -43,188 +47,28 @@
        !          2434:  #endif
        !          2435:  #include <time.h>
1.1       misho    2436:  
1.1.1.3 ! misho    2437: -#define SZOF(a)       (sizeof(a) / sizeof(a[0]))
        !          2438: -
        !          2439: -#include "cdf.h"
        !          2440: -
1.1       misho    2441: -#ifndef COMPILE_ONLY
                   2442: -protected void
                   2443: -file_mdump(struct magic *m)
                   2444: -{
1.1.1.3 ! misho    2445: -      static const char optyp[] = { FILE_OPS };
        !          2446: -      char tbuf[26];
1.1       misho    2447: -
1.1.1.2   misho    2448: -      (void) fprintf(stderr, "%u: %.*s %u", m->lineno,
                   2449: -          (m->cont_level & 7) + 1, ">>>>>>>>", m->offset);
1.1       misho    2450: -
                   2451: -      if (m->flag & INDIR) {
                   2452: -              (void) fprintf(stderr, "(%s,",
1.1.1.3 ! misho    2453: -                  /* Note: type is unsigned */
        !          2454: -                  (m->in_type < file_nnames) ? file_names[m->in_type] :
        !          2455: -                  "*bad in_type*");
1.1       misho    2456: -              if (m->in_op & FILE_OPINVERSE)
                   2457: -                      (void) fputc('~', stderr);
                   2458: -              (void) fprintf(stderr, "%c%u),",
1.1.1.3 ! misho    2459: -                  ((size_t)(m->in_op & FILE_OPS_MASK) <
        !          2460: -                  SZOF(optyp)) ? optyp[m->in_op & FILE_OPS_MASK] : '?',
        !          2461: -                  m->in_offset);
1.1       misho    2462: -      }
                   2463: -      (void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "",
1.1.1.3 ! misho    2464: -          /* Note: type is unsigned */
        !          2465: -          (m->type < file_nnames) ? file_names[m->type] : "*bad type");
1.1       misho    2466: -      if (m->mask_op & FILE_OPINVERSE)
                   2467: -              (void) fputc('~', stderr);
                   2468: -
                   2469: -      if (IS_STRING(m->type)) {
                   2470: -              if (m->str_flags) {
                   2471: -                      (void) fputc('/', stderr);
1.1.1.2   misho    2472: -                      if (m->str_flags & STRING_COMPACT_WHITESPACE) 
                   2473: -                              (void) fputc(CHAR_COMPACT_WHITESPACE, stderr);
                   2474: -                      if (m->str_flags & STRING_COMPACT_OPTIONAL_WHITESPACE) 
                   2475: -                              (void) fputc(CHAR_COMPACT_OPTIONAL_WHITESPACE,
1.1       misho    2476: -                                  stderr);
                   2477: -                      if (m->str_flags & STRING_IGNORE_LOWERCASE) 
                   2478: -                              (void) fputc(CHAR_IGNORE_LOWERCASE, stderr);
                   2479: -                      if (m->str_flags & STRING_IGNORE_UPPERCASE) 
                   2480: -                              (void) fputc(CHAR_IGNORE_UPPERCASE, stderr);
                   2481: -                      if (m->str_flags & REGEX_OFFSET_START) 
                   2482: -                              (void) fputc(CHAR_REGEX_OFFSET_START, stderr);
1.1.1.2   misho    2483: -                      if (m->str_flags & STRING_TEXTTEST)
                   2484: -                              (void) fputc(CHAR_TEXTTEST, stderr);
                   2485: -                      if (m->str_flags & STRING_BINTEST)
                   2486: -                              (void) fputc(CHAR_BINTEST, stderr);
                   2487: -                      if (m->str_flags & PSTRING_1_BE)
                   2488: -                              (void) fputc(CHAR_PSTRING_1_BE, stderr);
                   2489: -                      if (m->str_flags & PSTRING_2_BE)
                   2490: -                              (void) fputc(CHAR_PSTRING_2_BE, stderr);
                   2491: -                      if (m->str_flags & PSTRING_2_LE)
                   2492: -                              (void) fputc(CHAR_PSTRING_2_LE, stderr);
                   2493: -                      if (m->str_flags & PSTRING_4_BE)
                   2494: -                              (void) fputc(CHAR_PSTRING_4_BE, stderr);
                   2495: -                      if (m->str_flags & PSTRING_4_LE)
                   2496: -                              (void) fputc(CHAR_PSTRING_4_LE, stderr);
                   2497: -                      if (m->str_flags & PSTRING_LENGTH_INCLUDES_ITSELF)
                   2498: -                              (void) fputc(
                   2499: -                                  CHAR_PSTRING_LENGTH_INCLUDES_ITSELF,
                   2500: -                                  stderr);
1.1       misho    2501: -              }
                   2502: -              if (m->str_range)
                   2503: -                      (void) fprintf(stderr, "/%u", m->str_range);
                   2504: -      }
                   2505: -      else {
                   2506: -              if ((size_t)(m->mask_op & FILE_OPS_MASK) < SZOF(optyp))
                   2507: -                      (void) fputc(optyp[m->mask_op & FILE_OPS_MASK], stderr);
                   2508: -              else
                   2509: -                      (void) fputc('?', stderr);
                   2510: -                      
                   2511: -              if (m->num_mask) {
                   2512: -                      (void) fprintf(stderr, "%.8llx",
                   2513: -                          (unsigned long long)m->num_mask);
                   2514: -              }
                   2515: -      }
                   2516: -      (void) fprintf(stderr, ",%c", m->reln);
                   2517: -
                   2518: -      if (m->reln != 'x') {
                   2519: -              switch (m->type) {
                   2520: -              case FILE_BYTE:
                   2521: -              case FILE_SHORT:
                   2522: -              case FILE_LONG:
                   2523: -              case FILE_LESHORT:
                   2524: -              case FILE_LELONG:
                   2525: -              case FILE_MELONG:
                   2526: -              case FILE_BESHORT:
                   2527: -              case FILE_BELONG:
1.1.1.3 ! misho    2528: -              case FILE_INDIRECT:
1.1       misho    2529: -                      (void) fprintf(stderr, "%d", m->value.l);
                   2530: -                      break;
                   2531: -              case FILE_BEQUAD:
                   2532: -              case FILE_LEQUAD:
                   2533: -              case FILE_QUAD:
1.1.1.2   misho    2534: -                      (void) fprintf(stderr, "%" INT64_T_FORMAT "d",
1.1       misho    2535: -                          (unsigned long long)m->value.q);
                   2536: -                      break;
                   2537: -              case FILE_PSTRING:
                   2538: -              case FILE_STRING:
                   2539: -              case FILE_REGEX:
                   2540: -              case FILE_BESTRING16:
                   2541: -              case FILE_LESTRING16:
                   2542: -              case FILE_SEARCH:
                   2543: -                      file_showstr(stderr, m->value.s, (size_t)m->vallen);
                   2544: -                      break;
                   2545: -              case FILE_DATE:
                   2546: -              case FILE_LEDATE:
                   2547: -              case FILE_BEDATE:
                   2548: -              case FILE_MEDATE:
                   2549: -                      (void)fprintf(stderr, "%s,",
1.1.1.3 ! misho    2550: -                          file_fmttime(m->value.l, FILE_T_LOCAL, tbuf));
1.1       misho    2551: -                      break;
                   2552: -              case FILE_LDATE:
                   2553: -              case FILE_LELDATE:
                   2554: -              case FILE_BELDATE:
                   2555: -              case FILE_MELDATE:
                   2556: -                      (void)fprintf(stderr, "%s,",
1.1.1.3 ! misho    2557: -                          file_fmttime(m->value.l, 0, tbuf));
1.1       misho    2558: -              case FILE_QDATE:
                   2559: -              case FILE_LEQDATE:
                   2560: -              case FILE_BEQDATE:
                   2561: -                      (void)fprintf(stderr, "%s,",
1.1.1.3 ! misho    2562: -                          file_fmttime(m->value.q, FILE_T_LOCAL, tbuf));
1.1       misho    2563: -                      break;
                   2564: -              case FILE_QLDATE:
                   2565: -              case FILE_LEQLDATE:
                   2566: -              case FILE_BEQLDATE:
                   2567: -                      (void)fprintf(stderr, "%s,",
1.1.1.3 ! misho    2568: -                          file_fmttime(m->value.q, 0, tbuf));
        !          2569: -                      break;
        !          2570: -              case FILE_QWDATE:
        !          2571: -              case FILE_LEQWDATE:
        !          2572: -              case FILE_BEQWDATE:
        !          2573: -                      (void)fprintf(stderr, "%s,",
        !          2574: -                          file_fmttime(m->value.q, FILE_T_WINDOWS, tbuf));
1.1       misho    2575: -                      break;
                   2576: -              case FILE_FLOAT:
                   2577: -              case FILE_BEFLOAT:
                   2578: -              case FILE_LEFLOAT:
                   2579: -                      (void) fprintf(stderr, "%G", m->value.f);
                   2580: -                      break;
                   2581: -              case FILE_DOUBLE:
                   2582: -              case FILE_BEDOUBLE:
                   2583: -              case FILE_LEDOUBLE:
                   2584: -                      (void) fprintf(stderr, "%G", m->value.d);
                   2585: -                      break;
                   2586: -              case FILE_DEFAULT:
                   2587: -                      /* XXX - do anything here? */
                   2588: -                      break;
1.1.1.3 ! misho    2589: -              case FILE_USE:
        !          2590: -              case FILE_NAME:
        !          2591: -                      (void) fprintf(stderr, "'%s'", m->value.s);
        !          2592: -                      break;
1.1       misho    2593: -              default:
1.1.1.3 ! misho    2594: -                      (void) fprintf(stderr, "*bad type %d*", m->type);
1.1       misho    2595: -                      break;
                   2596: -              }
                   2597: -      }
                   2598: -      (void) fprintf(stderr, ",\"%s\"]\n", m->desc);
                   2599: -}
1.1.1.3 ! misho    2600: +#ifdef PHP_WIN32
        !          2601: +# define asctime_r php_asctime_r
        !          2602: +# define ctime_r php_ctime_r
        !          2603:  #endif
        !          2604:  
        !          2605: +#define SZOF(a)       (sizeof(a) / sizeof(a[0]))
        !          2606: +
1.1       misho    2607:  /*VARARGS*/
                   2608:  protected void
                   2609:  file_magwarn(struct magic_set *ms, const char *f, ...)
                   2610:  {
                   2611:        va_list va;
                   2612: +      char *expanded_format;
                   2613: +      TSRMLS_FETCH();
                   2614:  
                   2615: -      /* cuz we use stdout for most, stderr here */
                   2616: -      (void) fflush(stdout); 
                   2617: -
                   2618: -      if (ms->file)
                   2619: -              (void) fprintf(stderr, "%s, %lu: ", ms->file,
                   2620: -                  (unsigned long)ms->line);
                   2621: -      (void) fprintf(stderr, "Warning: ");
                   2622:        va_start(va, f);
                   2623: -      (void) vfprintf(stderr, f, va);
1.1.1.3 ! misho    2624: +      if (vasprintf(&expanded_format, f, va)); /* silence */
1.1       misho    2625:        va_end(va);
                   2626: -      (void) fputc('\n', stderr);
                   2627: +      
                   2628: +      php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Warning: %s", expanded_format);
                   2629: +
                   2630: +      free(expanded_format);
                   2631:  }
                   2632:  
                   2633:  protected const char *
1.1.1.3 ! misho    2634: @@ -235,7 +79,7 @@
        !          2635:        struct tm *tm;
        !          2636:  
        !          2637:        if (flags & FILE_T_WINDOWS) {
        !          2638: -              struct timespec ts;
        !          2639: +              struct timeval ts;
        !          2640:                cdf_timestamp_to_timespec(&ts, t);
        !          2641:                t = ts.tv_sec;
        !          2642:        }
1.1       misho    2643: diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
1.1.1.3 ! misho    2644: --- libmagic.orig/readcdf.c    2012-10-31 18:03:01.000000000 +0100
        !          2645: +++ libmagic/readcdf.c 2013-04-08 15:42:57.328298809 +0200
1.1       misho    2646: @@ -30,7 +30,11 @@
                   2647:  #endif
                   2648:  
                   2649:  #include <stdlib.h>
                   2650: +#ifdef PHP_WIN32
                   2651: +#include "win32/unistd.h"
                   2652: +#else
                   2653:  #include <unistd.h>
                   2654: +#endif
                   2655:  #include <string.h>
                   2656:  #include <time.h>
                   2657:  #include <ctype.h>
                   2658: @@ -46,7 +50,7 @@
                   2659:  {
1.1.1.2   misho    2660:          size_t i;
                   2661:          cdf_timestamp_t tp;
                   2662: -        struct timespec ts;
                   2663: +        struct timeval ts;
                   2664:          char buf[64];
                   2665:          const char *str = NULL;
                   2666:          const char *s;
1.1.1.3 ! misho    2667: @@ -125,8 +129,12 @@
1.1.1.2   misho    2668:                  case CDF_FILETIME:
                   2669:                          tp = info[i].pi_tp;
                   2670:                          if (tp != 0) {
1.1.1.3 ! misho    2671: -                              char tbuf[64];
1.1.1.2   misho    2672: -                                if (tp < 1000000000000000LL) {
1.1.1.3 ! misho    2673: +                                                      char tbuf[64];
1.1       misho    2674: +#if defined(PHP_WIN32) && _MSC_VER <= 1500
1.1.1.2   misho    2675: +                                                      if (tp < 1000000000000000i64) {
1.1       misho    2676: +#else
1.1.1.2   misho    2677: +                                                      if (tp < 1000000000000000LL) {
1.1       misho    2678: +#endif
1.1.1.2   misho    2679:                                          cdf_print_elapsed_time(tbuf,
                   2680:                                              sizeof(tbuf), tp);
1.1.1.3 ! misho    2681:                                          if (NOTMIME(ms) && file_printf(ms,
1.1.1.2   misho    2682: @@ -134,7 +142,9 @@
                   2683:                                                  return -1;
                   2684:                                  } else {
                   2685:                                          char *c, *ec;
                   2686: -                                        cdf_timestamp_to_timespec(&ts, tp);
                   2687: +                                        if (cdf_timestamp_to_timespec(&ts, tp) == -1) {
                   2688: +                                                                                      return -1;
                   2689: +                                                                              }
1.1.1.3 ! misho    2690:                                          c = cdf_ctime(&ts.tv_sec, tbuf);
1.1.1.2   misho    2691:                                          if ((ec = strchr(c, '\n')) != NULL)
                   2692:                                                  *ec = '\0';
1.1.1.3 ! misho    2693: @@ -314,9 +324,9 @@
        !          2694:                        if (file_printf(ms,
        !          2695:                            "Composite Document File V2 Document") == -1)
        !          2696:                            return -1;
        !          2697: -                      if (*expn)
        !          2698: -                          if (file_printf(ms, ", %s%s", corrupt, expn) == -1)
        !          2699: -                              return -1;
        !          2700: +                if (*expn)
        !          2701: +                        if (file_printf(ms, ", %s%s", corrupt, expn) == -1)
        !          2702: +                                return -1;
        !          2703:                    } else {
        !          2704:                        if (file_printf(ms, "application/CDFV2-corrupt") == -1)
        !          2705:                            return -1;
1.1       misho    2706: diff -u libmagic.orig/readelf.c libmagic/readelf.c
1.1.1.3 ! misho    2707: --- libmagic.orig/readelf.c    2013-03-21 18:45:14.000000000 +0100
        !          2708: +++ libmagic/readelf.c 2013-04-08 15:42:57.328298809 +0200
        !          2709: @@ -48,8 +48,8 @@
        !          2710:  private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
1.1       misho    2711:      off_t, int *, int);
1.1.1.2   misho    2712:  private int doshn(struct magic_set *, int, int, int, off_t, int, size_t,
1.1.1.3 ! misho    2713: -    off_t, int *, int, int);
1.1       misho    2714: -private size_t donote(struct magic_set *, void *, size_t, size_t, int,
1.1.1.3 ! misho    2715: +    off_t, int *, int);
1.1       misho    2716: +private size_t donote(struct magic_set *, unsigned char *, size_t, size_t, int,
                   2717:      int, size_t, int *);
                   2718:  
                   2719:  #define       ELF_ALIGN(a)    ((((a) + align - 1) / align) * align)
1.1.1.3 ! misho    2720: @@ -127,11 +127,17 @@
1.1       misho    2721:  
1.1.1.3 ! misho    2722:  #define elf_getu16(swap, value) getu16(swap, value)
        !          2723:  #define elf_getu32(swap, value) getu32(swap, value)
        !          2724: -#define elf_getu64(swap, value) getu64(swap, value)
        !          2725: +#ifdef USE_ARRAY_FOR_64BIT_TYPES
        !          2726: +# define elf_getu64(swap, array) \
        !          2727: +      ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 : elf_getu32(swap, array[0])) + \
        !          2728: +       (swap ? elf_getu32(swap, array[1]) : ((uint64_t)elf_getu32(swap, array[1]) << 32)))
        !          2729: +#else
        !          2730: +# define elf_getu64(swap, value) getu64(swap, value)
        !          2731: +#endif
        !          2732:  
        !          2733:  #define xsh_addr      (clazz == ELFCLASS32                    \
        !          2734: -                       ? (void *)&sh32                        \
        !          2735: -                       : (void *)&sh64)
        !          2736: +                       ? (void *) &sh32                       \
        !          2737: +                       : (void *) &sh64)
        !          2738:  #define xsh_sizeof    (clazz == ELFCLASS32                    \
        !          2739:                         ? sizeof(sh32)                         \
        !          2740:                         : sizeof(sh64))
        !          2741: @@ -168,8 +174,8 @@
        !          2742:                         ? elf_getu32(swap, ph32.p_filesz)      \
        !          2743:                         : elf_getu64(swap, ph64.p_filesz)))
        !          2744:  #define xnh_addr      (clazz == ELFCLASS32                    \
        !          2745: -                       ? (void *)&nh32                        \
        !          2746: -                       : (void *)&nh64)
        !          2747: +                       ? (void *) &nh32                       \
        !          2748: +                       : (void *) &nh64)
        !          2749:  #define xph_memsz     (size_t)((clazz == ELFCLASS32           \
        !          2750:                         ? elf_getu32(swap, ph32.p_memsz)       \
        !          2751:                         : elf_getu64(swap, ph64.p_memsz)))
        !          2752: @@ -189,8 +195,8 @@
        !          2753:                         ? prpsoffsets32[i]                     \
        !          2754:                         : prpsoffsets64[i])
        !          2755:  #define xcap_addr     (clazz == ELFCLASS32                    \
        !          2756: -                       ? (void *)&cap32                       \
        !          2757: -                       : (void *)&cap64)
        !          2758: +                       ? (void *) &cap32                      \
        !          2759: +                       : (void *) &cap64)
        !          2760:  #define xcap_sizeof   (clazz == ELFCLASS32                    \
        !          2761:                         ? sizeof cap32                         \
        !          2762:                         : sizeof cap64)
        !          2763: @@ -292,7 +298,7 @@
        !          2764:  {
        !          2765:        Elf32_Phdr ph32;
        !          2766:        Elf64_Phdr ph64;
        !          2767: -      size_t offset, len;
        !          2768: +      size_t offset;
        !          2769:        unsigned char nbuf[BUFSIZ];
        !          2770:        ssize_t bufsize;
        !          2771:  
        !          2772: @@ -306,7 +312,11 @@
        !          2773:         * Loop through all the program headers.
        !          2774:         */
        !          2775:        for ( ; num; num--) {
        !          2776: -              if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
        !          2777: +              if (FINFO_LSEEK_FUNC(fd, off, SEEK_SET) == (off_t)-1) {
        !          2778: +                      file_badseek(ms);
        !          2779: +                      return -1;
        !          2780: +              }
        !          2781: +              if (FINFO_READ_FUNC(fd, xph_addr, xph_sizeof) == -1) {
        !          2782:                        file_badread(ms);
        !          2783:                        return -1;
        !          2784:                }
        !          2785: @@ -324,8 +334,13 @@
        !          2786:                 * This is a PT_NOTE section; loop through all the notes
        !          2787:                 * in the section.
        !          2788:                 */
        !          2789: -              len = xph_filesz < sizeof(nbuf) ? xph_filesz : sizeof(nbuf);
        !          2790: -              if ((bufsize = pread(fd, nbuf, len, xph_offset)) == -1) {
        !          2791: +              if (FINFO_LSEEK_FUNC(fd, xph_offset, SEEK_SET) == (off_t)-1) {
        !          2792: +                      file_badseek(ms);
        !          2793: +                      return -1;
        !          2794: +              }
        !          2795: +              bufsize = FINFO_READ_FUNC(fd, nbuf,
        !          2796: +                  ((xph_filesz < sizeof(nbuf)) ? xph_filesz : sizeof(nbuf)));
        !          2797: +              if (bufsize == -1) {
        !          2798:                        file_badread(ms);
        !          2799:                        return -1;
        !          2800:                }
        !          2801: @@ -852,24 +867,12 @@
        !          2802:                return 0;
        !          2803:        }
1.1       misho    2804:  
1.1.1.3 ! misho    2805: -      /* Read offset of name section to be able to read section names later */
        !          2806: -      if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) == -1) {
        !          2807: -              file_badread(ms);
        !          2808: -              return -1;
        !          2809: -      }
        !          2810: -      name_off = xsh_offset;
        !          2811: -
        !          2812:        for ( ; num; num--) {
        !          2813: -              /* Read the name of this section. */
        !          2814: -              if (pread(fd, name, sizeof(name), name_off + xsh_name) == -1) {
        !          2815: -                      file_badread(ms);
        !          2816: +              if (FINFO_LSEEK_FUNC(fd, off, SEEK_SET) == (off_t)-1) {
        !          2817: +                      file_badseek(ms);
        !          2818:                        return -1;
        !          2819:                }
        !          2820: -              name[sizeof(name) - 1] = '\0';
        !          2821: -              if (strcmp(name, ".debug_info") == 0)
        !          2822: -                      stripped = 0;
        !          2823: -
        !          2824: -              if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) {
        !          2825: +              if (FINFO_READ_FUNC(fd, xsh_addr, xsh_sizeof) == -1) {
        !          2826:                        file_badread(ms);
        !          2827:                        return -1;
        !          2828:                }
        !          2829: @@ -894,14 +897,17 @@
1.1.1.2   misho    2830:                /* Things we can determine when we seek */
                   2831:                switch (xsh_type) {
                   2832:                case SHT_NOTE:
1.1.1.3 ! misho    2833: -                      if ((nbuf = malloc(xsh_size)) == NULL) {
1.1       misho    2834: -                              file_error(ms, errno, "Cannot allocate memory"
                   2835: -                                  " for note");
                   2836: +                      nbuf = emalloc((size_t)xsh_size);
1.1.1.3 ! misho    2837: +                      if ((noff = FINFO_LSEEK_FUNC(fd, (off_t)xsh_offset, SEEK_SET)) ==
        !          2838: +                          (off_t)-1) {
        !          2839: +                              file_badread(ms);
1.1       misho    2840: +                              efree(nbuf);
                   2841:                                return -1;
                   2842:                        }
1.1.1.3 ! misho    2843: -                      if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) {
        !          2844: +                      if (FINFO_READ_FUNC(fd, nbuf, (size_t)xsh_size) !=
        !          2845: +                          (ssize_t)xsh_size) {
1.1       misho    2846: +                              efree(nbuf);
                   2847:                                file_badread(ms);
1.1.1.3 ! misho    2848: -                              free(nbuf);
1.1       misho    2849:                                return -1;
                   2850:                        }
1.1.1.3 ! misho    2851:  
        !          2852: @@ -910,25 +916,16 @@
        !          2853:                                if (noff >= (off_t)xsh_size)
        !          2854:                                        break;
        !          2855:                                noff = donote(ms, nbuf, (size_t)noff,
        !          2856: -                                  xsh_size, clazz, swap, 4, flags);
        !          2857: +                                  (size_t)xsh_size, clazz, swap, 4,
        !          2858: +                                  flags);
1.1.1.2   misho    2859:                                if (noff == 0)
1.1       misho    2860:                                        break;
                   2861:                        }
                   2862: -                      free(nbuf);
                   2863: +                      efree(nbuf);
                   2864:                        break;
                   2865:                case SHT_SUNW_cap:
1.1.1.3 ! misho    2866: -                      switch (mach) {
        !          2867: -                      case EM_SPARC:
        !          2868: -                      case EM_SPARCV9:
        !          2869: -                      case EM_IA_64:
        !          2870: -                      case EM_386:
        !          2871: -                      case EM_AMD64:
        !          2872: -                              break;
        !          2873: -                      default:
        !          2874: -                              goto skip;
        !          2875: -                      }
        !          2876: -
        !          2877: -                      if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) {
        !          2878: +                      if (FINFO_LSEEK_FUNC(fd, (off_t)xsh_offset, SEEK_SET) ==
        !          2879: +                          (off_t)-1) {
        !          2880:                                file_badseek(ms);
        !          2881:                                return -1;
        !          2882:                        }
        !          2883: @@ -940,7 +937,7 @@
        !          2884:                                    MAX(sizeof cap32, sizeof cap64)];
        !          2885:                                if ((coff += xcap_sizeof) > (off_t)xsh_size)
        !          2886:                                        break;
        !          2887: -                              if (read(fd, cbuf, (size_t)xcap_sizeof) !=
        !          2888: +                              if (FINFO_READ_FUNC(fd, cbuf, (size_t)xcap_sizeof) !=
        !          2889:                                    (ssize_t)xcap_sizeof) {
        !          2890:                                        file_badread(ms);
        !          2891:                                        return -1;
        !          2892: @@ -966,13 +963,12 @@
        !          2893:                                        break;
        !          2894:                                }
        !          2895:                        }
        !          2896: -                      /*FALLTHROUGH*/
        !          2897: -              skip:
        !          2898: +                      break;
        !          2899: +
        !          2900:                default:
        !          2901:                        break;
        !          2902:                }
        !          2903:        }
        !          2904: -
        !          2905:        if (file_printf(ms, ", %sstripped", stripped ? "" : "not ") == -1)
        !          2906:                return -1;
        !          2907:        if (cap_hw1) {
        !          2908: @@ -1051,7 +1047,7 @@
        !          2909:        const char *shared_libraries = "";
        !          2910:        unsigned char nbuf[BUFSIZ];
        !          2911:        ssize_t bufsize;
        !          2912: -      size_t offset, align, len;
        !          2913: +      size_t offset, align;
        !          2914:        
        !          2915:        if (size != xph_sizeof) {
        !          2916:                if (file_printf(ms, ", corrupted program header size") == -1)
        !          2917: @@ -1060,8 +1056,13 @@
        !          2918:        }
        !          2919:  
        !          2920:        for ( ; num; num--) {
        !          2921: -              if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
        !          2922: -                      file_badread(ms);
        !          2923: +              if (FINFO_LSEEK_FUNC(fd, off, SEEK_SET) == (off_t)-1) {
        !          2924: +                      file_badseek(ms);
        !          2925: +                      return -1;
        !          2926: +              }
        !          2927: +
        !          2928: +              if (FINFO_READ_FUNC(fd, xph_addr, xph_sizeof) == -1) {
        !          2929: +                      file_badread(ms);
        !          2930:                        return -1;
        !          2931:                }
        !          2932:  
        !          2933: @@ -1099,9 +1100,12 @@
        !          2934:                         * This is a PT_NOTE section; loop through all the notes
        !          2935:                         * in the section.
        !          2936:                         */
        !          2937: -                      len = xph_filesz < sizeof(nbuf) ? xph_filesz
        !          2938: -                          : sizeof(nbuf);
        !          2939: -                      bufsize = pread(fd, nbuf, len, xph_offset);
        !          2940: +                      if (FINFO_LSEEK_FUNC(fd, xph_offset, SEEK_SET) == (off_t)-1) {
        !          2941: +                              file_badseek(ms);
        !          2942: +                              return -1;
        !          2943: +                      }
        !          2944: +                      bufsize = FINFO_READ_FUNC(fd, nbuf, ((xph_filesz < sizeof(nbuf)) ?
        !          2945: +                          xph_filesz : sizeof(nbuf)));
        !          2946:                        if (bufsize == -1) {
        !          2947:                                file_badread(ms);
        !          2948:                                return -1;
        !          2949: @@ -1162,7 +1166,7 @@
        !          2950:        /*
        !          2951:         * If we cannot seek, it must be a pipe, socket or fifo.
        !          2952:         */
        !          2953: -      if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
        !          2954: +      if((FINFO_LSEEK_FUNC(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
        !          2955:                fd = file_pipe2file(ms, fd, buf, nbytes);
        !          2956:  
        !          2957:        if (fstat(fd, &st) == -1) {
        !          2958: diff -u libmagic.orig/readelf.h libmagic/readelf.h
        !          2959: --- libmagic.orig/readelf.h    2013-03-21 18:45:14.000000000 +0100
        !          2960: +++ libmagic/readelf.h 2013-03-31 16:57:18.499744030 +0200
        !          2961: @@ -44,9 +44,17 @@
        !          2962:  typedef uint32_t      Elf32_Word;
        !          2963:  typedef uint8_t               Elf32_Char;
        !          2964:  
        !          2965: +#if SIZEOF_LONG_LONG != 8
        !          2966: +#define       USE_ARRAY_FOR_64BIT_TYPES
        !          2967: +typedef       uint32_t        Elf64_Addr[2];
        !          2968: +typedef       uint32_t        Elf64_Off[2];
        !          2969: +typedef uint32_t      Elf64_Xword[2];
        !          2970: +#else
        !          2971: +#undef USE_ARRAY_FOR_64BIT_TYPES
        !          2972:  typedef       uint64_t        Elf64_Addr;
        !          2973:  typedef       uint64_t        Elf64_Off;
        !          2974:  typedef uint64_t      Elf64_Xword;
        !          2975: +#endif
        !          2976:  typedef uint16_t      Elf64_Half;
        !          2977:  typedef uint32_t      Elf64_Word;
        !          2978:  typedef uint8_t               Elf64_Char;
1.1       misho    2979: diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
1.1.1.3 ! misho    2980: --- libmagic.orig/softmagic.c  2013-03-21 18:45:14.000000000 +0100
        !          2981: +++ libmagic/softmagic.c       2013-05-14 11:00:07.044745939 +0200
1.1       misho    2982: @@ -41,6 +41,11 @@
                   2983:  #include <stdlib.h>
                   2984:  #include <time.h>
                   2985:  
                   2986: +#ifndef PREG_OFFSET_CAPTURE
                   2987: +# define PREG_OFFSET_CAPTURE                 (1<<8)
                   2988: +#endif
                   2989: +
                   2990: +
                   2991:  
                   2992:  private int match(struct magic_set *, struct magic *, uint32_t,
1.1.1.3 ! misho    2993:      const unsigned char *, size_t, size_t, int, int, int, int, int *, int *,
        !          2994: @@ -132,7 +137,7 @@
1.1.1.2   misho    2995:                struct magic *m = &magic[magindex];
                   2996:  
1.1.1.3 ! misho    2997:                if (m->type != FILE_NAME)
1.1.1.2   misho    2998: -              if ((IS_STRING(m->type) &&
                   2999: +              if ((IS_LIBMAGIC_STRING(m->type) &&
1.1.1.3 ! misho    3000:  #define FLT (STRING_BINTEST | STRING_TEXTTEST)
        !          3001:                     ((text && (m->str_flags & FLT) == STRING_BINTEST) ||
        !          3002:                      (!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
        !          3003: @@ -209,8 +214,8 @@
1.1       misho    3004:                if (file_check_mem(ms, ++cont_level) == -1)
                   3005:                        return -1;
                   3006:  
                   3007: -              while (magic[magindex+1].cont_level != 0 &&
                   3008: -                  ++magindex < nmagic) {
1.1.1.3 ! misho    3009: +              while (magindex + 1 < nmagic && magic[magindex+1].cont_level != 0 &&
        !          3010: +                  ++magindex) {
1.1       misho    3011:                        m = &magic[magindex];
                   3012:                        ms->line = m->lineno; /* for messages */
                   3013:  
1.1.1.3 ! misho    3014: @@ -335,44 +340,22 @@
1.1       misho    3015:  private int
                   3016:  check_fmt(struct magic_set *ms, struct magic *m)
                   3017:  {
                   3018: -      regex_t rx;
                   3019: -      int rc;
                   3020: -
                   3021: -      if (strchr(m->desc, '%') == NULL)
                   3022: +      pcre *pce;
                   3023: +      int re_options;
                   3024: +      pcre_extra *re_extra;
                   3025: +      TSRMLS_FETCH();
                   3026: +      
                   3027: +      if (strchr(m->desc, '%') == NULL) {
                   3028:                return 0;
                   3029: -
                   3030: -      rc = regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
                   3031: -      if (rc) {
                   3032: -              char errmsg[512];
                   3033: -              (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
                   3034: -              file_magerror(ms, "regex error %d, (%s)", rc, errmsg);
                   3035: +      }
                   3036: +      
                   3037: +      if ((pce = pcre_get_compiled_regex("~%[-0-9.]*s~", &re_extra, &re_options TSRMLS_CC)) == NULL) {
                   3038:                return -1;
                   3039:        } else {
                   3040: -              rc = regexec(&rx, m->desc, 0, 0, 0);
                   3041: -              regfree(&rx);
                   3042: -              return !rc;
                   3043: +              return !pcre_exec(pce, re_extra, m->desc, strlen(m->desc), 0, re_options, NULL, 0);
                   3044:        }
                   3045:  }
                   3046:  
                   3047: -#ifndef HAVE_STRNDUP
                   3048: -char * strndup(const char *, size_t);
                   3049: -
                   3050: -char *
                   3051: -strndup(const char *str, size_t n)
                   3052: -{
                   3053: -      size_t len;
                   3054: -      char *copy;
                   3055: -
                   3056: -      for (len = 0; len < n && str[len]; len++)
                   3057: -              continue;
                   3058: -      if ((copy = malloc(len + 1)) == NULL)
                   3059: -              return NULL;
                   3060: -      (void)memcpy(copy, str, len);
                   3061: -      copy[len] = '\0';
                   3062: -      return copy;
                   3063: -}
                   3064: -#endif /* HAVE_STRNDUP */
                   3065: -
                   3066:  private int32_t
                   3067:  mprint(struct magic_set *ms, struct magic *m)
                   3068:  {
1.1.1.3 ! misho    3069: @@ -583,13 +566,13 @@
1.1       misho    3070:                char *cp;
                   3071:                int rval;
                   3072:  
                   3073: -              cp = strndup((const char *)ms->search.s, ms->search.rm_len);
                   3074: +              cp = estrndup((const char *)ms->search.s, ms->search.rm_len);
1.1.1.3 ! misho    3075:                if (cp == NULL) {
        !          3076:                        file_oomem(ms, ms->search.rm_len);
        !          3077:                        return -1;
        !          3078:                }
1.1       misho    3079:                rval = file_printf(ms, m->desc, cp);
                   3080: -              free(cp);
                   3081: +              efree(cp);
                   3082:  
                   3083:                if (rval == -1)
                   3084:                        return -1;
1.1.1.3 ! misho    3085: @@ -835,16 +818,16 @@
1.1       misho    3086:        if (m->num_mask) \
                   3087:                switch (m->mask_op & FILE_OPS_MASK) { \
                   3088:                case FILE_OPADD: \
                   3089: -                      p->fld += cast m->num_mask; \
                   3090: +                      p->fld += cast (int64_t)m->num_mask; \
                   3091:                        break; \
                   3092:                case FILE_OPMINUS: \
                   3093: -                      p->fld -= cast m->num_mask; \
                   3094: +                      p->fld -= cast (int64_t)m->num_mask; \
                   3095:                        break; \
                   3096:                case FILE_OPMULTIPLY: \
                   3097: -                      p->fld *= cast m->num_mask; \
                   3098: +                      p->fld *= cast (int64_t)m->num_mask; \
                   3099:                        break; \
                   3100:                case FILE_OPDIVIDE: \
                   3101: -                      p->fld /= cast m->num_mask; \
                   3102: +                      p->fld /= cast (int64_t)m->num_mask; \
                   3103:                        break; \
                   3104:                } \
                   3105:  
1.1.1.3 ! misho    3106: @@ -1145,9 +1128,6 @@
        !          3107:                    "nbytes=%zu, count=%u)\n", m->type, m->flag, offset, o,
        !          3108:                    nbytes, count);
1.1       misho    3109:                mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
                   3110: -#ifndef COMPILE_ONLY
                   3111: -              file_mdump(m);
                   3112: -#endif
                   3113:        }
                   3114:  
                   3115:        if (m->flag & INDIR) {
1.1.1.3 ! misho    3116: @@ -1644,9 +1624,6 @@
1.1       misho    3117:                if ((ms->flags & MAGIC_DEBUG) != 0) {
                   3118:                        mdebug(offset, (char *)(void *)p,
                   3119:                            sizeof(union VALUETYPE));
                   3120: -#ifndef COMPILE_ONLY
                   3121: -                      file_mdump(m);
                   3122: -#endif
                   3123:                }
                   3124:        }
                   3125:  
1.1.1.3 ! misho    3126: @@ -1717,12 +1694,12 @@
        !          3127:                ms->o.buf = sbuf;
        !          3128:                ms->offset = soffset;
        !          3129:                if (rv == 1) {
        !          3130: -                      if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
        !          3131: +              if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
        !          3132:                            file_printf(ms, m->desc, offset) == -1)
        !          3133: -                              return -1;
        !          3134: +                      return -1;
        !          3135:                        if (file_printf(ms, "%s", rbuf) == -1)
        !          3136:                                return -1;
        !          3137: -                      free(rbuf);
        !          3138: +                      efree(rbuf);
        !          3139:                }
        !          3140:                return rv;
        !          3141:  
        !          3142: @@ -1837,6 +1814,42 @@
1.1       misho    3143:        return file_strncmp(a, b, len, flags);
                   3144:  }
                   3145:  
1.1.1.2   misho    3146: +public void
1.1       misho    3147: +convert_libmagic_pattern(zval *pattern, int options)
                   3148: +{
                   3149: +              int i, j=0;
                   3150: +              char *t;
                   3151: +
                   3152: +              t = (char *) safe_emalloc(Z_STRLEN_P(pattern), 2, 5);
                   3153: +              
                   3154: +              t[j++] = '~';
                   3155: +              
                   3156: +              for (i=0; i<Z_STRLEN_P(pattern); i++, j++) {
                   3157: +                      switch (Z_STRVAL_P(pattern)[i]) {
                   3158: +                              case '~':
                   3159: +                                      t[j++] = '\\';
                   3160: +                                      t[j] = '~';
                   3161: +                                      break;
                   3162: +                              default:
                   3163: +                                      t[j] = Z_STRVAL_P(pattern)[i];
                   3164: +                                      break;
                   3165: +                      }
                   3166: +              }
                   3167: +              t[j++] = '~';
                   3168: +      
                   3169: +              if (options & PCRE_CASELESS) 
1.1.1.2   misho    3170: +                      t[j++] = 'i';
1.1       misho    3171: +      
                   3172: +              if (options & PCRE_MULTILINE)
1.1.1.2   misho    3173: +                      t[j++] = 'm';
1.1       misho    3174: +
1.1.1.2   misho    3175: +              t[j]='\0';
1.1       misho    3176: +      
                   3177: +              Z_STRVAL_P(pattern) = t;
                   3178: +              Z_STRLEN_P(pattern) = j;
                   3179: +
                   3180: +}
                   3181: +
                   3182:  private int
                   3183:  magiccheck(struct magic_set *ms, struct magic *m)
                   3184:  {
1.1.1.3 ! misho    3185: @@ -1996,69 +2009,157 @@
1.1       misho    3186:                break;
                   3187:        }
                   3188:        case FILE_REGEX: {
                   3189: -              int rc;
                   3190: -              regex_t rx;
                   3191: -              char errmsg[512];
                   3192: -
                   3193: -              if (ms->search.s == NULL)
                   3194: -                      return 0;
                   3195: -
1.1.1.3 ! misho    3196: -              l = 0;
1.1.1.2   misho    3197: -              rc = regcomp(&rx, m->value.s,
                   3198: -                  REG_EXTENDED|REG_NEWLINE|
                   3199: -                  ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
                   3200: -              if (rc) {
                   3201: -                      (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
                   3202: -                      file_magerror(ms, "regex error %d, (%s)",
                   3203: -                          rc, errmsg);
                   3204: -                      v = (uint64_t)-1;
                   3205: -              }
                   3206: -              else {
                   3207: -                      regmatch_t pmatch[1];
                   3208: -#ifndef REG_STARTEND
                   3209: -#define       REG_STARTEND    0
                   3210: -                      size_t l = ms->search.s_len - 1;
                   3211: -                      char c = ms->search.s[l];
                   3212: -                      ((char *)(intptr_t)ms->search.s)[l] = '\0';
1.1.1.3 ! misho    3213: -#else
1.1       misho    3214: -                      pmatch[0].rm_so = 0;
                   3215: -                      pmatch[0].rm_eo = ms->search.s_len;
1.1.1.3 ! misho    3216: -#endif
1.1       misho    3217: -                      rc = regexec(&rx, (const char *)ms->search.s,
                   3218: -                          1, pmatch, REG_STARTEND);
                   3219: -#if REG_STARTEND == 0
                   3220: -                      ((char *)(intptr_t)ms->search.s)[l] = c;
1.1.1.3 ! misho    3221: -#endif
        !          3222: -                      switch (rc) {
        !          3223: -                      case 0:
        !          3224: -                              ms->search.s += (int)pmatch[0].rm_so;
        !          3225: -                              ms->search.offset += (size_t)pmatch[0].rm_so;
        !          3226: -                              ms->search.rm_len =
        !          3227: -                                  (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so);
        !          3228: -                              v = 0;
        !          3229: -                              break;
        !          3230: +              zval *pattern;
        !          3231: +              int options = 0;
        !          3232: +              pcre_cache_entry *pce;
        !          3233: +              TSRMLS_FETCH();
        !          3234: +              
        !          3235: +              MAKE_STD_ZVAL(pattern);
        !          3236: +              ZVAL_STRINGL(pattern, (char *)m->value.s, m->vallen, 0);
        !          3237: +      
        !          3238: +              options |= PCRE_MULTILINE;
        !          3239: +              
        !          3240: +              if (m->str_flags & STRING_IGNORE_CASE) {
        !          3241: +                      options |= PCRE_CASELESS;
        !          3242: +              }
        !          3243: +              
        !          3244: +              convert_libmagic_pattern(pattern, options);
        !          3245: +              
        !          3246: +              l = v = 0;
        !          3247: +              if ((pce = pcre_get_compiled_regex_cache(Z_STRVAL_P(pattern), Z_STRLEN_P(pattern) TSRMLS_CC)) == NULL) {
1.1       misho    3248: +                      zval_dtor(pattern);
                   3249: +                      FREE_ZVAL(pattern);
                   3250: +                      return -1;
                   3251: +              } else {
                   3252: +                      /* pce now contains the compiled regex */
                   3253: +                      zval *retval;
                   3254: +                      zval *subpats;
                   3255: +                      char *haystack;
                   3256: +                      
                   3257: +                      MAKE_STD_ZVAL(retval);
                   3258: +                      ALLOC_INIT_ZVAL(subpats);
                   3259: +                      
                   3260: +                      /* Cut the search len from haystack, equals to REG_STARTEND */
                   3261: +                      haystack = estrndup(ms->search.s, ms->search.s_len);
                   3262: +
                   3263: +                      /* match v = 0, no match v = 1 */
                   3264: +                      php_pcre_match_impl(pce, haystack, ms->search.s_len, retval, subpats, 1, 1, PREG_OFFSET_CAPTURE, 0 TSRMLS_CC);
                   3265: +                      /* Free haystack */
                   3266: +                      efree(haystack);
                   3267: +                      
                   3268: +                      if (Z_LVAL_P(retval) < 0) {
                   3269: +                              zval_ptr_dtor(&subpats);
                   3270: +                              FREE_ZVAL(retval);
                   3271: +                              zval_dtor(pattern);
                   3272: +                              FREE_ZVAL(pattern);
                   3273: +                              return -1;
                   3274: +                      } else if ((Z_LVAL_P(retval) > 0) && (Z_TYPE_P(subpats) == IS_ARRAY)) {
                   3275: +                              
                   3276: +                              /* Need to fetch global match which equals pmatch[0] */
                   3277: +                              HashTable *ht = Z_ARRVAL_P(subpats);
                   3278: +                              HashPosition outer_pos;
                   3279: +                              zval *pattern_match = NULL, *pattern_offset = NULL;
                   3280: +                              
                   3281: +                              zend_hash_internal_pointer_reset_ex(ht, &outer_pos); 
                   3282: +                              
                   3283: +                              if (zend_hash_has_more_elements_ex(ht, &outer_pos) == SUCCESS &&
                   3284: +                                      zend_hash_move_forward_ex(ht, &outer_pos)) {
                   3285: +                                      
                   3286: +                                      zval **ppzval;
                   3287: +                                      
                   3288: +                                      /* The first element (should be) is the global match 
                   3289: +                                         Need to move to the inner array to get the global match */
                   3290: +                                      
                   3291: +                                      if (zend_hash_get_current_data_ex(ht, (void**)&ppzval, &outer_pos) != FAILURE) { 
                   3292: +                                              
                   3293: +                                              HashTable *inner_ht;
                   3294: +                                              HashPosition inner_pos;
                   3295: +                                              zval **match, **offset;
                   3296: +                                              zval tmpcopy = **ppzval, matchcopy, offsetcopy;
                   3297: +                                              
                   3298: +                                              zval_copy_ctor(&tmpcopy); 
                   3299: +                                              INIT_PZVAL(&tmpcopy);
                   3300: +                                              
                   3301: +                                              inner_ht = Z_ARRVAL(tmpcopy);
                   3302: +                                              
                   3303: +                                              /* If everything goes according to the master plan
                   3304: +                                                 tmpcopy now contains two elements:
                   3305: +                                                 0 = the match
                   3306: +                                                 1 = starting position of the match */
                   3307: +                                              zend_hash_internal_pointer_reset_ex(inner_ht, &inner_pos); 
                   3308: +                                              
                   3309: +                                              if (zend_hash_has_more_elements_ex(inner_ht, &inner_pos) == SUCCESS &&
                   3310: +                                                      zend_hash_move_forward_ex(inner_ht, &inner_pos)) {
                   3311: +                                              
                   3312: +                                                      if (zend_hash_get_current_data_ex(inner_ht, (void**)&match, &inner_pos) != FAILURE) { 
                   3313: +                                                                      
                   3314: +                                                              matchcopy = **match;
                   3315: +                                                              zval_copy_ctor(&matchcopy);
                   3316: +                                                              INIT_PZVAL(&matchcopy);
                   3317: +                                                              convert_to_string(&matchcopy); 
                   3318: +                                                              
                   3319: +                                                              MAKE_STD_ZVAL(pattern_match);
                   3320: +                                                              Z_STRVAL_P(pattern_match) = (char *)Z_STRVAL(matchcopy);
                   3321: +                                                              Z_STRLEN_P(pattern_match) = Z_STRLEN(matchcopy);
                   3322: +                                                              Z_TYPE_P(pattern_match) = IS_STRING; 
                   3323: +
                   3324: +                                                              zval_dtor(&matchcopy);
                   3325: +                                                      }
                   3326: +                                              }
                   3327: +                                              
                   3328: +                                              if (zend_hash_has_more_elements_ex(inner_ht, &inner_pos) == SUCCESS &&
                   3329: +                                                      zend_hash_move_forward_ex(inner_ht, &inner_pos)) {
                   3330: +                                                      
                   3331: +                                                      if (zend_hash_get_current_data_ex(inner_ht, (void**)&offset, &inner_pos) != FAILURE) { 
                   3332: +                                                              
                   3333: +                                                              offsetcopy = **offset;
                   3334: +                                                              zval_copy_ctor(&offsetcopy);
                   3335: +                                                              INIT_PZVAL(&offsetcopy);
                   3336: +                                                              convert_to_long(&offsetcopy); 
                   3337: +                                                              
                   3338: +                                                              MAKE_STD_ZVAL(pattern_offset);
                   3339: +                                                              Z_LVAL_P(pattern_offset) = Z_LVAL(offsetcopy);
                   3340: +                                                              Z_TYPE_P(pattern_offset) = IS_LONG;
                   3341: +                                                              
                   3342: +                                                              zval_dtor(&offsetcopy);
                   3343: +                                                      }
                   3344: +                                              }
                   3345: +                                              zval_dtor(&tmpcopy);    
                   3346: +                                      }
                   3347: +                                      
                   3348: +                                      if ((pattern_match != NULL) && (pattern_offset != NULL)) {
                   3349: +                                              ms->search.s += (int)Z_LVAL_P(pattern_offset); /* this is where the match starts */
                   3350: +                                              ms->search.offset += (size_t)Z_LVAL_P(pattern_offset); /* this is where the match starts as size_t */
                   3351: +                                              ms->search.rm_len = Z_STRLEN_P(pattern_match) /* This is the length of the matched pattern */;
                   3352: +                                              v = 0;
                   3353: +                                              
                   3354: +                                              efree(pattern_match);
                   3355: +                                              efree(pattern_offset);
                   3356: +                                              
                   3357: +                                      } else {
                   3358: +                                              zval_ptr_dtor(&subpats);
                   3359: +                                              FREE_ZVAL(retval);
                   3360: +                                              zval_dtor(pattern);
                   3361: +                                              FREE_ZVAL(pattern);
                   3362: +                                              return -1;
                   3363: +                                      }                                       
                   3364: +                              }
                   3365:  
                   3366: -                      case REG_NOMATCH:
                   3367: +                              
                   3368: +                      } else {
                   3369:                                v = 1;
                   3370: -                              break;
                   3371: -
                   3372: -                      default:
                   3373: -                              (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
                   3374: -                              file_magerror(ms, "regexec error %d, (%s)",
                   3375: -                                  rc, errmsg);
                   3376: -                              v = (uint64_t)-1;
                   3377: -                              break;
                   3378:                        }
                   3379: -                      regfree(&rx);
                   3380: +                      zval_ptr_dtor(&subpats);
                   3381: +                      FREE_ZVAL(retval);
                   3382:                }
                   3383: -              if (v == (uint64_t)-1)
                   3384: -                      return -1;
                   3385: -              break;
                   3386: +              zval_dtor(pattern);
                   3387: +              FREE_ZVAL(pattern);
                   3388: +              break;  
                   3389:        }
                   3390:        case FILE_INDIRECT:
1.1.1.3 ! misho    3391:        case FILE_USE:
        !          3392:        case FILE_NAME:
1.1       misho    3393: -              return 1;
                   3394: +              return 1;        
                   3395:        default:
                   3396:                file_magerror(ms, "invalid type %d in magiccheck()", m->type);
                   3397:                return -1;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>