--- embedaddon/php/ext/fileinfo/libmagic.patch 2012/02/21 23:47:56 1.1.1.1 +++ embedaddon/php/ext/fileinfo/libmagic.patch 2014/06/15 20:03:48 1.1.1.4 @@ -1,6 +1,6 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c ---- libmagic.orig/apprentice.c 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/apprentice.c 2011-09-15 23:29:29.000000000 +0800 +--- libmagic.orig/apprentice.c Thu Mar 21 18:45:14 2013 ++++ libmagic/apprentice.c Fri Apr 11 12:36:52 2014 @@ -29,6 +29,8 @@ * apprentice - make one pass through /etc/magic, learning its secrets. */ @@ -10,9 +10,11 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice #include "file.h" #ifndef lint -@@ -38,17 +40,32 @@ +@@ -36,18 +38,30 @@ + #endif /* lint */ + #include "magic.h" - #include "patchlevel.h" ++#include "patchlevel.h" #include -#ifdef HAVE_UNISTD_H + @@ -33,7 +35,6 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice +#else #include #endif -+ #include #include #include @@ -41,26 +42,11 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice -#ifdef QUICK -#include -#endif -+#ifndef PHP_WIN32 - #include -+#endif +-#include #define EATAB {while (isascii((unsigned char) *l) && \ isspace((unsigned char) *l)) ++l;} -@@ -116,12 +133,10 @@ - private int parse_strength(struct magic_set *, struct magic_entry *, const char *); - private int parse_apple(struct magic_set *, struct magic_entry *, const char *); - -- - private size_t maxmagic = 0; - private size_t magicsize = sizeof(struct magic); - - private const char usg_hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc"; -- - private struct { - const char *name; - size_t len; -@@ -135,38 +150,7 @@ +@@ -143,38 +157,7 @@ { NULL, 0, NULL } }; @@ -98,173 +84,229 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice -#endif /* COMPILE_ONLY */ +#include "../data_file.c" - static const struct type_tbl_s { + struct type_tbl_s { const char name[16]; -@@ -222,6 +206,10 @@ +@@ -255,6 +238,10 @@ + # undef XX # undef XX_NULL - }; +#ifndef S_ISDIR +#define S_ISDIR(mode) ((mode) & _S_IFDIR) +#endif + private int - get_type(const char *l, const char **t) + get_type(const struct type_tbl_s *tbl, const char *l, const char **t) { -@@ -279,15 +267,17 @@ - if (rv != 0) - return -1; - rv = apprentice_compile(ms, &magic, &nmagic, fn); -- free(magic); -+ efree(magic); - return rv; +@@ -378,7 +365,7 @@ + { + struct mlist *ml; + +- if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL) ++ if ((ml = CAST(struct mlist *, emalloc(sizeof(*ml)))) == NULL) + return -1; + + ml->map = idx == 0 ? map : NULL; +@@ -416,12 +403,13 @@ + return apprentice_compile(ms, map, fn); } -#ifndef COMPILE_ONLY - if ((rv = apprentice_map(ms, &magic, &nmagic, fn)) == -1) { + map = apprentice_map(ms, fn); + if (map == NULL) { - if (ms->flags & MAGIC_CHECK) - file_magwarn(ms, "using regular magic file `%s'", fn); -- rv = apprentice_load(ms, &magic, &nmagic, fn, action); +- map = apprentice_load(ms, fn, action); + if (fn) { + if (ms->flags & MAGIC_CHECK) + file_magwarn(ms, "using regular magic file `%s'", fn); -+ rv = apprentice_load(ms, &magic, &nmagic, fn, action); ++ map = apprentice_load(ms, fn, action); + } -+ - if (rv != 0) + if (map == NULL) return -1; } -@@ -299,11 +289,7 @@ - return -1; +@@ -444,7 +432,6 @@ } - -- if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL) { -- file_delmagic(magic, mapped, nmagic); -- file_oomem(ms, sizeof(*ml)); -- return -1; -- } -+ ml = emalloc(sizeof(*ml)); - - ml->magic = magic; - ml->nmagic = nmagic; -@@ -315,7 +301,6 @@ - mlist->prev = ml; - + return 0; -#endif /* COMPILE_ONLY */ } protected void -@@ -324,22 +309,18 @@ - if (p == NULL) +@@ -455,10 +442,16 @@ return; - switch (type) { -- case 2: + for (i = 0; i < MAGIC_SETS; i++) + mlist_free(ms->mlist[i]); +- free(ms->o.pbuf); +- free(ms->o.buf); +- free(ms->c.li); +- free(ms); ++ if (ms->o.pbuf) { ++ efree(ms->o.pbuf); ++ } ++ if (ms->o.buf) { ++ efree(ms->o.buf); ++ } ++ if (ms->c.li) { ++ efree(ms->c.li); ++ } ++ efree(ms); + } + + protected struct magic_set * +@@ -467,7 +460,7 @@ + struct magic_set *ms; + size_t i, len; + +- if ((ms = CAST(struct magic_set *, calloc((size_t)1, ++ if ((ms = CAST(struct magic_set *, ecalloc((size_t)1, + sizeof(struct magic_set)))) == NULL) + return NULL; + +@@ -479,7 +472,7 @@ + ms->o.buf = ms->o.pbuf = NULL; + len = (ms->c.len = 10) * sizeof(*ms->c.li); + +- if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL) ++ if ((ms->c.li = CAST(struct level_info *, emalloc(len))) == NULL) + goto free; + + ms->event_flags = 0; +@@ -490,7 +483,7 @@ + ms->line = 0; + return ms; + free: +- free(ms); ++ efree(ms); + return NULL; + } + +@@ -499,22 +492,26 @@ + { + if (map == NULL) + return; +- if (map->p == NULL) +- return; -#ifdef QUICK -- p--; -- (void)munmap((void *)p, sizeof(*p) * (entries + 1)); -+ case 3: -+ /* Do nothing, it's part of the code segment */ - break; --#else -- (void)&entries; -- abort(); -- /*NOTREACHED*/ +- if (map->len) +- (void)munmap(map->p, map->len); +- else -#endif -+ - case 1: - p--; - /*FALLTHROUGH*/ -+ - case 0: -- free(p); -+ efree(p); - break; -+ - default: - abort(); +- free(map->p); +- free(map); ++ if (map->p != php_magic_database) { ++ if (map->p == NULL) { ++ int j; ++ for (j = 0; j < MAGIC_SETS; j++) { ++ if (map->magic[j]) { ++ efree(map->magic[j]); ++ } ++ } ++ } else { ++ efree(map->p); ++ } ++ } ++ efree(map); + } + + private struct mlist * + mlist_alloc(void) + { + struct mlist *mlist; +- if ((mlist = CAST(struct mlist *, calloc(1, sizeof(*mlist)))) == NULL) { ++ if ((mlist = CAST(struct mlist *, ecalloc(1, sizeof(*mlist)))) == NULL) { + return NULL; } -@@ -357,20 +338,17 @@ + mlist->next = mlist->prev = mlist; +@@ -533,10 +530,10 @@ + struct mlist *next = ml->next; + if (ml->map) + apprentice_unmap(ml->map); +- free(ml); ++ efree(ml); + ml = next; + } +- free(ml); ++ efree(ml); + } - if (fn == NULL) - fn = getenv("MAGIC"); -- if (fn == NULL) -- fn = MAGIC; + /* const char *fn: list of magic files and directories */ +@@ -546,13 +543,28 @@ + char *p, *mfn; + int file_err, errs = -1; + size_t i; - ++/* XXX disabling default magic loading so the compiled in data is used */ ++#if 0 + if ((fn = magic_getpath(fn, action)) == NULL) + return -1; ++#endif + + init_file_tables(); + - if ((mfn = strdup(fn)) == NULL) { -- file_oomem(ms, strlen(fn)); -- return NULL; ++ if (fn == NULL) ++ fn = getenv("MAGIC"); + if (fn == NULL) { -+ mlist = emalloc(sizeof(*mlist)); -+ mlist->next = mlist->prev = mlist; -+ apprentice_1(ms, fn, action, mlist); -+ return mlist; - } ++ for (i = 0; i < MAGIC_SETS; i++) { ++ mlist_free(ms->mlist[i]); ++ if ((ms->mlist[i] = mlist_alloc()) == NULL) { ++ file_oomem(ms, sizeof(*ms->mlist[i])); ++ return -1; ++ } ++ } ++ return apprentice_1(ms, fn, action); ++ } + -+ mfn = estrdup(fn); - fn = mfn; - -- if ((mlist = CAST(struct mlist *, malloc(sizeof(*mlist)))) == NULL) { -- free(mfn); -- file_oomem(ms, sizeof(*mlist)); -- return NULL; -- } -+ mlist = emalloc(sizeof(*mlist)); - mlist->next = mlist->prev = mlist; - - while (fn) { -@@ -384,13 +362,13 @@ - fn = p; ++ if ((mfn = estrdup(fn)) == NULL) { + file_oomem(ms, strlen(fn)); + return -1; } - if (errs == -1) { -- free(mfn); -- free(mlist); -+ efree(mfn); -+ efree(mlist); - mlist = NULL; - file_error(ms, 0, "could not find any magic files!"); - return NULL; +@@ -567,7 +579,7 @@ + mlist_free(ms->mlist[i]); + while (i != 0); + } +- free(mfn); ++ efree(mfn); + return -1; + } } +@@ -584,7 +596,7 @@ + fn = p; + } + - free(mfn); + efree(mfn); - return mlist; - } -@@ -523,6 +501,7 @@ - abort(); - } + if (errs == -1) { + for (i = 0; i < MAGIC_SETS; i++) { +@@ -904,7 +916,7 @@ -+ - /* - * Magic entries with no description get a bonus because they depend - * on subsequent magic entries to print something. -@@ -538,8 +517,8 @@ - private int - apprentice_sort(const void *a, const void *b) - { -- const struct magic_entry *ma = CAST(const struct magic_entry *, a); -- const struct magic_entry *mb = CAST(const struct magic_entry *, b); -+ const struct magic_entry *ma = a; -+ const struct magic_entry *mb = b; - size_t sa = apprentice_magic_strength(ma->mp); - size_t sb = apprentice_magic_strength(mb->mp); - if (sa == sb) -@@ -617,34 +596,51 @@ + maxmagic[i] += ALLOC_INCR; + if ((mp = CAST(struct magic_entry *, +- realloc(mentry[i], sizeof(*mp) * maxmagic[i]))) == ++ erealloc(mentry[i], sizeof(*mp) * maxmagic[i]))) == + NULL) { + file_oomem(ms, sizeof(*mp) * maxmagic[i]); + return -1; +@@ -925,13 +937,24 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs, - struct magic_entry **marray, uint32_t *marraycount) + struct magic_entry **mentry, uint32_t *mentrycount) { -- char line[BUFSIZ]; +- size_t lineno = 0, llen = 0; + char buffer[BUFSIZ + 1]; -+ char *line; -+ size_t line_len; - size_t lineno = 0; + char *line = NULL; +- ssize_t len; ++ size_t len; ++ size_t lineno = 0; + struct magic_entry me; + - FILE *f = fopen(ms->file = fn, "r"); - if (f == NULL) { -+ + php_stream *stream; + + TSRMLS_FETCH(); + ++ ms->file = fn; +#if PHP_API_VERSION < 20100412 + stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL); +#else @@ -275,164 +317,208 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice if (errno != ENOENT) file_error(ms, errno, "cannot read magic file `%s'", fn); - (*errs)++; - } else { -+ - /* read and parse this file */ -- for (ms->line = 1; fgets(line, sizeof(line), f) != NULL; ms->line++) { -- size_t len; -- len = strlen(line); -- if (len == 0) /* null line, garbage, etc */ -+#if (PHP_MAJOR_VERSION < 6) -+ for (ms->line = 1; (line = php_stream_get_line(stream, buffer , BUFSIZ, &line_len)) != NULL; ms->line++) { -+#else -+ for (ms->line = 1; (line = php_stream_get_line(stream, ZSTR(buffer), BUFSIZ, &line_len)) != NULL; ms->line++) { -+#endif -+ if (line_len == 0) /* null line, garbage, etc */ - continue; -- if (line[len - 1] == '\n') { -+ -+ if (line[line_len - 1] == '\n') { - lineno++; -- line[len - 1] = '\0'; /* delete newline */ -+ line[line_len - 1] = '\0'; /* delete newline */ - } - if (line[0] == '\0') /* empty, do not parse */ - continue; - if (line[0] == '#') /* comment, do not parse */ - continue; -+ - if (line[0] == '!' && line[1] == ':') { - size_t i; +@@ -941,8 +964,7 @@ - for (i = 0; bang[i].name != NULL; i++) { -- if (len - 2 > bang[i].len && -+ if (line_len - 2 > bang[i].len && - memcmp(bang[i].name, line + 2, - bang[i].len) == 0) - break; -@@ -670,12 +666,11 @@ - } - continue; - } -- if (parse(ms, marray, marraycount, line, lineno, -- action) != 0) -+ if (parse(ms, marray, marraycount, line, lineno, action) != 0) + memset(&me, 0, sizeof(me)); + /* read and parse this file */ +- for (ms->line = 1; (len = getline(&line, &llen, f)) != -1; +- ms->line++) { ++ for (ms->line = 1; (line = php_stream_get_line(stream, buffer , BUFSIZ, &len)) != NULL; ms->line++) { + if (len == 0) /* null line, garbage, etc */ + continue; + if (line[len - 1] == '\n') { +@@ -994,14 +1016,13 @@ + goto again; + default: (*errs)++; +- break; +- } ++ break; } + } ++ } + if (me.mp) + (void)addentry(ms, &me, mentry, mentrycount); +- free(line); +- (void)fclose(f); ++ php_stream_close(stream); + } -- (void)fclose(f); -+ php_stream_close(stream); + /* +@@ -1080,7 +1101,7 @@ + mentrycount += me[i].cont_count; + + slen = sizeof(**ma) * mentrycount; +- if ((*ma = CAST(struct magic *, malloc(slen))) == NULL) { ++ if ((*ma = CAST(struct magic *, emalloc(slen))) == NULL) { + file_oomem(ms, slen); + return -1; } +@@ -1102,27 +1123,29 @@ + if (me == NULL) + return; + for (i = 0; i < nme; i++) +- free(me[i].mp); +- free(me); ++ efree(me[i].mp); ++ efree(me); } -@@ -690,7 +685,6 @@ - int errs = 0; - struct magic_entry *marray; - uint32_t marraycount, i, mentrycount = 0, starttest; -- size_t slen; - char subfn[MAXPATHLEN]; + private struct magic_map * + apprentice_load(struct magic_set *ms, const char *fn, int action) + { +- int errs = 0; ++ int errs = 0; + struct magic_entry *mentry[MAGIC_SETS] = { NULL }; + uint32_t mentrycount[MAGIC_SETS] = { 0 }; + uint32_t i, j; + size_t files = 0, maxfiles = 0; +- char **filearr = NULL, *mfn; ++ char **filearr = NULL; struct stat st; - DIR *dir; -@@ -698,12 +692,8 @@ + struct magic_map *map; +- DIR *dir; +- struct dirent *d; ++ php_stream *dir; ++ php_stream_dirent d; ++ ++ TSRMLS_FETCH(); ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */ -- maxmagic = MAXMAGIS; -- if ((marray = CAST(struct magic_entry *, calloc(maxmagic, -- sizeof(*marray)))) == NULL) { -- file_oomem(ms, maxmagic * sizeof(*marray)); -- return -1; -- } -+ maxmagic = MAXMAGIS; -+ marray = ecalloc(maxmagic, sizeof(*marray)); - marraycount = 0; +- if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) { ++ if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) { + file_oomem(ms, sizeof(*map)); + return NULL; + } +@@ -1131,23 +1154,37 @@ + if (action == FILE_CHECK) + (void)fprintf(stderr, "%s\n", usg_hdr); - /* print silly verbose header for USG compat. */ -@@ -713,14 +703,14 @@ ++ { ++ /* XXX the maxmagic has to be reset each time we load some new magic file. ++ Where file commando is used it's not essential as the CLI process ++ ends, multiple loading within the same process wouldn't work. */ ++ int k; ++ for (k = 0; k < MAGIC_SETS; k++) { ++ maxmagic[k] = 0; ++ } ++ } ++ /* load directory or file */ - /* FIXME: Read file names and sort them to prevent - non-determinism. See Debian bug #488562. */ - if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) { +- dir = opendir(fn); ++ /* FIXME: Read file names and sort them to prevent ++ non-determinism. See Debian bug #488562. */ + if (php_sys_stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) { - dir = opendir(fn); - if (dir) { - while ((d = readdir(dir)) != NULL) { - snprintf(subfn, sizeof(subfn), "%s/%s", - fn, d->d_name); - if (stat(subfn, &st) == 0 && -- S_ISREG(st.st_mode)) { -+ S_ISREG(st.st_mode)) { - load_1(ms, action, subfn, &errs, - &marray, &marraycount); ++ int mflen; ++ char mfn[MAXPATHLEN]; ++ ++ dir = php_stream_opendir((char *)fn, REPORT_ERRORS, NULL); + if (!dir) { + errs++; + goto out; + } +- while ((d = readdir(dir)) != NULL) { +- if (asprintf(&mfn, "%s/%s", fn, d->d_name) < 0) { ++ while (php_stream_readdir(dir, &d)) { ++ if ((mflen = snprintf(mfn, sizeof(mfn), "%s/%s", fn, d.d_name)) < 0) { + file_oomem(ms, +- strlen(fn) + strlen(d->d_name) + 2); ++ strlen(fn) + strlen(d.d_name) + 2); + errs++; +- closedir(dir); ++ php_stream_closedir(dir); + goto out; + } + if (stat(mfn, &st) == -1 || !S_ISREG(st.st_mode)) { +- free(mfn); + continue; + } + if (files >= maxfiles) { +@@ -1155,24 +1192,23 @@ + maxfiles = (maxfiles + 1) * 2; + mlen = maxfiles * sizeof(*filearr); + if ((filearr = CAST(char **, +- realloc(filearr, mlen))) == NULL) { ++ erealloc(filearr, mlen))) == NULL) { + file_oomem(ms, mlen); +- free(mfn); +- closedir(dir); ++ php_stream_closedir(dir); + errs++; + goto out; } -@@ -790,12 +780,7 @@ - for (i = 0; i < marraycount; i++) - mentrycount += marray[i].cont_count; - -- slen = sizeof(**magicp) * mentrycount; -- if ((*magicp = CAST(struct magic *, malloc(slen))) == NULL) { -- file_oomem(ms, slen); -- errs++; -- goto out; -- } -+ *magicp = emalloc(sizeof(**magicp) * mentrycount); - - mentrycount = 0; - for (i = 0; i < marraycount; i++) { -@@ -805,8 +790,8 @@ - } - out: - for (i = 0; i < marraycount; i++) -- free(marray[i].mp); -- free(marray); -+ efree(marray[i].mp); -+ efree(marray); + } +- filearr[files++] = mfn; ++ filearr[files++] = estrndup(mfn, (mflen > sizeof(mfn) - 1)? sizeof(mfn) - 1: mflen); + } +- closedir(dir); ++ php_stream_closedir(dir); + qsort(filearr, files, sizeof(*filearr), cmpstrp); + for (i = 0; i < files; i++) { + load_1(ms, action, filearr[i], &errs, mentry, + mentrycount); +- free(filearr[i]); ++ efree(filearr[i]); + } +- free(filearr); ++ efree(filearr); + } else + load_1(ms, action, fn, &errs, mentry, mentrycount); + if (errs) +@@ -1211,9 +1247,9 @@ if (errs) { - *magicp = NULL; - *nmagicp = 0; -@@ -1081,11 +1066,7 @@ + for (j = 0; j < MAGIC_SETS; j++) { + if (map->magic[j]) +- free(map->magic[j]); ++ efree(map->magic[j]); + } +- free(map); ++ efree(map); + return NULL; + } + return map; +@@ -1500,7 +1536,7 @@ if (me->cont_count == me->max_count) { struct magic *nm; size_t cnt = me->max_count + ALLOC_CHUNK; - if ((nm = CAST(struct magic *, realloc(me->mp, -- sizeof(*nm) * cnt))) == NULL) { -- file_oomem(ms, sizeof(*nm) * cnt); -- return -1; -- } -+ nm = erealloc(me->mp, sizeof(*nm) * cnt); - me->mp = m = nm; - me->max_count = cnt; ++ if ((nm = CAST(struct magic *, erealloc(me->mp, + sizeof(*nm) * cnt))) == NULL) { + file_oomem(ms, sizeof(*nm) * cnt); + return -1; +@@ -1515,7 +1551,7 @@ + static const size_t len = sizeof(*m) * ALLOC_CHUNK; + if (me->mp != NULL) + return 1; +- if ((m = CAST(struct magic *, malloc(len))) == NULL) { ++ if ((m = CAST(struct magic *, emalloc(len))) == NULL) { + file_oomem(ms, len); + return -1; } -@@ -1097,23 +1078,13 @@ - struct magic_entry *mp; - - maxmagic += ALLOC_INCR; -- if ((mp = CAST(struct magic_entry *, -- realloc(*mentryp, sizeof(*mp) * maxmagic))) == -- NULL) { -- file_oomem(ms, sizeof(*mp) * maxmagic); -- return -1; -- } -- (void)memset(&mp[*nmentryp], 0, sizeof(*mp) * -- ALLOC_INCR); -+ mp = erealloc(*mentryp, sizeof(*mp) * maxmagic); -+ (void)memset(&mp[*nmentryp], 0, sizeof(*mp) * ALLOC_INCR); - *mentryp = mp; +@@ -1688,7 +1724,7 @@ + m->type = get_standard_integer_type(l, &l); + else if (*l == 's' && !isalpha((unsigned char)l[1])) { + m->type = FILE_STRING; +- ++l; ++ ++l; + } } - me = &(*mentryp)[*nmentryp]; - if (me->mp == NULL) { -- size_t len = sizeof(*m) * ALLOC_CHUNK; -- if ((m = CAST(struct magic *, malloc(len))) == NULL) { -- file_oomem(ms, len); -- return -1; -- } -+ m = safe_emalloc(sizeof(*m), ALLOC_CHUNK, 0); - me->mp = m; - me->max_count = ALLOC_CHUNK; - } else -@@ -1264,7 +1235,7 @@ + } +@@ -1701,6 +1737,10 @@ + if (m->type == FILE_INVALID) { + if (ms->flags & MAGIC_CHECK) + file_magwarn(ms, "type `%s' invalid", l); ++ if (me->mp) { ++ efree(me->mp); ++ me->mp = NULL; ++ } + return -1; + } +@@ -1709,7 +1749,7 @@ + m->mask_op = 0; if (*l == '~') { - if (!IS_STRING(m->type)) @@ -440,16 +526,16 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice m->mask_op |= FILE_OPINVERSE; else if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "'~' invalid for string types"); -@@ -1274,7 +1245,7 @@ - m->str_flags = 0; - m->num_mask = 0; +@@ -1718,7 +1758,7 @@ + m->str_range = 0; + m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0; if ((op = get_op(*l)) != -1) { - if (!IS_STRING(m->type)) { + if (!IS_LIBMAGIC_STRING(m->type)) { uint64_t val; ++l; m->mask_op |= op; -@@ -1423,11 +1394,6 @@ +@@ -1909,11 +1949,6 @@ if (check_format(ms, m) == -1) return -1; } @@ -459,43 +545,52 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice - } -#endif m->mimetype[0] = '\0'; /* initialise MIME type to none */ - if (m->cont_level == 0) - ++(*nmentryp); /* make room for next */ -@@ -2053,56 +2019,68 @@ - - /* - * handle a compiled file. -+ * return -1 = error -+ * return 1 = memory structure you can free -+ * return 3 = bundled library from PHP - */ - private int - apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, - const char *fn) + return 0; + } +@@ -2554,59 +2589,80 @@ + private struct magic_map * + apprentice_map(struct magic_set *ms, const char *fn) { - int fd; - struct stat st; uint32_t *ptr; - uint32_t version; + uint32_t version, entries, nentries; int needsbyteswap; char *dbname = NULL; - void *mm = NULL; -+ int ret = 0; + struct magic_map *map; + size_t i; + php_stream *stream = NULL; + php_stream_statbuf st; + +- fd = -1; +- if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) { + -+ + TSRMLS_FETCH(); + ++ if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) { + file_oomem(ms, sizeof(*map)); ++ efree(map); + goto error; + } + + if (fn == NULL) { -+ mm = (void *)&php_magic_database; -+ ret = 3; ++ map->p = (void *)&php_magic_database; + goto internal_loaded; + } - ++ ++#ifdef PHP_WIN32 ++ /* Don't bother on windows with php_stream_open_wrapper, ++ return to give apprentice_load() a chance. */ ++ if (php_stream_stat_path_ex((char *)fn, 0, &st, NULL) == SUCCESS) { ++ if (st.sb.st_mode & S_IFDIR) { ++ goto error; ++ } ++ } ++#endif ++ dbname = mkdbname(ms, fn, 0); if (dbname == NULL) - goto error2; + goto error; - if ((fd = open(dbname, O_RDONLY|O_BINARY)) == -1) +#if PHP_API_VERSION < 20100412 @@ -505,155 +600,144 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice +#endif + + if (!stream) { - goto error2; + goto error; + } - if (fstat(fd, &st) == -1) { + if (php_stream_stat(stream, &st) < 0) { file_error(ms, errno, "cannot stat `%s'", dbname); - goto error1; + goto error; } - if (st.st_size < 8) { + + if (st.sb.st_size < 8) { file_error(ms, 0, "file `%s' is too small", dbname); - goto error1; + goto error; } +- map->len = (size_t)st.st_size; -#ifdef QUICK -- if ((mm = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE, +- if ((map->p = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) { - file_error(ms, errno, "cannot map `%s'", dbname); -- goto error1; +- goto error; - } --#define RET 2 -#else -- if ((mm = CAST(void *, malloc((size_t)st.st_size))) == NULL) { -- file_oomem(ms, (size_t)st.st_size); -- goto error1; -- } -- if (read(fd, mm, (size_t)st.st_size) != (ssize_t)st.st_size) { -+ mm = emalloc((size_t)st.sb.st_size); -+ if (php_stream_read(stream, mm, (size_t)st.sb.st_size) != (size_t)st.sb.st_size) { +- if ((map->p = CAST(void *, malloc(map->len))) == NULL) { ++ map->len = (size_t)st.sb.st_size; ++ if ((map->p = CAST(void *, emalloc(map->len))) == NULL) { + file_oomem(ms, map->len); + goto error; + } +- if (read(fd, map->p, map->len) != (ssize_t)map->len) { ++ if (php_stream_read(stream, map->p, (size_t)st.sb.st_size) != (size_t)st.sb.st_size) { file_badread(ms); - goto error1; + goto error; } --#define RET 1 + map->len = 0; + #define RET 1 -#endif -- *magicp = CAST(struct magic *, mm); - (void)close(fd); - fd = -1; -+ ret = 1; +- ptr = CAST(uint32_t *, map->p); + + php_stream_close(stream); + stream = NULL; + +internal_loaded: -+ *magicp = mm; - ptr = (uint32_t *)(void *)*magicp; ++ ptr = (uint32_t *)(void *)map->p; if (*ptr != MAGICNO) { if (swap4(*ptr) != MAGICNO) { -@@ -2110,42 +2088,65 @@ - goto error1; - } - needsbyteswap = 1; -- } else -+ } else { - needsbyteswap = 0; -+ } -+ - if (needsbyteswap) - version = swap4(ptr[1]); + file_error(ms, 0, "bad magic in `%s'", dbname); +@@ -2620,17 +2676,29 @@ else version = ptr[1]; -+ if (version != VERSIONNO) { - file_error(ms, 0, "File %d.%d supports only version %d magic " - "files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel, +- file_error(ms, 0, "File %s supports only version %d magic " +- "files. `%s' is version %d", VERSION, ++ file_error(ms, 0, "File %d.%d supports only version %d magic " ++ "files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel, VERSIONNO, dbname, version); - goto error1; + goto error; } -- *nmagicp = (uint32_t)(st.st_size / sizeof(struct magic)); -- if (*nmagicp > 0) +- entries = (uint32_t)(st.st_size / sizeof(struct magic)); +- if ((off_t)(entries * sizeof(struct magic)) != st.st_size) { +- file_error(ms, 0, "Size of `%s' %llu is not a multiple of %zu", +- dbname, (unsigned long long)st.st_size, +- sizeof(struct magic)); +- goto error; + + /* php_magic_database is a const, performing writes will segfault. This is for big-endian + machines only, PPC and Sparc specifically. Consider static variable or MINIT in + future. */ + if (needsbyteswap && fn == NULL) { -+ mm = emalloc(sizeof(php_magic_database)); -+ mm = memcpy(mm, php_magic_database, sizeof(php_magic_database)); -+ *magicp = mm; -+ ret = 1; ++ map->p = emalloc(sizeof(php_magic_database)); ++ map->p = memcpy(map->p, php_magic_database, sizeof(php_magic_database)); + } + -+ if (fn == NULL) { -+ *nmagicp = (sizeof(php_magic_database) / sizeof(struct magic)); -+ } else { -+ *nmagicp = (uint32_t)(st.sb.st_size / sizeof(struct magic)); -+ } -+ if (*nmagicp > 0) { - (*nmagicp)--; -+ } - (*magicp)++; -- if (needsbyteswap) -+ if (needsbyteswap) { - byteswap(*magicp, *nmagicp); ++ if (NULL != fn) { ++ nentries = (uint32_t)(st.sb.st_size / sizeof(struct magic)); ++ entries = (uint32_t)(st.sb.st_size / sizeof(struct magic)); ++ if ((off_t)(entries * sizeof(struct magic)) != st.sb.st_size) { ++ file_error(ms, 0, "Size of `%s' %llu is not a multiple of %zu", ++ dbname, (unsigned long long)st.sb.st_size, ++ sizeof(struct magic)); ++ goto error; ++ } + } + map->magic[0] = CAST(struct magic *, map->p) + 1; + nentries = 0; +@@ -2643,22 +2711,29 @@ + map->magic[i + 1] = map->magic[i] + map->nmagic[i]; + nentries += map->nmagic[i]; + } +- if (entries != nentries + 1) { ++ if (NULL != fn && entries != nentries + 1) { + file_error(ms, 0, "Inconsistent entries in `%s' %u != %u", + dbname, entries, nentries + 1); + goto error; + } ++ + if (needsbyteswap) + for (i = 0; i < MAGIC_SETS; i++) + byteswap(map->magic[i], map->nmagic[i]); - free(dbname); -- return RET; -+ } + + if (dbname) { + efree(dbname); + } -+ return ret; + return map; - error1: + error: - if (fd != -1) - (void)close(fd); -- if (mm) { --#ifdef QUICK -- (void)munmap((void *)mm, (size_t)st.st_size); --#else -- free(mm); --#endif + if (stream) { + php_stream_close(stream); + } -+ -+ if (mm && ret == 1) { -+ efree(mm); - } else { - *magicp = NULL; - *nmagicp = 0; - } - error2: + apprentice_unmap(map); - free(dbname); + if (dbname) { + efree(dbname); + } - return -1; + return NULL; } -@@ -2159,41 +2160,50 @@ - apprentice_compile(struct magic_set *ms, struct magic **magicp, - uint32_t *nmagicp, const char *fn) - { -- int fd; +@@ -2679,14 +2754,23 @@ char *dbname; int rv = -1; + uint32_t i; + php_stream *stream; - -- dbname = mkdbname(ms, fn, 1); ++ + TSRMLS_FETCH(); -- if (dbname == NULL) +- dbname = mkdbname(ms, fn, 1); + dbname = mkdbname(ms, fn, 0); -+ -+ if (dbname == NULL) { + + if (dbname == NULL) goto out; -+ } -- if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1) { +- if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1) +- { +/* wb+ == O_WRONLY|O_CREAT|O_TRUNC|O_BINARY */ +#if PHP_API_VERSION < 20100412 + stream = php_stream_open_wrapper((char *)fn, "wb+", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL); @@ -665,29 +749,38 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice file_error(ms, errno, "cannot open `%s'", dbname); goto out; } +@@ -2696,31 +2780,33 @@ + goto out; + } -- if (write(fd, ar, sizeof(ar)) != (ssize_t)sizeof(ar)) { -+ if (php_stream_write(stream, (char *)ar, sizeof(ar)) != (ssize_t)sizeof(ar)) { +- if (write(fd, map->nmagic, nm) != (ssize_t)nm) { ++ if (php_stream_write(stream, (const char *)map->nmagic, nm) != (ssize_t)nm) { file_error(ms, errno, "error writing `%s'", dbname); goto out; } -- if (lseek(fd, (off_t)sizeof(struct magic), SEEK_SET) -- != sizeof(struct magic)) { + assert(nm + sizeof(ar) < m); + +- if (lseek(fd, (off_t)m, SEEK_SET) != (off_t)m) { + if (php_stream_seek(stream,(off_t)sizeof(struct magic), SEEK_SET) != sizeof(struct magic)) { file_error(ms, errno, "error seeking `%s'", dbname); goto out; } -- if (write(fd, *magicp, (sizeof(struct magic) * *nmagicp)) -- != (ssize_t)(sizeof(struct magic) * *nmagicp)) { -+ if (php_stream_write(stream, (char *)*magicp, (sizeof(struct magic) * *nmagicp) != (ssize_t)(sizeof(struct magic) * *nmagicp))) { - file_error(ms, errno, "error writing `%s'", dbname); - goto out; + for (i = 0; i < MAGIC_SETS; i++) { + len = m * map->nmagic[i]; +- if (write(fd, map->magic[i], len) != (ssize_t)len) { ++ if (php_stream_write(stream, (const char *)map->magic[i], len) != (ssize_t)len) { + file_error(ms, errno, "error writing `%s'", dbname); + goto out; + } } -- (void)close(fd); -+ php_stream_close(stream); +- if (fd != -1) +- (void)close(fd); ++ if (stream) { ++ php_stream_close(stream); ++ } + rv = 0; out: @@ -696,7 +789,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice return rv; } -@@ -2206,6 +2216,7 @@ +@@ -2733,6 +2819,7 @@ { const char *p, *q; char *buf; @@ -704,26 +797,32 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice if (strip) { if ((p = strrchr(fn, '/')) != NULL) -@@ -2227,14 +2238,14 @@ +@@ -2754,16 +2841,18 @@ q++; /* Compatibility with old code that looked in .mime */ if (ms->flags & MAGIC_MIME) { -- asprintf(&buf, "%.*s.mime%s", (int)(q - fn), fn, ext); +- if (asprintf(&buf, "%.*s.mime%s", (int)(q - fn), fn, ext) < 0) +- return NULL; - if (access(buf, R_OK) != -1) { + spprintf(&buf, MAXPATHLEN, "%.*s.mime%s", (int)(q - fn), fn, ext); ++#ifdef PHP_WIN32 ++ if (VCWD_ACCESS(buf, R_OK) == 0) { ++#else + if (VCWD_ACCESS(buf, R_OK) != -1) { ++#endif ms->flags &= MAGIC_MIME_TYPE; return buf; } - free(buf); + efree(buf); } -- asprintf(&buf, "%.*s%s", (int)(q - fn), fn, ext); +- if (asprintf(&buf, "%.*s%s", (int)(q - fn), fn, ext) < 0) +- return NULL; + spprintf(&buf, MAXPATHLEN, "%.*s%s", (int)(q - fn), fn, ext); /* Compatibility with old code that looked in .mime */ if (strstr(p, ".mime") != NULL) -@@ -2324,7 +2335,7 @@ +@@ -2853,7 +2942,7 @@ m->offset = swap4((uint32_t)m->offset); m->in_offset = swap4((uint32_t)m->in_offset); m->lineno = swap4((uint32_t)m->lineno); @@ -733,34 +832,48 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice m->str_flags = swap4(m->str_flags); } diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c ---- libmagic.orig/ascmagic.c 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/ascmagic.c 2011-09-15 23:28:26.000000000 +0800 -@@ -144,10 +144,8 @@ - /* malloc size is a conservative overestimate; could be - improved, or at least realloced after conversion. */ - mlen = ulen * 6; -- if ((utf8_buf = CAST(unsigned char *, malloc(mlen))) == NULL) { -- file_oomem(ms, mlen); -- goto done; -- } -+ utf8_buf = emalloc(mlen); -+ - if ((utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen)) == NULL) - goto done; - if ((rv = file_softmagic(ms, utf8_buf, (size_t)(utf8_end - utf8_buf), -@@ -310,7 +308,7 @@ +--- libmagic.orig/ascmagic.c Wed Oct 31 18:03:01 2012 ++++ libmagic/ascmagic.c Mon Mar 10 16:40:55 2014 +@@ -139,7 +139,7 @@ + /* malloc size is a conservative overestimate; could be + improved, or at least realloced after conversion. */ + mlen = ulen * 6; +- if ((utf8_buf = CAST(unsigned char *, malloc(mlen))) == NULL) { ++ if ((utf8_buf = CAST(unsigned char *, emalloc(mlen))) == NULL) { + file_oomem(ms, mlen); + goto done; + } +@@ -147,7 +147,7 @@ + == NULL) + goto done; + if ((rv = file_softmagic(ms, utf8_buf, +- (size_t)(utf8_end - utf8_buf), TEXTTEST, text)) == 0) ++ (size_t)(utf8_end - utf8_buf), 0, TEXTTEST, text)) == 0) + rv = -1; + } + +@@ -211,6 +211,7 @@ + case 0: + if (file_printf(ms, ", ") == -1) + goto done; ++ break; + case -1: + goto done; + default: +@@ -296,7 +297,8 @@ + } rv = 1; done: - if (utf8_buf) -- free(utf8_buf); +- free(utf8_buf); ++ if (utf8_buf) + efree(utf8_buf); return rv; } diff -u libmagic.orig/cdf.c libmagic/cdf.c ---- libmagic.orig/cdf.c 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/cdf.c 2011-09-15 23:29:29.000000000 +0800 -@@ -40,7 +40,17 @@ +--- libmagic.orig/cdf.c Thu Mar 21 18:45:14 2013 ++++ libmagic/cdf.c Tue May 27 22:22:35 2014 +@@ -43,7 +43,17 @@ #include #endif #include @@ -778,7 +891,75 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c #include #include #include -@@ -1042,7 +1052,7 @@ +@@ -296,7 +306,10 @@ + if (info->i_fd == -1) + return -1; + +- if (pread(info->i_fd, buf, len, off) != (ssize_t)len) ++ if (FINFO_LSEEK_FUNC(info->i_fd, off, SEEK_SET) == (off_t)-1) ++ return -1; ++ ++ if (FINFO_READ_FUNC(info->i_fd, buf, len) != (ssize_t)len) + return -1; + + return (ssize_t)len; +@@ -810,6 +823,10 @@ + i, inp[i].pi_id, inp[i].pi_type, q - p, offs)); + if (inp[i].pi_type & CDF_VECTOR) { + nelements = CDF_GETUINT32(q, 1); ++ if (nelements == 0) { ++ DPRINTF(("CDF_VECTOR with nelements == 0\n")); ++ goto out; ++ } + o = 2; + } else { + nelements = 1; +@@ -884,7 +901,9 @@ + } + DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n", + nelements)); +- for (j = 0; j < nelements; j++, i++) { ++ for (j = 0; j < nelements && i < sh.sh_properties; ++ j++, i++) ++ { + uint32_t l = CDF_GETUINT32(q, o); + inp[i].pi_str.s_len = l; + inp[i].pi_str.s_buf = (const char *) +@@ -929,7 +948,7 @@ + cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h, + cdf_summary_info_header_t *ssi, cdf_property_info_t **info, size_t *count) + { +- size_t i, maxcount; ++ size_t maxcount; + const cdf_summary_info_header_t *si = + CAST(const cdf_summary_info_header_t *, sst->sst_tab); + const cdf_section_declaration_t *sd = +@@ -944,21 +963,13 @@ + ssi->si_os = CDF_TOLE2(si->si_os); + ssi->si_class = si->si_class; + cdf_swap_class(&ssi->si_class); +- ssi->si_count = CDF_TOLE2(si->si_count); ++ ssi->si_count = CDF_TOLE4(si->si_count); + *count = 0; + maxcount = 0; + *info = NULL; +- for (i = 0; i < CDF_TOLE4(si->si_count); i++) { +- if (i >= CDF_LOOP_LIMIT) { +- DPRINTF(("Unpack summary info loop limit")); +- errno = EFTYPE; +- return -1; +- } +- if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), +- info, count, &maxcount) == -1) { ++ if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), info, ++ count, &maxcount) == -1) + return -1; +- } +- } + return 0; + } + +@@ -1132,7 +1143,7 @@ cdf_directory_t *d; char name[__arraycount(d->d_name)]; cdf_stream_t scn; @@ -787,23 +968,16 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c static const char *types[] = { "empty", "user storage", "user stream", "lockbytes", "property", "root storage" }; -@@ -1094,13 +1104,13 @@ +@@ -1185,7 +1196,7 @@ cdf_dump_property_info(const cdf_property_info_t *info, size_t count) { cdf_timestamp_t tp; - struct timespec ts; + struct timeval ts; char buf[64]; - size_t i; + size_t i, j; - for (i = 0; i < count; i++) { - cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); -- (void)fprintf(stderr, "%zu) %s: ", i, buf); -+ (void)fprintf(stderr, "%zu) %s: ", i, buf); - switch (info[i].pi_type) { - case CDF_SIGNED16: - (void)fprintf(stderr, "signed 16 [%hd]\n", -@@ -1121,13 +1131,17 @@ +@@ -1229,7 +1240,11 @@ break; case CDF_FILETIME: tp = info[i].pi_tp; @@ -815,18 +989,25 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c cdf_print_elapsed_time(buf, sizeof(buf), tp); (void)fprintf(stderr, "timestamp %s\n", buf); } else { - cdf_timestamp_to_timespec(&ts, tp); - (void)fprintf(stderr, "timestamp %s", -- ctime(&ts.tv_sec)); -+ ctime(&ts.tv_sec)); - } - break; - case CDF_CLIPBOARD: diff -u libmagic.orig/cdf.h libmagic/cdf.h ---- libmagic.orig/cdf.h 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/cdf.h 2011-09-15 23:29:29.000000000 +0800 -@@ -42,7 +42,11 @@ +--- libmagic.orig/cdf.h Wed Oct 31 18:03:01 2012 ++++ libmagic/cdf.h Mon Dec 2 15:25:29 2013 +@@ -35,10 +35,12 @@ + #ifndef _H_CDF_ + #define _H_CDF_ +-#ifdef WIN32 ++#ifdef PHP_WIN32 + #include + #define timespec timeval + #define tv_nsec tv_usec ++#define asctime_r php_asctime_r ++#define ctime_r php_ctime_r + #endif + #ifdef __DJGPP__ + #define timespec timeval +@@ -57,7 +59,11 @@ + typedef struct { uint64_t h_magic; -#define CDF_MAGIC 0xE11AB1A1E011CFD0LL @@ -838,7 +1019,7 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h uint64_t h_uuid[2]; uint16_t h_revision; uint16_t h_version; -@@ -248,9 +252,9 @@ +@@ -267,9 +273,9 @@ size_t i_len; } cdf_info_t; @@ -852,8 +1033,8 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h void cdf_swap_header(cdf_header_t *); void cdf_unpack_header(cdf_header_t *, char *); diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c ---- libmagic.orig/cdf_time.c 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/cdf_time.c 2011-10-19 22:51:40.000000000 +0800 +--- libmagic.orig/cdf_time.c Wed Oct 31 18:03:01 2012 ++++ libmagic/cdf_time.c Mon Dec 2 15:25:29 2013 @@ -96,7 +96,7 @@ } @@ -863,36 +1044,37 @@ diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c { struct tm tm; #ifdef HAVE_STRUCT_TM_TM_ZONE -@@ -104,8 +104,8 @@ +@@ -104,8 +104,9 @@ #endif int rdays; - /* Unit is 100's of nanoseconds */ - ts->tv_nsec = (t % CDF_TIME_PREC) * 100; ++ /* XXX 5.14 at least introdced 100 ns intervals, this is to do */ + /* Time interval, in microseconds */ + ts->tv_usec = (t % CDF_TIME_PREC) * CDF_TIME_PREC; t /= CDF_TIME_PREC; - tm.tm_sec = t % 60; -@@ -117,7 +117,7 @@ - tm.tm_hour = t % 24; + tm.tm_sec = (int)(t % 60); +@@ -117,7 +118,7 @@ + tm.tm_hour = (int)(t % 24); t /= 24; - // XXX: Approx + /* XXX: Approx */ - tm.tm_year = CDF_BASE_YEAR + (t / 365); + tm.tm_year = (int)(CDF_BASE_YEAR + (t / 365)); rdays = cdf_getdays(tm.tm_year); -@@ -143,7 +143,7 @@ - } +@@ -144,7 +145,7 @@ int + /*ARGSUSED*/ -cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timespec *ts) +cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timeval *ts) { + #ifndef __lint__ (void)&t; - (void)&ts; -@@ -153,7 +153,7 @@ +@@ -156,7 +157,7 @@ errno = EINVAL; return -1; } @@ -901,18 +1083,18 @@ diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c *t = tm.tm_sec; *t += tm.tm_min * 60; *t += tm.tm_hour * 60 * 60; -@@ -167,7 +167,7 @@ +@@ -180,7 +181,7 @@ int main(int argc, char *argv[]) { - struct timespec ts; + struct timeval ts; + char buf[25]; static const cdf_timestamp_t tst = 0x01A5E403C2D59C00ULL; static const char *ref = "Sat Apr 23 01:30:00 1977"; - char *p, *q; diff -u libmagic.orig/compress.c libmagic/compress.c ---- libmagic.orig/compress.c 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/compress.c 2011-09-15 23:28:26.000000000 +0800 +--- libmagic.orig/compress.c Sun Jan 6 21:35:43 2013 ++++ libmagic/compress.c Mon Dec 2 15:25:29 2013 @@ -32,6 +32,7 @@ * uncompress(method, old, n, newch) - uncompress old into new, * using method, return sizeof new @@ -921,18 +1103,17 @@ diff -u libmagic.orig/compress.c libmagic/compress.c #include "file.h" #ifndef lint -@@ -45,7 +46,10 @@ +@@ -45,7 +46,8 @@ #endif #include #include +-#ifndef __MINGW32__ +#include +#ifndef PHP_WIN32 #include -+#endif - #ifdef HAVE_SYS_WAIT_H - #include #endif -@@ -57,6 +61,9 @@ + #ifdef HAVE_SYS_WAIT_H +@@ -59,6 +61,9 @@ #include #endif @@ -942,21 +1123,17 @@ diff -u libmagic.orig/compress.c libmagic/compress.c private const struct { const char magic[8]; size_t maglen; -@@ -79,12 +86,10 @@ - { "\3757zXZ\0",6,{ "xz", "-cd", NULL }, 1 }, /* XZ Utils */ - }; - --private size_t ncompr = sizeof(compr) / sizeof(compr[0]); -- +@@ -85,8 +90,7 @@ #define NODATA ((size_t)~0) -- private ssize_t swrite(int, const void *, size_t); +-#if HAVE_FORK +-private size_t ncompr = sizeof(compr) / sizeof(compr[0]); +#ifdef PHP_FILEINFO_UNCOMPRESS private size_t uncompressbuf(struct magic_set *, int, size_t, const unsigned char *, unsigned char **, size_t); #ifdef BUILTIN_DECOMPRESS -@@ -100,10 +105,13 @@ +@@ -102,10 +106,13 @@ size_t i, nsz; int rv = 0; int mime = ms->flags & MAGIC_MIME; @@ -970,64 +1147,85 @@ diff -u libmagic.orig/compress.c libmagic/compress.c for (i = 0; i < ncompr; i++) { if (nbytes < compr[i].maglen) continue; -@@ -133,10 +141,11 @@ +@@ -134,7 +141,8 @@ + } } error: - if (newbuf) -- free(newbuf); +- free(newbuf); ++ if (newbuf) + efree(newbuf); ms->flags |= MAGIC_COMPRESS; return rv; } -+#endif - - /* - * `safe' write for sockets and pipes. -@@ -169,7 +178,7 @@ +@@ -168,7 +176,7 @@ + * `safe' read for sockets and pipes. + */ protected ssize_t - sread(int fd, void *buf, size_t n, int canbepipe) +-sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__))) ++sread(int fd, void *buf, size_t n, int canbepipe) { -- int rv, cnt; -+ int rv; + ssize_t rv; #ifdef FIONREAD - int t = 0; - #endif -@@ -181,6 +190,7 @@ - #ifdef FIONREAD - if ((canbepipe && (ioctl(fd, FIONREAD, &t) == -1)) || (t == 0)) { - #ifdef FD_ZERO -+ int cnt; - for (cnt = 0;; cnt++) { - fd_set check; - struct timeval tout = {0, 100 * 1000}; -@@ -294,6 +304,7 @@ +@@ -216,7 +224,7 @@ + + nocheck: + do +- switch ((rv = read(fd, buf, n))) { ++ switch ((rv = FINFO_READ_FUNC(fd, buf, n))) { + case -1: + if (errno == EINTR) + continue; +@@ -293,13 +301,14 @@ + return -1; + } + (void)close(tfd); +- if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) { ++ if (FINFO_LSEEK_FUNC(fd, (off_t)0, SEEK_SET) == (off_t)-1) { + file_badseek(ms); + return -1; + } return fd; } - +-#if HAVE_FORK ++ +#ifdef PHP_FILEINFO_UNCOMPRESS #ifdef BUILTIN_DECOMPRESS #define FHCRC (1 << 1) -@@ -301,6 +312,7 @@ - #define FNAME (1 << 3) - #define FCOMMENT (1 << 4) +@@ -336,7 +345,7 @@ -+ - private size_t - uncompressgzipped(struct magic_set *ms, const unsigned char *old, - unsigned char **newch, size_t n) -@@ -330,9 +342,7 @@ - if (data_start >= n) return 0; - if ((*newch = CAST(unsigned char *, malloc(HOWMANY + 1))) == NULL) { -- return 0; -- } -+ *newch = (unsigned char *)emalloc(HOWMANY + 1)); ++ if ((*newch = CAST(unsigned char *, emalloc(HOWMANY + 1))) == NULL) { + return 0; + } - /* XXX: const castaway, via strchr */ - z.next_in = (Bytef *)strchr((const char *)old + data_start, -@@ -455,20 +465,14 @@ +@@ -397,19 +406,16 @@ + case 0: /* child */ + (void) close(0); + if (fd != -1) { +- if (dup(fd) == -1) +- _exit(1); +- (void) lseek(0, (off_t)0, SEEK_SET); ++ (void) dup(fd); ++ (void) FINFO_LSEEK_FUNC(0, (off_t)0, SEEK_SET); + } else { +- if (dup(fdin[0]) == -1) +- _exit(1); ++ (void) dup(fdin[0]); + (void) close(fdin[0]); + (void) close(fdin[1]); + } + + (void) close(1); +- if (dup(fdout[1]) == -1) +- _exit(1); ++ (void) dup(fdout[1]); + (void) close(fdout[0]); + (void) close(fdout[1]); + #ifndef DEBUG +@@ -466,20 +472,14 @@ fdin[1] = -1; } @@ -1051,15 +1249,16 @@ diff -u libmagic.orig/compress.c libmagic/compress.c n = 0; newch[0] = '\0'; goto err; -@@ -492,3 +496,4 @@ +@@ -503,4 +503,4 @@ return n; } } +-#endif +#endif /* if PHP_FILEINFO_UNCOMPRESS */ diff -u libmagic.orig/file.h libmagic/file.h ---- libmagic.orig/file.h 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/file.h 2011-09-15 23:28:26.000000000 +0800 -@@ -33,9 +33,7 @@ +--- libmagic.orig/file.h Mon Feb 18 16:40:59 2013 ++++ libmagic/file.h Mon Mar 10 16:40:55 2014 +@@ -33,11 +33,9 @@ #ifndef __file_h__ #define __file_h__ @@ -1068,13 +1267,17 @@ diff -u libmagic.orig/file.h libmagic/file.h -#endif +#include "config.h" - #include /* Include that here, to make sure __P gets defined */ - #include -@@ -46,9 +44,20 @@ +-#ifdef WIN32 ++#ifdef PHP_WIN32 + #ifdef _WIN64 + #define SIZE_T_FORMAT "I64" + #else +@@ -61,10 +59,20 @@ #ifdef HAVE_INTTYPES_H #include #endif -#include +-#include +#ifdef PHP_WIN32 +#include "win32/php_stdint.h" +#endif @@ -1092,16 +1295,16 @@ diff -u libmagic.orig/file.h libmagic/file.h /* Do this here and now, because struct stat gets re-defined on solaris */ #include #include -@@ -59,7 +68,7 @@ +@@ -75,7 +83,7 @@ #define MAGIC "/etc/magic" #endif --#ifdef __EMX__ +-#if defined(__EMX__) || defined (WIN32) +#if defined(__EMX__) || defined(PHP_WIN32) #define PATHSEP ';' #else #define PATHSEP ':' -@@ -81,12 +90,6 @@ +@@ -109,12 +117,6 @@ #endif #endif @@ -1114,16 +1317,16 @@ diff -u libmagic.orig/file.h libmagic/file.h #ifndef MIN #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif -@@ -189,7 +192,7 @@ - #define FILE_INDIRECT 41 - #define FILE_NAMES_SIZE 42/* size of array to contain all names */ +@@ -224,7 +226,7 @@ + #define FILE_USE 46 + #define FILE_NAMES_SIZE 47 /* size of array to contain all names */ -#define IS_STRING(t) \ +#define IS_LIBMAGIC_STRING(t) \ ((t) == FILE_STRING || \ (t) == FILE_PSTRING || \ (t) == FILE_BESTRING16 || \ -@@ -211,7 +214,7 @@ +@@ -248,7 +250,7 @@ #ifdef ENABLE_CONDITIONALS uint8_t cond; /* conditional type */ #else @@ -1132,17 +1335,28 @@ diff -u libmagic.orig/file.h libmagic/file.h #endif uint8_t factor_op; #define FILE_FACTOR_OP_PLUS '+' -@@ -345,20 +348,20 @@ - - struct stat; - protected const char *file_fmttime(uint32_t, int); +@@ -347,7 +349,7 @@ + /* list of magic entries */ + struct mlist { + struct magic *magic; /* array of magic entries */ +- uint32_t nmagic; /* number of entries in array */ ++ uint32_t nmagic; /* number of entries in array */ + void *map; /* internal resources used by entry */ + struct mlist *next, *prev; + }; +@@ -411,21 +413,18 @@ + protected const char *file_fmttime(uint64_t, int, char *); + protected struct magic_set *file_ms_alloc(int); + protected void file_ms_free(struct magic_set *); -protected int file_buffer(struct magic_set *, int, const char *, const void *, +protected int file_buffer(struct magic_set *, php_stream *, const char *, const void *, size_t); -protected int file_fsmagic(struct magic_set *, const char *, struct stat *); -+protected int file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *stream); ++protected int file_fsmagic(struct magic_set *, const char *, struct stat *, php_stream *); protected int file_pipe2file(struct magic_set *, int, const void *, size_t); -protected int file_vprintf(struct magic_set *, const char *, va_list); +-protected size_t file_printedlen(const struct magic_set *); + protected int file_replace(struct magic_set *, const char *, const char *); -protected int file_printf(struct magic_set *, const char *, ...) - __attribute__((__format__(__printf__, 2, 3))); +protected int file_printf(struct magic_set *, const char *, ...); @@ -1151,14 +1365,22 @@ diff -u libmagic.orig/file.h libmagic/file.h size_t); protected int file_trycdf(struct magic_set *, int, const unsigned char *, size_t); +-#if HAVE_FORK +#ifdef PHP_FILEINFO_UNCOMPRESS protected int file_zmagic(struct magic_set *, int, const char *, const unsigned char *, size_t); -+#endif - protected int file_ascmagic(struct magic_set *, const unsigned char *, size_t); - protected int file_ascmagic_with_encoding(struct magic_set *, - const unsigned char *, size_t, unichar *, size_t, const char *, -@@ -375,13 +378,9 @@ + #endif +@@ -438,21 +437,18 @@ + unichar **, size_t *, const char **, const char **, const char **); + protected int file_is_tar(struct magic_set *, const unsigned char *, size_t); + protected int file_softmagic(struct magic_set *, const unsigned char *, size_t, +- int, int); ++ size_t, int, int); + protected int file_apprentice(struct magic_set *, const char *, int); + protected int file_magicfind(struct magic_set *, const char *, struct mlist *); + protected uint64_t file_signextend(struct magic_set *, struct magic *, + uint64_t); ++protected void file_delmagic(struct magic *, int type, size_t entries); protected void file_badread(struct magic_set *); protected void file_badseek(struct magic_set *); protected void file_oomem(struct magic_set *, size_t); @@ -1175,7 +1397,13 @@ diff -u libmagic.orig/file.h libmagic/file.h protected void file_showstr(FILE *, const char *, size_t); protected size_t file_mbswidth(const char *); protected const char *file_getbuffer(struct magic_set *); -@@ -394,11 +393,8 @@ +@@ -462,16 +458,14 @@ + size_t *); + protected size_t file_pstring_length_size(const struct magic *); + protected size_t file_pstring_get_length(const struct magic *, const char *); ++protected size_t file_printedlen(const struct magic_set *ms); + #ifdef __EMX__ + protected int file_os2_apptype(struct magic_set *, const char *, const void *, size_t); #endif /* __EMX__ */ @@ -1187,10 +1415,13 @@ diff -u libmagic.orig/file.h libmagic/file.h #ifndef HAVE_STRERROR extern int sys_nerr; -@@ -411,20 +407,14 @@ +@@ -484,32 +478,16 @@ #define strtoul(a, b, c) strtol(a, b, c) #endif +-#ifndef HAVE_PREAD +-ssize_t pread(int, void *, size_t, off_t); +-#endif -#ifndef HAVE_VASPRINTF -int vasprintf(char **, const char *, va_list); -#endif @@ -1206,41 +1437,62 @@ diff -u libmagic.orig/file.h libmagic/file.h +#ifndef strlcat size_t strlcat(char *dst, const char *src, size_t siz); #endif + #ifndef HAVE_GETLINE + ssize_t getline(char **dst, size_t *len, FILE *fp); + ssize_t getdelim(char **dst, size_t *len, int delimiter, FILE *fp); + #endif +-#ifndef HAVE_CTIME_R +-char *ctime_r(const time_t *, char *); +-#endif +-#ifndef HAVE_ASCTIME_R +-char *asctime_r(const struct tm *, char *); +-#endif -+ #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK) #define QUICK +@@ -531,6 +509,14 @@ #endif + #else + #define FILE_RCSID(id) ++#endif ++ ++#ifdef PHP_WIN32 ++#define FINFO_LSEEK_FUNC _lseek ++#define FINFO_READ_FUNC _read ++#else ++#define FINFO_LSEEK_FUNC lseek ++#define FINFO_READ_FUNC read + #endif + + #endif /* __file_h__ */ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c ---- libmagic.orig/fsmagic.c 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/fsmagic.c 2011-09-15 23:28:26.000000000 +0800 -@@ -60,29 +60,19 @@ +--- libmagic.orig/fsmagic.c Thu Mar 21 18:45:14 2013 ++++ libmagic/fsmagic.c Mon Dec 2 15:25:29 2013 +@@ -59,27 +59,21 @@ + # define minor(dev) ((dev) & 0xff) #endif #undef HAVE_MAJOR - +-#ifdef S_IFLNK -private int -bad_link(struct magic_set *ms, int err, char *buf) -{ -- const char *errfmt; - int mime = ms->flags & MAGIC_MIME; - if ((mime & MAGIC_MIME_TYPE) && -- file_printf(ms, "application/x-symlink") +- file_printf(ms, "inode/symlink") - == -1) - return -1; - else if (!mime) { -- if (err == ELOOP) -- errfmt = "symbolic link in a loop"; -- else -- errfmt = "broken symbolic link to `%s'"; - if (ms->flags & MAGIC_ERROR) { -- file_error(ms, err, errfmt, buf); +- file_error(ms, err, +- "broken symbolic link to `%s'", buf); - return -1; - } -- if (file_printf(ms, errfmt, buf) == -1) +- if (file_printf(ms, "broken symbolic link to `%s'", buf) == -1) - return -1; - } - return 1; -} ++ +#ifdef PHP_WIN32 + +# undef S_IFIFO @@ -1253,22 +1505,23 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c + +#ifndef S_ISREG +#define S_ISREG(mode) ((mode) & _S_IFREG) -+#endif - + #endif ++ private int handle_mime(struct magic_set *ms, int mime, const char *str) -@@ -100,41 +90,36 @@ + { +@@ -96,49 +90,45 @@ } protected int -file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) +file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *stream) { -- int ret = 0; + int ret, did = 0; int mime = ms->flags & MAGIC_MIME; -#ifdef S_IFLNK - char buf[BUFSIZ+4]; -- int nch; +- ssize_t nch; - struct stat tstatbuf; -#endif + TSRMLS_FETCH(); @@ -1277,10 +1530,11 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c return 0; - if (fn == NULL) + -+ if (!fn && !stream) { ++ if (fn == NULL && !stream) { return 0; + } + #define COMMA (did++ ? ", " : "") - /* - * Fstat is cheaper but fails for files you don't have read perms on. - * On 4.2BSD and similar systems, use lstat() to identify symlinks. @@ -1296,6 +1550,7 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c - if (ms->flags & MAGIC_ERROR) { - file_error(ms, errno, "cannot stat `%s'", fn); - return -1; ++ + if (stream) { + php_stream_statbuf ssb; + if (php_stream_stat(stream, &ssb) < 0) { @@ -1317,24 +1572,29 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c - if (file_printf(ms, "cannot open `%s' (%s)", - fn, strerror(errno)) == -1) - return -1; -- return 1; +- ms->event_flags |= EVENT_HAD_ERR; +- return -1; } + ret = 1; if (!mime) { -@@ -154,172 +139,75 @@ + #ifdef S_ISUID +- if (sb->st_mode & S_ISUID) ++ if (sb->st_mode & S_ISUID) + if (file_printf(ms, "%ssetuid", COMMA) == -1) return -1; #endif +@@ -155,82 +145,43 @@ } -- -+ + switch (sb->st_mode & S_IFMT) { - case S_IFDIR: - if (mime) { -- if (handle_mime(ms, mime, "x-directory") == -1) +- if (handle_mime(ms, mime, "directory") == -1) - return -1; -- } else if (file_printf(ms, "directory") == -1) +- } else if (file_printf(ms, "%sdirectory", COMMA) == -1) - return -1; -- return 1; +- break; -#ifdef S_IFCHR - case S_IFCHR: - /* @@ -1342,30 +1602,56 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c - * like ordinary files. Otherwise, just report that they - * are block special files and go on to the next file. - */ -- if ((ms->flags & MAGIC_DEVICES) != 0) +- if ((ms->flags & MAGIC_DEVICES) != 0) { +- ret = 0; - break; +- } - if (mime) { -- if (handle_mime(ms, mime, "x-character-device") == -1) +- if (handle_mime(ms, mime, "chardevice") == -1) - return -1; - } else { -#ifdef HAVE_STAT_ST_RDEV -# ifdef dv_unit -- if (file_printf(ms, "character special (%d/%d/%d)", -- major(sb->st_rdev), dv_unit(sb->st_rdev), ++#ifndef PHP_WIN32 ++# ifdef S_IFCHR ++ case S_IFCHR: ++ /* ++ * If -s has been specified, treat character special files ++ * like ordinary files. Otherwise, just report that they ++ * are block special files and go on to the next file. ++ */ ++ if ((ms->flags & MAGIC_DEVICES) != 0) { ++ ret = 0; ++ break; ++ } ++ if (mime) { ++ if (handle_mime(ms, mime, "x-character-device") == -1) ++ return -1; ++ } else { ++# ifdef HAVE_STAT_ST_RDEV ++# ifdef dv_unit + if (file_printf(ms, "%scharacter special (%d/%d/%d)", + COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev), - dv_subunit(sb->st_rdev)) == -1) - return -1; -# else -- if (file_printf(ms, "character special (%ld/%ld)", -- (long)major(sb->st_rdev), (long)minor(sb->st_rdev)) -- == -1) ++ dv_subunit(sb->st_rdev)) == -1) ++ return -1; ++# else + if (file_printf(ms, "%scharacter special (%ld/%ld)", + COMMA, (long)major(sb->st_rdev), + (long)minor(sb->st_rdev)) == -1) - return -1; -# endif -#else -- if (file_printf(ms, "character special") == -1) ++ return -1; ++# endif ++# else + if (file_printf(ms, "%scharacter special", COMMA) == -1) - return -1; -#endif - } -- return 1; +- break; -#endif -#ifdef S_IFBLK - case S_IFBLK: @@ -1374,96 +1660,62 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c - * like ordinary files. Otherwise, just report that they - * are block special files and go on to the next file. - */ -- if ((ms->flags & MAGIC_DEVICES) != 0) +- if ((ms->flags & MAGIC_DEVICES) != 0) { +- ret = 0; - break; +- } - if (mime) { -- if (handle_mime(ms, mime, "x-block-device") == -1) +- if (handle_mime(ms, mime, "blockdevice") == -1) - return -1; - } else { -#ifdef HAVE_STAT_ST_RDEV -# ifdef dv_unit -- if (file_printf(ms, "block special (%d/%d/%d)", -- major(sb->st_rdev), dv_unit(sb->st_rdev), -- dv_subunit(sb->st_rdev)) == -1) +- if (file_printf(ms, "%sblock special (%d/%d/%d)", +- COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev), +- dv_subunit(sb->st_rdev)) == -1) - return -1; -# else -- if (file_printf(ms, "block special (%ld/%ld)", -- (long)major(sb->st_rdev), (long)minor(sb->st_rdev)) == -1) +- if (file_printf(ms, "%sblock special (%ld/%ld)", +- COMMA, (long)major(sb->st_rdev), +- (long)minor(sb->st_rdev)) == -1) - return -1; --# endif ++ return -1; ++# endif ++ } ++ return 1; + # endif -#else -- if (file_printf(ms, "block special") == -1) +- if (file_printf(ms, "%sblock special", COMMA) == -1) - return -1; --#endif + #endif - } -- return 1; +- break; -#endif - /* TODO add code to handle V7 MUX and Blit MUX files */ --#ifdef S_IFIFO -- case S_IFIFO: -- if((ms->flags & MAGIC_DEVICES) != 0) -- break; -- if (mime) { -- if (handle_mime(ms, mime, "x-fifo") == -1) -- return -1; -- } else if (file_printf(ms, "fifo (named pipe)") == -1) -- return -1; -- return 1; --#endif --#ifdef S_IFDOOR -- case S_IFDOOR: -- if (mime) { -- if (handle_mime(ms, mime, "x-door") == -1) -- return -1; -- } else if (file_printf(ms, "door") == -1) -- return -1; -- return 1; --#endif --#ifdef S_IFLNK -- case S_IFLNK: ++ + #ifdef S_IFIFO + case S_IFIFO: + if((ms->flags & MAGIC_DEVICES) != 0) +@@ -253,79 +204,14 @@ + #endif + #ifdef S_IFLNK + case S_IFLNK: - if ((nch = readlink(fn, buf, BUFSIZ-1)) <= 0) { -- if (ms->flags & MAGIC_ERROR) { ++ /* stat is used, if it made here then the link is broken */ + if (ms->flags & MAGIC_ERROR) { - file_error(ms, errno, "unreadable symlink `%s'", - fn); -- return -1; -+#ifndef PHP_WIN32 -+# ifdef S_IFCHR -+ case S_IFCHR: -+ /* -+ * If -s has been specified, treat character special files -+ * like ordinary files. Otherwise, just report that they -+ * are block special files and go on to the next file. -+ */ -+ if ((ms->flags & MAGIC_DEVICES) != 0) { -+ break; ++ file_error(ms, errno, "unreadable symlink `%s'", fn); + return -1; } - if (mime) { -- if (handle_mime(ms, mime, "x-symlink") == -1) -+ if (handle_mime(ms, mime, "x-character-device") == -1) - return -1; +- if (mime) { +- if (handle_mime(ms, mime, "symlink") == -1) +- return -1; - } else if (file_printf(ms, -- "unreadable symlink `%s' (%s)", fn, +- "%sunreadable symlink `%s' (%s)", COMMA, fn, - strerror(errno)) == -1) - return -1; -+ } else { -+# ifdef HAVE_STAT_ST_RDEV -+# ifdef dv_unit -+ if (file_printf(ms, "character special (%d/%d/%d)", -+ major(sb->st_rdev), dv_unit(sb->st_rdev), -+ dv_subunit(sb->st_rdev)) == -1) -+ return -1; -+# else -+ if (file_printf(ms, "character special (%ld/%ld)", -+ (long)major(sb->st_rdev), (long)minor(sb->st_rdev)) -+ == -1) -+ return -1; -+# endif -+# else -+ if (file_printf(ms, "character special") == -1) -+ return -1; -+# endif -+ } - return 1; +- break; - } - buf[nch] = '\0'; /* readlink(2) does not do this */ - @@ -1474,9 +1726,7 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c - } else { - char *tmp; - char buf2[BUFSIZ+BUFSIZ+4]; -+# endif -+#endif - +- - if ((tmp = strrchr(fn, '/')) == NULL) { - tmp = buf; /* in current directory anyway */ - } else { @@ -1484,30 +1734,17 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c - if (ms->flags & MAGIC_ERROR) { - file_error(ms, 0, - "path too long: `%s'", buf); -+#ifdef S_IFIFO -+ case S_IFIFO: -+ if((ms->flags & MAGIC_DEVICES) != 0) -+ break; -+ if (mime) { -+ if (handle_mime(ms, mime, "x-fifo") == -1) - return -1; +- return -1; - } -+ } else if (file_printf(ms, "fifo (named pipe)") == -1) -+ return -1; -+ return 1; -+#endif -+#ifdef S_IFDOOR -+ case S_IFDOOR: - if (mime) { +- if (mime) { - if (handle_mime(ms, mime, - "x-path-too-long") == -1) -+ if (handle_mime(ms, mime, "x-door") == -1) - return -1; +- return -1; - } else if (file_printf(ms, -- "path too long: `%s'", fn) == -1) -+ } else if (file_printf(ms, "door") == -1) - return -1; - return 1; +- "%spath too long: `%s'", COMMA, +- fn) == -1) +- return -1; +- break; - } - /* take dir part */ - (void)strlcpy(buf2, fn, sizeof buf2); @@ -1519,75 +1756,104 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c - if (stat(tmp, &tstatbuf) < 0) - return bad_link(ms, errno, buf); - } -+#endif - +- - /* Otherwise, handle it. */ - if ((ms->flags & MAGIC_SYMLINK) != 0) { - const char *p; - ms->flags &= MAGIC_SYMLINK; - p = magic_file(ms, buf); - ms->flags |= MAGIC_SYMLINK; -- return p != NULL ? 1 : -1; +- if (p == NULL) +- return -1; - } else { /* just print what it points to */ - if (mime) { -- if (handle_mime(ms, mime, "x-symlink") == -1) +- if (handle_mime(ms, mime, "symlink") == -1) - return -1; -- } else if (file_printf(ms, "symbolic link to `%s'", -- buf) == -1) +- } else if (file_printf(ms, "%ssymbolic link to `%s'", +- COMMA, buf) == -1) - return -1; - } -- return 1; -+#ifdef S_IFLNK -+ case S_IFLNK: -+ /* stat is used, if it made here then the link is broken */ -+ if (ms->flags & MAGIC_ERROR) { -+ file_error(ms, errno, "unreadable symlink `%s'", fn); -+ return -1; -+ } +- break; + return 1; #endif + #ifdef S_IFSOCK #ifndef __COHERENT__ case S_IFSOCK: -@@ -331,12 +219,14 @@ - return 1; +@@ -337,27 +223,27 @@ + break; #endif #endif - case S_IFREG: -- break; -- default: -- file_error(ms, 0, "invalid mode 0%o", sb->st_mode); -- return -1; -- /*NOTREACHED*/ -+ +- /* +- * regular file, check next possibility +- * +- * If stat() tells us the file has zero length, report here that +- * the file is empty, so we can skip all the work of opening and +- * reading the file. + case S_IFREG: -+ break; -+ -+ default: -+ file_error(ms, 0, "invalid mode 0%o", sb->st_mode); ++ /* ++ * regular file, check next possibility ++ * ++ * If stat() tells us the file has zero length, report here that ++ * the file is empty, so we can skip all the work of opening and ++ * reading the file. + * But if the -s option has been given, we skip this + * optimization, since on some systems, stat() reports zero + * size for raw disk partitions. (If the block special device + * really has zero length, the fact that it is empty will be + * detected and reported correctly when we read the file.) +- */ +- if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) { +- if (mime) { +- if (handle_mime(ms, mime, "x-empty") == -1) +- return -1; +- } else if (file_printf(ms, "%sempty", COMMA) == -1) ++ */ ++ if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) { ++ if (mime) { ++ if (handle_mime(ms, mime, "x-empty") == -1) + return -1; ++ } else if (file_printf(ms, "%sempty", COMMA) == -1) + return -1; -+ /*NOTREACHED*/ + break; +- } ++ } + ret = 0; + break; + +@@ -367,9 +253,5 @@ + /*NOTREACHED*/ } - /* +- if (!mime && did) { +- if (file_printf(ms, " ") == -1) +- return -1; +- } + return ret; + } diff -u libmagic.orig/funcs.c libmagic/funcs.c ---- libmagic.orig/funcs.c 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/funcs.c 2011-09-15 23:28:26.000000000 +0800 -@@ -41,52 +41,36 @@ +--- libmagic.orig/funcs.c Wed Oct 31 18:03:01 2012 ++++ libmagic/funcs.c Mon Mar 10 16:40:55 2014 +@@ -41,52 +41,42 @@ #if defined(HAVE_WCTYPE_H) #include #endif -#if defined(HAVE_LIMITS_H) -#include --#endif ++ ++#ifndef SIZE_MAX ++# define SIZE_MAX ((size_t) -1) + #endif -#ifndef SIZE_MAX -#define SIZE_MAX ((size_t)~0) -+#ifndef SIZE_MAX -+# define SIZE_MAX ((size_t) -1) ++#ifndef PREG_OFFSET_CAPTURE ++# define PREG_OFFSET_CAPTURE (1<<8) #endif ++extern public void convert_libmagic_pattern(zval *pattern, int options); ++ /* * Like printf, only we append to a buffer. */ @@ -1643,23 +1909,20 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c } /* -@@ -97,17 +81,32 @@ +@@ -97,17 +87,30 @@ file_error_core(struct magic_set *ms, int error, const char *f, va_list va, - uint32_t lineno) + size_t lineno) { + char *buf = NULL; + /* Only the first error is ok */ -- if (ms->event_flags & EVENT_HAD_ERR) -+ if (ms->event_flags & EVENT_HAD_ERR) { + if (ms->event_flags & EVENT_HAD_ERR) return; -+ } -+ if (lineno != 0) { - free(ms->o.buf); + efree(ms->o.buf); ms->o.buf = NULL; - file_printf(ms, "line %u: ", lineno); + file_printf(ms, "line %" SIZE_T_FORMAT "u: ", lineno); } - file_vprintf(ms, f, va); - if (error > 0) @@ -1681,37 +1944,26 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c ms->event_flags |= EVENT_HAD_ERR; ms->error = error; } -@@ -153,14 +152,13 @@ +@@ -154,10 +157,9 @@ file_error(ms, errno, "error reading"); } -#ifndef COMPILE_ONLY protected int --file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf, +-file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unused)), +- const void *buf, size_t nb) +file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const void *buf, - size_t nb) ++ size_t nb) { int m = 0, rv = 0, looks_text = 0; int mime = ms->flags & MAGIC_MIME; -- const unsigned char *ubuf = CAST(const unsigned char *, buf); -+ const unsigned char *ubuf = buf; - unichar *u8buf = NULL; - size_t ulen; - const char *code = NULL; -@@ -188,7 +186,7 @@ - &code, &code_mime, &type); +@@ -201,10 +203,10 @@ + } } - --#ifdef __EMX__ -+#if defined(__EMX__) - if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) { - switch (file_os2_apptype(ms, inname, buf, nb)) { - case -1: -@@ -201,13 +199,14 @@ - } #endif - +-#if HAVE_FORK - /* try compression stuff */ ++ +#if PHP_FILEINFO_UNCOMPRESS if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0) - if ((m = file_zmagic(ms, fd, inname, ubuf, nb)) != 0) { @@ -1719,13 +1971,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "zmagic %d\n", m); goto done; -- } -+ } -+#endif - - /* Check if we have a tar file */ - if ((ms->flags & MAGIC_NO_CHECK_TAR) == 0) -@@ -218,12 +217,17 @@ +@@ -219,16 +221,21 @@ } /* Check if we have a CDF file */ @@ -1748,7 +1994,12 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c /* try soft magic tests */ if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) -@@ -294,7 +298,6 @@ +- if ((m = file_softmagic(ms, ubuf, nb, BINTEST, ++ if ((m = file_softmagic(ms, ubuf, nb, 0, BINTEST, + looks_text)) != 0) { + if ((ms->flags & MAGIC_DEBUG) != 0) + (void)fprintf(stderr, "softmagic %d\n", m); +@@ -296,7 +303,6 @@ return m; } @@ -1756,7 +2007,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c protected int file_reset(struct magic_set *ms) -@@ -304,11 +307,11 @@ +@@ -306,11 +312,11 @@ return -1; } if (ms->o.buf) { @@ -1770,7 +2021,16 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c ms->o.pbuf = NULL; } ms->event_flags &= ~EVENT_HAD_ERR; -@@ -342,14 +345,10 @@ +@@ -329,7 +335,7 @@ + protected const char * + file_getbuffer(struct magic_set *ms) + { +- char *pbuf, *op, *np; ++ char *op, *np; + size_t psize, len; + + if (ms->event_flags & EVENT_HAD_ERR) +@@ -344,15 +350,13 @@ /* * 4 is for octal representation, + 1 is for NUL */ len = strlen(ms->o.buf); if (len > (SIZE_MAX - 1) / 4) { @@ -1779,32 +2039,109 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c } psize = len * 4 + 1; - if ((pbuf = CAST(char *, realloc(ms->o.pbuf, psize))) == NULL) { -- file_oomem(ms, psize); -- return NULL; -- } -+ pbuf = erealloc(ms->o.pbuf, psize); - ms->o.pbuf = pbuf; ++ if ((ms->o.pbuf = CAST(char *, erealloc(ms->o.pbuf, psize))) == NULL) { + file_oomem(ms, psize); + return NULL; + } +- ms->o.pbuf = pbuf; #if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH) -@@ -409,13 +408,7 @@ - + { +@@ -412,8 +416,8 @@ if (level >= ms->c.len) { len = (ms->c.len += 20) * sizeof(*ms->c.li); -- ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ? + ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ? - malloc(len) : - realloc(ms->c.li, len)); -- if (ms->c.li == NULL) { -- file_oomem(ms, len); -- return -1; ++ emalloc(len) : ++ erealloc(ms->c.li, len)); + if (ms->c.li == NULL) { + file_oomem(ms, len); + return -1; +@@ -433,29 +437,47 @@ + return ms->o.buf == NULL ? 0 : strlen(ms->o.buf); + } + +-protected int ++ ++protected int + file_replace(struct magic_set *ms, const char *pat, const char *rep) + { +- regex_t rx; +- int rc; ++ zval *patt; ++ int opts = 0; ++ pcre_cache_entry *pce; ++ char *res; ++ zval *repl; ++ int res_len, rep_cnt = 0; ++ TSRMLS_FETCH(); ++ ++ MAKE_STD_ZVAL(patt); ++ ZVAL_STRINGL(patt, pat, strlen(pat), 0); ++ opts |= PCRE_MULTILINE; ++ convert_libmagic_pattern(patt, opts); ++ if ((pce = pcre_get_compiled_regex_cache(Z_STRVAL_P(patt), Z_STRLEN_P(patt) TSRMLS_CC)) == NULL) { ++ zval_dtor(patt); ++ FREE_ZVAL(patt); ++ return -1; ++ } ++ ++ MAKE_STD_ZVAL(repl); ++ ZVAL_STRINGL(repl, rep, strlen(rep), 0); ++ ++ res = php_pcre_replace_impl(pce, ms->o.buf, strlen(ms->o.buf), repl, ++ 0, &res_len, -1, &rep_cnt TSRMLS_CC); + +- rc = regcomp(&rx, pat, REG_EXTENDED); +- if (rc) { +- char errmsg[512]; +- (void)regerror(rc, &rx, errmsg, sizeof(errmsg)); +- file_magerror(ms, "regex error %d, (%s)", rc, errmsg); ++ FREE_ZVAL(repl); ++ zval_dtor(patt); ++ FREE_ZVAL(patt); ++ ++ if (NULL == res) { + return -1; +- } else { +- regmatch_t rm; +- int nm = 0; +- while (regexec(&rx, ms->o.buf, 1, &rm, 0) == 0) { +- ms->o.buf[rm.rm_so] = '\0'; +- if (file_printf(ms, "%s%s", rep, +- rm.rm_eo != 0 ? ms->o.buf + rm.rm_eo : "") == -1) +- return -1; +- nm++; - } -+ ms->c.li = (ms->c.li == NULL) ? emalloc(len) : erealloc(ms->c.li, len); +- regfree(&rx); +- return nm; } - ms->c.li[level].got_match = 0; - #ifdef ENABLE_CONDITIONALS ++ ++ strncpy(ms->o.buf, res, res_len); ++ ms->o.buf[res_len] = '\0'; ++ ++ efree(res); ++ ++ return rep_cnt; + } ++ diff -u libmagic.orig/magic.c libmagic/magic.c ---- libmagic.orig/magic.c 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/magic.c 2011-09-15 23:29:29.000000000 +0800 -@@ -34,14 +34,19 @@ +--- libmagic.orig/magic.c Fri Jan 11 17:43:09 2013 ++++ libmagic/magic.c Mon Dec 2 15:29:02 2013 +@@ -25,11 +25,6 @@ + * SUCH DAMAGE. + */ + +-#ifdef WIN32 +-#include +-#include +-#endif +- + #include "file.h" + + #ifndef lint +@@ -39,15 +34,24 @@ #include "magic.h" #include @@ -1822,130 +2159,130 @@ diff -u libmagic.orig/magic.c libmagic/magic.c +# include "php_config.h" #endif -#ifdef HAVE_LIMITS_H +-#include /* for PIPE_BUF */ + - #include /* for PIPE_BUF */ --#endif ++#ifdef PHP_WIN32 ++#include + #endif ++#include /* for PIPE_BUF */ ++ #if defined(HAVE_UTIMES) # include -@@ -57,7 +62,9 @@ - #include /* for read() */ + #elif defined(HAVE_UTIME) +@@ -71,18 +75,25 @@ #endif - --#include /* for byte swapping */ -+#ifndef PHP_WIN32 -+# include /* for byte swapping */ -+#endif - - #include "patchlevel.h" - -@@ -70,13 +77,16 @@ #endif - #endif +#ifdef PHP_WIN32 +# undef S_IFLNK +# undef S_IFIFO +#endif + - private void free_mlist(struct mlist *); private void close_and_restore(const struct magic_set *, const char *, int, const struct stat *); private int unreadable_info(struct magic_set *, mode_t, const char *); ++#if 0 + private const char* get_default_magic(void); -#ifndef COMPILE_ONLY -private const char *file_or_fd(struct magic_set *, const char *, int); --#endif + #endif +private const char *file_or_stream(struct magic_set *, const char *, php_stream *); #ifndef STDIN_FILENO #define STDIN_FILENO 0 -@@ -86,11 +96,8 @@ - magic_open(int flags) + #endif + ++/* XXX this functionality is excluded in php, enable it in apprentice.c:340 */ ++#if 0 + private const char * + get_default_magic(void) { - struct magic_set *ms; -- size_t len; +@@ -90,7 +101,7 @@ + static char *default_magic; + char *home, *hmagicpath; -- if ((ms = CAST(magic_set *, calloc((size_t)1, -- sizeof(struct magic_set)))) == NULL) -- return NULL; -+ ms = ecalloc((size_t)1, sizeof(struct magic_set)); +-#ifndef WIN32 ++#ifndef PHP_WIN32 + struct stat st; - if (magic_setflags(ms, flags) == -1) { - errno = EINVAL; -@@ -98,11 +105,9 @@ + if (default_magic) { +@@ -104,17 +115,17 @@ + return MAGIC; + if (stat(hmagicpath, &st) == -1) { + free(hmagicpath); +- if (asprintf(&hmagicpath, "%s/.magic", home) < 0) ++ if (asprintf(&hmagicpath, "%s/.magic", home) < 0) ++ return MAGIC; ++ if (stat(hmagicpath, &st) == -1) ++ goto out; ++ if (S_ISDIR(st.st_mode)) { ++ free(hmagicpath); ++ if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0) + return MAGIC; +- if (stat(hmagicpath, &st) == -1) ++ if (access(hmagicpath, R_OK) == -1) + goto out; +- if (S_ISDIR(st.st_mode)) { +- free(hmagicpath); +- if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0) +- return MAGIC; +- if (access(hmagicpath, R_OK) == -1) +- goto out; +- } ++ } } - ms->o.buf = ms->o.pbuf = NULL; -- len = (ms->c.len = 10) * sizeof(*ms->c.li); -- -- if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL) -- goto free; + if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0) +@@ -128,6 +139,7 @@ + #else + char *hmagicp = hmagicpath; + char *tmppath = NULL; ++ LPTSTR dllpath; -+ ms->c.li = emalloc((ms->c.len = 10) * sizeof(*ms->c.li)); -+ - ms->event_flags = 0; - ms->error = -1; - ms->mlist = NULL; -@@ -110,7 +115,7 @@ - ms->line = 0; - return ms; - free: -- free(ms); -+ efree(ms); - return NULL; - } - -@@ -126,10 +131,10 @@ - struct mlist *next = ml->next; - struct magic *mg = ml->magic; - file_delmagic(mg, ml->mapped, ml->nmagic); -- free(ml); -+ efree(ml); - ml = next; + #define APPENDPATH() \ + do { \ +@@ -172,7 +184,7 @@ } -- free(ml); -+ efree(ml); + + /* Third, try to get magic file relative to dll location */ +- LPTSTR dllpath = malloc(sizeof(*dllpath) * (MAX_PATH + 1)); ++ dllpath = malloc(sizeof(*dllpath) * (MAX_PATH + 1)); + dllpath[MAX_PATH] = 0; /* just in case long path gets truncated and not null terminated */ + if (GetModuleFileNameA(NULL, dllpath, MAX_PATH)){ + PathRemoveFileSpecA(dllpath); +@@ -210,6 +222,7 @@ + + return action == FILE_LOAD ? get_default_magic() : MAGIC; } ++#endif - private int -@@ -153,11 +158,19 @@ - public void - magic_close(struct magic_set *ms) + public struct magic_set * + magic_open(int flags) +@@ -250,7 +263,7 @@ + magic_load(struct magic_set *ms, const char *magicfile) { -- free_mlist(ms->mlist); -- free(ms->o.pbuf); -- free(ms->o.buf); -- free(ms->c.li); -- free(ms); -+ if (ms->mlist) { -+ free_mlist(ms->mlist); -+ } -+ if (ms->o.pbuf) { -+ efree(ms->o.pbuf); -+ } -+ if (ms->o.buf) { -+ efree(ms->o.buf); -+ } -+ if (ms->c.li) { -+ efree(ms->c.li); -+ } -+ efree(ms); + if (ms == NULL) +- return -1; ++ return -1; + return file_apprentice(ms, magicfile, FILE_LOAD); } - /* -@@ -183,21 +196,10 @@ - return ml ? 0 : -1; +@@ -262,13 +275,6 @@ + return file_apprentice(ms, magicfile, FILE_COMPILE); } -public int -magic_check(struct magic_set *ms, const char *magicfile) -{ -- struct mlist *ml = file_apprentice(ms, magicfile, FILE_CHECK); -- free_mlist(ml); -- return ml ? 0 : -1; +- if (ms == NULL) +- return -1; +- return file_apprentice(ms, magicfile, FILE_CHECK); -} -- - private void + + public int + magic_list(struct magic_set *ms, const char *magicfile) +@@ -282,9 +288,6 @@ close_and_restore(const struct magic_set *ms, const char *name, int fd, const struct stat *sb) { @@ -1955,7 +2292,7 @@ diff -u libmagic.orig/magic.c libmagic/magic.c if ((ms->flags & MAGIC_PRESERVE_ATIME) != 0) { /* -@@ -224,7 +226,6 @@ +@@ -311,7 +314,6 @@ } } @@ -1963,19 +2300,19 @@ diff -u libmagic.orig/magic.c libmagic/magic.c /* * find type of descriptor -@@ -232,7 +233,7 @@ - public const char * - magic_descriptor(struct magic_set *ms, int fd) +@@ -321,7 +323,7 @@ { + if (ms == NULL) + return NULL; - return file_or_fd(ms, NULL, fd); + return file_or_stream(ms, NULL, NULL); } /* -@@ -241,103 +242,95 @@ - public const char * - magic_file(struct magic_set *ms, const char *inname) +@@ -332,30 +334,42 @@ { + if (ms == NULL) + return NULL; - return file_or_fd(ms, inname, STDIN_FILENO); + return file_or_stream(ms, inname, NULL); +} @@ -1983,6 +2320,8 @@ diff -u libmagic.orig/magic.c libmagic/magic.c +public const char * +magic_stream(struct magic_set *ms, php_stream *stream) +{ ++ if (ms == NULL) ++ return NULL; + return file_or_stream(ms, NULL, stream); } @@ -2011,43 +2350,16 @@ diff -u libmagic.orig/magic.c libmagic/magic.c - return NULL; + buf = emalloc(HOWMANY + SLOP); -- if (file_reset(ms) == -1) -+ if (file_reset(ms) == -1) { + if (file_reset(ms) == -1) goto done; -+ } - switch (file_fsmagic(ms, inname, &sb)) { -- case -1: /* error */ -- goto done; -- case 0: /* nothing found */ -- break; -- default: /* matched it and printed type */ + switch (file_fsmagic(ms, inname, &sb, stream)) { -+ case -1: /* error */ -+ goto done; -+ case 0: /* nothing found */ -+ break; -+ default: /* matched it and printed type */ -+ rv = 0; -+ goto done; -+ } -+ -+ errno = 0; -+ -+ if (!stream && inname) { -+ no_in_stream = 1; -+#if PHP_API_VERSION < 20100412 -+ stream = php_stream_open_wrapper((char *)inname, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL); -+#else -+ stream = php_stream_open_wrapper((char *)inname, "rb", REPORT_ERRORS, NULL); -+#endif -+ } -+ -+ if (!stream) { -+ if (unreadable_info(ms, sb.st_mode, inname) == -1) -+ goto done; - rv = 0; + case -1: /* error */ goto done; + case 0: /* nothing found */ +@@ -365,68 +379,48 @@ + goto done; } - if (inname == NULL) { @@ -2055,19 +2367,35 @@ diff -u libmagic.orig/magic.c libmagic/magic.c - ispipe = 1; - } else { - int flags = O_RDONLY|O_BINARY; -- ++ errno = 0; + - if (stat(inname, &sb) == 0 && S_ISFIFO(sb.st_mode)) { +-#ifdef O_NONBLOCK - flags |= O_NONBLOCK; ++ if (!stream && inname) { ++ no_in_stream = 1; ++#if PHP_API_VERSION < 20100412 ++ stream = php_stream_open_wrapper((char *)inname, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL); ++#else ++ stream = php_stream_open_wrapper((char *)inname, "rb", REPORT_ERRORS, NULL); + #endif - ispipe = 1; - } -- ++ } + - errno = 0; - if ((fd = open(inname, flags)) < 0) { - if (unreadable_info(ms, sb.st_mode, inname) == -1) - goto done; - rv = 0; -- goto done; ++ if (!stream) { ++ if (unreadable_info(ms, sb.st_mode, inname) == -1) + goto done; - } ++ rv = 0; ++ goto done; ++ } ++ #ifdef O_NONBLOCK - if ((flags = fcntl(fd, F_GETFL)) != -1) { - flags &= ~O_NONBLOCK; @@ -2125,11 +2453,7 @@ diff -u libmagic.orig/magic.c libmagic/magic.c return rv == 0 ? file_getbuffer(ms) : NULL; } -- - public const char * - magic_buffer(struct magic_set *ms, const void *buf, size_t nb) - { -@@ -345,14 +338,13 @@ +@@ -440,14 +434,13 @@ return NULL; /* * The main work is done here! @@ -2147,73 +2471,28 @@ diff -u libmagic.orig/magic.c libmagic/magic.c public const char * magic_error(struct magic_set *ms) diff -u libmagic.orig/magic.h libmagic/magic.h ---- libmagic.orig/magic.h 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/magic.h 2011-09-15 23:28:26.000000000 +0800 -@@ -70,6 +70,7 @@ - void magic_close(magic_t); +--- libmagic.orig/magic.h Thu Mar 21 18:52:42 2013 ++++ libmagic/magic.h Mon Dec 2 15:25:29 2013 +@@ -87,6 +87,7 @@ + const char *magic_getpath(const char *, int); const char *magic_file(magic_t, const char *); +const char *magic_stream(magic_t, php_stream *); const char *magic_descriptor(magic_t, int); const char *magic_buffer(magic_t, const void *, size_t); -@@ -78,7 +79,6 @@ - +@@ -96,7 +97,6 @@ + int magic_version(void); int magic_load(magic_t, const char *); int magic_compile(magic_t, const char *); -int magic_check(magic_t, const char *); + int magic_list(magic_t, const char *); int magic_errno(magic_t); - #ifdef __cplusplus -diff -u libmagic.orig/patchlevel.h libmagic/patchlevel.h ---- libmagic.orig/patchlevel.h 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/patchlevel.h 2011-09-15 23:28:26.000000000 +0800 -@@ -3,23 +3,23 @@ - - /* - * Patchlevel file for Ian Darwin's MAGIC command. -- * $File: patchlevel.h,v 1.74 2009/05/06 20:32:48 christos Exp $ -+ * $File: patchlevel.h,v 1.68 2008/03/22 21:39:43 christos Exp $ - * -- * $Log: libmagic.patch,v $ -- * Revision 1.1.1.1 2012/02/21 23:47:56 misho -- * php -- * -- * Revision 1.74 2009/05/06 20:32:48 christos -- * welcome to 5.03 -+ * $Log: libmagic.patch,v $ -+ * Revision 1.1.1.1 2012/02/21 23:47:56 misho -+ * php -+ * -+ * Revision 1.4 2009/05/04 20:52:43 scottmac -+ * Update libmagic to 5.02 - * -- * Revision 1.73 2009/05/04 15:15:13 christos -- * 5.02... -+ * Revision 1.3 2009/03/15 23:02:35 scottmac -+ * Update fileinfo to libmagic 5.00 and remove dependency on dirent.h on Windows - * -- * Revision 1.72 2009/04/30 21:20:15 christos -- * 5.01 we are almost here. -+ * Revision 1.2 2008/11/02 16:09:27 scottmac -+ * Update libmagic to 4.26 and add support for v6 of the magic file format. - * -- * Revision 1.71 2009/01/21 19:09:42 christos -- * file 5.0 -+ * Revision 1.1 2008/07/11 14:13:50 derick -+ * - Move lib to libmagic - * -- * Revision 1.70 2008/08/30 10:01:01 christos -- * file 4.26 -+ * Revision 1.1 2008/07/11 14:10:50 derick -+ * - Step one for bundling the libmagic library. Some config.m4 issues left. - * - * Revision 1.69 2008/07/02 15:27:05 christos - * welcome to 4.25 diff -u libmagic.orig/print.c libmagic/print.c ---- libmagic.orig/print.c 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/print.c 2011-09-15 23:29:29.000000000 +0800 -@@ -28,6 +28,8 @@ +--- libmagic.orig/print.c Thu Mar 21 18:45:14 2013 ++++ libmagic/print.c Mon Dec 2 15:29:02 2013 +@@ -28,13 +28,17 @@ /* * print.c - debugging printout routines */ @@ -2221,55 +2500,59 @@ diff -u libmagic.orig/print.c libmagic/print.c +#include "php.h" #include "file.h" ++#include "cdf.h" -@@ -35,6 +37,7 @@ - FILE_RCSID("@(#)$File: print.c,v 1.66 2009/02/03 20:27:51 christos Exp $") + #ifndef lint + FILE_RCSID("@(#)$File: print.c,v 1.76 2013/02/26 18:25:00 christos Exp $") #endif /* lint */ +#include #include #include #include -@@ -45,157 +48,21 @@ +@@ -43,188 +47,28 @@ + #endif + #include - #define SZOF(a) (sizeof(a) / sizeof(a[0])) - +-#define SZOF(a) (sizeof(a) / sizeof(a[0])) +- +-#include "cdf.h" +- -#ifndef COMPILE_ONLY -protected void -file_mdump(struct magic *m) -{ -- private const char optyp[] = { FILE_OPS }; +- static const char optyp[] = { FILE_OPS }; +- char tbuf[26]; - -- (void) fprintf(stderr, "[%u", m->lineno); -- (void) fprintf(stderr, ">>>>>>>> %u" + 8 - (m->cont_level & 7), -- m->offset); +- (void) fprintf(stderr, "%u: %.*s %u", m->lineno, +- (m->cont_level & 7) + 1, ">>>>>>>>", m->offset); - - if (m->flag & INDIR) { - (void) fprintf(stderr, "(%s,", -- /* Note: type is unsigned */ -- (m->in_type < file_nnames) ? -- file_names[m->in_type] : "*bad*"); +- /* Note: type is unsigned */ +- (m->in_type < file_nnames) ? file_names[m->in_type] : +- "*bad in_type*"); - if (m->in_op & FILE_OPINVERSE) - (void) fputc('~', stderr); - (void) fprintf(stderr, "%c%u),", -- ((size_t)(m->in_op & FILE_OPS_MASK) < -- SZOF(optyp)) ? -- optyp[m->in_op & FILE_OPS_MASK] : '?', -- m->in_offset); +- ((size_t)(m->in_op & FILE_OPS_MASK) < +- SZOF(optyp)) ? optyp[m->in_op & FILE_OPS_MASK] : '?', +- m->in_offset); - } - (void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "", -- /* Note: type is unsigned */ -- (m->type < file_nnames) ? file_names[m->type] : "*bad*"); +- /* Note: type is unsigned */ +- (m->type < file_nnames) ? file_names[m->type] : "*bad type"); - if (m->mask_op & FILE_OPINVERSE) - (void) fputc('~', stderr); - - if (IS_STRING(m->type)) { - if (m->str_flags) { - (void) fputc('/', stderr); -- if (m->str_flags & STRING_COMPACT_BLANK) -- (void) fputc(CHAR_COMPACT_BLANK, stderr); -- if (m->str_flags & STRING_COMPACT_OPTIONAL_BLANK) -- (void) fputc(CHAR_COMPACT_OPTIONAL_BLANK, +- if (m->str_flags & STRING_COMPACT_WHITESPACE) +- (void) fputc(CHAR_COMPACT_WHITESPACE, stderr); +- if (m->str_flags & STRING_COMPACT_OPTIONAL_WHITESPACE) +- (void) fputc(CHAR_COMPACT_OPTIONAL_WHITESPACE, - stderr); - if (m->str_flags & STRING_IGNORE_LOWERCASE) - (void) fputc(CHAR_IGNORE_LOWERCASE, stderr); @@ -2277,6 +2560,24 @@ diff -u libmagic.orig/print.c libmagic/print.c - (void) fputc(CHAR_IGNORE_UPPERCASE, stderr); - if (m->str_flags & REGEX_OFFSET_START) - (void) fputc(CHAR_REGEX_OFFSET_START, stderr); +- if (m->str_flags & STRING_TEXTTEST) +- (void) fputc(CHAR_TEXTTEST, stderr); +- if (m->str_flags & STRING_BINTEST) +- (void) fputc(CHAR_BINTEST, stderr); +- if (m->str_flags & PSTRING_1_BE) +- (void) fputc(CHAR_PSTRING_1_BE, stderr); +- if (m->str_flags & PSTRING_2_BE) +- (void) fputc(CHAR_PSTRING_2_BE, stderr); +- if (m->str_flags & PSTRING_2_LE) +- (void) fputc(CHAR_PSTRING_2_LE, stderr); +- if (m->str_flags & PSTRING_4_BE) +- (void) fputc(CHAR_PSTRING_4_BE, stderr); +- if (m->str_flags & PSTRING_4_LE) +- (void) fputc(CHAR_PSTRING_4_LE, stderr); +- if (m->str_flags & PSTRING_LENGTH_INCLUDES_ITSELF) +- (void) fputc( +- CHAR_PSTRING_LENGTH_INCLUDES_ITSELF, +- stderr); - } - if (m->str_range) - (void) fprintf(stderr, "/%u", m->str_range); @@ -2304,12 +2605,13 @@ diff -u libmagic.orig/print.c libmagic/print.c - case FILE_MELONG: - case FILE_BESHORT: - case FILE_BELONG: +- case FILE_INDIRECT: - (void) fprintf(stderr, "%d", m->value.l); - break; - case FILE_BEQUAD: - case FILE_LEQUAD: - case FILE_QUAD: -- (void) fprintf(stderr, "%lld", +- (void) fprintf(stderr, "%" INT64_T_FORMAT "d", - (unsigned long long)m->value.q); - break; - case FILE_PSTRING: @@ -2325,27 +2627,32 @@ diff -u libmagic.orig/print.c libmagic/print.c - case FILE_BEDATE: - case FILE_MEDATE: - (void)fprintf(stderr, "%s,", -- file_fmttime(m->value.l, 1)); +- file_fmttime(m->value.l, FILE_T_LOCAL, tbuf)); - break; - case FILE_LDATE: - case FILE_LELDATE: - case FILE_BELDATE: - case FILE_MELDATE: - (void)fprintf(stderr, "%s,", -- file_fmttime(m->value.l, 0)); -- break; +- file_fmttime(m->value.l, 0, tbuf)); - case FILE_QDATE: - case FILE_LEQDATE: - case FILE_BEQDATE: - (void)fprintf(stderr, "%s,", -- file_fmttime((uint32_t)m->value.q, 1)); +- file_fmttime(m->value.q, FILE_T_LOCAL, tbuf)); - break; - case FILE_QLDATE: - case FILE_LEQLDATE: - case FILE_BEQLDATE: - (void)fprintf(stderr, "%s,", -- file_fmttime((uint32_t)m->value.q, 0)); +- file_fmttime(m->value.q, 0, tbuf)); - break; +- case FILE_QWDATE: +- case FILE_LEQWDATE: +- case FILE_BEQWDATE: +- (void)fprintf(stderr, "%s,", +- file_fmttime(m->value.q, FILE_T_WINDOWS, tbuf)); +- break; - case FILE_FLOAT: - case FILE_BEFLOAT: - case FILE_LEFLOAT: @@ -2359,15 +2666,24 @@ diff -u libmagic.orig/print.c libmagic/print.c - case FILE_DEFAULT: - /* XXX - do anything here? */ - break; +- case FILE_USE: +- case FILE_NAME: +- (void) fprintf(stderr, "'%s'", m->value.s); +- break; - default: -- (void) fputs("*bad*", stderr); +- (void) fprintf(stderr, "*bad type %d*", m->type); - break; - } - } - (void) fprintf(stderr, ",\"%s\"]\n", m->desc); -} --#endif -- ++#ifdef PHP_WIN32 ++# define asctime_r php_asctime_r ++# define ctime_r php_ctime_r + #endif + ++#define SZOF(a) (sizeof(a) / sizeof(a[0])) ++ /*VARARGS*/ protected void file_magwarn(struct magic_set *ms, const char *f, ...) @@ -2385,7 +2701,7 @@ diff -u libmagic.orig/print.c libmagic/print.c - (void) fprintf(stderr, "Warning: "); va_start(va, f); - (void) vfprintf(stderr, f, va); -+ vasprintf(&expanded_format, f, va); ++ if (vasprintf(&expanded_format, f, va)); /* silence */ va_end(va); - (void) fputc('\n', stderr); + @@ -2395,9 +2711,18 @@ diff -u libmagic.orig/print.c libmagic/print.c } protected const char * +@@ -235,7 +79,7 @@ + struct tm *tm; + + if (flags & FILE_T_WINDOWS) { +- struct timespec ts; ++ struct timeval ts; + cdf_timestamp_to_timespec(&ts, t); + t = ts.tv_sec; + } diff -u libmagic.orig/readcdf.c libmagic/readcdf.c ---- libmagic.orig/readcdf.c 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/readcdf.c 2011-09-15 23:29:29.000000000 +0800 +--- libmagic.orig/readcdf.c Wed Oct 31 18:03:01 2012 ++++ libmagic/readcdf.c Thu Apr 24 19:54:40 2014 @@ -30,7 +30,11 @@ #endif @@ -2410,109 +2735,343 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c #include #include #include -@@ -46,7 +50,7 @@ +@@ -46,12 +50,14 @@ { - size_t i; - cdf_timestamp_t tp; -- struct timespec ts; -+ struct timeval ts; - char buf[64]; - const char *str = "vnd.ms-office"; - const char *s; -@@ -106,7 +110,11 @@ - case CDF_FILETIME: - tp = info[i].pi_tp; - if (tp != 0) { + size_t i; + cdf_timestamp_t tp; +- struct timespec ts; ++ struct timeval ts; + char buf[64]; + const char *str = NULL; + const char *s; + int len; + ++ memset(&ts, 0, sizeof(ts)); ++ + for (i = 0; i < count; i++) { + cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); + switch (info[i].pi_type) { +@@ -125,8 +131,12 @@ + case CDF_FILETIME: + tp = info[i].pi_tp; + if (tp != 0) { +- char tbuf[64]; +- if (tp < 1000000000000000LL) { ++ char tbuf[64]; +#if defined(PHP_WIN32) && _MSC_VER <= 1500 -+ if (tp < 1000000000000000i64) { ++ if (tp < 1000000000000000i64) { +#else - if (tp < 1000000000000000LL) { ++ if (tp < 1000000000000000LL) { +#endif - char tbuf[64]; - cdf_print_elapsed_time(tbuf, - sizeof(tbuf), tp); -@@ -115,7 +123,10 @@ - return -1; - } else { - char *c, *ec; -- cdf_timestamp_to_timespec(&ts, tp); -+ -+ if (cdf_timestamp_to_timespec(&ts, tp) == -1) { -+ return -1; -+ } - c = ctime(&ts.tv_sec); - if ((ec = strchr(c, '\n')) != NULL) - *ec = '\0'; + cdf_print_elapsed_time(tbuf, + sizeof(tbuf), tp); + if (NOTMIME(ms) && file_printf(ms, +@@ -134,9 +144,13 @@ + return -1; + } else { + char *c, *ec; +- cdf_timestamp_to_timespec(&ts, tp); +- c = cdf_ctime(&ts.tv_sec, tbuf); +- if ((ec = strchr(c, '\n')) != NULL) ++ const time_t sec = ts.tv_sec; ++ if (cdf_timestamp_to_timespec(&ts, tp) == -1) { ++ return -1; ++ } ++ c = cdf_ctime(&sec, tbuf); ++ if (c != NULL && ++ (ec = strchr(c, '\n')) != NULL) + *ec = '\0'; + + if (NOTMIME(ms) && file_printf(ms, +@@ -314,9 +328,9 @@ + if (file_printf(ms, + "Composite Document File V2 Document") == -1) + return -1; +- if (*expn) +- if (file_printf(ms, ", %s%s", corrupt, expn) == -1) +- return -1; ++ if (*expn) ++ if (file_printf(ms, ", %s%s", corrupt, expn) == -1) ++ return -1; + } else { + if (file_printf(ms, "application/CDFV2-corrupt") == -1) + return -1; diff -u libmagic.orig/readelf.c libmagic/readelf.c ---- libmagic.orig/readelf.c 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/readelf.c 2011-09-15 23:28:26.000000000 +0800 -@@ -49,7 +49,7 @@ +--- libmagic.orig/readelf.c Thu Mar 21 18:45:14 2013 ++++ libmagic/readelf.c Mon Dec 2 15:25:29 2013 +@@ -48,8 +48,8 @@ + private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t, off_t, int *, int); - private int doshn(struct magic_set *, int, int, int, off_t, int, size_t, int *, - int); + private int doshn(struct magic_set *, int, int, int, off_t, int, size_t, +- off_t, int *, int, int); -private size_t donote(struct magic_set *, void *, size_t, size_t, int, ++ off_t, int *, int); +private size_t donote(struct magic_set *, unsigned char *, size_t, size_t, int, int, size_t, int *); #define ELF_ALIGN(a) ((((a) + align - 1) / align) * align) -@@ -364,7 +364,7 @@ - #endif +@@ -127,11 +127,17 @@ - private size_t --donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, -+donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size, - int clazz, int swap, size_t align, int *flags) + #define elf_getu16(swap, value) getu16(swap, value) + #define elf_getu32(swap, value) getu32(swap, value) +-#define elf_getu64(swap, value) getu64(swap, value) ++#ifdef USE_ARRAY_FOR_64BIT_TYPES ++# define elf_getu64(swap, array) \ ++ ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 : elf_getu32(swap, array[0])) + \ ++ (swap ? elf_getu32(swap, array[1]) : ((uint64_t)elf_getu32(swap, array[1]) << 32))) ++#else ++# define elf_getu64(swap, value) getu64(swap, value) ++#endif + + #define xsh_addr (clazz == ELFCLASS32 \ +- ? (void *)&sh32 \ +- : (void *)&sh64) ++ ? (void *) &sh32 \ ++ : (void *) &sh64) + #define xsh_sizeof (clazz == ELFCLASS32 \ + ? sizeof(sh32) \ + : sizeof(sh64)) +@@ -168,8 +174,8 @@ + ? elf_getu32(swap, ph32.p_filesz) \ + : elf_getu64(swap, ph64.p_filesz))) + #define xnh_addr (clazz == ELFCLASS32 \ +- ? (void *)&nh32 \ +- : (void *)&nh64) ++ ? (void *) &nh32 \ ++ : (void *) &nh64) + #define xph_memsz (size_t)((clazz == ELFCLASS32 \ + ? elf_getu32(swap, ph32.p_memsz) \ + : elf_getu64(swap, ph64.p_memsz))) +@@ -189,8 +195,8 @@ + ? prpsoffsets32[i] \ + : prpsoffsets64[i]) + #define xcap_addr (clazz == ELFCLASS32 \ +- ? (void *)&cap32 \ +- : (void *)&cap64) ++ ? (void *) &cap32 \ ++ : (void *) &cap64) + #define xcap_sizeof (clazz == ELFCLASS32 \ + ? sizeof cap32 \ + : sizeof cap64) +@@ -292,7 +298,7 @@ { - Elf32_Nhdr nh32; -@@ -374,7 +374,6 @@ - int os_style = -1; - #endif - uint32_t namesz, descsz; -- unsigned char *nbuf = CAST(unsigned char *, vbuf); + Elf32_Phdr ph32; + Elf64_Phdr ph64; +- size_t offset, len; ++ size_t offset; + unsigned char nbuf[BUFSIZ]; + ssize_t bufsize; - (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof); - offset += xnh_sizeof; -@@ -855,20 +854,16 @@ - file_badread(ms); - return -1; - } -- if ((nbuf = malloc((size_t)xsh_size)) == NULL) { +@@ -306,7 +312,11 @@ + * Loop through all the program headers. + */ + for ( ; num; num--) { +- if (pread(fd, xph_addr, xph_sizeof, off) == -1) { ++ if (FINFO_LSEEK_FUNC(fd, off, SEEK_SET) == (off_t)-1) { ++ file_badseek(ms); ++ return -1; ++ } ++ if (FINFO_READ_FUNC(fd, xph_addr, xph_sizeof) == -1) { + file_badread(ms); + return -1; + } +@@ -324,8 +334,13 @@ + * This is a PT_NOTE section; loop through all the notes + * in the section. + */ +- len = xph_filesz < sizeof(nbuf) ? xph_filesz : sizeof(nbuf); +- if ((bufsize = pread(fd, nbuf, len, xph_offset)) == -1) { ++ if (FINFO_LSEEK_FUNC(fd, xph_offset, SEEK_SET) == (off_t)-1) { ++ file_badseek(ms); ++ return -1; ++ } ++ bufsize = FINFO_READ_FUNC(fd, nbuf, ++ ((xph_filesz < sizeof(nbuf)) ? xph_filesz : sizeof(nbuf))); ++ if (bufsize == -1) { + file_badread(ms); + return -1; + } +@@ -852,24 +867,12 @@ + return 0; + } + +- /* Read offset of name section to be able to read section names later */ +- if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) == -1) { +- file_badread(ms); +- return -1; +- } +- name_off = xsh_offset; +- + for ( ; num; num--) { +- /* Read the name of this section. */ +- if (pread(fd, name, sizeof(name), name_off + xsh_name) == -1) { +- file_badread(ms); ++ if (FINFO_LSEEK_FUNC(fd, off, SEEK_SET) == (off_t)-1) { ++ file_badseek(ms); + return -1; + } +- name[sizeof(name) - 1] = '\0'; +- if (strcmp(name, ".debug_info") == 0) +- stripped = 0; +- +- if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) { ++ if (FINFO_READ_FUNC(fd, xsh_addr, xsh_sizeof) == -1) { + file_badread(ms); + return -1; + } +@@ -894,14 +897,17 @@ + /* Things we can determine when we seek */ + switch (xsh_type) { + case SHT_NOTE: +- if ((nbuf = malloc(xsh_size)) == NULL) { - file_error(ms, errno, "Cannot allocate memory" - " for note"); -- return -1; -- } + nbuf = emalloc((size_t)xsh_size); - if ((noff = lseek(fd, (off_t)xsh_offset, SEEK_SET)) == - (off_t)-1) { - file_badread(ms); -- free(nbuf); ++ if ((noff = FINFO_LSEEK_FUNC(fd, (off_t)xsh_offset, SEEK_SET)) == ++ (off_t)-1) { ++ file_badread(ms); + efree(nbuf); return -1; } - if (read(fd, nbuf, (size_t)xsh_size) != - (ssize_t)xsh_size) { -- free(nbuf); +- if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) { ++ if (FINFO_READ_FUNC(fd, nbuf, (size_t)xsh_size) != ++ (ssize_t)xsh_size) { + efree(nbuf); file_badread(ms); +- free(nbuf); return -1; } -@@ -884,11 +879,11 @@ + +@@ -910,25 +916,16 @@ + if (noff >= (off_t)xsh_size) break; + noff = donote(ms, nbuf, (size_t)noff, +- xsh_size, clazz, swap, 4, flags); ++ (size_t)xsh_size, clazz, swap, 4, ++ flags); + if (noff == 0) + break; } - if ((lseek(fd, off, SEEK_SET)) == (off_t)-1) { -- free(nbuf); -+ efree(nbuf); - file_badread(ms); - return -1; - } - free(nbuf); + efree(nbuf); break; case SHT_SUNW_cap: - { +- switch (mach) { +- case EM_SPARC: +- case EM_SPARCV9: +- case EM_IA_64: +- case EM_386: +- case EM_AMD64: +- break; +- default: +- goto skip; +- } +- +- if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) { ++ if (FINFO_LSEEK_FUNC(fd, (off_t)xsh_offset, SEEK_SET) == ++ (off_t)-1) { + file_badseek(ms); + return -1; + } +@@ -940,7 +937,7 @@ + MAX(sizeof cap32, sizeof cap64)]; + if ((coff += xcap_sizeof) > (off_t)xsh_size) + break; +- if (read(fd, cbuf, (size_t)xcap_sizeof) != ++ if (FINFO_READ_FUNC(fd, cbuf, (size_t)xcap_sizeof) != + (ssize_t)xcap_sizeof) { + file_badread(ms); + return -1; +@@ -966,13 +963,12 @@ + break; + } + } +- /*FALLTHROUGH*/ +- skip: ++ break; ++ + default: + break; + } + } +- + if (file_printf(ms, ", %sstripped", stripped ? "" : "not ") == -1) + return -1; + if (cap_hw1) { +@@ -1051,7 +1047,7 @@ + const char *shared_libraries = ""; + unsigned char nbuf[BUFSIZ]; + ssize_t bufsize; +- size_t offset, align, len; ++ size_t offset, align; + + if (size != xph_sizeof) { + if (file_printf(ms, ", corrupted program header size") == -1) +@@ -1060,8 +1056,13 @@ + } + + for ( ; num; num--) { +- if (pread(fd, xph_addr, xph_sizeof, off) == -1) { +- file_badread(ms); ++ if (FINFO_LSEEK_FUNC(fd, off, SEEK_SET) == (off_t)-1) { ++ file_badseek(ms); ++ return -1; ++ } ++ ++ if (FINFO_READ_FUNC(fd, xph_addr, xph_sizeof) == -1) { ++ file_badread(ms); + return -1; + } + +@@ -1099,9 +1100,12 @@ + * This is a PT_NOTE section; loop through all the notes + * in the section. + */ +- len = xph_filesz < sizeof(nbuf) ? xph_filesz +- : sizeof(nbuf); +- bufsize = pread(fd, nbuf, len, xph_offset); ++ if (FINFO_LSEEK_FUNC(fd, xph_offset, SEEK_SET) == (off_t)-1) { ++ file_badseek(ms); ++ return -1; ++ } ++ bufsize = FINFO_READ_FUNC(fd, nbuf, ((xph_filesz < sizeof(nbuf)) ? ++ xph_filesz : sizeof(nbuf))); + if (bufsize == -1) { + file_badread(ms); + return -1; +@@ -1162,7 +1166,7 @@ + /* + * If we cannot seek, it must be a pipe, socket or fifo. + */ +- if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE)) ++ if((FINFO_LSEEK_FUNC(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE)) + fd = file_pipe2file(ms, fd, buf, nbytes); + + if (fstat(fd, &st) == -1) { +diff -u libmagic.orig/readelf.h libmagic/readelf.h +--- libmagic.orig/readelf.h Thu Mar 21 18:45:14 2013 ++++ libmagic/readelf.h Mon Dec 2 15:25:29 2013 +@@ -44,9 +44,17 @@ + typedef uint32_t Elf32_Word; + typedef uint8_t Elf32_Char; + ++#if SIZEOF_LONG_LONG != 8 ++#define USE_ARRAY_FOR_64BIT_TYPES ++typedef uint32_t Elf64_Addr[2]; ++typedef uint32_t Elf64_Off[2]; ++typedef uint32_t Elf64_Xword[2]; ++#else ++#undef USE_ARRAY_FOR_64BIT_TYPES + typedef uint64_t Elf64_Addr; + typedef uint64_t Elf64_Off; + typedef uint64_t Elf64_Xword; ++#endif + typedef uint16_t Elf64_Half; + typedef uint32_t Elf64_Word; + typedef uint8_t Elf64_Char; diff -u libmagic.orig/softmagic.c libmagic/softmagic.c ---- libmagic.orig/softmagic.c 2011-09-15 23:28:13.000000000 +0800 -+++ libmagic/softmagic.c 2011-09-15 23:29:29.000000000 +0800 +--- libmagic.orig/softmagic.c Thu Mar 21 18:45:14 2013 ++++ libmagic/softmagic.c Mon Mar 10 16:40:55 2014 @@ -41,6 +41,11 @@ #include #include @@ -2524,54 +3083,53 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c + private int match(struct magic_set *, struct magic *, uint32_t, - const unsigned char *, size_t, int); -@@ -125,9 +130,9 @@ + const unsigned char *, size_t, size_t, int, int, int, int, int *, int *, +@@ -62,6 +67,8 @@ + private void cvt_32(union VALUETYPE *, const struct magic *); + private void cvt_64(union VALUETYPE *, const struct magic *); - if ((m->flag & BINTEST) != mode) { - /* Skip sub-tests */ -- while (magic[magindex + 1].cont_level != 0 && -- ++magindex < nmagic) -- continue; -+ while (magindex < nmagic - 1 && magic[magindex + 1].cont_level != 0) { -+ magindex++; -+ } - continue; /* Skip to next top-level test*/ - } ++#define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o))) ++ + /* + * softmagic - lookup one file in parsed, in-memory copy of database + * Passed the name and FILE * of one file to be typed. +@@ -69,13 +76,13 @@ + /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ + protected int + file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, +- int mode, int text) ++ size_t level, int mode, int text) + { + struct mlist *ml; + int rv, printed_something = 0, need_separator = 0; + for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next) + if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode, +- text, 0, 0, &printed_something, &need_separator, ++ text, 0, level, &printed_something, &need_separator, + NULL)) != 0) + return rv; -@@ -162,9 +167,9 @@ - * main entry didn't match, - * flush its continuations - */ -- while (magindex < nmagic - 1 && -- magic[magindex + 1].cont_level != 0) -+ while (magindex < nmagic - 1 && magic[magindex + 1].cont_level != 0) { - magindex++; -+ } - continue; - } +@@ -132,7 +139,7 @@ + struct magic *m = &magic[magindex]; -@@ -191,8 +196,8 @@ + if (m->type != FILE_NAME) +- if ((IS_STRING(m->type) && ++ if ((IS_LIBMAGIC_STRING(m->type) && + #define FLT (STRING_BINTEST | STRING_TEXTTEST) + ((text && (m->str_flags & FLT) == STRING_BINTEST) || + (!text && (m->str_flags & FLT) == STRING_TEXTTEST))) || +@@ -209,8 +216,8 @@ if (file_check_mem(ms, ++cont_level) == -1) return -1; - while (magic[magindex+1].cont_level != 0 && - ++magindex < nmagic) { -+ while (magindex < nmagic - 1 && magic[magindex + 1].cont_level != 0) { -+ magindex++; ++ while (magindex + 1 < nmagic && magic[magindex+1].cont_level != 0 && ++ ++magindex) { m = &magic[magindex]; ms->line = m->lineno; /* for messages */ -@@ -207,8 +212,7 @@ - } - ms->offset = m->offset; - if (m->flag & OFFADD) { -- ms->offset += -- ms->c.li[cont_level - 1].off; -+ ms->offset += ms->c.li[cont_level - 1].off; - } - - #ifdef ENABLE_CONDITIONALS -@@ -313,44 +317,22 @@ +@@ -335,44 +342,22 @@ private int check_fmt(struct magic_set *ms, struct magic *m) { @@ -2626,24 +3184,23 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c private int32_t mprint(struct magic_set *ms, struct magic *m) { -@@ -533,13 +515,10 @@ +@@ -583,13 +568,13 @@ char *cp; int rval; - cp = strndup((const char *)ms->search.s, ms->search.rm_len); -- if (cp == NULL) { -- file_oomem(ms, ms->search.rm_len); -- return -1; -- } + cp = estrndup((const char *)ms->search.s, ms->search.rm_len); -+ + if (cp == NULL) { + file_oomem(ms, ms->search.rm_len); + return -1; + } rval = file_printf(ms, m->desc, cp); - free(cp); + efree(cp); if (rval == -1) return -1; -@@ -733,16 +712,16 @@ +@@ -835,16 +820,16 @@ if (m->num_mask) \ switch (m->mask_op & FILE_OPS_MASK) { \ case FILE_OPADD: \ @@ -2664,9 +3221,9 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c break; \ } \ -@@ -1033,16 +1012,13 @@ - - if ((ms->flags & MAGIC_DEBUG) != 0) { +@@ -1145,9 +1130,6 @@ + "nbytes=%zu, count=%u)\n", m->type, m->flag, offset, o, + nbytes, count); mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE)); -#ifndef COMPILE_ONLY - file_mdump(m); @@ -2674,16 +3231,79 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c } if (m->flag & INDIR) { - int off = m->in_offset; - if (m->in_op & FILE_OPINDIRECT) { -- const union VALUETYPE *q = CAST(const union VALUETYPE *, -- ((const void *)(s + offset + off))); -+ const union VALUETYPE *q = -+ ((const void *)(s + offset + off)); - switch (m->in_type) { - case FILE_BYTE: - off = q->b; -@@ -1522,9 +1498,6 @@ +@@ -1191,7 +1173,7 @@ + } + switch (cvt_flip(m->in_type, flip)) { + case FILE_BYTE: +- if (nbytes < (offset + 1)) ++ if (OFFSET_OOB(nbytes, offset, 1)) + return 0; + if (off) { + switch (m->in_op & FILE_OPS_MASK) { +@@ -1226,7 +1208,7 @@ + offset = ~offset; + break; + case FILE_BESHORT: +- if (nbytes < (offset + 2)) ++ if (OFFSET_OOB(nbytes, offset, 2)) + return 0; + if (off) { + switch (m->in_op & FILE_OPS_MASK) { +@@ -1278,7 +1260,7 @@ + offset = ~offset; + break; + case FILE_LESHORT: +- if (nbytes < (offset + 2)) ++ if (OFFSET_OOB(nbytes, offset, 2)) + return 0; + if (off) { + switch (m->in_op & FILE_OPS_MASK) { +@@ -1330,7 +1312,7 @@ + offset = ~offset; + break; + case FILE_SHORT: +- if (nbytes < (offset + 2)) ++ if (OFFSET_OOB(nbytes, offset, 2)) + return 0; + if (off) { + switch (m->in_op & FILE_OPS_MASK) { +@@ -1367,7 +1349,7 @@ + break; + case FILE_BELONG: + case FILE_BEID3: +- if (nbytes < (offset + 4)) ++ if (OFFSET_OOB(nbytes, offset, 4)) + return 0; + if (off) { + switch (m->in_op & FILE_OPS_MASK) { +@@ -1438,7 +1420,7 @@ + break; + case FILE_LELONG: + case FILE_LEID3: +- if (nbytes < (offset + 4)) ++ if (OFFSET_OOB(nbytes, offset, 4)) + return 0; + if (off) { + switch (m->in_op & FILE_OPS_MASK) { +@@ -1508,7 +1490,7 @@ + offset = ~offset; + break; + case FILE_MELONG: +- if (nbytes < (offset + 4)) ++ if (OFFSET_OOB(nbytes, offset, 4)) + return 0; + if (off) { + switch (m->in_op & FILE_OPS_MASK) { +@@ -1578,7 +1560,7 @@ + offset = ~offset; + break; + case FILE_LONG: +- if (nbytes < (offset + 4)) ++ if (OFFSET_OOB(nbytes, offset, 4)) + return 0; + if (off) { + switch (m->in_op & FILE_OPS_MASK) { +@@ -1644,23 +1626,20 @@ if ((ms->flags & MAGIC_DEBUG) != 0) { mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE)); @@ -2693,11 +3313,105 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c } } -@@ -1672,6 +1645,65 @@ + /* Verify we have enough data to match magic type */ + switch (m->type) { + case FILE_BYTE: +- if (nbytes < (offset + 1)) /* should alway be true */ ++ if (OFFSET_OOB(nbytes, offset, 1)) + return 0; + break; + + case FILE_SHORT: + case FILE_BESHORT: + case FILE_LESHORT: +- if (nbytes < (offset + 2)) ++ if (OFFSET_OOB(nbytes, offset, 2)) + return 0; + break; + +@@ -1679,38 +1658,40 @@ + case FILE_FLOAT: + case FILE_BEFLOAT: + case FILE_LEFLOAT: +- if (nbytes < (offset + 4)) ++ if (OFFSET_OOB(nbytes, offset, 4)) + return 0; + break; + + case FILE_DOUBLE: + case FILE_BEDOUBLE: + case FILE_LEDOUBLE: +- if (nbytes < (offset + 8)) ++ if (OFFSET_OOB(nbytes, offset, 8)) + return 0; + break; + + case FILE_STRING: + case FILE_PSTRING: + case FILE_SEARCH: +- if (nbytes < (offset + m->vallen)) ++ if (OFFSET_OOB(nbytes, offset, m->vallen)) + return 0; + break; + + case FILE_REGEX: +- if (nbytes < offset) ++ if (OFFSET_OOB(nbytes, offset, 0)) + return 0; + break; + + case FILE_INDIRECT: +- if (nbytes < offset) ++ if (offset == 0) ++ return 0; ++ if (OFFSET_OOB(nbytes, offset, 0)) + return 0; + sbuf = ms->o.buf; + soffset = ms->offset; + ms->o.buf = NULL; + ms->offset = 0; + rv = file_softmagic(ms, s + offset, nbytes - offset, +- BINTEST, text); ++ recursion_level, BINTEST, text); + if ((ms->flags & MAGIC_DEBUG) != 0) + fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv); + rbuf = ms->o.buf; +@@ -1718,16 +1699,26 @@ + ms->offset = soffset; + if (rv == 1) { + if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 && +- file_printf(ms, m->desc, offset) == -1) ++ file_printf(ms, m->desc, offset) == -1) { ++ if (rbuf) { ++ efree(rbuf); ++ } + return -1; +- if (file_printf(ms, "%s", rbuf) == -1) ++ } ++ if (file_printf(ms, "%s", rbuf) == -1) { ++ if (rbuf) { ++ efree(rbuf); ++ } + return -1; +- free(rbuf); ++ } ++ } ++ if (rbuf) { ++ efree(rbuf); + } + return rv; + + case FILE_USE: +- if (nbytes < offset) ++ if (OFFSET_OOB(nbytes, offset, 0)) + return 0; + sbuf = m->value.s; + if (*sbuf == '^') { +@@ -1837,6 +1828,42 @@ return file_strncmp(a, b, len, flags); } -+private void ++public void +convert_libmagic_pattern(zval *pattern, int options) +{ + int i, j=0; @@ -2709,29 +3423,6 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c + + for (i=0; isearch.s_len - 1; - char c = ms->search.s[l]; - ((char *)(intptr_t)ms->search.s)[l] = '\0'; +-#else +- pmatch[0].rm_so = 0; +- pmatch[0].rm_eo = ms->search.s_len; +-#endif +- rc = regexec(&rx, (const char *)ms->search.s, +- 1, pmatch, REG_STARTEND); +-#if REG_STARTEND == 0 +- ((char *)(intptr_t)ms->search.s)[l] = c; +-#endif +- switch (rc) { +- case 0: +- ms->search.s += (int)pmatch[0].rm_so; +- ms->search.offset += (size_t)pmatch[0].rm_so; +- ms->search.rm_len = +- (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so); +- v = 0; +- break; + zval *pattern; + int options = 0; + pcre_cache_entry *pce; @@ -2803,17 +3511,8 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c + + convert_libmagic_pattern(pattern, options); + -+#if (PHP_MAJOR_VERSION < 6) ++ l = v = 0; + if ((pce = pcre_get_compiled_regex_cache(Z_STRVAL_P(pattern), Z_STRLEN_P(pattern) TSRMLS_CC)) == NULL) { - #else -- pmatch[0].rm_so = 0; -- pmatch[0].rm_eo = ms->search.s_len; -+ if ((pce = pcre_get_compiled_regex_cache(IS_STRING, Z_STRVAL_P(pattern), Z_STRLEN_P(pattern) TSRMLS_CC)) == NULL) { - #endif -- rc = regexec(&rx, (const char *)ms->search.s, -- 1, pmatch, REG_STARTEND); --#if REG_STARTEND == 0 -- ((char *)(intptr_t)ms->search.s)[l] = c; + zval_dtor(pattern); + FREE_ZVAL(pattern); + return -1; @@ -2830,19 +3529,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c + haystack = estrndup(ms->search.s, ms->search.s_len); + + /* match v = 0, no match v = 1 */ -+#if (PHP_MAJOR_VERSION < 6) + php_pcre_match_impl(pce, haystack, ms->search.s_len, retval, subpats, 1, 1, PREG_OFFSET_CAPTURE, 0 TSRMLS_CC); -+#else -+ php_pcre_match_impl(pce, IS_STRING, haystack, ms->search.s_len, retval, subpats, 1, 1, PREG_OFFSET_CAPTURE, 0 TSRMLS_CC); - #endif -- switch (rc) { -- case 0: -- ms->search.s += (int)pmatch[0].rm_so; -- ms->search.offset += (size_t)pmatch[0].rm_so; -- ms->search.rm_len = -- (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so); -- v = 0; -- break; + /* Free haystack */ + efree(haystack); + @@ -2969,92 +3656,11 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c + break; } case FILE_INDIRECT: + case FILE_USE: + case FILE_NAME: - return 1; + return 1; default: file_magerror(ms, "invalid type %d in magiccheck()", m->type); return -1; -@@ -1900,7 +2027,7 @@ - case 'x': - if ((ms->flags & MAGIC_DEBUG) != 0) - (void) fprintf(stderr, "%llu == *any* = 1\n", -- (unsigned long long)v); -+ (uint64_t)v); - matched = 1; - break; - -@@ -1908,7 +2035,7 @@ - matched = v != l; - if ((ms->flags & MAGIC_DEBUG) != 0) - (void) fprintf(stderr, "%llu != %llu = %d\n", -- (unsigned long long)v, (unsigned long long)l, -+ (uint64_t)v, (uint64_t)l, - matched); - break; - -@@ -1916,7 +2043,7 @@ - matched = v == l; - if ((ms->flags & MAGIC_DEBUG) != 0) - (void) fprintf(stderr, "%llu == %llu = %d\n", -- (unsigned long long)v, (unsigned long long)l, -+ (uint64_t)v, (uint64_t)l, - matched); - break; - -@@ -1925,14 +2052,14 @@ - matched = v > l; - if ((ms->flags & MAGIC_DEBUG) != 0) - (void) fprintf(stderr, "%llu > %llu = %d\n", -- (unsigned long long)v, -- (unsigned long long)l, matched); -+ (uint64_t)v, -+ (uint64_t)l, matched); - } - else { - matched = (int64_t) v > (int64_t) l; - if ((ms->flags & MAGIC_DEBUG) != 0) - (void) fprintf(stderr, "%lld > %lld = %d\n", -- (long long)v, (long long)l, matched); -+ (uint64_t)v, (uint64_t)l, matched); - } - break; - -@@ -1941,14 +2068,14 @@ - matched = v < l; - if ((ms->flags & MAGIC_DEBUG) != 0) - (void) fprintf(stderr, "%llu < %llu = %d\n", -- (unsigned long long)v, -- (unsigned long long)l, matched); -+ (uint64_t)v, -+ (uint64_t)l, matched); - } - else { - matched = (int64_t) v < (int64_t) l; - if ((ms->flags & MAGIC_DEBUG) != 0) - (void) fprintf(stderr, "%lld < %lld = %d\n", -- (long long)v, (long long)l, matched); -+ (int64_t)v, (int64_t)l, matched); - } - break; - -@@ -1956,16 +2083,16 @@ - matched = (v & l) == l; - if ((ms->flags & MAGIC_DEBUG) != 0) - (void) fprintf(stderr, "((%llx & %llx) == %llx) = %d\n", -- (unsigned long long)v, (unsigned long long)l, -- (unsigned long long)l, matched); -+ (uint64_t)v, (uint64_t)l, -+ (uint64_t)l, matched); - break; - - case '^': - matched = (v & l) != l; - if ((ms->flags & MAGIC_DEBUG) != 0) - (void) fprintf(stderr, "((%llx & %llx) != %llx) = %d\n", -- (unsigned long long)v, (unsigned long long)l, -- (unsigned long long)l, matched); -+ (uint64_t)v, (uint64_t)l, -+ (uint64_t)l, matched); - break; - - default: +