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