35FILE_RCSID(
"@(#)$File: apprentice.c,v 1.342 2023/07/17 14:38:35 christos Exp $")
58#ifdef HAVE_SYS_BSWAP_H
63#define EATAB {while (isascii(CAST(unsigned char, *l)) && \
64 isspace(CAST(unsigned char, *l))) ++l;}
65#define LOWCASE(l) (isupper(CAST(unsigned char, l)) ? \
66 tolower(CAST(unsigned char, l)) : (l))
71#if defined(__osf__) && defined(__DECC)
78#define MAP_FAILED (void *) -1
85#define ALLOC_CHUNK CAST(size_t, 10)
86#define ALLOC_INCR CAST(size_t, 200)
88#define MAP_TYPE_USER 0
89#define MAP_TYPE_MALLOC 1
90#define MAP_TYPE_MMAP 2
136#if defined(HAVE_BYTESWAP_H)
137#define swap2(x) bswap_16(x)
138#define swap4(x) bswap_32(x)
139#define swap8(x) bswap_64(x)
140#elif defined(HAVE_SYS_BSWAP_H)
141#define swap2(x) bswap16(x)
142#define swap4(x) bswap32(x)
143#define swap8(x) bswap64(x)
161 const char *,
size_t);
178#define DECLARE_FIELD(name) { # name, sizeof(# name) - 1, parse_ ## name }
191int main(
int,
char *[]);
194main(
int argc,
char *argv[])
206 (
void)
fprintf(stderr,
"Usage: %s file\n", progname);
237# define XX(s) s, (sizeof(s) - 1)
238# define XX_NULL "", 0
306static const struct type_tbl_s special_tbl[] = {
321 for (
p = tbl;
p->len;
p++) {
333 if (
sizeof(off_t) ==
sizeof(
int))
335 if (
sizeof(off_t) ==
sizeof(
long))
345 if (isalpha(
CAST(
unsigned char, l[1]))) {
380 }
else if (isdigit(
CAST(
unsigned char, l[1]))) {
391 if (isdigit(
CAST(
unsigned char, l[2]))) {
435 for (
p = type_tbl;
p->len;
p++) {
475 file_error(ms, 0,
"magic element size %lu != %lu",
476 CAST(
unsigned long,
sizeof(*map->
magic[0])),
515 printf(
"Text patterns:\n");
543 freelocale(ms->c_lc_ctype);
555 sizeof(*ms)))) ==
NULL)
574 ms->
file =
"unknown";
586 ms->c_lc_ctype = newlocale(LC_CTYPE_MASK,
"C", 0);
601 if (map->
p ==
NULL) {
666 int fileerr, errs = -1;
701 for (
j = 0;
j < i;
j++) {
718 errs =
MAX(errs, fileerr);
729 file_error(ms, 0,
"could not find any valid magic files!");
753 file_error(ms, 0,
"Invalid action %d", action);
774 for (
p = str; *
p;
p++)
789 while (*
p && *
p !=
']')
794 while (*
p && *
p !=
'}')
804 return rv == 0 ? 1 :
rv;
1022 if (m->
desc[0] ==
'\0') {
1032 if (m[i].desc[0] !=
'\0')
1066 if (m->
desc[0] ==
'\0')
1097 uint32_t magindex, descindex, mimeindex, lineindex;
1100 for (magindex = 0; magindex < ml->
nmagic; magindex++) {
1104 while (magindex + 1 < ml->
nmagic &&
1114 lineindex = descindex = mimeindex = magindex;
1115 for (; magindex + 1 < ml->
nmagic &&
1118 uint32_t mi = magindex + 1;
1232 if (mset[i].me ==
NULL || mset[i].
count == mset[i].
max) {
1237 erealloc(mset[i].me,
sizeof(*
mp) * incr))) ==
1245 mset[i].
max =
CAST(uint32_t, incr);
1248 mset[i].
me[mset[i].
count++] = *me;
1249 memset(me, 0,
sizeof(*me));
1272 if (stream ==
NULL) {
1273 if (
errno != ENOENT)
1280 memset(&me, 0,
sizeof(me));
1294 if (
line[1] ==
':') {
1297 for (i = 0;
bang[i].name !=
NULL; i++) {
1305 "Unknown !: entry `%s'",
line);
1311 "No current entry for :!%s type",
1327 switch (parse(ms, &me,
line, lineno, action)) {
1360 static const char text[] =
"text";
1361 static const char binary[] =
"binary";
1362 static const size_t len =
sizeof(
text);
1364 uint32_t i = starttest;
1373 me[i].
mp->
desc[0] ? me[i].
mp->
desc :
"(no description)",
1378 isspace(
CAST(
unsigned char,
p[-1]))) &&
1380 || (
p[
len] ==
'\0' ||
1381 isspace(
CAST(
unsigned char,
p[
len])))))
1383 "binary test for text type\n");
1393 for (i = 0; i < nme; i++) {
1403 "level 0 \"default\" did not sort last");
1412 struct magic **ma, uint32_t *nma)
1414 uint32_t i, mentrycount = 0;
1417 for (i = 0; i < nme; i++)
1420 if (mentrycount == 0) {
1426 slen =
sizeof(**ma) * mentrycount;
1433 for (i = 0; i < nme; i++) {
1448 for (i = 0; i < nme; i++)
1458 size_t files = 0, maxfiles = 0;
1459 char **filearr =
NULL;
1467 memset(mset, 0,
sizeof(mset));
1495 if ((mflen =
snprintf(mfn,
sizeof(mfn),
"%s/%s", fn, d.
d_name)) < 0) {
1505 if (files >= maxfiles) {
1507 maxfiles = (maxfiles + 1) * 2;
1508 mlen = maxfiles *
sizeof(*filearr);
1509 if ((filearr =
CAST(
char **,
1517 filearr[files++] =
estrndup(mfn, (mflen >
sizeof(mfn) - 1)?
sizeof(mfn) - 1: mflen);
1521 qsort(filearr, files,
sizeof(*filearr),
cmpstrp);
1522 for (i = 0; i < files; i++) {
1523 load_1(ms, action, filearr[i], &errs, mset);
1529 load_1(ms, action, fn, &errs, mset);
1535 for (i = 0; i < mset[
j].
count; ) {
1536 if (mset[
j].
me[i].mp->cont_level != 0) {
1543 qsort(mset[
j].
me, mset[
j].
count,
sizeof(*mset[0].
me),
1588 v =
CAST(
signed char,
v);
1672 "'/BHhLl' modifiers are only allowed for pascal strings\n");
1678 if (m->str_flags != 0) {
1680 "no modifiers allowed for 16-bit strings\n");
1688 "'/%c' only allowed on regex and search\n",
1694 if (m->str_range == 0) {
1696 "missing range; defaulting to %d\n",
1747#ifdef ENABLE_CONDITIONALS
1751 static const struct cond_tbl_s {
1761 const struct cond_tbl_s *
p;
1763 for (
p = cond_tbl;
p->len;
p++) {
1765 isspace(
CAST(
unsigned char, l[
p->len]))) {
1821 const char *l = *lp;
1823 while (!isspace(
CAST(
unsigned char, *++l)))
1843 const char *l = *lp;
1849 val =
CAST(uint64_t, strtoull(l, &t, 0));
1859 const char *l = *lp;
1863 while (!isspace(
CAST(
unsigned char, *++l))) {
1865 case '0':
case '1':
case '2':
1866 case '3':
case '4':
case '5':
1867 case '6':
case '7':
case '8':
1872 m->str_range =
CAST(uint32_t, strtoul(l, &t, 0));
1873 if (m->str_range == 0)
1905#define SET_LENGTH(a) m->str_flags = (m->str_flags & ~PSTRING_LEN) | (a)
1948 if (l[1] ==
'/' && !isspace(
CAST(
unsigned char, l[2])))
1965 size_t lineno,
int action)
1967#ifdef ENABLE_CONDITIONALS
1968 static uint32_t last_cont_level = 0;
1972 const char *l =
line;
1987#ifdef ENABLE_CONDITIONALS
2006 "than one larger than current level %u",
cont_level,
2012 sizeof(*nm) * cnt))) ==
NULL) {
2082 if (*l ==
'.' || *l ==
',') {
2138 "indirect offset type `%c' invalid",
2149 if ((op =
get_op(*l)) != -1) {
2157 if (isdigit(
CAST(
unsigned char, *l)) || *l ==
'-') {
2162 "in_offset `%s' invalid", l);
2171 "missing ')' in indirect offset");
2177#ifdef ENABLE_CONDITIONALS
2222 && !isalpha(
CAST(
unsigned char, l[1]))) {
2243 "declared at top level", l);
2260 if ((op =
get_op(*l)) != -1) {
2267 "invalid string/indirect op: "
2319 if (*l ==
'x' && ((isascii(
CAST(
unsigned char, l[1])) &&
2320 isspace(
CAST(
unsigned char, l[1]))) || !l[1])) {
2345 }
else if ((l[0] ==
'\\') && (l[1] ==
'b')) {
2350 for (i = 0; (m->
desc[i++] = *l++) !=
'\0' && i <
sizeof(m->
desc); )
2352 if (i ==
sizeof(m->
desc)) {
2353 m->
desc[
sizeof(m->
desc) - 1] =
'\0';
2384 const char *l =
line;
2392 "Current entry already has a strength type: %c %d",
2397 file_magwarn(ms,
"%s: Strength setting is not supported in "
2398 "\"name\" magic entries",
2418 factor = strtoul(l, &el, 0);
2423 if (*el && !isspace(
CAST(
unsigned char, *el))) {
2429 file_magwarn(ms,
"Cannot have factor op `%c' and factor %u",
2443 return (isascii(x) && isalnum(x)) ||
strchr(extra, x);
2452 const char *l =
line;
2456 if (
buf[0] !=
'\0') {
2458 file_magwarn(ms,
"Current entry already has a %s type "
2463 if (*m->
desc ==
'\0') {
2465 "description for adding a %s type",
name);
2470 for (i = 0; *l && i < llen && i <
len &&
goodchar(*l, extra);
2474 if (i ==
len && *l) {
2481 if (!isspace(
CAST(
unsigned char, *l)) && !
goodchar(*l, extra))
2505 sizeof(me->
mp[0].
apple),
"APPLE",
"!+-./?", 0);
2517 sizeof(me->
mp[0].
ext),
"EXTENSION",
",!+-/@?_$&~", 0);
2532 sizeof(me->
mp[0].
mimetype),
"MIME",
"+-/.$?:{}", 1);
2542 *estr =
"missing format spec";
2578#define CHECKLEN() do { \
2579 for (len = cnt = 0; isdigit(CAST(unsigned char, *ptr)); ptr++, cnt++) \
2580 len = len * 10 + (*ptr - '0'); \
2581 if (cnt > 5 || len > 1024) \
2697 while (isdigit(
CAST(
unsigned char, *
ptr)))
2701 while (isdigit(
CAST(
unsigned char , *
ptr)))
2718 *estr =
"not valid";
2746 file_magwarn(ms,
"Internal error inconsistency between "
2747 "m->type and format strings");
2751 file_magwarn(ms,
"No format string for `%s' with description "
2763 "`%s' in description `%s'", estr,
2771 "Too many format strings (should have at most one) "
2772 "for `%s' with description `%s'",
2818 zend_string_release(pattern);
2821 zend_string_release(pattern);
2840 m->
value.
f = (float)strtod(*
p, &ep);
2860 ull =
CAST(uint64_t, strtoull(*
p, &ep, 0));
2872 "Expected numeric type got `%s'",
2873 type_tbl[m->
type].name);
2876 for (q = *
p; isspace(
CAST(
unsigned char, *q)); q++)
2878 if (*q ==
'-' && ull != UINT64_MAX)
2879 ull = -
CAST(int64_t, ull);
2882 x =
CAST(uint64_t, ull & ~0xffULL);
2883 y = (x & ~0xffULL) != ~0xffULL;
2886 x =
CAST(uint64_t, ull & ~0xffffULL);
2887 y = (x & ~0xffffULL) != ~0xffffULL;
2890 x =
CAST(uint64_t, ull & ~0xffffffffULL);
2891 y = (x & ~0xffffffffULL) != ~0xffffffffULL;
2898 fprintf(stderr,
"Bad width %zu", ts);
2903 " type `%s' value %#" PRIx64,
2904 type_tbl[m->
type].name, ull);
2925 const char *origs =
s;
2927 size_t plen =
sizeof(m->
value.
s);
2929 char *pmax =
p + plen - 1;
2932 size_t bracket_nesting = 0;
2934 while ((c = *
s++) !=
'\0') {
2935 if (isspace(
CAST(
unsigned char, c)))
2938 file_error(ms, 0,
"string too long: `%s'", origs);
2945 if (c ==
']' && bracket_nesting > 0) {
2948 *
p++ =
CAST(
char, c);
2960 bracket_nesting == 0 && warn) {
2962 "use \\\\. instead");
2969 "escaped tab found, use \\\\t instead");
2975 if (isprint(
CAST(
unsigned char, c))) {
2980 strchr(
"[]().*?^$|{}", c)
2988 "unknown escape sequence: "
3013 *
p++ =
CAST(
char, c);
3055 if (c >=
'0' && c <=
'7') {
3056 val = (
val << 3) | (c -
'0');
3058 if (c >=
'0' && c <=
'7')
3059 val = (
val << 3) | (c-
'0');
3103 if (!isascii(
CAST(
unsigned char, c)))
3105 if (isdigit(
CAST(
unsigned char, c)))
3107 if ((c >=
'a') && (c <=
'f'))
3108 return c + 10 -
'a';
3109 if (( c>=
'A') && (c <=
'F'))
3110 return c + 10 -
'A';
3134 if (c >= 040 && c <= 0176)
3135 (
void) fputc(c, fp);
3137 (
void) fputc(
'\\', fp);
3140 (
void) fputc(
'a', fp);
3144 (
void) fputc(
'b', fp);
3148 (
void) fputc(
'f', fp);
3152 (
void) fputc(
'n', fp);
3156 (
void) fputc(
'r', fp);
3160 (
void) fputc(
't', fp);
3164 (
void) fputc(
'v', fp);
3209 uint32_t version, entries = 0, nentries;
3211 char *dbname =
NULL;
3226 goto internal_loaded;
3233 if (st.
sb.st_mode & S_IFDIR) {
3256 file_error(ms, 0,
"file `%s' is too %s", dbname,
3257 st.
sb.st_size < 8 ?
"small" :
"large");
3274 ptr = (uint32_t *)(
void *)map->
p;
3277 file_error(ms, 0,
"bad magic in `%s'", dbname);
3288 file_error(ms, 0,
"File %d supports only version %d magic "
3297 if (needsbyteswap && fn ==
NULL) {
3303 nentries = (uint32_t)(st.
sb.st_size /
sizeof(
struct magic));
3304 entries = (uint32_t)(st.
sb.st_size /
sizeof(
struct magic));
3306 file_error(ms, 0,
"Size of `%s' %llu is not a multiple of %zu",
3307 dbname, (
unsigned long long)st.
sb.st_size,
3308 sizeof(
struct magic));
3321 nentries += map->
nmagic[i];
3323 if (
NULL != fn && entries != nentries + 1) {
3324 file_error(ms, 0,
"Inconsistent entries in `%s' %u != %u",
3325 dbname, entries, nentries + 1);
3355 static const size_t m =
sizeof(**map->
magic);
3378 memset(&hdr, 0,
sizeof(hdr));
3383 if (
php_stream_write(stream,(
const char *)&hdr,
sizeof(hdr)) != (ssize_t)
sizeof(hdr)) {
3420 for (q = fn; *q; q++)
3423 for (
p =
ext +
sizeof(
ext) - 1;
p >=
ext && q >= fn;
p--, q--)
3461 for (i = 0; i < nmagic; i++)
3465#if !defined(HAVE_BYTESWAP_H) && !defined(HAVE_SYS_BSWAP_H)
3473 uint8_t *
s =
RCAST(uint8_t *,
RCAST(
void *, &sv));
3487 uint8_t *
s =
RCAST(uint8_t *,
RCAST(
void *, &sv));
3503 uint8_t *
s =
RCAST(uint8_t *,
RCAST(
void *, &sv));
3532 const unsigned char *c;
3534 for (c = us; *c; c++) {
3535 if ((*c & 0x80) == 0)
3540 for (; c >= us; c--) {
3545 for (c = us; *c; c++) {
3547 if ((*c & 0x80) == 0)
3569 m->str_range =
swap4(m->str_range);
3570 m->str_flags =
swap4(m->str_flags);
3574 m->num_mask =
swap8(m->num_mask);
3592 "(bad pascal string length %d)",
3602 const unsigned char *
s =
RCAST(
const unsigned char *, ss);
3603 unsigned int s3, s2, s1, s0;
3612 len = (s1 << 8) | s0;
3617 len = (s0 << 8) | s1;
3624 len = (s3 << 24) | (s2 << 16) | (s1 << 8) | s0;
3631 len = (s0 << 24) | (s1 << 16) | (s2 << 8) | s3;
3635 "(bad pascal string length %d)",
3660 for (i = 0; i < ml->
nmagic; i++) {
file_private int parse_mime(struct magic_set *, struct magic_entry *, const char *, size_t)
file_private int check_format_type(const char *, int, const char **)
file_private size_t typesize(int type)
file_private uint32_t set_text_binary(struct magic_set *ms, struct magic_entry *me, uint32_t nme, uint32_t starttest)
file_protected struct magic_set * file_ms_alloc(int flags)
file_private void byteswap(struct magic *, uint32_t)
file_private int parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp)
file_private uint64_t swap8(uint64_t)
file_private void magic_entry_free(struct magic_entry *me, uint32_t nme)
file_private const char usg_hdr[]
file_private int goodchar(unsigned char x, const char *extra)
file_protected uintmax_t file_varint2uintmax_t(const unsigned char *us, int t, size_t *l)
file_private int coalesce_entries(struct magic_set *ms, struct magic_entry *me, uint32_t nme, struct magic **ma, uint32_t *nma)
file_private int check_cond(struct magic_set *ms, int cond, uint32_t cont_level)
file_private int getvalue(struct magic_set *ms, struct magic *, const char **, int)
file_private uint16_t swap2(uint16_t)
file_protected void file_showstr(FILE *fp, const char *s, size_t len)
file_private int parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp)
file_private void bs1(struct magic *)
int file_formats[FILE_NAMES_SIZE]
#define DECLARE_FIELD(name)
file_private void mlist_free_all(struct magic_set *)
file_private struct magic_map * apprentice_map(struct magic_set *, const char *)
const size_t file_nformats
file_private int check_format(struct magic_set *, struct magic *)
file_private uint32_t swap4(uint32_t)
file_private void apprentice_unmap(struct magic_map *)
file_private struct mlist * mlist_alloc(void)
file_private size_t nonmagic(const char *str)
file_private int parse_strength(struct magic_set *, struct magic_entry *, const char *, size_t)
file_private void mlist_free(struct mlist *)
file_private void set_test_type(struct magic *mstart, struct magic *m)
int(* fun)(struct magic_set *, struct magic_entry *, const char *, size_t)
file_private int cmpstrp(const void *p1, const void *p2)
file_private size_t magicsize
file_protected size_t file_pstring_length_size(struct magic_set *ms, const struct magic *m)
file_private char * mkdbname(struct magic_set *, const char *, int)
file_private int apprentice_1(struct magic_set *, const char *, int)
file_private void parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp, int op)
file_protected uint64_t file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
file_protected void file_ms_free(struct magic_set *ms)
file_private struct magic_map * apprentice_load(struct magic_set *, const char *, int)
file_protected int file_magicfind(struct magic_set *ms, const char *name, struct mlist *v)
file_protected size_t file_pstring_get_length(struct magic_set *ms, const struct magic *m, const char *ss)
file_private int parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line, size_t llen, zend_off_t off, size_t len, const char *name, const char *extra, int nt)
file_private ssize_t apprentice_magic_strength_1(const struct magic *)
file_private void eatsize(const char **)
file_private void apprentice_list(struct mlist *, int)
file_private int string_modifier_check(struct magic_set *ms, struct magic *m)
file_private int parse_apple(struct magic_set *, struct magic_entry *, const char *, size_t)
file_private int apprentice_sort(const void *, const void *)
file_private void set_last_default(struct magic_set *ms, struct magic_entry *me, uint32_t nme)
file_protected int file_apprentice(struct magic_set *ms, const char *fn, int action)
file_private const char ext[]
file_private int hextoint(int)
file_private int apprentice_compile(struct magic_set *, struct magic_map *, const char *)
file_private int addentry(struct magic_set *ms, struct magic_entry *me, struct magic_entry_set *mset)
file_private off_t maxoff_t(void)
file_private int add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx)
file_private int get_type(const struct type_tbl_s *tbl, const char *l, const char **t)
file_private int get_cond(const char *l, const char **t)
file_private int parse_ext(struct magic_set *, struct magic_entry *, const char *, size_t)
file_private struct @270140275377037011347114072344362023036171337212 bang[]
file_private int get_standard_integer_type(const char *l, const char **t)
file_private void init_file_tables(void)
file_private void load_1(struct magic_set *ms, int action, const char *fn, int *errs, struct magic_entry_set *mset)
file_protected size_t file_magic_strength(const struct magic *m, size_t nmagic __attribute__((__unused__)))
file_private int get_op(char)
const char * file_names[FILE_NAMES_SIZE]
file_private void mlist_free_one(struct mlist *ml)
fprintf($stream, string $format, mixed ... $values)
getenv(?string $name=null, bool $local_only=false)
printf(string $format, mixed ... $values)
strrchr(string $haystack, string $needle, bool $before_needle=false)
dir(string $directory, $context=null)
count(Countable|array $value, int $mode=COUNT_NORMAL)
strstr(string $haystack, string $needle, bool $before_needle=false)
assert(mixed $assertion, Throwable|string|null $description=null)
strchr(string $haystack, string $needle, bool $before_needle=false)
const unsigned char php_magic_database[8313][1024]
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
file_protected int file_looks_utf8(const unsigned char *buf, size_t nbytes, file_unichar_t *ubuf, size_t *ulen)
#define CHAR_REGEX_OFFSET_START
#define CHAR_PSTRING_1_LE
#define CHAR_PSTRING_2_LE
#define INDIRECT_RELATIVE
#define PSTRING_LENGTH_INCLUDES_ITSELF
#define CHAR_INDIRECT_RELATIVE
#define FILE_FACTOR_OP_NONE
file_protected void file_protected void file_protected void file_magwarn(struct magic_set *, const char *,...) __attribute__((__format__(__printf__
file_protected int file_protected int file_reset(struct magic_set *, int)
#define CHAR_IGNORE_UPPERCASE
file_protected void file_protected void file_protected void file_protected void file_mdump(struct magic *)
#define CHAR_IGNORE_LOWERCASE
#define STRING_COMPACT_WHITESPACE
#define IS_LIBMAGIC_STRING(t)
file_protected void file_badread(struct magic_set *)
#define FILE_FACTOR_OP_PLUS
file_protected void file_protected void file_magerror(struct magic_set *, const char *,...) __attribute__((__format__(__printf__
#define STRING_COMPACT_OPTIONAL_WHITESPACE
#define CHAR_PSTRING_4_BE
#define CHAR_COMPACT_OPTIONAL_WHITESPACE
#define REGEX_OFFSET_START
#define CHAR_PSTRING_4_LE
#define FILE_ELF_NOTES_MAX
#define STRING_IGNORE_LOWERCASE
#define FILE_ELF_SHSIZE_MAX
file_protected int file_parse_guid(const char *, uint64_t *)
#define FILE_FACTOR_OP_DIV
file_protected void file_error(struct magic_set *, int, const char *,...) __attribute__((__format__(__printf__
file_protected char * file_printable(struct magic_set *, char *, size_t, const char *, size_t)
#define CHAR_PSTRING_2_BE
file_protected void file_oomem(struct magic_set *, size_t)
file_protected int file_check_mem(struct magic_set *, unsigned int)
#define STRING_IGNORE_UPPERCASE
#define FILE_ELF_PHNUM_MAX
#define CHAR_COMPACT_WHITESPACE
#define FILE_FACTOR_OP_TIMES
#define FILE_ELF_SHNUM_MAX
#define FILE_FACTOR_OP_MINUS
#define FILE_ENCODING_MAX
#define STRING_DEFAULT_RANGE
#define CHAR_PSTRING_LENGTH_INCLUDES_ITSELF
file_public int magic_setflags(struct magic_set *ms, int flags)
file_public const char * magic_error(struct magic_set *ms)
file_public int magic_compile(struct magic_set *ms, const char *magicfile)
file_public void magic_close(struct magic_set *ms)
file_public struct magic_set * magic_open(int flags)
const char * magic_getpath(const char *, int)
unsigned const char * text
PHP_JSON_API size_t int options
zend_string * convert_libmagic_pattern(const char *val, size_t len, uint32_t options)
#define offsetof(STRUCTURE, FIELD)
PHPAPI pcre_cache_entry * pcre_get_compiled_regex_cache(zend_string *regex)
struct _pcre_cache_entry pcre_cache_entry
struct _php_stream php_stream
#define php_stream_stat_path_ex(path, flags, ssb, context)
#define php_stream_read(stream, buf, count)
struct _php_stream_dirent php_stream_dirent
#define php_stream_readdir(dirstream, dirent)
#define php_stream_get_line(stream, buf, maxlen, retlen)
#define php_stream_opendir(path, options, context)
#define php_stream_close(stream)
#define php_stream_closedir(dirstream)
#define php_stream_open_wrapper(path, mode, options, opened)
#define php_stream_stat(stream, ssb)
struct _php_stream_statbuf php_stream_statbuf
#define php_stream_write(stream, buf, count)
struct magic * magic[MAGIC_SETS]
uint32_t nmagic[MAGIC_SETS]
struct mlist * mlist[MAGIC_SETS]
unsigned char us[MAXstring]
#define estrndup(s, length)
#define ecalloc(nmemb, size)
#define erealloc(ptr, size)
strncmp(string $string1, string $string2, int $length)
strcmp(string $string1, string $string2)
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
struct _zend_string zend_string
#define VCWD_ACCESS(pathname, mode)