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