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