Merge branch 'PHP-7.4'

* PHP-7.4:
  Ported limagic 5.37
This commit is contained in:
Anatol Belski 2019-05-30 02:23:20 +02:00
commit 8f85961326
31 changed files with 153843 additions and 129444 deletions

View File

@ -657,6 +657,7 @@ utime \
vasprintf \
asprintf \
nanosleep \
memmem \
)
AX_FUNC_WHICH_GETHOSTBYNAME_R

View File

@ -10,7 +10,7 @@ if test "$PHP_FILEINFO" != "no"; then
libmagic/apprentice.c libmagic/apptype.c libmagic/ascmagic.c \
libmagic/cdf.c libmagic/cdf_time.c libmagic/compress.c \
libmagic/encoding.c libmagic/fsmagic.c libmagic/funcs.c \
libmagic/is_tar.c libmagic/magic.c libmagic/print.c \
libmagic/is_json.c libmagic/is_tar.c libmagic/magic.c libmagic/print.c \
libmagic/readcdf.c libmagic/softmagic.c libmagic/der.c \
libmagic/buffer.c"

View File

@ -6,7 +6,7 @@ if (PHP_FILEINFO != 'no') {
LIBMAGIC_SOURCES=" apprentice.c apptype.c ascmagic.c \
cdf.c cdf_time.c compress.c \
encoding.c fsmagic.c funcs.c \
is_tar.c magic.c print.c \
is_json.c is_tar.c magic.c print.c \
readcdf.c softmagic.c der.c \
strcasestr.c buffer.c";

File diff suppressed because it is too large Load Diff

View File

@ -66,10 +66,11 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.270 2018/02/21 21:26:48 christos Exp $")
#define MAXMAGIC_SIZE SSIZE_MAX
#endif
#define EATAB {while (isascii((unsigned char) *l) && \
isspace((unsigned char) *l)) ++l;}
#define LOWCASE(l) (isupper((unsigned char) (l)) ? \
tolower((unsigned char) (l)) : (l))
#define EATAB {while (isascii(CAST(unsigned char, *l)) && \
isspace(CAST(unsigned char, *l))) ++l;}
#define LOWCASE(l) (isupper(CAST(unsigned char, l)) ? \
tolower(CAST(unsigned char, l)) : (l))
/*
* Work around a bug in headers on Digital Unix.
* At least confirmed for: OSF1 V4.0 878
@ -92,8 +93,8 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.270 2018/02/21 21:26:48 christos Exp $")
#define MAP_FILE 0
#endif
#define ALLOC_CHUNK (size_t)10
#define ALLOC_INCR (size_t)200
#define ALLOC_CHUNK CAST(size_t, 10)
#define ALLOC_INCR CAST(size_t, 200)
#define MAP_TYPE_USER 0
#define MAP_TYPE_MALLOC 1
@ -275,12 +276,21 @@ get_type(const struct type_tbl_s *tbl, const char *l, const char **t)
return p->type;
}
private off_t
maxoff_t(void) {
if (/*CONSTCOND*/sizeof(off_t) == sizeof(int))
return CAST(off_t, INT_MAX);
if (/*CONSTCOND*/sizeof(off_t) == sizeof(long))
return CAST(off_t, LONG_MAX);
return 0x7fffffff;
}
private int
get_standard_integer_type(const char *l, const char **t)
{
int type;
if (isalpha((unsigned char)l[1])) {
if (isalpha(CAST(unsigned char, l[1]))) {
switch (l[1]) {
case 'C':
/* "dC" and "uC" */
@ -315,7 +325,7 @@ get_standard_integer_type(const char *l, const char **t)
return FILE_INVALID;
}
l += 2;
} else if (isdigit((unsigned char)l[1])) {
} else if (isdigit(CAST(unsigned char, l[1]))) {
/*
* "d{num}" and "u{num}"; we only support {num} values
* of 1, 2, 4, and 8 - the Single UNIX Specification
@ -326,7 +336,7 @@ get_standard_integer_type(const char *l, const char **t)
* neither of them support values bigger than 8 or
* non-power-of-2 values.
*/
if (isdigit((unsigned char)l[2])) {
if (isdigit(CAST(unsigned char, l[2]))) {
/* Multi-digit, so > 9 */
return FILE_INVALID;
}
@ -410,8 +420,8 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
if (magicsize != FILE_MAGICSIZE) {
file_error(ms, 0, "magic element size %lu != %lu",
(unsigned long)sizeof(*map->magic[0]),
(unsigned long)FILE_MAGICSIZE);
CAST(unsigned long, sizeof(*map->magic[0])),
CAST(unsigned long, FILE_MAGICSIZE));
return -1;
}
@ -423,7 +433,7 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
}
map = apprentice_map(ms, fn);
if (map == (struct magic_map *)-1)
if (map == RCAST(struct magic_map *, -1))
return -1;
if (map == NULL) {
if (fn) {
@ -480,7 +490,7 @@ file_ms_alloc(int flags)
struct magic_set *ms;
size_t i, len;
if ((ms = CAST(struct magic_set *, ecalloc((size_t)1,
if ((ms = CAST(struct magic_set *, ecalloc(CAST(size_t, 1u),
sizeof(struct magic_set)))) == NULL)
return NULL;
@ -545,6 +555,14 @@ mlist_alloc(void)
return mlist;
}
private void
mlist_free_one(struct mlist *ml)
{
if (ml->map)
apprentice_unmap(CAST(struct magic_map *, ml->map));
efree(ml);
}
private void
mlist_free(struct mlist *mlist)
{
@ -553,14 +571,11 @@ mlist_free(struct mlist *mlist)
if (mlist == NULL)
return;
ml = mlist->next;
for (ml = mlist->next; (next = ml->next) != NULL; ml = next) {
if (ml->map)
apprentice_unmap(CAST(struct magic_map *, ml->map));
efree(ml);
if (ml == mlist)
break;
for (ml = mlist->next; ml != mlist; ml = next) {
next = ml->next;
mlist_free_one(ml);
}
mlist_free_one(mlist);
}
/* const char *fn: list of magic files and directories */
@ -571,8 +586,7 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
int fileerr, errs = -1;
size_t i;
if (ms->mlist[0] != NULL)
(void)file_reset(ms, 0);
(void)file_reset(ms, 0);
/* XXX disabling default magic loading so the compiled in data is used */
#if 0
@ -759,7 +773,7 @@ typesize(int type)
case FILE_LEDOUBLE:
return 8;
default:
return (size_t)~0;
return CAST(size_t, ~0);
}
}
@ -769,8 +783,9 @@ typesize(int type)
private size_t
apprentice_magic_strength(const struct magic *m)
{
#define MULT 10
size_t ts, v, val = 2 * MULT; /* baseline strength */
#define MULT 10U
size_t ts, v;
ssize_t val = 2 * MULT; /* baseline strength */
switch (m->type) {
case FILE_DEFAULT: /* make sure this sorts last */
@ -813,7 +828,7 @@ apprentice_magic_strength(const struct magic *m)
case FILE_BEDOUBLE:
case FILE_LEDOUBLE:
ts = typesize(m->type);
if (ts == (size_t)~0)
if (ts == CAST(size_t, ~0))
abort();
val += ts * MULT;
break;
@ -829,6 +844,8 @@ apprentice_magic_strength(const struct magic *m)
break;
case FILE_SEARCH:
if (m->vallen == 0)
break;
val += m->vallen * MAX(MULT / m->vallen, 1);
break;
@ -876,9 +893,6 @@ apprentice_magic_strength(const struct magic *m)
abort();
}
if (val == 0) /* ensure we only return 0 for FILE_DEFAULT */
val = 1;
switch (m->factor_op) {
case FILE_FACTOR_OP_NONE:
break;
@ -898,6 +912,9 @@ apprentice_magic_strength(const struct magic *m)
abort();
}
if (val <= 0) /* ensure we only return 0 for FILE_DEFAULT */
val = 1;
/*
* Magic entries with no description get a bonus because they depend
* on subsequent magic entries to print something.
@ -1026,7 +1043,7 @@ set_test_type(struct magic *mstart, struct magic *m)
break;
/* binary test if pattern is not text */
if (file_looks_utf8(m->value.us, (size_t)m->vallen, NULL,
if (file_looks_utf8(m->value.us, CAST(size_t, m->vallen), NULL,
NULL) <= 0)
mstart->flag |= BINTEST;
else
@ -1076,7 +1093,7 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
{
char buffer[BUFSIZ + 1];
char *line = NULL;
size_t len;
ssize_t len;
size_t lineno = 0;
struct magic_entry me;
@ -1112,7 +1129,7 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
size_t i;
for (i = 0; bang[i].name != NULL; i++) {
if ((size_t)(len - 2) > bang[i].len &&
if (CAST(size_t, len - 2) > bang[i].len &&
memcmp(bang[i].name, line + 2,
bang[i].len) == 0)
break;
@ -1165,7 +1182,7 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
private int
cmpstrp(const void *p1, const void *p2)
{
return strcmp(*(char *const *)p1, *(char *const *)p2);
return strcmp(*RCAST(char *const *, p1), *RCAST(char *const *, p2));
}
@ -1191,10 +1208,10 @@ set_text_binary(struct magic_set *ms, struct magic_entry *me, uint32_t nme,
if (me[i].mp->flag & BINTEST) {
char *p = strstr(me[i].mp->desc, text);
if (p && (p == me[i].mp->desc ||
isspace((unsigned char)p[-1])) &&
isspace(CAST(unsigned char, p[-1]))) &&
(p + len - me[i].mp->desc == MAXstring
|| (p[len] == '\0' ||
isspace((unsigned char)p[len]))))
isspace(CAST(unsigned char, p[len])))))
(void)fprintf(stderr, "*** Possible "
"binary test for text type\n");
}
@ -1327,12 +1344,14 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
filearr[files++] = estrndup(mfn, (mflen > sizeof(mfn) - 1)? sizeof(mfn) - 1: mflen);
}
php_stream_closedir(dir);
qsort(filearr, files, sizeof(*filearr), cmpstrp);
for (i = 0; i < files; i++) {
load_1(ms, action, filearr[i], &errs, mset);
efree(filearr[i]);
if (filearr) {
qsort(filearr, files, sizeof(*filearr), cmpstrp);
for (i = 0; i < files; i++) {
load_1(ms, action, filearr[i], &errs, mset);
efree(filearr[i]);
}
efree(filearr);
}
efree(filearr);
} else
load_1(ms, action, fn, &errs, mset);
if (errs)
@ -1390,12 +1409,12 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
* the sign extension must have happened.
*/
case FILE_BYTE:
v = (signed char) v;
v = CAST(signed char, v);
break;
case FILE_SHORT:
case FILE_BESHORT:
case FILE_LESHORT:
v = (short) v;
v = CAST(short, v);
break;
case FILE_DATE:
case FILE_BEDATE:
@ -1412,7 +1431,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
case FILE_FLOAT:
case FILE_BEFLOAT:
case FILE_LEFLOAT:
v = (int32_t) v;
v = CAST(int32_t, v);
break;
case FILE_QUAD:
case FILE_BEQUAD:
@ -1429,7 +1448,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
case FILE_DOUBLE:
case FILE_BEDOUBLE:
case FILE_LEDOUBLE:
v = (int64_t) v;
v = CAST(int64_t, v);
break;
case FILE_STRING:
case FILE_PSTRING:
@ -1556,7 +1575,7 @@ get_cond(const char *l, const char **t)
for (p = cond_tbl; p->len; p++) {
if (strncmp(l, p->name, p->len) == 0 &&
isspace((unsigned char)l[p->len])) {
isspace(CAST(unsigned char, l[p->len]))) {
if (t)
*t = l + p->len;
break;
@ -1614,7 +1633,7 @@ parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp)
{
const char *l = *lp;
while (!isspace((unsigned char)*++l))
while (!isspace(CAST(unsigned char, *++l)))
switch (*l) {
case CHAR_INDIRECT_RELATIVE:
m->str_flags |= INDIRECT_RELATIVE;
@ -1640,7 +1659,7 @@ parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp,
++l;
m->mask_op |= op;
val = (uint64_t)strtoull(l, &t, 0);
val = CAST(uint64_t, strtoull(l, &t, 0));
l = t;
m->num_mask = file_signextend(ms, m, val);
eatsize(&l);
@ -1654,7 +1673,7 @@ parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp)
char *t;
int have_range = 0;
while (!isspace((unsigned char)*++l)) {
while (!isspace(CAST(unsigned char, *++l))) {
switch (*l) {
case '0': case '1': case '2':
case '3': case '4': case '5':
@ -1736,7 +1755,7 @@ parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp)
goto out;
}
/* allow multiple '/' for readability */
if (l[1] == '/' && !isspace((unsigned char)l[2]))
if (l[1] == '/' && !isspace(CAST(unsigned char, l[2])))
l++;
}
if (string_modifier_check(ms, m) == -1)
@ -1791,7 +1810,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
return -1;
}
m = &me->mp[me->cont_count - 1];
diff = (int32_t)cont_level - (int32_t)m->cont_level;
diff = CAST(int32_t, cont_level) - CAST(int32_t, m->cont_level);
if (diff > 1)
file_magwarn(ms, "New continuation level %u is more "
"than one larger than current level %u", cont_level,
@ -1804,7 +1823,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
file_oomem(ms, sizeof(*nm) * cnt);
return -1;
}
me->mp = m = nm;
me->mp = nm;
me->max_count = CAST(uint32_t, cnt);
}
m = &me->mp[me->cont_count++];
@ -1850,7 +1869,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
}
/* get offset, then skip over it */
m->offset = (int32_t)strtol(l, &t, 0);
m->offset = CAST(int32_t, strtol(l, &t, 0));
if (l == t) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms, "offset `%s' invalid", l);
@ -1909,6 +1928,12 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
case 'I':
m->in_type = FILE_BEID3;
break;
case 'q':
m->in_type = FILE_LEQUAD;
break;
case 'Q':
m->in_type = FILE_BEQUAD;
break;
default:
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms,
@ -1931,8 +1956,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
m->in_op |= FILE_OPINDIRECT;
l++;
}
if (isdigit((unsigned char)*l) || *l == '-') {
m->in_offset = (int32_t)strtol(l, &t, 0);
if (isdigit(CAST(unsigned char, *l)) || *l == '-') {
m->in_offset = CAST(int32_t, strtol(l, &t, 0));
if (l == t) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms,
@ -1995,7 +2020,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
*/
if (*l == 'd')
m->type = get_standard_integer_type(l, &l);
else if (*l == 's' && !isalpha((unsigned char)l[1])) {
else if (*l == 's'
&& !isalpha(CAST(unsigned char, l[1]))) {
m->type = FILE_STRING;
++l;
}
@ -2085,8 +2111,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
break;
default:
m->reln = '='; /* the default relation */
if (*l == 'x' && ((isascii((unsigned char)l[1]) &&
isspace((unsigned char)l[1])) || !l[1])) {
if (*l == 'x' && ((isascii(CAST(unsigned char, l[1])) &&
isspace(CAST(unsigned char, l[1]))) || !l[1])) {
m->reln = *l;
++l;
}
@ -2178,11 +2204,11 @@ parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line)
file_magwarn(ms, "Too large factor `%lu'", factor);
goto out;
}
if (*el && !isspace((unsigned char)*el)) {
if (*el && !isspace(CAST(unsigned char, *el))) {
file_magwarn(ms, "Bad factor `%s'", l);
goto out;
}
m->factor = (uint8_t)factor;
m->factor = CAST(uint8_t, factor);
if (m->factor == 0 && m->factor_op == FILE_FACTOR_OP_DIV) {
file_magwarn(ms, "Cannot have factor op `%c' and factor %u",
m->factor_op, m->factor);
@ -2213,7 +2239,7 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
if (buf[0] != '\0') {
len = nt ? strlen(buf) : len;
file_magwarn(ms, "Current entry already has a %s type "
"`%.*s', new type `%s'", name, (int)len, buf, l);
"`%.*s', new type `%s'", name, CAST(int, len), buf, l);
return -1;
}
@ -2234,7 +2260,7 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
file_magwarn(ms, "%s type `%s' truncated %"
SIZE_T_FORMAT "u", name, line, i);
} else {
if (!isspace((unsigned char)*l) && !goodchar(*l, extra))
if (!isspace(CAST(unsigned char, *l)) && !goodchar(*l, extra))
file_magwarn(ms, "%s type `%s' has bad char '%c'",
name, line, *l);
if (nt)
@ -2336,7 +2362,7 @@ check_format_type(const char *ptr, int type, const char **estr)
if (*ptr == '#')
ptr++;
#define CHECKLEN() do { \
for (len = cnt = 0; isdigit((unsigned char)*ptr); ptr++, cnt++) \
for (len = cnt = 0; isdigit(CAST(unsigned char, *ptr)); ptr++, cnt++) \
len = len * 10 + (*ptr - '0'); \
if (cnt > 5 || len > 1024) \
goto toolong; \
@ -2454,11 +2480,11 @@ check_format_type(const char *ptr, int type, const char **estr)
case FILE_FMT_STR:
if (*ptr == '-')
ptr++;
while (isdigit((unsigned char )*ptr))
while (isdigit(CAST(unsigned char, *ptr)))
ptr++;
if (*ptr == '.') {
ptr++;
while (isdigit((unsigned char )*ptr))
while (isdigit(CAST(unsigned char , *ptr)))
ptr++;
}
@ -2608,7 +2634,7 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
return 0;
default:
errno = 0;
ull = (uint64_t)strtoull(*p, &ep, 0);
ull = CAST(uint64_t, strtoull(*p, &ep, 0));
m->value.q = file_signextend(ms, m, ull);
if (*p == ep) {
file_magwarn(ms, "Unparseable number `%s'", *p);
@ -2617,24 +2643,24 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
uint64_t x;
const char *q;
if (ts == (size_t)~0) {
if (ts == CAST(size_t, ~0)) {
file_magwarn(ms,
"Expected numeric type got `%s'",
type_tbl[m->type].name);
}
for (q = *p; isspace((unsigned char)*q); q++)
for (q = *p; isspace(CAST(unsigned char, *q)); q++)
continue;
if (*q == '-')
ull = -(int64_t)ull;
ull = -CAST(int64_t, ull);
switch (ts) {
case 1:
x = (uint64_t)(ull & ~0xffULL);
x = CAST(uint64_t, ull & ~0xffULL);
break;
case 2:
x = (uint64_t)(ull & ~0xffffULL);
x = CAST(uint64_t, ull & ~0xffffULL);
break;
case 4:
x = (uint64_t)(ull & ~0xffffffffULL);
x = CAST(uint64_t, ull & ~0xffffffffULL);
break;
case 8:
x = 0;
@ -2674,7 +2700,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
int val;
while ((c = *s++) != '\0') {
if (isspace((unsigned char) c))
if (isspace(CAST(unsigned char, c)))
break;
if (p >= pmax) {
file_error(ms, 0, "string too long: `%s'", origs);
@ -2698,7 +2724,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
/*FALLTHROUGH*/
default:
if (warn) {
if (isprint((unsigned char)c)) {
if (isprint(CAST(unsigned char, c))) {
/* Allow escaping of
* ``relations'' */
if (strchr("<>&^=!", c) == NULL
@ -2736,7 +2762,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
case '!':
/* and baskslash itself */
case '\\':
*p++ = (char) c;
*p++ = CAST(char, c);
break;
case 'a':
@ -2788,7 +2814,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
}
else
--s;
*p++ = (char)val;
*p++ = CAST(char, val);
break;
/* \x and up to 2 hex digits */
@ -2804,18 +2830,18 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
--s;
} else
--s;
*p++ = (char)val;
*p++ = CAST(char, val);
break;
}
} else
*p++ = (char)c;
*p++ = CAST(char, c);
}
--s;
out:
*p = '\0';
m->vallen = CAST(unsigned char, (p - origp));
if (m->type == FILE_PSTRING)
m->vallen += (unsigned char)file_pstring_length_size(m);
m->vallen += CAST(unsigned char, file_pstring_length_size(m));
return s;
}
@ -2824,9 +2850,9 @@ out:
private int
hextoint(int c)
{
if (!isascii((unsigned char) c))
if (!isascii(CAST(unsigned char, c)))
return -1;
if (isdigit((unsigned char) c))
if (isdigit(CAST(unsigned char, c)))
return c - '0';
if ((c >= 'a') && (c <= 'f'))
return c + 10 - 'a';
@ -2931,7 +2957,7 @@ apprentice_buf(struct magic_set *ms, struct magic *buf, size_t len)
{
struct magic_map *map;
if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) {
if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
file_oomem(ms, sizeof(*map));
return NULL;
}
@ -2979,7 +3005,7 @@ apprentice_map(struct magic_set *ms, const char *fn)
return to give apprentice_load() a chance. */
if (php_stream_stat_path_ex((char *)fn, 0, &st, NULL) == SUCCESS) {
if (st.sb.st_mode & S_IFDIR) {
return NULL;
goto error;
}
}
#endif
@ -2994,27 +3020,26 @@ apprentice_map(struct magic_set *ms, const char *fn)
goto error;
}
#ifndef PHP_WIN32
if (php_stream_stat(stream, &st) < 0) {
file_error(ms, errno, "cannot stat `%s'", dbname);
goto error;
}
if (st.sb.st_size < 8 || st.sb.st_size > MAXMAGIC_SIZE) {
#endif
if (st.sb.st_size < 8 || st.sb.st_size > maxoff_t()) {
file_error(ms, 0, "file `%s' is too %s", dbname,
st.sb.st_size < 8 ? "small" : "large");
goto error;
}
map->len = (size_t)st.sb.st_size;
if ((map->p = CAST(void *, emalloc(map->len))) == NULL) {
file_oomem(ms, map->len);
goto error;
}
map->type = MAP_TYPE_MALLOC;
map->len = CAST(size_t, st.sb.st_size);
map->p = CAST(void *, emalloc(map->len));
if (php_stream_read(stream, map->p, (size_t)st.sb.st_size) != (size_t)st.sb.st_size) {
file_badread(ms);
goto error;
}
map->len = 0;
#define RET 1
php_stream_close(stream);
stream = NULL;
@ -3122,7 +3147,7 @@ check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname)
VERSIONNO, dbname, version);
return -1;
}
entries = (uint32_t)(map->len / sizeof(struct magic));
entries = CAST(uint32_t, map->len / sizeof(struct magic));
if ((entries * sizeof(struct magic)) != map->len) {
file_error(ms, 0, "Size of `%s' %" SIZE_T_FORMAT "u is not "
"a multiple of %" SIZE_T_FORMAT "u",
@ -3239,7 +3264,7 @@ mkdbname(struct magic_set *ms, const char *fn, int strip)
q++;
/* Compatibility with old code that looked in .mime */
if (ms->flags & MAGIC_MIME) {
spprintf(&buf, MAXPATHLEN, "%.*s.mime%s", (int)(q - fn), fn, ext);
spprintf(&buf, MAXPATHLEN, "%.*s.mime%s", CAST(int, q - fn), fn, ext);
#ifdef PHP_WIN32
if (VCWD_ACCESS(buf, R_OK) == 0) {
#else
@ -3250,7 +3275,7 @@ mkdbname(struct magic_set *ms, const char *fn, int strip)
}
efree(buf);
}
spprintf(&buf, MAXPATHLEN, "%.*s%s", (int)(q - fn), fn, ext);
spprintf(&buf, MAXPATHLEN, "%.*s%s", CAST(int, q - fn), fn, ext);
/* Compatibility with old code that looked in .mime */
if (strstr(fn, ".mime") != NULL)
@ -3276,8 +3301,8 @@ private uint16_t
swap2(uint16_t sv)
{
uint16_t rv;
uint8_t *s = (uint8_t *)(void *)&sv;
uint8_t *d = (uint8_t *)(void *)&rv;
uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
d[0] = s[1];
d[1] = s[0];
return rv;
@ -3290,8 +3315,8 @@ private uint32_t
swap4(uint32_t sv)
{
uint32_t rv;
uint8_t *s = (uint8_t *)(void *)&sv;
uint8_t *d = (uint8_t *)(void *)&rv;
uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
@ -3306,8 +3331,8 @@ private uint64_t
swap8(uint64_t sv)
{
uint64_t rv;
uint8_t *s = (uint8_t *)(void *)&sv;
uint8_t *d = (uint8_t *)(void *)&rv;
uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
#if 0
d[0] = s[3];
d[1] = s[2];
@ -3337,9 +3362,9 @@ private void
bs1(struct magic *m)
{
m->cont_level = swap2(m->cont_level);
m->offset = swap4((int32_t)m->offset);
m->in_offset = swap4((uint32_t)m->in_offset);
m->lineno = swap4((uint32_t)m->lineno);
m->offset = swap4(CAST(uint32_t, m->offset));
m->in_offset = swap4(CAST(uint32_t, m->in_offset));
m->lineno = swap4(CAST(uint32_t, m->lineno));
if (IS_LIBMAGIC_STRING(m->type)) {
m->str_range = swap4(m->str_range);
m->str_flags = swap4(m->str_flags);
@ -3371,7 +3396,7 @@ protected size_t
file_pstring_get_length(const struct magic *m, const char *ss)
{
size_t len = 0;
const unsigned char *s = (const unsigned char *)ss;
const unsigned char *s = RCAST(const unsigned char *, ss);
unsigned int s3, s2, s1, s0;
switch (m->str_flags & PSTRING_LEN) {

View File

@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: apptype.c,v 1.13 2011/09/07 21:57:15 christos Exp $")
FILE_RCSID("@(#)$File: apptype.c,v 1.14 2018/09/09 20:33:28 christos Exp $")
#endif /* lint */
#include <stdlib.h>

View File

@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: ascmagic.c,v 1.98 2017/11/02 20:25:39 christos Exp $")
FILE_RCSID("@(#)$File: ascmagic.c,v 1.104 2019/05/07 02:27:11 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -80,7 +80,13 @@ file_ascmagic(struct magic_set *ms, const struct buffer *b, int text)
const char *type = NULL;
bb = *b;
bb.flen = trim_nuls(b->fbuf, b->flen);
bb.flen = trim_nuls(CAST(const unsigned char *, b->fbuf), b->flen);
/*
* Avoid trimming at an odd byte if the original buffer was evenly
* sized; this avoids losing the last character on UTF-16 LE text
*/
if ((bb.flen & 1) && !(b->flen & 1))
bb.flen++;
/* If file doesn't look like any sort of text, give up. */
if (file_encoding(ms, &bb, &ubuf, &ulen, &code, &code_mime,
@ -96,17 +102,18 @@ file_ascmagic(struct magic_set *ms, const struct buffer *b, int text)
}
protected int
file_ascmagic_with_encoding(struct magic_set *ms,
file_ascmagic_with_encoding(struct magic_set *ms,
const struct buffer *b, unichar *ubuf, size_t ulen, const char *code,
const char *type, int text)
{
struct buffer bb;
const unsigned char *buf = b->fbuf;
const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
size_t nbytes = b->flen;
unsigned char *utf8_buf = NULL, *utf8_end;
size_t mlen, i;
size_t mlen, i, len;
int rv = -1;
int mime = ms->flags & MAGIC_MIME;
int need_separator = 0;
const char *subtype = NULL;
const char *subtype_mime = NULL;
@ -121,7 +128,7 @@ file_ascmagic_with_encoding(struct magic_set *ms,
int n_nel = 0;
int executable = 0;
size_t last_line_end = (size_t)-1;
size_t last_line_end = CAST(size_t, -1);
int has_long_lines = 0;
nbytes = trim_nuls(buf, nbytes);
@ -144,12 +151,14 @@ file_ascmagic_with_encoding(struct magic_set *ms,
if ((utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen))
== NULL)
goto done;
buffer_init(&bb, b->fd, utf8_buf,
(size_t)(utf8_end - utf8_buf));
buffer_init(&bb, b->fd, &b->st, utf8_buf,
CAST(size_t, utf8_end - utf8_buf));
if ((rv = file_softmagic(ms, &bb, NULL, NULL,
TEXTTEST, text)) == 0)
rv = -1;
else
need_separator = 1;
buffer_fini(&bb);
if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))) {
rv = rv == -1 ? 0 : 1;
@ -200,8 +209,21 @@ file_ascmagic_with_encoding(struct magic_set *ms,
rv = 0;
goto done;
}
len = file_printedlen(ms);
if (mime) {
if (!file_printedlen(ms) && (mime & MAGIC_MIME_TYPE) != 0) {
if ((mime & MAGIC_MIME_TYPE) != 0) {
if (len) {
/*
* Softmagic printed something, we
* are either done, or we need a separator
*/
if ((ms->flags & MAGIC_CONTINUE) == 0) {
rv = 1;
goto done;
}
if (need_separator && file_separator(ms) == -1)
goto done;
}
if (subtype_mime) {
if (file_printf(ms, "%s", subtype_mime) == -1)
goto done;
@ -211,7 +233,7 @@ file_ascmagic_with_encoding(struct magic_set *ms,
}
}
} else {
if (file_printedlen(ms)) {
if (len) {
switch (file_replace(ms, " text$", ", ")) {
case 0:
switch (file_replace(ms, " text executable$",
@ -325,42 +347,42 @@ encode_utf8(unsigned char *buf, size_t len, unichar *ubuf, size_t ulen)
if (ubuf[i] <= 0x7f) {
if (end - buf < 1)
return NULL;
*buf++ = (unsigned char)ubuf[i];
*buf++ = CAST(unsigned char, ubuf[i]);
} else if (ubuf[i] <= 0x7ff) {
if (end - buf < 2)
return NULL;
*buf++ = (unsigned char)((ubuf[i] >> 6) + 0xc0);
*buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, (ubuf[i] >> 6) + 0xc0);
*buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
} else if (ubuf[i] <= 0xffff) {
if (end - buf < 3)
return NULL;
*buf++ = (unsigned char)((ubuf[i] >> 12) + 0xe0);
*buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
*buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, (ubuf[i] >> 12) + 0xe0);
*buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
} else if (ubuf[i] <= 0x1fffff) {
if (end - buf < 4)
return NULL;
*buf++ = (unsigned char)((ubuf[i] >> 18) + 0xf0);
*buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80);
*buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
*buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, (ubuf[i] >> 18) + 0xf0);
*buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
} else if (ubuf[i] <= 0x3ffffff) {
if (end - buf < 5)
return NULL;
*buf++ = (unsigned char)((ubuf[i] >> 24) + 0xf8);
*buf++ = (unsigned char)(((ubuf[i] >> 18) & 0x3f) + 0x80);
*buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80);
*buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
*buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, (ubuf[i] >> 24) + 0xf8);
*buf++ = CAST(unsigned char, ((ubuf[i] >> 18) & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
} else if (ubuf[i] <= 0x7fffffff) {
if (end - buf < 6)
return NULL;
*buf++ = (unsigned char)((ubuf[i] >> 30) + 0xfc);
*buf++ = (unsigned char)(((ubuf[i] >> 24) & 0x3f) + 0x80);
*buf++ = (unsigned char)(((ubuf[i] >> 18) & 0x3f) + 0x80);
*buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80);
*buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
*buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, (ubuf[i] >> 30) + 0xfc);
*buf++ = CAST(unsigned char, ((ubuf[i] >> 24) & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, ((ubuf[i] >> 18) & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80);
*buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
} else /* Invalid character */
return NULL;
}

View File

@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: buffer.c,v 1.4 2018/02/21 21:26:00 christos Exp $")
FILE_RCSID("@(#)$File: buffer.c,v 1.6 2019/05/07 02:27:11 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -41,10 +41,13 @@ FILE_RCSID("@(#)$File: buffer.c,v 1.4 2018/02/21 21:26:00 christos Exp $")
#include <sys/stat.h>
void
buffer_init(struct buffer *b, int fd, const void *data, size_t len)
buffer_init(struct buffer *b, int fd, const zend_stat_t *st, const void *data,
size_t len)
{
b->fd = fd;
if (b->fd == -1 || zend_fstat(b->fd, &b->st) == -1)
if (st)
memcpy(&b->st, st, sizeof(b->st));
else if (b->fd == -1 || zend_fstat(b->fd, &b->st) == -1)
memset(&b->st, 0, sizeof(b->st));
b->fbuf = data;
b->flen = len;
@ -56,7 +59,7 @@ buffer_init(struct buffer *b, int fd, const void *data, size_t len)
void
buffer_fini(struct buffer *b)
{
efree(b->ebuf);
efree(b->ebuf);
}
int
@ -65,13 +68,13 @@ buffer_fill(const struct buffer *bb)
struct buffer *b = CCAST(struct buffer *, bb);
if (b->elen != 0)
return b->elen == (size_t)~0 ? -1 : 0;
return b->elen == CAST(size_t, ~0) ? -1 : 0;
if (!S_ISREG(b->st.st_mode))
goto out;
b->elen = (size_t)b->st.st_size < b->flen ?
(size_t)b->st.st_size : b->flen;
b->elen = CAST(size_t, b->st.st_size) < b->flen ?
CAST(size_t, b->st.st_size) : b->flen;
if ((b->ebuf = emalloc(b->elen)) == NULL)
goto out;
@ -85,6 +88,6 @@ buffer_fill(const struct buffer *bb)
return 0;
out:
b->elen = (size_t)~0;
b->elen = CAST(size_t, ~0);
return -1;
}

View File

@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: cdf.c,v 1.110 2017/12/19 00:21:21 christos Exp $")
FILE_RCSID("@(#)$File: cdf.c,v 1.114 2019/02/20 02:35:27 christos Exp $")
#endif
#include <assert.h>
@ -57,9 +57,7 @@ FILE_RCSID("@(#)$File: cdf.c,v 1.110 2017/12/19 00:21:21 christos Exp $")
#include <string.h>
#include <time.h>
#include <ctype.h>
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifndef EFTYPE
#define EFTYPE EINVAL
@ -78,11 +76,14 @@ static union {
uint32_t u;
} cdf_bo;
#define NEED_SWAP (cdf_bo.u == (uint32_t)0x01020304)
#define NEED_SWAP (cdf_bo.u == CAST(uint32_t, 0x01020304))
#define CDF_TOLE8(x) ((uint64_t)(NEED_SWAP ? _cdf_tole8(x) : (uint64_t)(x)))
#define CDF_TOLE4(x) ((uint32_t)(NEED_SWAP ? _cdf_tole4(x) : (uint32_t)(x)))
#define CDF_TOLE2(x) ((uint16_t)(NEED_SWAP ? _cdf_tole2(x) : (uint16_t)(x)))
#define CDF_TOLE8(x) \
(CAST(uint64_t, NEED_SWAP ? _cdf_tole8(x) : CAST(uint64_t, x)))
#define CDF_TOLE4(x) \
(CAST(uint32_t, NEED_SWAP ? _cdf_tole4(x) : CAST(uint32_t, x)))
#define CDF_TOLE2(x) \
(CAST(uint16_t, NEED_SWAP ? _cdf_tole2(x) : CAST(uint16_t, x)))
#define CDF_TOLE(x) (/*CONSTCOND*/sizeof(x) == 2 ? \
CDF_TOLE2(CAST(uint16_t, x)) : \
(/*CONSTCOND*/sizeof(x) == 4 ? \
@ -101,8 +102,8 @@ static uint16_t
_cdf_tole2(uint16_t sv)
{
uint16_t rv;
uint8_t *s = (uint8_t *)(void *)&sv;
uint8_t *d = (uint8_t *)(void *)&rv;
uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
d[0] = s[1];
d[1] = s[0];
return rv;
@ -115,8 +116,8 @@ static uint32_t
_cdf_tole4(uint32_t sv)
{
uint32_t rv;
uint8_t *s = (uint8_t *)(void *)&sv;
uint8_t *d = (uint8_t *)(void *)&rv;
uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
@ -131,8 +132,8 @@ static uint64_t
_cdf_tole8(uint64_t sv)
{
uint64_t rv;
uint8_t *s = (uint8_t *)(void *)&sv;
uint8_t *d = (uint8_t *)(void *)&rv;
uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
d[0] = s[7];
d[1] = s[6];
d[2] = s[5];
@ -197,15 +198,17 @@ cdf_swap_header(cdf_header_t *h)
h->h_min_size_standard_stream =
CDF_TOLE4(h->h_min_size_standard_stream);
h->h_secid_first_sector_in_short_sat =
CDF_TOLE4((uint32_t)h->h_secid_first_sector_in_short_sat);
CDF_TOLE4(CAST(uint32_t, h->h_secid_first_sector_in_short_sat));
h->h_num_sectors_in_short_sat =
CDF_TOLE4(h->h_num_sectors_in_short_sat);
h->h_secid_first_sector_in_master_sat =
CDF_TOLE4((uint32_t)h->h_secid_first_sector_in_master_sat);
CDF_TOLE4(CAST(uint32_t, h->h_secid_first_sector_in_master_sat));
h->h_num_sectors_in_master_sat =
CDF_TOLE4(h->h_num_sectors_in_master_sat);
for (i = 0; i < __arraycount(h->h_master_sat); i++)
h->h_master_sat[i] = CDF_TOLE4((uint32_t)h->h_master_sat[i]);
for (i = 0; i < __arraycount(h->h_master_sat); i++) {
h->h_master_sat[i] =
CDF_TOLE4(CAST(uint32_t, h->h_master_sat[i]));
}
}
void
@ -238,15 +241,16 @@ void
cdf_swap_dir(cdf_directory_t *d)
{
d->d_namelen = CDF_TOLE2(d->d_namelen);
d->d_left_child = CDF_TOLE4((uint32_t)d->d_left_child);
d->d_right_child = CDF_TOLE4((uint32_t)d->d_right_child);
d->d_storage = CDF_TOLE4((uint32_t)d->d_storage);
d->d_left_child = CDF_TOLE4(CAST(uint32_t, d->d_left_child));
d->d_right_child = CDF_TOLE4(CAST(uint32_t, d->d_right_child));
d->d_storage = CDF_TOLE4(CAST(uint32_t, d->d_storage));
d->d_storage_uuid[0] = CDF_TOLE8(d->d_storage_uuid[0]);
d->d_storage_uuid[1] = CDF_TOLE8(d->d_storage_uuid[1]);
d->d_flags = CDF_TOLE4(d->d_flags);
d->d_created = CDF_TOLE8((uint64_t)d->d_created);
d->d_modified = CDF_TOLE8((uint64_t)d->d_modified);
d->d_stream_first_sector = CDF_TOLE4((uint32_t)d->d_stream_first_sector);
d->d_created = CDF_TOLE8(CAST(uint64_t, d->d_created));
d->d_modified = CDF_TOLE8(CAST(uint64_t, d->d_modified));
d->d_stream_first_sector = CDF_TOLE4(
CAST(uint32_t, d->d_stream_first_sector));
d->d_size = CDF_TOLE4(d->d_size);
}
@ -305,11 +309,11 @@ static int
cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h,
const void *p, size_t tail, int line)
{
const char *b = (const char *)sst->sst_tab;
const char *e = ((const char *)p) + tail;
const char *b = RCAST(const char *, sst->sst_tab);
const char *e = RCAST(const char *, p) + tail;
size_t ss = cdf_check_stream(sst, h);
/*LINTED*/(void)&line;
if (e >= b && (size_t)(e - b) <= ss * sst->sst_len)
if (e >= b && CAST(size_t, e - b) <= ss * sst->sst_len)
return 0;
DPRINTF(("%d: offset begin %p < end %p || %" SIZE_T_FORMAT "u"
" > %" SIZE_T_FORMAT "u [%" SIZE_T_FORMAT "u %"
@ -322,15 +326,14 @@ cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h,
static ssize_t
cdf_read(const cdf_info_t *info, zend_off_t off, void *buf, size_t len)
{
size_t siz = (size_t)off + len;
size_t siz = CAST(size_t, off + len);
if ((zend_off_t)(off + len) != (zend_off_t)siz) {
if (CAST(zend_off_t, off + len) != CAST(zend_off_t, siz))
goto out;
}
if (info->i_buf != NULL && info->i_len >= siz) {
(void)memcpy(buf, &info->i_buf[off], len);
return (ssize_t)len;
return CAST(ssize_t, len);
}
if (info->i_fd == -1)
@ -342,7 +345,7 @@ cdf_read(const cdf_info_t *info, zend_off_t off, void *buf, size_t len)
if (FINFO_READ_FUNC(info->i_fd, buf, len) != (ssize_t)len)
return -1;
return (ssize_t)len;
return CAST(ssize_t, len);
out:
errno = EINVAL;
return -1;
@ -354,7 +357,7 @@ cdf_read_header(const cdf_info_t *info, cdf_header_t *h)
char buf[512];
(void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
if (cdf_read(info, (zend_off_t)0, buf, sizeof(buf)) == -1)
if (cdf_read(info, CAST(zend_off_t, 0), buf, sizeof(buf)) == -1)
return -1;
cdf_unpack_header(h, buf);
cdf_swap_header(h);
@ -385,25 +388,27 @@ ssize_t
cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len,
const cdf_header_t *h, cdf_secid_t id)
{
size_t ss = CDF_SEC_SIZE(h);
size_t pos = CDF_SEC_POS(h, id);
assert(CDF_SEC_SIZE(h) == len);
return cdf_read(info, (zend_off_t)pos, ((char *)buf) + offs, len);
assert(ss == len);
return cdf_read(info, CAST(zend_off_t, pos), RCAST(char *, buf) + offs, len);
}
ssize_t
cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs,
size_t len, const cdf_header_t *h, cdf_secid_t id)
{
size_t ss = CDF_SHORT_SEC_SIZE(h);
size_t pos = CDF_SHORT_SEC_POS(h, id);
assert(CDF_SHORT_SEC_SIZE(h) == len);
assert(ss == len);
if (pos + len > CDF_SEC_SIZE(h) * sst->sst_len) {
DPRINTF(("Out of bounds read %" SIZE_T_FORMAT "u > %"
SIZE_T_FORMAT "u\n",
pos + len, CDF_SEC_SIZE(h) * sst->sst_len));
goto out;
}
(void)memcpy(((char *)buf) + offs,
((const char *)sst->sst_tab) + pos, len);
(void)memcpy(RCAST(char *, buf) + offs,
RCAST(const char *, sst->sst_tab) + pos, len);
return len;
out:
errno = EFTYPE;
@ -446,7 +451,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
if (h->h_master_sat[i] < 0)
break;
if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
h->h_master_sat[i]) != (ssize_t)ss) {
h->h_master_sat[i]) != CAST(ssize_t, ss)) {
DPRINTF(("Reading sector %d", h->h_master_sat[i]));
goto out1;
}
@ -463,27 +468,29 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
DPRINTF(("Reading master sector loop limit"));
goto out3;
}
if (cdf_read_sector(info, msa, 0, ss, h, mid) != (ssize_t)ss) {
if (cdf_read_sector(info, msa, 0, ss, h, mid) !=
CAST(ssize_t, ss)) {
DPRINTF(("Reading master sector %d", mid));
goto out2;
}
for (k = 0; k < nsatpersec; k++, i++) {
sec = CDF_TOLE4((uint32_t)msa[k]);
sec = CDF_TOLE4(CAST(uint32_t, msa[k]));
if (sec < 0)
goto out;
if (i >= sat->sat_len) {
DPRINTF(("Out of bounds reading MSA %" SIZE_T_FORMAT
"u >= %" SIZE_T_FORMAT "u", i, sat->sat_len));
DPRINTF(("Out of bounds reading MSA %"
SIZE_T_FORMAT "u >= %" SIZE_T_FORMAT "u",
i, sat->sat_len));
goto out3;
}
if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
sec) != (ssize_t)ss) {
sec) != CAST(ssize_t, ss)) {
DPRINTF(("Reading sector %d",
CDF_TOLE4(msa[k])));
goto out2;
}
}
mid = CDF_TOLE4((uint32_t)msa[nsatpersec]);
mid = CDF_TOLE4(CAST(uint32_t, msa[nsatpersec]));
}
out:
sat->sat_len = i;
@ -502,7 +509,7 @@ size_t
cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
{
size_t i, j;
cdf_secid_t maxsector = (cdf_secid_t)((sat->sat_len * size)
cdf_secid_t maxsector = CAST(cdf_secid_t, (sat->sat_len * size)
/ sizeof(maxsector));
DPRINTF(("Chain:"));
@ -522,7 +529,7 @@ cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
DPRINTF(("Sector %d >= %d\n", sid, maxsector));
goto out;
}
sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
}
if (i == 0) {
DPRINTF((" none, sid: %d\n", sid));
@ -533,7 +540,7 @@ cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
return i;
out:
errno = EFTYPE;
return (size_t)-1;
return CAST(size_t, -1);
}
int
@ -550,7 +557,7 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
if (sid == CDF_SECID_END_OF_CHAIN || len == 0)
return cdf_zero_stream(scn);
if (scn->sst_len == (size_t)-1)
if (scn->sst_len == CAST(size_t, -1))
goto out;
scn->sst_tab = CDF_CALLOC(scn->sst_len, ss);
@ -569,7 +576,7 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
goto out;
}
if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h,
sid)) != (ssize_t)ss) {
sid)) != CAST(ssize_t, ss)) {
if (i == scn->sst_len - 1 && nr > 0) {
/* Last sector might be truncated */
return 0;
@ -577,7 +584,7 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
DPRINTF(("Reading long sector chain %d", sid));
goto out;
}
sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
}
return 0;
out:
@ -596,7 +603,7 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
scn->sst_dirlen = len;
scn->sst_ss = ss;
if (scn->sst_len == (size_t)-1)
if (scn->sst_len == CAST(size_t, -1))
goto out;
scn->sst_tab = CDF_CALLOC(scn->sst_len, ss);
@ -615,11 +622,11 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
goto out;
}
if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h,
sid) != (ssize_t)ss) {
sid) != CAST(ssize_t, ss)) {
DPRINTF(("Reading short sector chain %d", sid));
goto out;
}
sid = CDF_TOLE4((uint32_t)ssat->sat_tab[sid]);
sid = CDF_TOLE4(CAST(uint32_t, ssat->sat_tab[sid]));
}
return 0;
out:
@ -650,7 +657,7 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
cdf_secid_t sid = h->h_secid_first_directory;
ns = cdf_count_chain(sat, sid, ss);
if (ns == (size_t)-1)
if (ns == CAST(size_t, -1))
return -1;
nd = ss / CDF_DIRECTORY_SIZE;
@ -671,7 +678,8 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
DPRINTF(("Read dir loop limit"));
goto out;
}
if (cdf_read_sector(info, buf, 0, ss, h, sid) != (ssize_t)ss) {
if (cdf_read_sector(info, buf, 0, ss, h, sid) !=
CAST(ssize_t, ss)) {
DPRINTF(("Reading directory sector %d", sid));
goto out;
}
@ -679,7 +687,7 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
cdf_unpack_dir(&dir->dir_tab[i * nd + j],
&buf[j * CDF_DIRECTORY_SIZE]);
}
sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
}
if (NEED_SWAP)
for (i = 0; i < dir->dir_len; i++)
@ -704,7 +712,7 @@ cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
ssat->sat_tab = NULL;
ssat->sat_len = cdf_count_chain(sat, sid, ss);
if (ssat->sat_len == (size_t)-1)
if (ssat->sat_len == CAST(size_t, -1))
goto out;
ssat->sat_tab = CAST(cdf_secid_t *, CDF_CALLOC(ssat->sat_len, ss));
@ -723,11 +731,11 @@ cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
goto out;
}
if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) !=
(ssize_t)ss) {
CAST(ssize_t, ss)) {
DPRINTF(("Reading short sat sector %d", sid));
goto out1;
}
sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
}
return 0;
out:
@ -777,7 +785,7 @@ cdf_namecmp(const char *d, const uint16_t *s, size_t l)
{
for (; l--; d++, s++)
if (*d != CDF_TOLE2(*s))
return (unsigned char)*d - CDF_TOLE2(*s);
return CAST(unsigned char, *d) - CDF_TOLE2(*s);
return 0;
}
@ -882,8 +890,8 @@ cdf_grow_info(cdf_property_info_t **info, size_t *maxcount, size_t incr)
size_t newcount = *maxcount + incr;
if (newcount > CDF_PROP_LIMIT) {
DPRINTF(("exceeded property limit %zu > %zu\n",
newcount, CDF_PROP_LIMIT));
DPRINTF(("exceeded property limit %" SIZE_T_FORMAT "u > %"
SIZE_T_FORMAT "u\n", newcount, CDF_PROP_LIMIT));
goto out;
}
inp = CAST(cdf_property_info_t *,
@ -908,7 +916,7 @@ cdf_copy_info(cdf_property_info_t *inp, const void *p, const void *e,
if (inp->pi_type & CDF_VECTOR)
return 0;
if ((size_t)(CAST(const char *, e) - CAST(const char *, p)) < len)
if (CAST(size_t, CAST(const char *, e) - CAST(const char *, p)) < len)
return 0;
(void)memcpy(&inp->pi_val, p, len);
@ -1051,10 +1059,10 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
inp[i].pi_str.s_buf = CAST(const char *,
CAST(const void *, &q[o4]));
DPRINTF(("o=%zu l=%d(%" SIZE_T_FORMAT
"u), t=%zu s=%s\n", o4, l,
CDF_ROUND(l, sizeof(l)), left,
inp[i].pi_str.s_buf));
DPRINTF(("o=%" SIZE_T_FORMAT "u l=%d(%"
SIZE_T_FORMAT "u), t=%" SIZE_T_FORMAT
"u s=%s\n", o4, l, CDF_ROUND(l, sizeof(l)),
left, inp[i].pi_str.s_buf));
if (l & 1)
l++;
@ -1094,8 +1102,9 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h,
const cdf_summary_info_header_t *si =
CAST(const cdf_summary_info_header_t *, sst->sst_tab);
const cdf_section_declaration_t *sd =
CAST(const cdf_section_declaration_t *, (const void *)
((const char *)sst->sst_tab + CDF_SECTION_DECLARATION_OFFSET));
CAST(const cdf_section_declaration_t *, RCAST(const void *,
RCAST(const char *, sst->sst_tab)
+ CDF_SECTION_DECLARATION_OFFSET));
if (cdf_check_stream_offset(sst, h, si, sizeof(*si), __LINE__) == -1 ||
cdf_check_stream_offset(sst, h, sd, sizeof(*sd), __LINE__) == -1)
@ -1246,28 +1255,28 @@ cdf_print_elapsed_time(char *buf, size_t bufsiz, cdf_timestamp_t ts)
int days, hours, mins, secs;
ts /= CDF_TIME_PREC;
secs = (int)(ts % 60);
secs = CAST(int, ts % 60);
ts /= 60;
mins = (int)(ts % 60);
mins = CAST(int, ts % 60);
ts /= 60;
hours = (int)(ts % 24);
hours = CAST(int, ts % 24);
ts /= 24;
days = (int)ts;
days = CAST(int, ts);
if (days) {
len += snprintf(buf + len, bufsiz - len, "%dd+", days);
if ((size_t)len >= bufsiz)
if (CAST(size_t, len) >= bufsiz)
return len;
}
if (days || hours) {
len += snprintf(buf + len, bufsiz - len, "%.2d:", hours);
if ((size_t)len >= bufsiz)
if (CAST(size_t, len) >= bufsiz)
return len;
}
len += snprintf(buf + len, bufsiz - len, "%.2d:", mins);
if ((size_t)len >= bufsiz)
if (CAST(size_t, len) >= bufsiz)
return len;
len += snprintf(buf + len, bufsiz - len, "%.2d", secs);
@ -1279,7 +1288,7 @@ cdf_u16tos8(char *buf, size_t len, const uint16_t *p)
{
size_t i;
for (i = 0; i < len && p[i]; i++)
buf[i] = (char)p[i];
buf[i] = CAST(char, p[i]);
buf[i] = '\0';
return buf;
}

View File

@ -76,9 +76,9 @@ typedef struct {
cdf_secid_t h_master_sat[436/4];
} cdf_header_t;
#define CDF_SEC_SIZE(h) ((size_t)(1 << (h)->h_sec_size_p2))
#define CDF_SEC_SIZE(h) CAST(size_t, 1 << (h)->h_sec_size_p2)
#define CDF_SEC_POS(h, secid) (CDF_SEC_SIZE(h) + (secid) * CDF_SEC_SIZE(h))
#define CDF_SHORT_SEC_SIZE(h) ((size_t)(1 << (h)->h_short_sec_size_p2))
#define CDF_SHORT_SEC_SIZE(h) CAST(size_t, 1 << (h)->h_short_sec_size_p2)
#define CDF_SHORT_SEC_POS(h, secid) ((secid) * CDF_SHORT_SEC_SIZE(h))
typedef int32_t cdf_dirid_t;

View File

@ -28,7 +28,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: cdf_time.c,v 1.16 2017/03/29 15:57:48 christos Exp $")
FILE_RCSID("@(#)$File: cdf_time.c,v 1.19 2019/03/12 20:43:05 christos Exp $")
#endif
#include <time.h>
@ -69,7 +69,7 @@ cdf_getday(int year, int days)
{
size_t m;
for (m = 0; m < sizeof(mdays) / sizeof(mdays[0]); m++) {
for (m = 0; m < __arraycount(mdays); m++) {
int sub = mdays[m] + (m == 1 && isleap(year));
if (days < sub)
return days;
@ -86,14 +86,14 @@ cdf_getmonth(int year, int days)
{
size_t m;
for (m = 0; m < sizeof(mdays) / sizeof(mdays[0]); m++) {
for (m = 0; m < __arraycount(mdays); m++) {
days -= mdays[m];
if (m == 1 && isleap(year))
days--;
if (days <= 0)
return (int)m;
return CAST(int, m);
}
return (int)m;
return CAST(int, m);
}
int
@ -109,22 +109,22 @@ cdf_timestamp_to_timespec(struct timespec *ts, cdf_timestamp_t t)
ts->tv_nsec = (t % CDF_TIME_PREC) * 100;
t /= CDF_TIME_PREC;
tm.tm_sec = (int)(t % 60);
tm.tm_sec = CAST(int, t % 60);
t /= 60;
tm.tm_min = (int)(t % 60);
tm.tm_min = CAST(int, t % 60);
t /= 60;
tm.tm_hour = (int)(t % 24);
tm.tm_hour = CAST(int, t % 24);
t /= 24;
/* XXX: Approx */
tm.tm_year = (int)(CDF_BASE_YEAR + (t / 365));
tm.tm_year = CAST(int, CDF_BASE_YEAR + (t / 365));
rdays = cdf_getdays(tm.tm_year);
t -= rdays - 1;
tm.tm_mday = cdf_getday(tm.tm_year, (int)t);
tm.tm_mon = cdf_getmonth(tm.tm_year, (int)t);
tm.tm_mday = cdf_getday(tm.tm_year, CAST(int, t));
tm.tm_mon = cdf_getmonth(tm.tm_year, CAST(int, t));
tm.tm_wday = 0;
tm.tm_yday = 0;
tm.tm_isdst = 0;
@ -173,7 +173,7 @@ cdf_ctime(const time_t *sec, char *buf)
if (ptr != NULL)
return buf;
(void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n",
(long long)*sec);
CAST(long long, *sec));
return buf;
}

View File

@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: compress.c,v 1.104 2017/03/29 15:57:48 christos Exp $")
FILE_RCSID("@(#)$File: compress.c,v 1.121 2019/05/07 02:27:11 christos Exp $")
#endif
#include "magic.h"
@ -67,6 +67,53 @@ typedef void (*sig_t)(int);
#undef FIONREAD
#if defined(PHP_FILEINFO_UNCOMPRESS)
#define BUILTIN_BZLIB
#include <bzlib.h>
#endif
#ifdef DEBUG
int tty = -1;
#define DPRINTF(...) do { \
if (tty == -1) \
tty = open("/dev/tty", O_RDWR); \
if (tty == -1) \
abort(); \
dprintf(tty, __VA_ARGS__); \
} while (/*CONSTCOND*/0)
#else
#define DPRINTF(...)
#endif
#ifdef ZLIBSUPPORT
/*
* The following python code is not really used because ZLIBSUPPORT is only
* defined if we have a built-in zlib, and the built-in zlib handles that.
* That is not true for android where we have zlib.h and not -lz.
*/
static const char zlibcode[] =
"import sys, zlib; sys.stdout.write(zlib.decompress(sys.stdin.read()))";
static const char *zlib_args[] = { "python", "-c", zlibcode, NULL };
static int
zlibcmp(const unsigned char *buf)
{
unsigned short x = 1;
unsigned char *s = CAST(unsigned char *, CAST(void *, &x));
if ((buf[0] & 0xf) != 8 || (buf[0] & 0x80) != 0)
return 0;
if (s[0] != 1) /* endianness test */
x = buf[0] | (buf[1] << 8);
else
x = buf[1] | (buf[0] << 8);
if (x % 31)
return 0;
return 1;
}
#endif
#define gzip_flags "-cd"
#define lrzip_flags "-do"
#define lzip_flags gzip_flags
@ -97,41 +144,45 @@ static const char *zstd_args[] = {
"zstd", "-cd", NULL
};
#define do_zlib NULL
#define do_bzlib NULL
private const struct {
const void *magic;
size_t maglen;
const char **argv;
void *unused;
} compr[] = {
{ "\037\235", 2, gzip_args }, /* compressed */
{ "\037\235", 2, gzip_args, NULL }, /* compressed */
/* Uncompress can get stuck; so use gzip first if we have it
* Idea from Damien Clark, thanks! */
{ "\037\235", 2, uncompress_args }, /* compressed */
{ "\037\213", 2, gzip_args }, /* gzipped */
{ "\037\236", 2, gzip_args }, /* frozen */
{ "\037\240", 2, gzip_args }, /* SCO LZH */
{ "\037\235", 2, uncompress_args, NULL }, /* compressed */
{ "\037\213", 2, gzip_args, do_zlib }, /* gzipped */
{ "\037\236", 2, gzip_args, NULL }, /* frozen */
{ "\037\240", 2, gzip_args, NULL }, /* SCO LZH */
/* the standard pack utilities do not accept standard input */
{ "\037\036", 2, gzip_args }, /* packed */
{ "PK\3\4", 4, gzip_args }, /* pkzipped, */
{ "\037\036", 2, gzip_args, NULL }, /* packed */
{ "PK\3\4", 4, gzip_args, NULL }, /* pkzipped, */
/* ...only first file examined */
{ "BZh", 3, bzip2_args }, /* bzip2-ed */
{ "LZIP", 4, lzip_args }, /* lzip-ed */
{ "\3757zXZ\0", 6, xz_args }, /* XZ Utils */
{ "LRZI", 4, lrzip_args }, /* LRZIP */
{ "\004\"M\030",4, lz4_args }, /* LZ4 */
{ "\x28\xB5\x2F\xFD", 4, zstd_args }, /* zstd */
{ "BZh", 3, bzip2_args, do_bzlib }, /* bzip2-ed */
{ "LZIP", 4, lzip_args, NULL }, /* lzip-ed */
{ "\3757zXZ\0", 6, xz_args, NULL }, /* XZ Utils */
{ "LRZI", 4, lrzip_args, NULL }, /* LRZIP */
{ "\004\"M\030",4, lz4_args, NULL }, /* LZ4 */
{ "\x28\xB5\x2F\xFD", 4, zstd_args, NULL }, /* zstd */
#ifdef ZLIBSUPPORT
{ RCAST(const void *, zlibcmp), 0, zlib_args }, /* zlib */
{ RCAST(const void *, zlibcmp), 0, zlib_args, NULL }, /* zlib */
#endif
};
#endif
#define OKDATA 0
#define NODATA 1
#define ERRDATA 2
private ssize_t swrite(int, const void *, size_t);
#ifdef PHP_FILEINFO_UNCOMPRESS
private size_t ncompr = sizeof(compr) / sizeof(compr[0]);
#if HAVE_FORK
private size_t ncompr = __arraycount(compr);
private int uncompressbuf(int, size_t, size_t, const unsigned char *,
unsigned char **, size_t *);
#ifdef BUILTIN_DECOMPRESS
@ -140,12 +191,33 @@ private int uncompresszlib(const unsigned char *, unsigned char **, size_t,
private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
size_t *);
#endif
#ifdef BUILTIN_BZLIB
private int uncompressbzlib(const unsigned char *, unsigned char **, size_t,
size_t *, int);
#endif
static int makeerror(unsigned char **, size_t *, const char *, ...);
private const char *methodname(size_t);
private int
format_decompression_error(struct magic_set *ms, size_t i, unsigned char *buf)
{
unsigned char *p;
int mime = ms->flags & MAGIC_MIME;
if (!mime)
return file_printf(ms, "ERROR:[%s: %s]", methodname(i), buf);
for (p = buf; *p; p++)
if (!isalnum(*p))
*p = '-';
return file_printf(ms, "application/x-decompression-error-%s-%s",
methodname(i), buf);
}
protected int
file_zmagic(struct magic_set *ms, int fd, const char *name,
const unsigned char *buf, size_t nbytes)
file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
{
unsigned char *newbuf = NULL;
size_t i, nsz;
@ -153,16 +225,15 @@ file_zmagic(struct magic_set *ms, int fd, const char *name,
file_pushbuf_t *pb;
int urv, prv, rv = 0;
int mime = ms->flags & MAGIC_MIME;
#ifdef HAVE_SIGNAL_H
sig_t osigpipe;
#endif
int fd = b->fd;
const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
size_t nbytes = b->flen;
int sa_saved = 0;
struct sigaction sig_act;
if ((ms->flags & MAGIC_COMPRESS) == 0)
return 0;
#ifdef HAVE_SIGNAL_H
osigpipe = signal(SIGPIPE, SIG_IGN);
#endif
for (i = 0; i < ncompr; i++) {
int zm;
if (nbytes < compr[i].maglen)
@ -177,20 +248,28 @@ file_zmagic(struct magic_set *ms, int fd, const char *name,
if (!zm)
continue;
/* Prevent SIGPIPE death if child dies unexpectedly */
if (!sa_saved) {
//We can use sig_act for both new and old, but
struct sigaction new_act;
memset(&new_act, 0, sizeof(new_act));
new_act.sa_handler = SIG_IGN;
sa_saved = sigaction(SIGPIPE, &new_act, &sig_act) != -1;
}
nsz = nbytes;
urv = uncompressbuf(fd, ms->bytes_max, i, buf, &newbuf, &nsz);
DPRINTF("uncompressbuf = %d, %s, %zu\n", urv, (char *)newbuf,
nsz);
DPRINTF("uncompressbuf = %d, %s, %" SIZE_T_FORMAT "u\n", urv,
(char *)newbuf, nsz);
switch (urv) {
case OKDATA:
case ERRDATA:
ms->flags &= ~MAGIC_COMPRESS;
if (urv == ERRDATA)
prv = file_printf(ms, "%s ERROR: %s",
methodname(i), newbuf);
prv = format_decompression_error(ms, i, newbuf);
else
prv = file_buffer(ms, -1, name, newbuf, nsz);
prv = file_buffer(ms, NULL, NULL, name, newbuf, nsz);
if (prv == -1)
goto error;
rv = 1;
@ -207,8 +286,11 @@ file_zmagic(struct magic_set *ms, int fd, const char *name,
* XXX: If file_buffer fails here, we overwrite
* the compressed text. FIXME.
*/
if (file_buffer(ms, -1, NULL, buf, nbytes) == -1)
if (file_buffer(ms, NULL, NULL, NULL, buf, nbytes) == -1) {
if (file_pop_buffer(ms, pb) != NULL)
abort();
goto error;
}
if ((rbuf = file_pop_buffer(ms, pb)) != NULL) {
if (file_printf(ms, "%s", rbuf) == -1) {
efree(rbuf);
@ -232,9 +314,9 @@ file_zmagic(struct magic_set *ms, int fd, const char *name,
out:
DPRINTF("rv = %d\n", rv);
#ifdef HAVE_SIGNAL_H
(void)signal(SIGPIPE, osigpipe);
#endif
if (sa_saved && sig_act.sa_handler != SIG_IGN)
(void)sigaction(SIGPIPE, &sig_act, NULL);
if (newbuf)
efree(newbuf);
ms->flags |= MAGIC_COMPRESS;
@ -311,7 +393,7 @@ sread(int fd, void *buf, size_t n, int canbepipe)
(void)ioctl(fd, FIONREAD, &t);
}
if (t > 0 && (size_t)t < n) {
if (t > 0 && CAST(size_t, t) < n) {
n = t;
rn = n;
}
@ -356,6 +438,7 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
{
int te;
tfd = mkstemp(buf);
(void)umask(ou);
te = errno;
(void)unlink(buf);
errno = te;
@ -367,11 +450,11 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
return -1;
}
if (swrite(tfd, startbuf, nbytes) != (ssize_t)nbytes)
if (swrite(tfd, startbuf, nbytes) != CAST(ssize_t, nbytes))
r = 1;
else {
while ((r = sread(fd, buf, sizeof(buf), 1)) > 0)
if (swrite(tfd, buf, (size_t)r) != r)
if (swrite(tfd, buf, CAST(size_t, r)) != r)
break;
}
@ -474,7 +557,7 @@ uncompresszlib(const unsigned char *old, unsigned char **newch,
if (rc != Z_OK && rc != Z_STREAM_END)
goto err;
*n = (size_t)z.total_out;
*n = CAST(size_t, z.total_out);
rc = inflateEnd(&z);
if (rc != Z_OK)
goto err;
@ -484,8 +567,8 @@ uncompresszlib(const unsigned char *old, unsigned char **newch,
return OKDATA;
err:
strlcpy((char *)*newch, z.msg ? z.msg : zError(rc), bytes_max);
*n = strlen((char *)*newch);
strlcpy(RCAST(char *, *newch), z.msg ? z.msg : zError(rc), bytes_max);
*n = strlen(RCAST(char *, *newch));
return ERRDATA;
}
#endif
@ -505,7 +588,7 @@ makeerror(unsigned char **buf, size_t *len, const char *fmt, ...)
*len = 0;
return NODATA;
}
*buf = (unsigned char *)msg;
*buf = RCAST(unsigned char *, msg);
*len = strlen(msg);
return ERRDATA;
}
@ -527,52 +610,42 @@ closep(int *fd)
closefd(fd, i);
}
static void
copydesc(int i, int *fd)
static int
copydesc(int i, int fd)
{
int j = fd[i == STDIN_FILENO ? 0 : 1];
if (j == i)
return;
if (dup2(j, i) == -1) {
DPRINTF("dup(%d, %d) failed (%s)\n", j, i, strerror(errno));
if (fd == i)
return 0; /* "no dup was necessary" */
if (dup2(fd, i) == -1) {
DPRINTF("dup(%d, %d) failed (%s)\n", fd, i, strerror(errno));
exit(1);
}
closep(fd);
return 1;
}
static void
writechild(int fdp[3][2], const void *old, size_t n)
static pid_t
writechild(int fd, const void *old, size_t n)
{
int status;
pid_t pid;
closefd(fdp[STDIN_FILENO], 0);
/*
* fork again, to avoid blocking because both
* pipes filled
*/
switch (fork()) {
case 0: /* child */
closefd(fdp[STDOUT_FILENO], 0);
if (swrite(fdp[STDIN_FILENO][1], old, n) != (ssize_t)n) {
pid = fork();
if (pid == -1) {
DPRINTF("Fork failed (%s)\n", strerror(errno));
exit(1);
}
if (pid == 0) {
/* child */
if (swrite(fd, old, n) != CAST(ssize_t, n)) {
DPRINTF("Write failed (%s)\n", strerror(errno));
exit(1);
}
exit(0);
/*NOTREACHED*/
case -1:
DPRINTF("Fork failed (%s)\n", strerror(errno));
exit(1);
/*NOTREACHED*/
default: /* parent */
if (wait(&status) == -1) {
DPRINTF("Wait failed (%s)\n", strerror(errno));
exit(1);
}
DPRINTF("Grandchild wait return %#x\n", status);
}
closefd(fdp[STDIN_FILENO], 1);
/* parent */
return pid;
}
static ssize_t
@ -582,17 +655,17 @@ filter_error(unsigned char *ubuf, ssize_t n)
char *buf;
ubuf[n] = '\0';
buf = (char *)ubuf;
while (isspace((unsigned char)*buf))
buf = RCAST(char *, ubuf);
while (isspace(CAST(unsigned char, *buf)))
buf++;
DPRINTF("Filter error[[[%s]]]\n", buf);
if ((p = strchr((char *)buf, '\n')) != NULL)
if ((p = strchr(CAST(char *, buf), '\n')) != NULL)
*p = '\0';
if ((p = strchr((char *)buf, ';')) != NULL)
if ((p = strchr(CAST(char *, buf), ';')) != NULL)
*p = '\0';
if ((p = strrchr((char *)buf, ':')) != NULL) {
if ((p = strrchr(CAST(char *, buf), ':')) != NULL) {
++p;
while (isspace((unsigned char)*p))
while (isspace(CAST(unsigned char, *p)))
p++;
n = strlen(p);
memmove(ubuf, p, CAST(size_t, n + 1));
@ -619,7 +692,9 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
unsigned char **newch, size_t* n)
{
int fdp[3][2];
int status, rv;
int status, rv, w;
pid_t pid;
pid_t writepid = -1;
size_t i;
ssize_t r;
@ -643,43 +718,68 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
return makeerror(newch, n, "Cannot create pipe, %s",
strerror(errno));
}
switch (fork()) {
case 0: /* child */
if (fd != -1) {
fdp[STDIN_FILENO][0] = fd;
(void) lseek(fd, (off_t)0, SEEK_SET);
}
for (i = 0; i < __arraycount(fdp); i++)
copydesc(CAST(int, i), fdp[i]);
/* For processes with large mapped virtual sizes, vfork
* may be _much_ faster (10-100 times) than fork.
*/
pid = vfork();
if (pid == -1) {
return makeerror(newch, n, "Cannot vfork, %s",
strerror(errno));
}
if (pid == 0) {
/* child */
/* Note: we are after vfork, do not modify memory
* in a way which confuses parent. In particular,
* do not modify fdp[i][j].
*/
if (fd != -1) {
(void) lseek(fd, CAST(off_t, 0), SEEK_SET);
if (copydesc(STDIN_FILENO, fd))
(void) close(fd);
} else {
if (copydesc(STDIN_FILENO, fdp[STDIN_FILENO][0]))
(void) close(fdp[STDIN_FILENO][0]);
if (fdp[STDIN_FILENO][1] > 2)
(void) close(fdp[STDIN_FILENO][1]);
}
///FIXME: if one of the fdp[i][j] is 0 or 1, this can bomb spectacularly
if (copydesc(STDOUT_FILENO, fdp[STDOUT_FILENO][1]))
(void) close(fdp[STDOUT_FILENO][1]);
if (fdp[STDOUT_FILENO][0] > 2)
(void) close(fdp[STDOUT_FILENO][0]);
if (copydesc(STDERR_FILENO, fdp[STDERR_FILENO][1]))
(void) close(fdp[STDERR_FILENO][1]);
if (fdp[STDERR_FILENO][0] > 2)
(void) close(fdp[STDERR_FILENO][0]);
(void)execvp(compr[method].argv[0],
(char *const *)(intptr_t)compr[method].argv);
RCAST(char *const *, RCAST(intptr_t, compr[method].argv)));
dprintf(STDERR_FILENO, "exec `%s' failed, %s",
compr[method].argv[0], strerror(errno));
exit(1);
/*NOTREACHED*/
case -1:
return makeerror(newch, n, "Cannot fork, %s",
_exit(1); /* _exit(), not exit(), because of vfork */
}
/* parent */
/* Close write sides of child stdout/err pipes */
for (i = 1; i < __arraycount(fdp); i++)
closefd(fdp[i], 1);
/* Write the buffer data to child stdin, if we don't have fd */
if (fd == -1) {
closefd(fdp[STDIN_FILENO], 0);
writepid = writechild(fdp[STDIN_FILENO][1], old, *n);
closefd(fdp[STDIN_FILENO], 1);
}
*newch = CAST(unsigned char *, malloc(bytes_max + 1));
if (*newch == NULL) {
rv = makeerror(newch, n, "No buffer, %s",
strerror(errno));
default: /* parent */
for (i = 1; i < __arraycount(fdp); i++)
closefd(fdp[i], 1);
/* Write the buffer data to the child, if we don't have fd */
if (fd == -1)
writechild(fdp, old, *n);
*newch = CAST(unsigned char *, emalloc(bytes_max + 1));
if (*newch == NULL) {
rv = makeerror(newch, n, "No buffer, %s",
strerror(errno));
goto err;
}
rv = OKDATA;
if ((r = sread(fdp[STDOUT_FILENO][0], *newch, bytes_max, 0)) > 0)
break;
goto err;
}
rv = OKDATA;
r = sread(fdp[STDOUT_FILENO][0], *newch, bytes_max, 0);
if (r <= 0) {
DPRINTF("Read stdout failed %d (%s)\n", fdp[STDOUT_FILENO][0],
r != -1 ? strerror(errno) : "no data");
@ -688,9 +788,9 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
(r = sread(fdp[STDERR_FILENO][0], *newch, bytes_max, 0)) > 0)
{
r = filter_error(*newch, r);
break;
goto ok;
}
efree(*newch);
free(*newch);
if (r == 0)
rv = makeerror(newch, n, "Read failed, %s",
strerror(errno));
@ -698,5 +798,40 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
rv = makeerror(newch, n, "No data");
goto err;
}
ok:
*n = r;
/* NUL terminate, as every buffer is handled here. */
(*newch)[*n] = '\0';
err:
closefd(fdp[STDIN_FILENO], 1);
closefd(fdp[STDOUT_FILENO], 0);
closefd(fdp[STDERR_FILENO], 0);
w = waitpid(pid, &status, 0);
wait_err:
if (w == -1) {
free(*newch);
rv = makeerror(newch, n, "Wait failed, %s", strerror(errno));
DPRINTF("Child wait return %#x\n", status);
} else if (!WIFEXITED(status)) {
DPRINTF("Child not exited (%#x)\n", status);
} else if (WEXITSTATUS(status) != 0) {
DPRINTF("Child exited (%#x)\n", WEXITSTATUS(status));
}
if (writepid > 0) {
/* _After_ we know decompressor has exited, our input writer
* definitely will exit now (at worst, writing fails in it,
* since output fd is closed now on the reading size).
*/
w = waitpid(writepid, &status, 0);
writepid = -1;
goto wait_err;
}
closefd(fdp[STDIN_FILENO], 0); //why? it is already closed here!
DPRINTF("Returning %p n=%" SIZE_T_FORMAT "u rv=%d\n", *newch, *n, rv);
return rv;
}
#endif /* if PHP_FILEINFO_UNCOMPRESS */
#endif
#endif

View File

@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: der.c,v 1.12 2017/02/10 18:14:01 christos Exp $")
FILE_RCSID("@(#)$File: der.c,v 1.16 2019/02/20 02:35:27 christos Exp $")
#endif
#endif
@ -58,7 +58,7 @@ FILE_RCSID("@(#)$File: der.c,v 1.12 2017/02/10 18:14:01 christos Exp $")
#include <err.h>
#endif
#define DER_BAD ((uint32_t)-1)
#define DER_BAD CAST(uint32_t, -1)
#define DER_CLASS_UNIVERSAL 0
#define DER_CLASS_APPLICATION 1
@ -201,7 +201,7 @@ getlength(const uint8_t *c, size_t *p, size_t l)
for (i = 0; i < digits; i++)
len = (len << 8) | c[(*p)++];
if (*p + len >= l)
if (len > UINT32_MAX - *p || *p + len >= l)
return DER_BAD;
return CAST(uint32_t, len);
}
@ -227,7 +227,7 @@ der_data(char *buf, size_t blen, uint32_t tag, const void *q, uint32_t len)
case DER_TAG_UTF8_STRING:
case DER_TAG_IA5_STRING:
case DER_TAG_UTCTIME:
return snprintf(buf, blen, "%.*s", len, (const char *)q);
return snprintf(buf, blen, "%.*s", len, RCAST(const char *, q));
default:
break;
}
@ -248,18 +248,21 @@ der_offs(struct magic_set *ms, struct magic *m, size_t nbytes)
if (gettag(b, &offs, len) == DER_BAD)
return -1;
DPRINTF(("%s1: %d %zu %u\n", __func__, ms->offset, offs, m->offset));
DPRINTF(("%s1: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset,
offs, m->offset));
uint32_t tlen = getlength(b, &offs, len);
if (tlen == DER_BAD)
return -1;
DPRINTF(("%s2: %d %zu %u\n", __func__, ms->offset, offs, tlen));
DPRINTF(("%s2: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset,
offs, tlen));
offs += ms->offset + m->offset;
DPRINTF(("cont_level = %d\n", m->cont_level));
#ifdef DEBUG_DER
for (size_t i = 0; i < m->cont_level; i++)
printf("cont_level[%zu] = %u\n", i, ms->c.li[i].off);
printf("cont_level[%" SIZE_T_FORMAT "u] = %u\n", i,
ms->c.li[i].off);
#endif
if (m->cont_level != 0) {
if (offs + tlen > nbytes)
@ -307,22 +310,23 @@ again:
s++;
goto val;
default:
if (!isdigit((unsigned char)*s))
if (!isdigit(CAST(unsigned char, *s)))
return 0;
slen = 0;
do
slen = slen * 10 + *s - '0';
while (isdigit((unsigned char)*++s));
while (isdigit(CAST(unsigned char, *++s)));
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "%s: len %zu %u\n", __func__,
slen, tlen);
fprintf(stderr, "%s: len %" SIZE_T_FORMAT "u %u\n",
__func__, slen, tlen);
if (tlen != slen)
return 0;
goto again;
}
val:
DPRINTF(("%s: before data %zu %u\n", __func__, offs, tlen));
DPRINTF(("%s: before data %" SIZE_T_FORMAT "u %u\n", __func__, offs,
tlen));
der_data(buf, sizeof(buf), tag, b + offs, tlen);
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "%s: data %s %s\n", __func__, buf, s);
@ -371,7 +375,8 @@ printdata(size_t level, const void *v, size_t x, size_t l)
break;
uint32_t len = getlength(p, &x, ep - p + x);
printf("%zu %zu-%zu %c,%c,%s,%u:", level, ox, x,
printf("%" SIZE_T_FORMAT "u %" SIZE_T_FORMAT "u-%"
SIZE_T_FORMAT "u %c,%c,%s,%u:", level, ox, x,
der_class[c], der_type[t],
der_tag(buf, sizeof(buf), tag), len);
q = p + x;

View File

@ -41,8 +41,8 @@
return toomany(ms, "program headers", phnum);
flags |= FLAGS_IS_CORE;
if (dophn_core(ms, clazz, swap, fd,
(zend_off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
(size_t)elf_getu16(swap, elfhdr.e_phentsize),
CAST(zend_off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)),
fsize, &flags, &notecount) == -1)
return -1;
break;
@ -56,8 +56,8 @@
if (shnum > ms->elf_shnum_max)
return toomany(ms, "section", shnum);
if (dophn_exec(ms, clazz, swap, fd,
(zend_off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
(size_t)elf_getu16(swap, elfhdr.e_phentsize),
CAST(zend_off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)),
fsize, shnum, &flags, &notecount) == -1)
return -1;
/*FALLTHROUGH*/
@ -66,10 +66,10 @@
if (shnum > ms->elf_shnum_max)
return toomany(ms, "section headers", shnum);
if (doshn(ms, clazz, swap, fd,
(zend_off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
(size_t)elf_getu16(swap, elfhdr.e_shentsize),
CAST(zend_off_t, elf_getu(swap, elfhdr.e_shoff)), shnum,
CAST(size_t, elf_getu16(swap, elfhdr.e_shentsize)),
fsize, elf_getu16(swap, elfhdr.e_machine),
(int)elf_getu16(swap, elfhdr.e_shstrndx),
CAST(int, elf_getu16(swap, elfhdr.e_shstrndx)),
&flags, &notecount) == -1)
return -1;
break;

View File

@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: encoding.c,v 1.14 2017/11/02 20:25:39 christos Exp $")
FILE_RCSID("@(#)$File: encoding.c,v 1.20 2019/04/15 16:48:41 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -49,6 +49,7 @@ private int looks_utf8_with_BOM(const unsigned char *, size_t, unichar *,
size_t *);
private int looks_utf7(const unsigned char *, size_t, unichar *, size_t *);
private int looks_ucs16(const unsigned char *, size_t, unichar *, size_t *);
private int looks_ucs32(const unsigned char *, size_t, unichar *, size_t *);
private int looks_latin1(const unsigned char *, size_t, unichar *, size_t *);
private int looks_extended(const unsigned char *, size_t, unichar *, size_t *);
private void from_ebcdic(const unsigned char *, size_t, unsigned char *);
@ -69,7 +70,7 @@ protected int
file_encoding(struct magic_set *ms, const struct buffer *b, unichar **ubuf,
size_t *ulen, const char **code, const char **code_mime, const char **type)
{
const unsigned char *buf = b->fbuf;
const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
size_t nbytes = b->flen;
size_t mlen;
int rv = 1, ucs_type;
@ -88,12 +89,13 @@ file_encoding(struct magic_set *ms, const struct buffer *b, unichar **ubuf,
*code_mime = "binary";
mlen = (nbytes + 1) * sizeof((*ubuf)[0]);
if ((*ubuf = CAST(unichar *, ecalloc((size_t)1, mlen))) == NULL) {
if ((*ubuf = CAST(unichar *, ecalloc(CAST(size_t, 1), mlen))) == NULL) {
file_oomem(ms, mlen);
goto done;
}
mlen = (nbytes + 1) * sizeof(nbuf[0]);
if ((nbuf = CAST(unsigned char *, ecalloc((size_t)1, mlen))) == NULL) {
if ((nbuf = CAST(unsigned char *,
ecalloc(CAST(size_t, 1), mlen))) == NULL) {
file_oomem(ms, mlen);
goto done;
}
@ -116,6 +118,15 @@ file_encoding(struct magic_set *ms, const struct buffer *b, unichar **ubuf,
DPRINTF(("utf8 %" SIZE_T_FORMAT "u\n", *ulen));
*code = "UTF-8 Unicode";
*code_mime = "utf-8";
} else if ((ucs_type = looks_ucs32(buf, nbytes, *ubuf, ulen)) != 0) {
if (ucs_type == 1) {
*code = "Little-endian UTF-32 Unicode";
*code_mime = "utf-32le";
} else {
*code = "Big-endian UTF-32 Unicode";
*code_mime = "utf-32be";
}
DPRINTF(("ucs32 %" SIZE_T_FORMAT "u\n", *ulen));
} else if ((ucs_type = looks_ucs16(buf, nbytes, *ubuf, ulen)) != 0) {
if (ucs_type == 1) {
*code = "Little-endian UTF-16 Unicode";
@ -410,7 +421,7 @@ looks_utf7(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
}
private int
looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf,
looks_ucs16(const unsigned char *bf, size_t nbytes, unichar *ubf,
size_t *ulen)
{
int bigend;
@ -419,9 +430,9 @@ looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf,
if (nbytes < 2)
return 0;
if (buf[0] == 0xff && buf[1] == 0xfe)
if (bf[0] == 0xff && bf[1] == 0xfe)
bigend = 0;
else if (buf[0] == 0xfe && buf[1] == 0xff)
else if (bf[0] == 0xfe && bf[1] == 0xff)
bigend = 1;
else
return 0;
@ -432,20 +443,64 @@ looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf,
/* XXX fix to properly handle chars > 65536 */
if (bigend)
ubuf[(*ulen)++] = buf[i + 1] + 256 * buf[i];
ubf[(*ulen)++] = bf[i + 1]
| (CAST(unichar, bf[i]) << 8);
else
ubuf[(*ulen)++] = buf[i] + 256 * buf[i + 1];
ubf[(*ulen)++] = bf[i]
| (CAST(unichar, bf[i + 1]) << 8);
if (ubuf[*ulen - 1] == 0xfffe)
if (ubf[*ulen - 1] == 0xfffe)
return 0;
if (ubuf[*ulen - 1] < 128 &&
text_chars[(size_t)ubuf[*ulen - 1]] != T)
if (ubf[*ulen - 1] < 128 &&
text_chars[CAST(size_t, ubf[*ulen - 1])] != T)
return 0;
}
return 1 + bigend;
}
private int
looks_ucs32(const unsigned char *bf, size_t nbytes, unichar *ubf,
size_t *ulen)
{
int bigend;
size_t i;
if (nbytes < 4)
return 0;
if (bf[0] == 0xff && bf[1] == 0xfe && bf[2] == 0 && bf[3] == 0)
bigend = 0;
else if (bf[0] == 0 && bf[1] == 0 && bf[2] == 0xfe && bf[3] == 0xff)
bigend = 1;
else
return 0;
*ulen = 0;
for (i = 4; i + 3 < nbytes; i += 4) {
/* XXX fix to properly handle chars > 65536 */
if (bigend)
ubf[(*ulen)++] = CAST(unichar, bf[i + 3])
| (CAST(unichar, bf[i + 2]) << 8)
| (CAST(unichar, bf[i + 1]) << 16)
| (CAST(unichar, bf[i]) << 24);
else
ubf[(*ulen)++] = CAST(unichar, bf[i + 0])
| (CAST(unichar, bf[i + 1]) << 8)
| (CAST(unichar, bf[i + 2]) << 16)
| (CAST(unichar, bf[i + 3]) << 24);
if (ubf[*ulen - 1] == 0xfffe)
return 0;
if (ubf[*ulen - 1] < 128 &&
text_chars[CAST(size_t, ubf[*ulen - 1])] != T)
return 0;
}
return 1 + bigend;
}
#undef F
#undef T
#undef I

View File

@ -27,7 +27,7 @@
*/
/*
* file.h - definitions for file(1) program
* @(#)$File: file.h,v 1.182 2017/04/07 19:46:44 christos Exp $
* @(#)$File: file.h,v 1.206 2019/05/07 02:27:11 christos Exp $
*/
#ifndef __file_h__
@ -56,6 +56,9 @@
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <stdint.h>
#endif
#ifdef HAVE_INTTYPES_H
@ -379,7 +382,7 @@ struct mlist {
#define CCAST(T, b) const_cast<T>(b)
#else
#define CAST(T, b) ((T)(b))
#define RCAST(T, b) ((T)(b))
#define RCAST(T, b) ((T)(uintptr_t)(b))
#define CCAST(T, b) ((T)(uintptr_t)(b))
#endif
@ -413,6 +416,7 @@ struct magic_set {
#define EVENT_HAD_ERR 0x01
const char *file;
size_t line; /* current magic line number */
mode_t mode; /* copy of current stat mode */
/* data for searches */
struct {
@ -448,10 +452,11 @@ typedef unsigned long unichar;
protected const char *file_fmttime(uint64_t, int, char *);
protected struct magic_set *file_ms_alloc(int);
protected void file_ms_free(struct magic_set *);
protected int file_buffer(struct magic_set *, php_stream *, const char *, const void *,
protected int file_buffer(struct magic_set *, php_stream *, zend_stat_t *, const char *, const void *,
size_t);
protected int file_fsmagic(struct magic_set *, const char *, zend_stat_t *, php_stream *);
protected int file_fsmagic(struct magic_set *, const char *, zend_stat_t *);
protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
protected int file_separator(struct magic_set *);
protected size_t file_printedlen(const struct magic_set *);
protected int file_replace(struct magic_set *, const char *, const char *);
protected int file_printf(struct magic_set *, const char *, ...);
@ -468,6 +473,7 @@ protected int file_ascmagic_with_encoding(struct magic_set *,
const struct buffer *, unichar *, size_t, const char *, const char *, int);
protected int file_encoding(struct magic_set *, const struct buffer *,
unichar **, size_t *, const char **, const char **, const char **);
protected int file_is_json(struct magic_set *, const struct buffer *);
protected int file_is_tar(struct magic_set *, const struct buffer *);
protected int file_softmagic(struct magic_set *, const struct buffer *,
uint16_t *, uint16_t *, int, int);
@ -492,13 +498,14 @@ protected int file_looks_utf8(const unsigned char *, size_t, unichar *,
size_t *);
protected size_t file_pstring_length_size(const struct magic *);
protected size_t file_pstring_get_length(const struct magic *, const char *);
protected char * file_printable(char *, size_t, const char *);
protected char * file_printable(char *, size_t, const char *, size_t);
#ifdef __EMX__
protected int file_os2_apptype(struct magic_set *, const char *, const void *,
size_t);
#endif /* __EMX__ */
protected void buffer_init(struct buffer *, int, const void *, size_t);
protected void buffer_init(struct buffer *, int, const zend_stat_t *,
const void *, size_t);
protected void buffer_fini(struct buffer *);
protected int buffer_fill(const struct buffer *);
@ -523,10 +530,6 @@ extern char *sys_errlist[];
(((e) >= 0 && (e) < sys_nerr) ? sys_errlist[(e)] : "Unknown error")
#endif
#ifndef HAVE_STRTOUL
#define strtoul(a, b, c) strtol(a, b, c)
#endif
#ifndef strlcpy
size_t strlcpy(char *, const char *, size_t);
#endif
@ -554,6 +557,9 @@ char *asctime_r(const struct tm *, char *);
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifndef O_NONBLOCK
#define O_NONBLOCK 0
#endif
#ifndef __cplusplus
#if defined(__GNUC__) && (__GNUC__ >= 3)

View File

@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: fsmagic.c,v 1.77 2017/05/24 19:17:50 christos Exp $")
FILE_RCSID("@(#)$File: fsmagic.c,v 1.80 2019/04/23 18:59:27 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -46,11 +46,14 @@ FILE_RCSID("@(#)$File: fsmagic.c,v 1.77 2017/05/24 19:17:50 christos Exp $")
# include <sys/mkdev.h>
# define HAVE_MAJOR
#endif
#ifdef MAJOR_IN_SYSMACROS
#ifdef HAVE_SYS_SYSMACROS_H
# include <sys/sysmacros.h>
#endif
#ifdef MAJOR_IN_SYSMACROS
# define HAVE_MAJOR
#endif
#ifdef major /* Might be defined in sys/types.h. */
#if defined(major) && !defined(HAVE_MAJOR)
/* Might be defined in sys/types.h. */
# define HAVE_MAJOR
#endif
#ifdef WIN32
@ -84,39 +87,27 @@ handle_mime(struct magic_set *ms, int mime, const char *str)
}
protected int
file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb, php_stream *stream)
file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb)
{
int ret, did = 0;
int mime = ms->flags & MAGIC_MIME;
int silent = ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION);
if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))
if (fn == NULL)
return 0;
if (fn == NULL && !stream) {
return 0;
}
#define COMMA (did++ ? ", " : "")
ret = php_sys_stat(fn, sb);
if (stream) {
php_stream_statbuf ssb;
if (php_stream_stat(stream, &ssb) < 0) {
if (ms->flags & MAGIC_ERROR) {
file_error(ms, errno, "cannot stat `%s'", fn);
return -1;
}
return 0;
}
memcpy(sb, &ssb.sb, sizeof(struct stat));
} else {
if (php_sys_stat(fn, sb) != 0) {
if (ms->flags & MAGIC_ERROR) {
file_error(ms, errno, "cannot stat `%s'", fn);
return -1;
}
return 0;
if (ret) {
if (ms->flags & MAGIC_ERROR) {
file_error(ms, errno, "cannot stat `%s'", fn);
return -1;
}
if (file_printf(ms, "cannot open `%s' (%s)",
fn, strerror(errno)) == -1)
return -1;
return 0;
}
ret = 1;
@ -183,6 +174,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb, php_stream *
if (mime) {
if (handle_mime(ms, mime, "fifo") == -1)
return -1;
} else if (silent) {
} else if (file_printf(ms, "%sfifo (named pipe)", COMMA) == -1)
return -1;
break;
@ -192,6 +184,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb, php_stream *
if (mime) {
if (handle_mime(ms, mime, "door") == -1)
return -1;
} else if (silent) {
} else if (file_printf(ms, "%sdoor", COMMA) == -1)
return -1;
break;

View File

@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: funcs.c,v 1.94 2017/11/02 20:25:39 christos Exp $")
FILE_RCSID("@(#)$File: funcs.c,v 1.104 2019/05/07 02:27:11 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -41,9 +41,7 @@ FILE_RCSID("@(#)$File: funcs.c,v 1.94 2017/11/02 20:25:39 christos Exp $")
#if defined(HAVE_WCTYPE_H)
#include <wctype.h>
#endif
#if defined(HAVE_LOCALE_H)
#include <locale.h>
#endif
#include <limits.h>
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)~0)
@ -157,36 +155,83 @@ file_badread(struct magic_set *ms)
file_error(ms, errno, "error reading");
}
protected int
file_separator(struct magic_set *ms)
{
return file_printf(ms, "\n- ");
}
static int
checkdone(struct magic_set *ms, int *rv)
{
if ((ms->flags & MAGIC_CONTINUE) == 0)
return 1;
if (file_printf(ms, "\n- ") == -1)
if (file_separator(ms) == -1)
*rv = -1;
return 0;
}
protected int
file_default(struct magic_set *ms, size_t nb)
{
if (ms->flags & MAGIC_MIME) {
if ((ms->flags & MAGIC_MIME_TYPE) &&
file_printf(ms, "application/%s",
nb ? "octet-stream" : "x-empty") == -1)
return -1;
return 1;
}
if (ms->flags & MAGIC_APPLE) {
if (file_printf(ms, "UNKNUNKN") == -1)
return -1;
return 1;
}
if (ms->flags & MAGIC_EXTENSION) {
if (file_printf(ms, "???") == -1)
return -1;
return 1;
}
return 0;
}
/*
* The magic detection functions return:
* 1: found
* 0: not found
* -1: error
*/
/*ARGSUSED*/
protected int
file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const void *buf,
size_t nb)
file_buffer(struct magic_set *ms, php_stream *stream, zend_stat_t *st,
const char *inname,
const void *buf, size_t nb)
{
int m = 0, rv = 0, looks_text = 0;
const char *code = NULL;
const char *code_mime = "binary";
const char *type = "application/octet-stream";
const char *def = "data";
const char *ftype = NULL;
char *rbuf = NULL;
struct buffer b;
int fd = -1;
buffer_init(&b, fd, buf, nb);
if (stream) {
#ifdef _WIN64
php_socket_t _fd = fd;
#else
int _fd;
#endif
int _ret = php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&_fd, 0);
if (SUCCESS == _ret) {
fd = (int)_fd;
}
}
buffer_init(&b, fd, st, buf, nb);
ms->mode = b.st.st_mode;
if (nb == 0) {
def = "empty";
type = "application/x-empty";
goto simple;
} else if (nb == 1) {
def = "very short file (no magic)";
@ -235,50 +280,64 @@ file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const
}
}
/* Check if we have a CDF file */
if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0 && stream) {
#ifdef _WIN64
php_socket_t _fd = fd;
int _ret = php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&_fd, 0);
fd = (int)_fd;
#else
int _ret = php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&fd, 0);
#endif
if (SUCCESS == _ret) {
m = file_trycdf(ms, &b);
if ((ms->flags & MAGIC_DEBUG) != 0)
(void)fprintf(stderr, "[try cdf %d]\n", m);
if (m) {
if (checkdone(ms, &rv))
goto done;
}
/* Check if we have a JSON file */
if ((ms->flags & MAGIC_NO_CHECK_JSON) == 0) {
m = file_is_json(ms, &b);
if ((ms->flags & MAGIC_DEBUG) != 0)
(void)fprintf(stderr, "[try json %d]\n", m);
if (m) {
if (checkdone(ms, &rv))
goto done;
}
}
/* Check if we have a CDF file */
if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) {
m = file_trycdf(ms, &b);
if ((ms->flags & MAGIC_DEBUG) != 0)
(void)fprintf(stderr, "[try cdf %d]\n", m);
if (m) {
if (checkdone(ms, &rv))
goto done;
}
}
#ifdef BUILTIN_ELF
if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && nb > 5 && fd != -1) {
file_pushbuf_t *pb;
/*
* We matched something in the file, so this
* *might* be an ELF file, and the file is at
* least 5 bytes long, so if it's an ELF file
* it has at least one byte past the ELF magic
* number - try extracting information from the
* ELF headers that cannot easily be extracted
* with rules in the magic file. We we don't
* print the information yet.
*/
if ((pb = file_push_buffer(ms)) == NULL)
return -1;
rv = file_tryelf(ms, &b);
rbuf = file_pop_buffer(ms, pb);
if (rv == -1) {
free(rbuf);
rbuf = NULL;
}
if ((ms->flags & MAGIC_DEBUG) != 0)
(void)fprintf(stderr, "[try elf %d]\n", m);
}
#endif
/* try soft magic tests */
if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) {
m = file_softmagic(ms, &b, NULL, NULL, BINTEST, looks_text);
if ((ms->flags & MAGIC_DEBUG) != 0)
(void)fprintf(stderr, "[try softmagic %d]\n", m);
if (m == 1 && rbuf) {
if (file_printf(ms, "%s", rbuf) == -1)
goto done;
}
if (m) {
#ifdef BUILTIN_ELF
if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 &&
nb > 5 && fd != -1) {
/*
* We matched something in the file, so this
* *might* be an ELF file, and the file is at
* least 5 bytes long, so if it's an ELF file
* it has at least one byte past the ELF magic
* number - try extracting information from the
* ELF headers that cannot easily * be
* extracted with rules in the magic file.
*/
m = file_tryelf(ms, &b);
if ((ms->flags & MAGIC_DEBUG) != 0)
(void)fprintf(stderr, "[try elf %d]\n",
m);
}
#endif
if (checkdone(ms, &rv))
goto done;
}
@ -291,27 +350,18 @@ file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const
if ((ms->flags & MAGIC_DEBUG) != 0)
(void)fprintf(stderr, "[try ascmagic %d]\n", m);
if (m) {
if (checkdone(ms, &rv))
goto done;
goto done;
}
}
simple:
/* give up */
m = 1;
if (ms->flags & MAGIC_MIME) {
if ((ms->flags & MAGIC_MIME_TYPE) &&
file_printf(ms, "%s", type) == -1)
rv = -1;
} else if (ms->flags & MAGIC_APPLE) {
if (file_printf(ms, "UNKNUNKN") == -1)
rv = -1;
} else if (ms->flags & MAGIC_EXTENSION) {
if (file_printf(ms, "???") == -1)
rv = -1;
} else {
if (file_printf(ms, "%s", def) == -1)
rv = -1;
if (m == 0) {
m = 1;
rv = file_default(ms, nb);
if (rv == 0)
if (file_printf(ms, "%s", def) == -1)
rv = -1;
}
done:
if ((ms->flags & MAGIC_MIME_ENCODING) != 0) {
@ -324,6 +374,7 @@ simple:
#if PHP_FILEINFO_UNCOMPRESS
done_encoding:
#endif
efree(rbuf);
buffer_fini(&b);
if (rv)
return rv;
@ -354,9 +405,9 @@ file_reset(struct magic_set *ms, int checkloaded)
#define OCTALIFY(n, o) \
/*LINTED*/ \
(void)(*(n)++ = '\\', \
*(n)++ = (((uint32_t)*(o) >> 6) & 3) + '0', \
*(n)++ = (((uint32_t)*(o) >> 3) & 7) + '0', \
*(n)++ = (((uint32_t)*(o) >> 0) & 7) + '0', \
*(n)++ = ((CAST(uint32_t, *(o)) >> 6) & 3) + '0', \
*(n)++ = ((CAST(uint32_t, *(o)) >> 3) & 7) + '0', \
*(n)++ = ((CAST(uint32_t, *(o)) >> 0) & 7) + '0', \
(o)++)
protected const char *
@ -402,9 +453,9 @@ file_getbuffer(struct magic_set *ms)
while (op < eop) {
bytesconsumed = mbrtowc(&nextchar, op,
(size_t)(eop - op), &state);
if (bytesconsumed == (size_t)(-1) ||
bytesconsumed == (size_t)(-2)) {
CAST(size_t, eop - op), &state);
if (bytesconsumed == CAST(size_t, -1) ||
bytesconsumed == CAST(size_t, -2)) {
mb_conv = 0;
break;
}
@ -427,7 +478,7 @@ file_getbuffer(struct magic_set *ms)
#endif
for (np = ms->o.pbuf, op = ms->o.buf; *op;) {
if (isprint((unsigned char)*op)) {
if (isprint(CAST(unsigned char, *op))) {
*np++ = *op++;
} else {
OCTALIFY(np, op);
@ -550,12 +601,13 @@ file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
* convert string to ascii printable format.
*/
protected char *
file_printable(char *buf, size_t bufsiz, const char *str)
file_printable(char *buf, size_t bufsiz, const char *str, size_t slen)
{
char *ptr, *eptr;
const unsigned char *s = (const unsigned char *)str;
char *ptr, *eptr = buf + bufsiz - 1;
const unsigned char *s = RCAST(const unsigned char *, str);
const unsigned char *es = s + slen;
for (ptr = buf, eptr = ptr + bufsiz - 1; ptr < eptr && *s; s++) {
for (ptr = buf; ptr < eptr && s < es && *s; s++) {
if (isprint(*s)) {
*ptr++ = *s;
continue;

View File

@ -0,0 +1,462 @@
/*-
* Copyright (c) 2018 Christos Zoulas
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Parse JSON object serialization format (RFC-7159)
*/
#ifndef TEST
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: is_json.c,v 1.13 2019/03/02 01:08:10 christos Exp $")
#endif
#include <string.h>
#include "magic.h"
#endif
#ifdef DEBUG
#include <stdio.h>
#define DPRINTF(a, b, c) \
printf("%s [%.2x/%c] %.20s\n", (a), *(b), *(b), (const char *)(c))
#else
#define DPRINTF(a, b, c) do { } while (/*CONSTCOND*/0)
#endif
#define JSON_ARRAY 0
#define JSON_CONSTANT 1
#define JSON_NUMBER 2
#define JSON_OBJECT 3
#define JSON_STRING 4
#define JSON_ARRAYN 5
#define JSON_MAX 6
/*
* if JSON_COUNT != 0:
* count all the objects, require that we have the whole data file
* otherwise:
* stop if we find an object or an array
*/
#ifndef JSON_COUNT
#define JSON_COUNT 0
#endif
static int json_parse(const unsigned char **, const unsigned char *, size_t *,
size_t);
static int
json_isspace(const unsigned char uc)
{
switch (uc) {
case ' ':
case '\n':
case '\r':
case '\t':
return 1;
default:
return 0;
}
}
static int
json_isdigit(unsigned char uc)
{
switch (uc) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return 1;
default:
return 0;
}
}
static int
json_isxdigit(unsigned char uc)
{
if (json_isdigit(uc))
return 1;
switch (uc) {
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
return 1;
default:
return 0;
}
}
static const unsigned char *
json_skip_space(const unsigned char *uc, const unsigned char *ue)
{
while (uc < ue && json_isspace(*uc))
uc++;
return uc;
}
static int
json_parse_string(const unsigned char **ucp, const unsigned char *ue)
{
const unsigned char *uc = *ucp;
size_t i;
DPRINTF("Parse string: ", uc, *ucp);
while (uc < ue) {
switch (*uc++) {
case '\0':
goto out;
case '\\':
if (uc == ue)
goto out;
switch (*uc++) {
case '\0':
goto out;
case '"':
case '\\':
case '/':
case 'b':
case 'f':
case 'n':
case 'r':
case 't':
continue;
case 'u':
if (ue - uc < 4) {
uc = ue;
goto out;
}
for (i = 0; i < 4; i++)
if (!json_isxdigit(*uc++))
goto out;
continue;
default:
goto out;
}
case '"':
*ucp = uc;
return 1;
default:
continue;
}
}
out:
DPRINTF("Bad string: ", uc, *ucp);
*ucp = uc;
return 0;
}
static int
json_parse_array(const unsigned char **ucp, const unsigned char *ue,
size_t *st, size_t lvl)
{
const unsigned char *uc = *ucp;
int more = 0; /* Array has more than 1 element */
DPRINTF("Parse array: ", uc, *ucp);
while (uc < ue) {
if (!json_parse(&uc, ue, st, lvl + 1))
goto out;
if (uc == ue)
goto out;
switch (*uc) {
case ',':
more++;
uc++;
continue;
case ']':
if (more)
st[JSON_ARRAYN]++;
*ucp = uc + 1;
return 1;
default:
goto out;
}
}
out:
DPRINTF("Bad array: ", uc, *ucp);
*ucp = uc;
return 0;
}
static int
json_parse_object(const unsigned char **ucp, const unsigned char *ue,
size_t *st, size_t lvl)
{
const unsigned char *uc = *ucp;
DPRINTF("Parse object: ", uc, *ucp);
while (uc < ue) {
uc = json_skip_space(uc, ue);
if (uc == ue)
goto out;
if (*uc++ != '"') {
DPRINTF("not string", uc, *ucp);
goto out;
}
DPRINTF("next field", uc, *ucp);
if (!json_parse_string(&uc, ue)) {
DPRINTF("not string", uc, *ucp);
goto out;
}
uc = json_skip_space(uc, ue);
if (uc == ue)
goto out;
if (*uc++ != ':') {
DPRINTF("not colon", uc, *ucp);
goto out;
}
if (!json_parse(&uc, ue, st, lvl + 1)) {
DPRINTF("not json", uc, *ucp);
goto out;
}
if (uc == ue)
goto out;
switch (*uc++) {
case ',':
continue;
case '}': /* { */
*ucp = uc;
DPRINTF("Good object: ", uc, *ucp);
return 1;
default:
*ucp = uc - 1;
DPRINTF("not more", uc, *ucp);
goto out;
}
}
out:
DPRINTF("Bad object: ", uc, *ucp);
*ucp = uc;
return 0;
}
static int
json_parse_number(const unsigned char **ucp, const unsigned char *ue)
{
const unsigned char *uc = *ucp;
int got = 0;
DPRINTF("Parse number: ", uc, *ucp);
if (uc == ue)
return 0;
if (*uc == '-')
uc++;
for (; uc < ue; uc++) {
if (!json_isdigit(*uc))
break;
got = 1;
}
if (uc == ue)
goto out;
if (*uc == '.')
uc++;
for (; uc < ue; uc++) {
if (!json_isdigit(*uc))
break;
got = 1;
}
if (uc == ue)
goto out;
if (got && (*uc == 'e' || *uc == 'E')) {
uc++;
got = 0;
if (uc == ue)
goto out;
if (*uc == '+' || *uc == '-')
uc++;
for (; uc < ue; uc++) {
if (!json_isdigit(*uc))
break;
got = 1;
}
}
out:
if (!got)
DPRINTF("Bad number: ", uc, *ucp);
else
DPRINTF("Good number: ", uc, *ucp);
*ucp = uc;
return got;
}
static int
json_parse_const(const unsigned char **ucp, const unsigned char *ue,
const char *str, size_t len)
{
const unsigned char *uc = *ucp;
DPRINTF("Parse const: ", uc, *ucp);
for (len--; uc < ue && --len;) {
if (*uc++ == *++str)
continue;
}
if (len)
DPRINTF("Bad const: ", uc, *ucp);
*ucp = uc;
return len == 0;
}
static int
json_parse(const unsigned char **ucp, const unsigned char *ue,
size_t *st, size_t lvl)
{
const unsigned char *uc;
int rv = 0;
int t;
uc = json_skip_space(*ucp, ue);
if (uc == ue)
goto out;
// Avoid recursion
if (lvl > 20)
return 0;
#if JSON_COUNT
/* bail quickly if not counting */
if (lvl > 1 && (st[JSON_OBJECT] || st[JSON_ARRAYN]))
return 1;
#endif
DPRINTF("Parse general: ", uc, *ucp);
switch (*uc++) {
case '"':
rv = json_parse_string(&uc, ue);
t = JSON_STRING;
break;
case '[':
rv = json_parse_array(&uc, ue, st, lvl + 1);
t = JSON_ARRAY;
break;
case '{': /* '}' */
rv = json_parse_object(&uc, ue, st, lvl + 1);
t = JSON_OBJECT;
break;
case 't':
rv = json_parse_const(&uc, ue, "true", sizeof("true"));
t = JSON_CONSTANT;
break;
case 'f':
rv = json_parse_const(&uc, ue, "false", sizeof("false"));
t = JSON_CONSTANT;
break;
case 'n':
rv = json_parse_const(&uc, ue, "null", sizeof("null"));
t = JSON_CONSTANT;
break;
default:
--uc;
rv = json_parse_number(&uc, ue);
t = JSON_NUMBER;
break;
}
if (rv)
st[t]++;
uc = json_skip_space(uc, ue);
out:
*ucp = uc;
DPRINTF("End general: ", uc, *ucp);
if (lvl == 0)
return rv && (st[JSON_ARRAYN] || st[JSON_OBJECT]);
return rv;
}
#ifndef TEST
int
file_is_json(struct magic_set *ms, const struct buffer *b)
{
const unsigned char *uc = CAST(const unsigned char *, b->fbuf);
const unsigned char *ue = uc + b->flen;
size_t st[JSON_MAX];
int mime = ms->flags & MAGIC_MIME;
if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) != 0)
return 0;
memset(st, 0, sizeof(st));
if (!json_parse(&uc, ue, st, 0))
return 0;
if (mime == MAGIC_MIME_ENCODING)
return 1;
if (mime) {
if (file_printf(ms, "application/json") == -1)
return -1;
return 1;
}
if (file_printf(ms, "JSON data") == -1)
return -1;
#if JSON_COUNT
#define P(n) st[n], st[n] > 1 ? "s" : ""
if (file_printf(ms, " (%" SIZE_T_FORMAT "u object%s, %" SIZE_T_FORMAT
"u array%s, %" SIZE_T_FORMAT "u string%s, %" SIZE_T_FORMAT
"u constant%s, %" SIZE_T_FORMAT "u number%s, %" SIZE_T_FORMAT
"u >1array%s)",
P(JSON_OBJECT), P(JSON_ARRAY), P(JSON_STRING), P(JSON_CONSTANT),
P(JSON_NUMBER), P(JSON_ARRAYN))
== -1)
return -1;
#endif
return 1;
}
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <err.h>
int
main(int argc, char *argv[])
{
int fd, rv;
struct stat st;
unsigned char *p;
size_t stats[JSON_MAX];
if ((fd = open(argv[1], O_RDONLY)) == -1)
err(EXIT_FAILURE, "Can't open `%s'", argv[1]);
if (fstat(fd, &st) == -1)
err(EXIT_FAILURE, "Can't stat `%s'", argv[1]);
if ((p = malloc(st.st_size)) == NULL)
err(EXIT_FAILURE, "Can't allocate %jd bytes",
(intmax_t)st.st_size);
if (read(fd, p, st.st_size) != st.st_size)
err(EXIT_FAILURE, "Can't read %jd bytes",
(intmax_t)st.st_size);
memset(stats, 0, sizeof(stats));
printf("is json %d\n", json_parse((const unsigned char **)&p,
p + st.st_size, stats, 0));
return 0;
}
#endif

View File

@ -40,7 +40,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: is_tar.c,v 1.41 2017/11/02 20:25:39 christos Exp $")
FILE_RCSID("@(#)$File: is_tar.c,v 1.44 2019/02/20 02:35:27 christos Exp $")
#endif
#include "magic.h"
@ -62,7 +62,7 @@ static const char tartype[][32] = { /* should be equal to messages */
protected int
file_is_tar(struct magic_set *ms, const struct buffer *b)
{
const unsigned char *buf = b->fbuf;
const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
size_t nbytes = b->flen;
/*
* Do the tar test first, because if the first file in the tar
@ -78,9 +78,13 @@ file_is_tar(struct magic_set *ms, const struct buffer *b)
if (tar < 1 || tar > 3)
return 0;
if (mime == MAGIC_MIME_ENCODING)
return 1;
if (file_printf(ms, "%s", mime ? "application/x-tar" :
tartype[tar - 1]) == -1)
return -1;
return 1;
}
@ -94,7 +98,8 @@ file_is_tar(struct magic_set *ms, const struct buffer *b)
private int
is_tar(const unsigned char *buf, size_t nbytes)
{
const union record *header = (const union record *)(const void *)buf;
const union record *header = RCAST(const union record *,
RCAST(const void *, buf));
size_t i;
int sum, recsum;
const unsigned char *p, *ep;
@ -143,7 +148,7 @@ from_oct(const char *where, size_t digs)
if (digs == 0)
return -1;
while (isspace((unsigned char)*where)) { /* Skip spaces */
while (isspace(CAST(unsigned char, *where))) { /* Skip spaces */
where++;
if (digs-- == 0)
return -1; /* All blank field */
@ -154,7 +159,7 @@ from_oct(const char *where, size_t digs)
digs--;
}
if (digs > 0 && *where && !isspace((unsigned char)*where))
if (digs > 0 && *where && !isspace(CAST(unsigned char, *where)))
return -1; /* Ended on non-(space/NUL) */
return value;

View File

@ -28,7 +28,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: magic.c,v 1.102 2017/08/28 13:39:18 christos Exp $")
FILE_RCSID("@(#)$File: magic.c,v 1.111 2019/05/07 02:27:11 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -45,7 +45,6 @@ FILE_RCSID("@(#)$File: magic.c,v 1.102 2017/08/28 13:39:18 christos Exp $")
#ifdef PHP_WIN32
#include <shlwapi.h>
#endif
#include <limits.h> /* for PIPE_BUF */
#if defined(HAVE_UTIMES)
@ -233,10 +232,6 @@ file_or_stream(struct magic_set *ms, const char *inname, php_stream *stream)
if (file_reset(ms, 1) == -1)
goto out;
if (!inname && !stream) {
return NULL;
}
/*
* one extra for terminating '\0', and
* some overlapping space for matches near EOF
@ -245,7 +240,7 @@ file_or_stream(struct magic_set *ms, const char *inname, php_stream *stream)
if ((buf = CAST(unsigned char *, emalloc(ms->bytes_max + SLOP))) == NULL)
return NULL;
switch (file_fsmagic(ms, inname, &sb, stream)) {
switch (file_fsmagic(ms, inname, &sb)) {
case -1: /* error */
goto done;
case 0: /* nothing found */
@ -257,21 +252,26 @@ file_or_stream(struct magic_set *ms, const char *inname, php_stream *stream)
errno = 0;
if (!stream && inname) {
if (inname && !stream) {
no_in_stream = 1;
stream = php_stream_open_wrapper((char *)inname, "rb", REPORT_ERRORS, NULL);
}
if (!stream) {
if (unreadable_info(ms, sb.st_mode, inname) == -1)
if (!stream) {
if (unreadable_info(ms, sb.st_mode, inname) == -1)
goto done;
rv = -1;
goto done;
rv = 0;
goto done;
}
}
#ifdef O_NONBLOCK
/* we should be already be in non blocking mode for network socket */
#endif
php_stream_statbuf ssb;
if (php_stream_stat(stream, &ssb) < 0) {
if (ms->flags & MAGIC_ERROR) {
file_error(ms, errno, "cannot stat `%s'", inname);
rv = -1;
goto done;
}
}
memcpy(&sb, &ssb.sb, sizeof(zend_stat_t));
/*
* try looking at the first ms->bytes_max bytes
@ -282,7 +282,7 @@ file_or_stream(struct magic_set *ms, const char *inname, php_stream *stream)
}
(void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
if (file_buffer(ms, stream, inname, buf, (size_t)nbytes) == -1)
if (file_buffer(ms, stream, &sb, inname, buf, CAST(size_t, nbytes)) == -1)
goto done;
rv = 0;
done:
@ -307,7 +307,7 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
* The main work is done here!
* We have the file name and/or the data buffer to be identified.
*/
if (file_buffer(ms, NULL, NULL, buf, nb) == -1) {
if (file_buffer(ms, NULL, NULL, NULL, buf, nb) == -1) {
return NULL;
}
return file_getbuffer(ms);
@ -360,27 +360,29 @@ magic_version(void)
public int
magic_setparam(struct magic_set *ms, int param, const void *val)
{
if (ms == NULL)
return -1;
switch (param) {
case MAGIC_PARAM_INDIR_MAX:
ms->indir_max = (uint16_t)*(const size_t *)val;
ms->indir_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0;
case MAGIC_PARAM_NAME_MAX:
ms->name_max = (uint16_t)*(const size_t *)val;
ms->name_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0;
case MAGIC_PARAM_ELF_PHNUM_MAX:
ms->elf_phnum_max = (uint16_t)*(const size_t *)val;
ms->elf_phnum_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0;
case MAGIC_PARAM_ELF_SHNUM_MAX:
ms->elf_shnum_max = (uint16_t)*(const size_t *)val;
ms->elf_shnum_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0;
case MAGIC_PARAM_ELF_NOTES_MAX:
ms->elf_notes_max = (uint16_t)*(const size_t *)val;
ms->elf_notes_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0;
case MAGIC_PARAM_REGEX_MAX:
ms->elf_notes_max = (uint16_t)*(const size_t *)val;
ms->regex_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0;
case MAGIC_PARAM_BYTES_MAX:
ms->bytes_max = *(const size_t *)val;
ms->bytes_max = *CAST(const size_t *, val);
return 0;
default:
errno = EINVAL;
@ -391,27 +393,29 @@ magic_setparam(struct magic_set *ms, int param, const void *val)
public int
magic_getparam(struct magic_set *ms, int param, void *val)
{
if (ms == NULL)
return -1;
switch (param) {
case MAGIC_PARAM_INDIR_MAX:
*(size_t *)val = ms->indir_max;
*CAST(size_t *, val) = ms->indir_max;
return 0;
case MAGIC_PARAM_NAME_MAX:
*(size_t *)val = ms->name_max;
*CAST(size_t *, val) = ms->name_max;
return 0;
case MAGIC_PARAM_ELF_PHNUM_MAX:
*(size_t *)val = ms->elf_phnum_max;
*CAST(size_t *, val) = ms->elf_phnum_max;
return 0;
case MAGIC_PARAM_ELF_SHNUM_MAX:
*(size_t *)val = ms->elf_shnum_max;
*CAST(size_t *, val) = ms->elf_shnum_max;
return 0;
case MAGIC_PARAM_ELF_NOTES_MAX:
*(size_t *)val = ms->elf_notes_max;
*CAST(size_t *, val) = ms->elf_notes_max;
return 0;
case MAGIC_PARAM_REGEX_MAX:
*(size_t *)val = ms->regex_max;
*CAST(size_t *, val) = ms->regex_max;
return 0;
case MAGIC_PARAM_BYTES_MAX:
*(size_t *)val = ms->bytes_max;
*CAST(size_t *, val) = ms->bytes_max;
return 0;
default:
errno = EINVAL;

View File

@ -58,6 +58,7 @@
#define MAGIC_NO_CHECK_CDF 0x0040000 /* Don't check for cdf files */
#define MAGIC_NO_CHECK_TOKENS 0x0100000 /* Don't check tokens */
#define MAGIC_NO_CHECK_ENCODING 0x0200000 /* Don't check text encodings */
#define MAGIC_NO_CHECK_JSON 0x0400000 /* Don't check for JSON files */
/* No built-in tests; only consult the magic file */
#define MAGIC_NO_CHECK_BUILTIN ( \
@ -70,6 +71,7 @@
MAGIC_NO_CHECK_CDF | \
MAGIC_NO_CHECK_TOKENS | \
MAGIC_NO_CHECK_ENCODING | \
MAGIC_NO_CHECK_JSON | \
0 \
)
@ -96,7 +98,7 @@ b\22no_check_cdf\0\
b\23no_check_reserved0\0\
b\24no_check_tokens\0\
b\25no_check_encoding\0\
b\26no_check_reserved1\0\
b\26no_check_json\0\
b\27no_check_reserved2\0\
b\30extension\0\
b\31transp_compression\0\
@ -109,7 +111,7 @@ b\31transp_compression\0\
#define MAGIC_NO_CHECK_FORTRAN 0x000000 /* Don't check ascii/fortran */
#define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */
#define MAGIC_VERSION 533 /* This implementation */
#define MAGIC_VERSION 537 /* This implementation */
#ifdef __cplusplus

View File

@ -1,11 +1,15 @@
#define FILE_VERSION_MAJOR 5
#define patchlevel 33
#define patchlevel 37
/*
* Patchlevel file for Ian Darwin's MAGIC command.
* $File: patchlevel.h,v 1.68 2008/03/22 21:39:43 christos Exp $
*
* $Log$
* Revision 2.1 2019/05/30 22:27:12 ab
* Update libmagic to 5.37
*
* $Log$
* Revision 2.1 2018/04/26 22:27:12 ab
* Update libmagic to 5.33
*

View File

@ -33,7 +33,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: print.c,v 1.82 2017/02/10 18:14:01 christos Exp $")
FILE_RCSID("@(#)$File: print.c,v 1.85 2019/03/12 20:43:05 christos Exp $")
#endif /* lint */
#include <string.h>
@ -66,9 +66,9 @@ file_mdump(struct magic *m)
if (m->in_op & FILE_OPINVERSE)
(void) fputc('~', stderr);
(void) fprintf(stderr, "%c%u),",
((size_t)(m->in_op & FILE_OPS_MASK) <
SZOF(optyp)) ? optyp[m->in_op & FILE_OPS_MASK] : '?',
m->in_offset);
(CAST(size_t, m->in_op & FILE_OPS_MASK) <
__arraycount(optyp)) ?
optyp[m->in_op & FILE_OPS_MASK] : '?', m->in_offset);
}
(void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "",
/* Note: type is unsigned */
@ -79,16 +79,16 @@ file_mdump(struct magic *m)
if (IS_LIBMAGIC_STRING(m->type)) {
if (m->str_flags) {
(void) fputc('/', stderr);
if (m->str_flags & STRING_COMPACT_WHITESPACE)
if (m->str_flags & STRING_COMPACT_WHITESPACE)
(void) fputc(CHAR_COMPACT_WHITESPACE, stderr);
if (m->str_flags & STRING_COMPACT_OPTIONAL_WHITESPACE)
if (m->str_flags & STRING_COMPACT_OPTIONAL_WHITESPACE)
(void) fputc(CHAR_COMPACT_OPTIONAL_WHITESPACE,
stderr);
if (m->str_flags & STRING_IGNORE_LOWERCASE)
if (m->str_flags & STRING_IGNORE_LOWERCASE)
(void) fputc(CHAR_IGNORE_LOWERCASE, stderr);
if (m->str_flags & STRING_IGNORE_UPPERCASE)
if (m->str_flags & STRING_IGNORE_UPPERCASE)
(void) fputc(CHAR_IGNORE_UPPERCASE, stderr);
if (m->str_flags & REGEX_OFFSET_START)
if (m->str_flags & REGEX_OFFSET_START)
(void) fputc(CHAR_REGEX_OFFSET_START, stderr);
if (m->str_flags & STRING_TEXTTEST)
(void) fputc(CHAR_TEXTTEST, stderr);
@ -113,14 +113,15 @@ file_mdump(struct magic *m)
(void) fprintf(stderr, "/%u", m->str_range);
}
else {
if ((size_t)(m->mask_op & FILE_OPS_MASK) < SZOF(optyp))
if (CAST(size_t, m->mask_op & FILE_OPS_MASK) <
__arraycount(optyp))
(void) fputc(optyp[m->mask_op & FILE_OPS_MASK], stderr);
else
(void) fputc('?', stderr);
if (m->num_mask) {
(void) fprintf(stderr, "%.8llx",
(unsigned long long)m->num_mask);
CAST(unsigned long long, m->num_mask));
}
}
(void) fprintf(stderr, ",%c", m->reln);
@ -142,7 +143,7 @@ file_mdump(struct magic *m)
case FILE_LEQUAD:
case FILE_QUAD:
(void) fprintf(stderr, "%" INT64_T_FORMAT "d",
(unsigned long long)m->value.q);
CAST(long long, m->value.q));
break;
case FILE_PSTRING:
case FILE_STRING:
@ -150,7 +151,8 @@ file_mdump(struct magic *m)
case FILE_BESTRING16:
case FILE_LESTRING16:
case FILE_SEARCH:
file_showstr(stderr, m->value.s, (size_t)m->vallen);
file_showstr(stderr, m->value.s,
CAST(size_t, m->vallen));
break;
case FILE_DATE:
case FILE_LEDATE:
@ -244,7 +246,7 @@ file_fmttime(uint64_t v, int flags, char *buf)
} else {
// XXX: perhaps detect and print something if overflow
// on 32 bit time_t?
t = (time_t)v;
t = CAST(time_t, v);
}
if (flags & FILE_T_LOCAL) {

View File

@ -26,7 +26,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: readcdf.c,v 1.66 2017/11/02 20:25:39 christos Exp $")
FILE_RCSID("@(#)$File: readcdf.c,v 1.73 2019/03/12 20:43:05 christos Exp $")
#endif
#include <assert.h>
@ -43,10 +43,6 @@ FILE_RCSID("@(#)$File: readcdf.c,v 1.66 2017/11/02 20:25:39 christos Exp $")
#include "cdf.h"
#include "magic.h"
#ifndef __arraycount
#define __arraycount(a) (sizeof(a) / sizeof(a[0]))
#endif
#define NOTMIME(ms) (((ms)->flags & MAGIC_MIME) == 0)
static const struct nv {
@ -131,13 +127,13 @@ private int
cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
size_t count, const cdf_directory_t *root_storage)
{
size_t i;
cdf_timestamp_t tp;
struct timespec ts;
char buf[64];
const char *str = NULL;
const char *s, *e;
int len;
size_t i;
cdf_timestamp_t tp;
struct timespec ts;
char buf[64];
const char *str = NULL;
const char *s, *e;
int len;
memset(&ts, 0, sizeof(ts));
@ -145,106 +141,106 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
str = cdf_clsid_to_mime(root_storage->d_storage_uuid,
clsid2mime);
for (i = 0; i < count; i++) {
cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
switch (info[i].pi_type) {
case CDF_NULL:
break;
case CDF_SIGNED16:
if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf,
info[i].pi_s16) == -1)
return -1;
break;
case CDF_SIGNED32:
if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf,
info[i].pi_s32) == -1)
return -1;
break;
case CDF_UNSIGNED32:
if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf,
info[i].pi_u32) == -1)
return -1;
break;
case CDF_FLOAT:
if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf,
info[i].pi_f) == -1)
return -1;
break;
case CDF_DOUBLE:
if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf,
info[i].pi_d) == -1)
return -1;
break;
case CDF_LENGTH32_STRING:
case CDF_LENGTH32_WSTRING:
len = info[i].pi_str.s_len;
if (len > 1) {
char vbuf[1024];
size_t j, k = 1;
for (i = 0; i < count; i++) {
cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
switch (info[i].pi_type) {
case CDF_NULL:
break;
case CDF_SIGNED16:
if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf,
info[i].pi_s16) == -1)
return -1;
break;
case CDF_SIGNED32:
if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf,
info[i].pi_s32) == -1)
return -1;
break;
case CDF_UNSIGNED32:
if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf,
info[i].pi_u32) == -1)
return -1;
break;
case CDF_FLOAT:
if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf,
info[i].pi_f) == -1)
return -1;
break;
case CDF_DOUBLE:
if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf,
info[i].pi_d) == -1)
return -1;
break;
case CDF_LENGTH32_STRING:
case CDF_LENGTH32_WSTRING:
len = info[i].pi_str.s_len;
if (len > 1) {
char vbuf[1024];
size_t j, k = 1;
if (info[i].pi_type == CDF_LENGTH32_WSTRING)
k++;
s = info[i].pi_str.s_buf;
if (info[i].pi_type == CDF_LENGTH32_WSTRING)
k++;
s = info[i].pi_str.s_buf;
e = info[i].pi_str.s_buf + len;
for (j = 0; s < e && j < sizeof(vbuf)
for (j = 0; s < e && j < sizeof(vbuf)
&& len--; s += k) {
if (*s == '\0')
break;
if (isprint((unsigned char)*s))
vbuf[j++] = *s;
}
if (j == sizeof(vbuf))
--j;
vbuf[j] = '\0';
if (NOTMIME(ms)) {
if (vbuf[0]) {
if (file_printf(ms, ", %s: %s",
buf, vbuf) == -1)
return -1;
}
} else if (str == NULL && info[i].pi_id ==
if (*s == '\0')
break;
if (isprint(CAST(unsigned char, *s)))
vbuf[j++] = *s;
}
if (j == sizeof(vbuf))
--j;
vbuf[j] = '\0';
if (NOTMIME(ms)) {
if (vbuf[0]) {
if (file_printf(ms, ", %s: %s",
buf, vbuf) == -1)
return -1;
}
} else if (str == NULL && info[i].pi_id ==
CDF_PROPERTY_NAME_OF_APPLICATION) {
str = cdf_app_to_mime(vbuf, app2mime);
}
}
break;
case CDF_FILETIME:
tp = info[i].pi_tp;
if (tp != 0) {
break;
case CDF_FILETIME:
tp = info[i].pi_tp;
if (tp != 0) {
char tbuf[64];
if (tp < 1000000000000000LL) {
cdf_print_elapsed_time(tbuf,
sizeof(tbuf), tp);
if (NOTMIME(ms) && file_printf(ms,
", %s: %s", buf, tbuf) == -1)
return -1;
} else {
char *c, *ec;
cdf_timestamp_to_timespec(&ts, tp);
c = cdf_ctime(&ts.tv_sec, tbuf);
if (c != NULL &&
if (tp < 1000000000000000LL) {
cdf_print_elapsed_time(tbuf,
sizeof(tbuf), tp);
if (NOTMIME(ms) && file_printf(ms,
", %s: %s", buf, tbuf) == -1)
return -1;
} else {
char *c, *ec;
cdf_timestamp_to_timespec(&ts, tp);
c = cdf_ctime(&ts.tv_sec, tbuf);
if (c != NULL &&
(ec = strchr(c, '\n')) != NULL)
*ec = '\0';
if (NOTMIME(ms) && file_printf(ms,
", %s: %s", buf, c) == -1)
return -1;
}
}
break;
case CDF_CLIPBOARD:
break;
default:
return -1;
}
}
if (!NOTMIME(ms)) {
if (NOTMIME(ms) && file_printf(ms,
", %s: %s", buf, c) == -1)
return -1;
}
}
break;
case CDF_CLIPBOARD:
break;
default:
return -1;
}
}
if (ms->flags & MAGIC_MIME_TYPE) {
if (str == NULL)
return 0;
if (file_printf(ms, "application/%s", str) == -1)
return -1;
}
return 1;
if (file_printf(ms, "application/%s", str) == -1)
return -1;
}
return 1;
}
private int
@ -256,7 +252,7 @@ cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h,
char buf[256];
cdf_catalog_entry_t *ce;
if (NOTMIME(ms)) {
if (NOTMIME(ms)) {
if (file_printf(ms, "Microsoft Thumbs.db [") == -1)
return -1;
if (cdf_unpack_catalog(h, sst, &cat) == -1)
@ -271,7 +267,7 @@ cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h,
return -1;
}
efree(cat);
} else {
} else if (ms->flags & MAGIC_MIME_TYPE) {
if (file_printf(ms, "application/CDFV2") == -1)
return -1;
}
@ -282,44 +278,44 @@ private int
cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
const cdf_stream_t *sst, const cdf_directory_t *root_storage)
{
cdf_summary_info_header_t si;
cdf_property_info_t *info;
size_t count;
int m;
cdf_summary_info_header_t si;
cdf_property_info_t *info;
size_t count;
int m;
if (cdf_unpack_summary_info(sst, h, &si, &info, &count) == -1)
return -1;
if (cdf_unpack_summary_info(sst, h, &si, &info, &count) == -1)
return -1;
if (NOTMIME(ms)) {
if (NOTMIME(ms)) {
const char *str;
if (file_printf(ms, "Composite Document File V2 Document")
if (file_printf(ms, "Composite Document File V2 Document")
== -1)
return -1;
return -1;
if (file_printf(ms, ", %s Endian",
si.si_byte_order == 0xfffe ? "Little" : "Big") == -1)
return -2;
switch (si.si_os) {
case 2:
if (file_printf(ms, ", Os: Windows, Version %d.%d",
si.si_os_version & 0xff,
(uint32_t)si.si_os_version >> 8) == -1)
return -2;
break;
case 1:
if (file_printf(ms, ", Os: MacOS, Version %d.%d",
(uint32_t)si.si_os_version >> 8,
si.si_os_version & 0xff) == -1)
return -2;
break;
default:
if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
si.si_os_version & 0xff,
(uint32_t)si.si_os_version >> 8) == -1)
return -2;
break;
}
if (file_printf(ms, ", %s Endian",
si.si_byte_order == 0xfffe ? "Little" : "Big") == -1)
return -2;
switch (si.si_os) {
case 2:
if (file_printf(ms, ", Os: Windows, Version %d.%d",
si.si_os_version & 0xff,
CAST(uint32_t, si.si_os_version) >> 8) == -1)
return -2;
break;
case 1:
if (file_printf(ms, ", Os: MacOS, Version %d.%d",
CAST(uint32_t, si.si_os_version) >> 8,
si.si_os_version & 0xff) == -1)
return -2;
break;
default:
if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
si.si_os_version & 0xff,
CAST(uint32_t, si.si_os_version) >> 8) == -1)
return -2;
break;
}
if (root_storage) {
str = cdf_clsid_to_mime(root_storage->d_storage_uuid,
clsid2desc);
@ -330,10 +326,10 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
}
}
m = cdf_file_property_info(ms, info, count, root_storage);
efree(info);
m = cdf_file_property_info(ms, info, count, root_storage);
efree(info);
return m == -1 ? -2 : m;
return m == -1 ? -2 : m;
}
#ifdef notdef
@ -381,10 +377,10 @@ cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info,
size_t j, k;
#ifdef CDF_DEBUG
cdf_dump_summary_info(h, scn);
cdf_dump_summary_info(h, scn);
#endif
if ((i = cdf_file_summary_info(ms, h, scn, root_storage)) < 0) {
*expn = "Can't expand summary_info";
if ((i = cdf_file_summary_info(ms, h, scn, root_storage)) < 0) {
*expn = "Can't expand summary_info";
return i;
}
if (i == 1)
@ -392,7 +388,7 @@ cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info,
for (j = 0; str == NULL && j < dir->dir_len; j++) {
d = &dir->dir_tab[j];
for (k = 0; k < sizeof(name); k++)
name[k] = (char)cdf_tole2(d->d_name[k]);
name[k] = CAST(char, cdf_tole2(d->d_name[k]));
str = cdf_app_to_mime(name,
NOTMIME(ms) ? name2desc : name2mime);
}
@ -402,7 +398,7 @@ cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info,
return -1;
i = 1;
}
} else {
} else if (ms->flags & MAGIC_MIME_TYPE) {
if (str == NULL)
str = "vnd.ms-office";
if (file_printf(ms, "application/%s", str) == -1)
@ -513,7 +509,7 @@ cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir)
if (NOTMIME(ms)) {
if (file_printf(ms, "CDFV2 %s", si->name) == -1)
return -1;
} else {
} else if (ms->flags & MAGIC_MIME_TYPE) {
if (file_printf(ms, "application/%s", si->mime) == -1)
return -1;
}
@ -526,57 +522,57 @@ protected int
file_trycdf(struct magic_set *ms, const struct buffer *b)
{
int fd = b->fd;
const unsigned char *buf = b->fbuf;
const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
size_t nbytes = b->flen;
cdf_info_t info;
cdf_header_t h;
cdf_sat_t sat, ssat;
cdf_stream_t sst, scn;
cdf_dir_t dir;
int i;
const char *expn = "";
const cdf_directory_t *root_storage;
cdf_info_t info;
cdf_header_t h;
cdf_sat_t sat, ssat;
cdf_stream_t sst, scn;
cdf_dir_t dir;
int i;
const char *expn = "";
const cdf_directory_t *root_storage;
scn.sst_tab = NULL;
info.i_fd = fd;
info.i_buf = buf;
info.i_len = nbytes;
if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))
return 0;
if (cdf_read_header(&info, &h) == -1)
return 0;
scn.sst_tab = NULL;
info.i_fd = fd;
info.i_buf = buf;
info.i_len = nbytes;
if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))
return 0;
if (cdf_read_header(&info, &h) == -1)
return 0;
#ifdef CDF_DEBUG
cdf_dump_header(&h);
cdf_dump_header(&h);
#endif
if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
expn = "Can't read SAT";
goto out0;
}
if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
expn = "Can't read SAT";
goto out0;
}
#ifdef CDF_DEBUG
cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
#endif
if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
expn = "Can't read SSAT";
goto out1;
}
if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
expn = "Can't read SSAT";
goto out1;
}
#ifdef CDF_DEBUG
cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
#endif
if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
expn = "Can't read directory";
goto out2;
}
if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
expn = "Can't read directory";
goto out2;
}
if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst,
if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst,
&root_storage)) == -1) {
expn = "Cannot read short stream";
goto out3;
}
expn = "Cannot read short stream";
goto out3;
}
#ifdef CDF_DEBUG
cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
#endif
#ifdef notdef
if (root_storage) {
@ -600,7 +596,7 @@ file_trycdf(struct magic_set *ms, const struct buffer *b)
if (file_printf(ms,
"Hangul (Korean) Word Processor File 5.x") == -1)
return -1;
} else {
} else if (ms->flags & MAGIC_MIME_TYPE) {
if (file_printf(ms, "application/x-hwp") == -1)
return -1;
}
@ -611,10 +607,10 @@ file_trycdf(struct magic_set *ms, const struct buffer *b)
}
}
if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
&scn)) == -1) {
if (errno != ESRCH) {
expn = "Cannot read summary info";
if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
&scn)) == -1) {
if (errno != ESRCH) {
expn = "Cannot read summary info";
}
} else {
i = cdf_check_summary_info(ms, &info, &h,
@ -647,19 +643,20 @@ out2:
out1:
efree(sat.sat_tab);
out0:
if (i == -1) {
if (NOTMIME(ms)) {
/* If we handled it already, return */
if (i != -1)
return i;
/* Provide a default handler */
if (NOTMIME(ms)) {
if (file_printf(ms,
"Composite Document File V2 Document") == -1)
return -1;
if (*expn)
if (file_printf(ms, ", %s", expn) == -1)
return -1;
} else {
if (*expn)
if (file_printf(ms, ", %s", expn) == -1)
return -1;
} else if (ms->flags & MAGIC_MIME_TYPE) {
if (file_printf(ms, "application/CDFV2") == -1)
return -1;
}
i = 1;
return -1;
}
return i;
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +1,7 @@
diff -u a/magic/Magdir/c-lang b/magic/Magdir/c-lang
--- a/magic/Magdir/c-lang 2017-08-14 09:40:38.000000000 +0200
+++ b/magic/Magdir/c-lang 2018-11-10 13:06:33.171398452 +0100
@@ -13,61 +13,61 @@
# C
# Check for class if include is found, otherwise class is beaten by include becouse of lowered strength
0 regex \^#include C
->0 regex \^class[[:space:]]+
+>0 regex/4096 \^class[[:space:]]+
>>&0 regex \\{[\.\*]\\}(;)?$ \b++
>&0 clear x source text
!:strength + 13
!:mime text/x-c
-0 regex \^#[[:space:]]*pragma C source text
+0 regex/4096 \^#[[:space:]]*pragma C source text
!:mime text/x-c
-0 regex \^#[[:space:]]*(if\|ifn)def
->&0 regex \^#[[:space:]]*endif$ C source text
+0 regex/4096 \^#[[:space:]]*(if\|ifn)def
+>&0 regex/4096 \^#[[:space:]]*endif$ C source text
!:mime text/x-c
-0 regex \^#[[:space:]]*(if\|ifn)def
->&0 regex \^#[[:space:]]*define C source text
+0 regex/4096 \^#[[:space:]]*(if\|ifn)def
+>&0 regex/4096 \^#[[:space:]]*define C source text
!:mime text/x-c
-0 regex \^[[:space:]]*char(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$ C source text
+0 regex/4096 \^[[:space:]]*char(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$ C source text
!:mime text/x-c
-0 regex \^[[:space:]]*double(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$ C source text
+0 regex/4096 \^[[:space:]]*double(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$ C source text
!:mime text/x-c
-0 regex \^[[:space:]]*extern[[:space:]]+ C source text
+0 regex/4096 \^[[:space:]]*extern[[:space:]]+ C source text
!:mime text/x-c
-0 regex \^[[:space:]]*float(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$ C source text
+0 regex/4096 \^[[:space:]]*float(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$ C source text
!:mime text/x-c
-0 regex \^struct[[:space:]]+ C source text
+0 regex/4096 \^struct[[:space:]]+ C source text
!:mime text/x-c
-0 regex \^union[[:space:]]+ C source text
+0 regex/4096 \^union[[:space:]]+ C source text
!:mime text/x-c
0 search/8192 main(
->&0 regex \\)[[:space:]]*\\{ C source text
+>&0 regex/4096 \\)[[:space:]]*\\{ C source text
!:mime text/x-c
# C++
# The strength of these rules is increased so they beat the C rules above
-0 regex \^namespace[[:space:]]+[_[:alpha:]]{1,30}[[:space:]]*\\{ C++ source text
+0 regex/4096 \^namespace[[:space:]]+[_[:alpha:]]{1,30}[[:space:]]*\\{ C++ source text
!:strength + 30
!:mime text/x-c++
# using namespace [namespace] or using std::[lib]
-0 regex \^using[[:space:]]+(namespace\ )?std(::)?[[:alpha:]]*[[:space:]]*; C++ source text
+0 regex/4096 \^using[[:space:]]+(namespace\ )?std(::)?[[:alpha:]]*[[:space:]]*; C++ source text
!:strength + 30
!:mime text/x-c++
-0 regex \^[[:space:]]*template[[:space:]]*<.*>[[:space:]]*$ C++ source text
+0 regex/4096 \^[[:space:]]*template[[:space:]]*<.*>[[:space:]]*$ C++ source text
!:strength + 30
!:mime text/x-c++
-0 regex \^[[:space:]]*virtual[[:space:]]+.*[};][[:space:]]*$ C++ source text
+0 regex/4096 \^[[:space:]]*virtual[[:space:]]+.*[};][[:space:]]*$ C++ source text
!:strength + 30
!:mime text/x-c++
# But class alone is reduced to avoid beating php (Jens Schleusener)
-0 regex \^[[:space:]]*class[[:space:]]+[[:digit:][:alpha:]:_]+[[:space:]]*\\{(.*[\n]*)*\\}(;)?$ C++ source text
+0 regex/4096 \^[[:space:]]*class[[:space:]]+[[:digit:][:alpha:]:_]+[[:space:]]*\\{(.*[\n]*)*\\}(;)?$ C++ source text
!:strength + 13
!:mime text/x-c++
-0 regex \^[[:space:]]*public: C++ source text
+0 regex/4096 \^[[:space:]]*public: C++ source text
!:strength + 30
!:mime text/x-c++
-0 regex \^[[:space:]]*private: C++ source text
+0 regex/4096 \^[[:space:]]*private: C++ source text
!:strength + 30
!:mime text/x-c++
-0 regex \^[[:space:]]*protected: C++ source text
+0 regex/4096 \^[[:space:]]*protected: C++ source text
!:strength + 30
!:mime text/x-c++
diff -u a/magic/Magdir/python b/magic/Magdir/python
--- a/magic/Magdir/python 2017-08-14 09:40:38.000000000 +0200
+++ b/magic/Magdir/python 2018-11-10 13:06:36.799268528 +0100
@@ -63,7 +63,7 @@
!:mime text/x-python
# import module [as abrev]
-0 regex \^import\ [_[:alpha:]]+\ as\ [[:alpha:]][[:space:]]*$ Python script text executable
+0 regex/4096 \^import\ [_[:alpha:]]+\ as\ [[:alpha:]][[:space:]]*$ Python script text executable
!:mime text/x-python
# comments
@@ -79,7 +79,7 @@
# except: or finally:
# block
0 search/4096 try:
->&0 regex \^[[:space:]]*except.*:$ Python script text executable
+>&0 regex/4096 \^[[:space:]]*except.*:$ Python script text executable
!:strength + 15
!:mime text/x-python
>&0 search/4096 finally: Python script text executable
@@ -91,7 +91,7 @@
!:mime text/x-python
# def name(*args, **kwargs):
-0 regex \^[[:space:]]{0,50}def\ {1,50}[_a-zA-Z]{1,100}
+0 regex/4096 \^[[:space:]]{0,50}def\ {1,50}[_a-zA-Z]{1,100}
>&0 regex \\(([[:alpha:]*_,\ ]){0,255}\\):$ Python script text executable
!:strength + 15
!:mime text/x-python
diff -u a/magic/Magdir/rpm b/magic/Magdir/rpm
--- a/magic/Magdir/rpm 2013-01-11 17:45:23.000000000 +0100
+++ b/magic/Magdir/rpm 2018-11-10 12:27:29.858619326 +0100
diff --git a/magic/Magdir/rpm b/magic/Magdir/rpm
index 9a795f8..31db083 100644
--- a/magic/Magdir/rpm
+++ b/magic/Magdir/rpm
@@ -29,6 +29,7 @@
>>8 beshort 17 SuperH
>>8 beshort 18 Xtensa
@ -125,53 +10,10 @@ diff -u a/magic/Magdir/rpm b/magic/Magdir/rpm
#delta RPM Daniel Novotny (dnovotny@redhat.com)
0 string drpm Delta RPM
diff -u a/magic/Magdir/ruby b/magic/Magdir/ruby
--- a/magic/Magdir/ruby 2017-08-14 15:39:18.000000000 +0200
+++ b/magic/Magdir/ruby 2018-11-10 13:06:28.703557761 +0100
@@ -22,30 +22,30 @@
# What looks like ruby, but does not have a shebang
# (modules and such)
# From: Lubomir Rintel <lkundrak@v3.sk>
-0 regex \^[[:space:]]*require[[:space:]]'[A-Za-z_/]+'
+0 regex/4096 \^[[:space:]]*require[[:space:]]'[A-Za-z_/]+'
>0 regex def\ [a-z]|\ do$
->>&0 regex \^[[:space:]]*end([[:space:]]+[;#].*)?$ Ruby script text
+>>&0 regex/4096 \^[[:space:]]*end([[:space:]]+[;#].*)?$ Ruby script text
!:strength + 30
!:mime text/x-ruby
-0 regex \^[[:space:]]*(class|module)[[:space:]][A-Z]
+0 regex/4096 \^[[:space:]]*(class|module)[[:space:]][A-Z]
>0 regex (modul|includ)e\ [A-Z]|def\ [a-z]
->>&0 regex \^[[:space:]]*end([[:space:]]+[;#].*)?$ Ruby script text
+>>&0 regex/4096 \^[[:space:]]*end([[:space:]]+[;#].*)?$ Ruby script text
!:strength + 30
!:mime text/x-ruby
# Classes with no modules or defs, beats simple ASCII
-0 regex \^[[:space:]]*(class|module)[[:space:]][A-Z]
->&0 regex \^[[:space:]]*end([[:space:]]+[;#if].*)?$ Ruby script text
+0 regex/4096 \^[[:space:]]*(class|module)[[:space:]][A-Z]
+>&0 regex/4096 \^[[:space:]]*end([[:space:]]+[;#if].*)?$ Ruby script text
!:strength + 10
!:mime text/x-ruby
# Looks for function definition to balance python magic
# def name (args)
# end
-0 regex \^[[:space:]]*def\ [a-z]|def\ [[:alpha:]]+::[a-z]
->&0 regex \^[[:space:]]*end([[:space:]]+[;#].*)?$ Ruby script text
+0 regex/4096 \^[[:space:]]*def\ [a-z]|def\ [[:alpha:]]+::[a-z]
+>&0 regex/4096 \^[[:space:]]*end([[:space:]]+[;#].*)?$ Ruby script text
!:strength + 10
!:mime text/x-ruby
-0 regex \^[[:space:]]*require[[:space:]]'[A-Za-z_/]+' Ruby script text
+0 regex/4096 \^[[:space:]]*require[[:space:]]'[A-Za-z_/]+' Ruby script text
!:mime text/x-ruby
-0 regex \^[[:space:]]*include\ ([A-Z]+[a-z]*(::))+ Ruby script text
+0 regex/4096 \^[[:space:]]*include\ ([A-Z]+[a-z]*(::))+ Ruby script text
!:mime text/x-ruby
diff -u a/magic/Magdir/securitycerts b/magic/Magdir/securitycerts
--- a/magic/Magdir/securitycerts 2009-09-19 18:28:12.000000000 +0200
+++ b/magic/Magdir/securitycerts 2018-11-10 12:27:29.858619326 +0100
diff --git a/magic/Magdir/securitycerts b/magic/Magdir/securitycerts
index 8785dd8..1c340be 100644
--- a/magic/Magdir/securitycerts
+++ b/magic/Magdir/securitycerts
@@ -4,3 +4,5 @@
0 search/1 -----BEGIN\ CERTIFICATE------ RFC1421 Security Certificate text
0 search/1 -----BEGIN\ NEW\ CERTIFICATE RFC1421 Security Certificate Signing Request text

View File

@ -26,8 +26,8 @@ var_dump( finfo_file( $finfo, $magicFile.chr(0).$magicFile) );
--EXPECTF--
*** Testing finfo_file() : basic functionality ***
string(28) "text/x-php; charset=us-ascii"
string(32) "PHP script, ASCII text\012- data"
string(40) "application/octet-stream; charset=binary"
string(%d) "PHP script, ASCII text%A"
string(32) "text/plain; charset=unknown-8bit"
Warning: finfo_file(): Invalid path in %s%efinfo_file_basic.php on line %d
bool(false)

View File

@ -25,5 +25,5 @@ var_dump( finfo_file( $finfo, $file, FILEINFO_CONTINUE ) );
--EXPECTF--
*** Testing finfo_file() : regex rules ***
string(28) "text/plain; charset=us-ascii"
string(%d) "awk%sscript, ASCII text\012- data"
string(%d) "awk%sscript, ASCII text%A"
===DONE===

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff